Introductory Programming in Python: Lesson 6
Flow Control: Conditionals

[Prev: Basic Input] [Course Outline] [Next: Flow Control: Conditional Loops]

The if Statement

Yet another thing our programs so far have not been able to do is change their behaviour based on certain conditions. More simply put, we want to be able to specify that our programs should execute one set of statements under certain conditions, and under other conditions those statements should be ignored. Now as always, we smart humans can come up with dozens of ways of specifying conditions;

Computers however are not so smart, and decidedly less flexible. In general a computer is aware of two, and only two, conditions: True and False. Now if your mind immediately leaps back to one of the five basic types of variables available in python, namely boolean, then congratulations, you're thinking like a programmer already!

In addition to computers only being aware of two conditions, programming languages generally have very few ways of determining what those conditions are and acting upon them. Python specifically has three methods, the most prevalent of which is the if statement. Put the following in a file called 'second.py':

x = raw_input("Enter a number: ")
if x > '3':
    print "You entered", x
    print "'x' is larger than 3"

Now run your program using python second.py and enter '2' when prompted.

sirlark@hephaestus ~/scratch $ python second.py 
Enter a number: 2

Hmmmm! Why didn't our print statements execute? If, as we believe, the program executes from top to bottom, the print statements should have been executed. Obviously, that if x > '3': is doing something we are unaware of, so let's experiment a little more. Run the program again, but this time enter '5' at the prompt.

sirlark@hephaestus ~/scratch $ python second.py 
Enter a number: 5
You entered 5
'x' is larger than 3

Okay! Our program just acted differently based on the input we gave it, or rather, based on the conditions determined by the input. Looking back at the last three lines of our program, there's a lot of new stuff in there that needs explanation, so we'll break it down. The if statement takes the format:

if <expression>:
    statement
    statement
    ...

What 'if' does, is check whether the expression provided has a value of True, and if so, the statement immediately following is executed, otherwise it is not executed. Now you might be thinking, how can a number be true or false? Well if we look carefully at our expression x > '3' we see that we have in fact made a logical proposition. We propose that the value of 'x' is greater than 3. The if statement checks whether the proposition, often also called a boolean expression (in reference to the type of its value), is true and acts accordingly. Propositions are simply specialised forms of expressions that have a value of either True or False.

'True' and 'False' are special words to python, known as reserved words, meaning they have been reserved for a particular purpose. Other reserved words we have encountered include 'print', and 'if'. The complete list of python's reserved words can be found here.

Note that when forming our proposition we used a specific operator, the greater than sign ('>'). When forming propositions we can use a specific set of operators, called comparison operators. If both 'a' and 'b' are expressions of any type:

Propositions, being expressions themselves, follow the usual rules for composition of expressions. This means that we can have an expression, (x > 3) == (y < 4), in which we have two propositions 'x > 3' and 'y < 4' which have been composed into the total expression. The entire proposition is true only if both the sub-propositions have the same truth value at the time the expression is evaluated.

Theoretically we could use arithmetic operators to compose propositions in the same way we do arithmetic expressions, as in (x == 3) + (y == 4). But in practice this doesn't work, as the arithmetic operators promote the truth values to integers, where True is 1 and False is 0. So what we actually get is

>>> x = 3
>>> y = 4
>>> (x == 3) + (y == 4)
2
>>>

Instead we must use logical operators, also known as boolean operators, to compose propositions. There are only three logical operators, listed below. If 'expr1' and 'expr2' are both propositions:

Using these logical operators we are now able to express very detailed and precise conditions to be checked by the if statement. Taking our previously expressed English examples:

We can now express them in python as follows

if weather == 'raining':
    pass #don't go out
if (num_traffic_lights_passed == 2) and (location_type == 'traffic lights'):
    pass #turn left

Hmmm, we still don't have a good way to express 'when', but we'll get there. In the meanwhile, note the statement pass. Pass is another reserved word in python, and means quite simply 'do nothing'. We need it because 'if statements' require a statement to execute if the expression they evaluate is True.

Pitfalls in Translation

We need to be aware of some common pitfalls that we will encounter when translating English language logic (forgive the oxymoron) into mathematical or computer logic. Examine the following examples:

Note that all expressions in python have a truth value. In general, any expression with a non-zero value is considered to be true. Specifically; 0, the empty string (''), None, and empty sequences or containers (we'll cover these later) are all considered False. Every other value for an expression is true. This actually means that expressions such as (x > 3) and (7) are valid as propositions, and in fact are often meaningful too, especially when checking for non-zero or non-empty variables. It does however mean that the wrong examples listed above are valid code but evaluate to something totally different from what we want.

Check out the python documentation page on boolean operators for more detailed information.

Executing Multiple Statements Conditionally

What 'if' does, is check whether the expression provided has a value of True, and if so, the statement immediately following is executed, otherwise it is not executed.

Examining what we said previously, we notice nasty phrases like 'the statement', indicating one, singular, statement. However, most of the time we actually want to execute a number of statements under certain conditions, and none of those statements if the aforementioned conditions are not met. Python, like most programming languages, provides us with the ability to group collections of statements into blocks, much like composition of expressions. Such blocks can be treated as a single statement for the purposes of if statements, and others we will encounter soon.

Unlike most other languages python allows us to specify blocks using indentation. Lines of code that have the same indentation are considered to be members of the same block. Blocks can also be nested inside one another, such lines constituting inner blocks are also members of their encompassing outer blocks. This is best illustrated using an example. (line numbers are not part of the code)

  1: #this program takes three numbers as input, and counts how many of
  2: #those numbers is even, and how many even numbers are negative
  3: #if an even number is entered, if it is negative, a message is printed
  4: 
  5: #set the counts for even and negative to 0
  6: even = 0
  7: negative = 0
  8: 
  9: #get the first number
 10: first = int(raw_input("Enter the first number: "))
 11: if first % 2 == 0:
 12:     print "The first number is even"
 13:     even = even + 1
 14:     if first < 0:
 15:         print "The first number is negative"
 16:         negative = negative + 1
 17: 
 18: #get the second number
 19: second = int(raw_input("Enter the second number: "))
 20: if second % 2 == 0:
 21:     print "The second number is even"
 22:     even = even + 1
 23:     if second < 0:
 24:         print "The second number is negative"
 25:         negative = negative + 1
 26: 
 27: #get the third number
 28: third = int(raw_input("Enter the third number: "))
 29: if third % 2 == 0:
 30:     print "The third number is even"
 31:     even = even + 1
 32:     if third < 0:
 33:         print "The third number is negative"
 34:         negative = negative + 1
 35: 
 36: print "There were", even, "even numbers and", negative, "negative numbers"

Running this program and giving the numbers 2, -4, and 7 as input produces

sirlark@hephaestus ~/scratch $ python illus.py 
Enter the first number: 2
The first number is even
Enter the second number: -4
The second number is even
The second number is negative
Enter the third number: 7
There were 2 even numbers and 1 negative numbers

Firstly, let's get the indentation and nesting thing out of the way. Looking at lines 12 through to 16 we see they are more indented than the if statement on line 11. Thus these lines form a block of statements. Since this block is immediately after an if statement, all the statements in the block will only be executed if the if statement's expression is True. For the first number we gave as input (2), this is the case, so we start executing the block. When we get to line 14 we encounter a second if statement. This second if statement is nested inside the first, because it will only be executed if the outer if statement (line 11) has an expression that evaluates to True. Lines 15 and 16 form a nested block, but are not executed because 2 is not negative, or more specifically because 2 is not less than 0. Conversely, lines 24 and 25 will be executed because -4 is less than 0.

Despite the fact that this example is an order of magnitude larger than any previous examples, there are only two new things. The first being indentation and nesting, the second being the use of int() around our raw_input functions. Remember that raw_input() returns a string. So even if the user types in 2, raw_input() returns not 2 but the string '2'. Strings and numbers don't really play nice together, especially when they're being compared to one another, so we need to convert the string into an integer. This is known as type casting or coercion. We can do it for any basic python type ...

>>> float("3.1415")
3.1415
>>> str(143)
'143'
>>> bool(None)
False
>>> bool(-1)
True
>>>

Specifying Execution Code for Alternate Conditions

So now we have a handle on basic if statements, we come up against the next hurdle. If our condition isn't met, our if block statements simply aren't executed. But what if we want something else executed instead of nothing when the condition isn't met. Enter the if ... else statement.

1: first = int(raw_input("Enter a number: "))
2: if first % 2 == 0:
3:     print first, "is even"
4: else:
5:     print first, "is odd"

Now, if 'first' is not even, the program will print a message saying it is odd, instead of doing nothing. The indentation is of key importance here again. Note that 'else' is at the same indentation level as the 'if' and is also followed by a colon (':'). The statement to be executed if 'first' is not even, on line 5, is known as the else clause, as the statement on line 3 is known as the if clause.

Finally we have to deal with the case where things are not as clear cut, not so black and white.

 1: colour = raw_input("Enter the name of a colour: ")
 2: if colour == "Red":
 3:     print "Red is a primary colour"
 4: elif colour == "Green":
 5:     print "Green is a primary colour"
 6: elif colour == "Blue":
 7:     print "Blue is a primary colour"
 8: else:
 9:     print colour, "is not a primary Colour"

Running this a couple of with various inputs we get

sirlark@hephaestus ~/scratch $ python illus.py 
Enter the name of a colour: Red
Red is a primary colour
sirlark@hephaestus ~/scratch $ python illus.py 
Enter the name of a colour: Green
Green is a primary colour
sirlark@hephaestus ~/scratch $ python illus.py 
Enter the name of a colour: blue
blue is not a primary Colour
sirlark@hephaestus ~/scratch $

The first run things happen as expected; We get to line 2, the value of colour is Red, the expression for the if statement is True, we execute line 3 ... and then the program finishes! This is because line 4 is not part of the block constituting line 2's if clause, because it has a lower indentation level. Also line's 4, 6 and 8 are all still part of the same if statement. Let's look at the second run a little more closely to see what happens.

We get to line 2, the value of colour is Green. Green is not equal to Red, so we don't execute line 3. Instead we jump to the else ... hang on! What is 'elif'? 'elif' is short for 'else if' and allows one to set up alternate conditions if earlier conditions haven't been met. So we get to the 'elif' on line 4. Green is Green so we execute line 5.

The third run illustrates nicely that in fact strings in python are case sensitive too. Not just the language, but the data we manipulate with it is considered case sensitive. 'Blue' and 'blue' are different strings.

Formal Summary

if <expression>:
    statement
    statement
    ...
[elif <expression>:
    statement
    statement
    ...]
[elif <expression>:
    statement
    statement
    ...]
[...]
[else:
    statement
    statement
    ...]

Exercises

  1. What is an example condition to check whether a number x is divisible by some other number y?
  2. Given the English phrase, "If you're not on the VIP list or the staff list, you can't come in.", write down an equivalent python condition.
  3. Is 1 == '1'? Why?
  4. Write a program that asks the user to enter two numbers. If the second number is not zero, print the quotient of the two numbers, otherwise print a message to the effect of not being able to divide by zero.
  5. Write a program that asks the user to enter 5 numbers, and prints the smallest number entered.
  6. Write a program that asks the user to enter 5 numbers, and prints the largest number entered.
  7. Write a program that asks the user to enter 5 numbers, and prints their average.
  8. Write a program that asks the user to enter a four digit year, and prints out whether that year is a leap year or not. Hint: Look up 'leap year' on Wikipedia for the definition of a leap year, and work from there.
  9. Write a program that asks the user for a phrase, and checks whether the first letter of the phrase is a capital letter. Tell the user their punctuation is bad if it isn't. Hint: you can use the 'in' operator on strings, e.g.
if c in 'acgt':
    print c, 'is a nucleotide base'
  1. Write a program that asks the user to enter 3 names, then outputs them sorted alphabetically.
  2. Write a program that asks the user to enter a number, then prints out all the numbers from 1 to 10 by which the entered number is divisible.
[Prev: Basic Input] [Course Outline] [Next: Flow Control: Conditional Loops]