Python Expressions¶
Read time: 31 minutes (7938 words)
See also
Text: Chapter 2, section 2.6, 2.7
We have played at a low level with a fair amount of Python, but it is time to get into details at a more complete level. Let’s start With a simple assignment statement, and move into expressions.
We have seen a basic assignment statement. It is formed by naming a container
to receive a value on the left hand side of an assignment operator
, which
is just the familiar equal sign (=
). What goes on the right hand side can
be a simple value (actually, it is called a literal value
because it is
literally
there), or it can be a more complex expression, something we
will get to in a bit.
Reading values from the user¶
It is common to put a value into a container another way. Very few useful programs can be written by just assigning values to containers then manipulating those containers. Instead, we want to let the user of the program decide what values we should use when the program is run.
Python has a simple statement that lets the user do just that. It looks like this:
x = input("Enter the price of the car: ")
This statement looks a bit like a simple assignment statement, but it involves
another of those funny function
things. This one, the input
function,
wants a string as a parameter. The string should be a message to the user
telling them what to enter. Whatever they type will be placed in the container
on the left.
There is a problem with this, will the user type in what you told them to
enter? Well, if your users are anything like those I have run into, the answer
is a big NO!. They will do whatever they like. Python deals with this by
accepting whatever they type in as a string
, even if that input is actually
a nice number. In order to put that string into a container we intend to use as
a number, we need to ask Python to convert
it for us. That is done by using
a special fnnction whose name is the type
of the number we want. In this
case, since we want to allow dollars and cents in the price, we will use the
float
function. (If we want to chop off the fractional part, we would use
the int
function).
price = input("enter the price of the car: ")
price = float(price)
Is there anything wrong with using the same variable twice in this code?
Actually, no. In the first line we get a string
from the user and save it in
a container named price
. In the second line, we retrieve that string, hand
it to the float
function and put whatever comes back into the same
container. Python lets this happen without complaining. Any container can hold
anything Python can set up. That is kind of nice when you are learning, but it
is also a source of problems if you are not careful.
It is up to you to know what is in a given container at any time. If you
forget, you can ask Python to tell you by using the type
function.
>>> price = input("Enter the price of the car: ")
Enter the price of the car: 10000.00
>>> print (type(price))
<class 'str'>
>>> price = float(price)
>>> print(type(price))
<class 'float'>
Wow, did you see that? I put a function call inside another function call. Perhaps we need to study this a bit more.
Dealing with problems¶
In the above example, we assumed that the user actually typed in a good number. What happens if they do something funny?
>>> price = input("Enter the price of the car: ")
Enter the price of the car: 123,456.78
>>> price = float(price)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '123,456.78'
This response is called an exception
, meaning that Python cannot figure out
what to do. That simple comma, something we humans might do automatically, is a
problem here! For the present, we will assume that users do what we ask them to
do (not a good idea in real life). We will see what we can do about this kind
of problem later on.
Expressions¶
An expression is just a series of Python components that consist of numbers, math operators and variables we set up to hold interesting data. Where expressions can go in a program is kind of interesting. The answer is basically simple. An expression can go any place Python wants to obtain a single value that it can use for some purpose. If we put an expression in that spot, Python will stop what it is doing and evaluate the expression to reduce it to a value it can use.
As we saw in the last example above, this can get pretty interesting. The
print
function wants a single parameter to print. Instead, we gave
it the name of a function to activate first, so it stopped and asked that
function to do its job and give us back a value to print. The second function
needed a parameter, so we gave it the name of a variable. When the second
function got done, the value it handed back was the thing finally printer. In
this case, it was a funny looking string. Phew!
A more normal expression¶
Here is a common example:
a = 5
b = 6
c = a + b
The first two lines are simple assignments
of a value to a variable. The last
line has an expression in it. The expression is the thing on the right-hand
side of the assignment operator (the equal sign). The expression is a simple
mathematical addition of two terms
. In this example the terms are just the
names of variables we created above this expression. Python will look into the
containers it set up to hold values when we defined the variables and pull out
the current value stored there. (Remember that those containers are called
variables for a reason. That value might change as the program runs!)
Once both terms have been looked up, the math plus operator (+
) tells
Python to add the two terms producing a single result that is the sum of the
two values. That final value is placed in the container named c
. Simple
enough.
Expressions can get more complex and involve more operators. For now, let’s concentrate on the big four:
+
- addition-
- subtraction*
- multiplication/
- division//
- integer division (no fraction!)
That last one is odd in that we might not want to produce a result with a
fraction. We control this by picking the right operator
.
Operator precedence¶
There is something about the way computers evaluate expressions that catches
beginners off guard. Each operator has a precedence
which is a fancy term
for importance in an expression. We always do the important operations first,
then the less important after that according to the precedence rules. This is
not so bad, but you must remember it to make sure you do the right math!
In our big four (OK five) the precedence rules are these:
Multiply and division have identical precedence and have the highest precedence (importance)
addition and subtraction are equal, and lower in precedence
So how do we evaluate something like this:
d = a + 2 * b
A typical beginner would do the addition first, then the multiply. It is common to work from left to right, since that is the way we read (here at least). However, the multiply operator has a higher precedence so it should happen first. Plugging in the current values from our code above this is what python would do:
d = 5 + 2 * 6
d = 5 + 12
d = 17
Using parentheses to force things¶
Suppose we really wanted Python to add two to the current value of a
, then
do the multiplication. How can we make that happen?
Here is how:
d = (a + 2) * b
Now the rules are a bit different. We always evaluate everything inside paremtheses before applying any precedence rules for operators outside those parentheses. If we have multiple operators inside the parentheses, the normal rules apply as we evaluate the sub-expression, just like before. Phew.
We can have multiple levels of parentheses. When you do this, you get into
trouble fast. It is a common mistake to have unbalanced
parentheses. There
must be as many open parentheses marks as close parentheses marks, and they
must not overlap wrongly.
What do you thing this will do?
>>> a = (5 * ( 3 + ( 7 / 2 + 6) * 2)
...
OK, that was a test. Now evaluate this:
>>> a = (5 * ( 3 + ( 7 / 2 + 6) * 2))
>>> print(a)
110.0
Did you figure it out, or did you just let Python do the thinking?
Other operators¶
Python has a few other operators you can use.
The exponential operator¶
Suppose you want to raise some number to a power
. You can use the **
operator
>>> print(3 ** 2)
9
Hmmm:
print(9 ** 0.5)
3.0
Smart cookie, that Python interpreter!
The remainder operator¶
Sometimes it is handy to figure out the remainder after division, where we are doing integer division.
>>> print( 7/2 )
3.5
>>> print( 7 // 2)
3
>>> print(7 % 3)
1
That %
operator is called the modulus
operator (or just mod
). Most
languages have this one.
When would this be useful? A common situation is printing out a bunch of text
and wanting to cause some additional lines to be skipped when the page gets
full. The %
operator will produce a zero result when the division has no
remainder. So, if we wanted to do something every 77 lines, we might do this:
if (num_lines % 77) == 0:
# print extra stuff
Note
We will get into logical expressions
soon
Another example is converting time in seconds to hours, minutes and seconds (see the book for examples of this).