.. _python-expressions: Python Expressions ################## .. wordcount:: .. vim:ft=rst spell: .. seealso:: 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: .. code-block:: python 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). .. code-block:: python 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. .. code-block:: text >>> price = input("Enter the price of the car: ") Enter the price of the car: 10000.00 >>> print (type(price)) >>> price = float(price) >>> print(type(price)) 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? .. code-block:: python >>> 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 "", line 1, in 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: .. code-block:: python 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: .. code-block:: python 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: .. code-block:: python 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: .. code-block:: python 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? .. code-block:: python >>> a = (5 * ( 3 + ( 7 / 2 + 6) * 2) ... OK, that was a test. Now evaluate this: .. code-block:: python >>> 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 .. code-block:: python >>> print(3 ** 2) 9 Hmmm: .. code-block:: python 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. .. code-block:: python >>> 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: .. code-block:: python 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).