On this page

Decisions

Every program so far has done the same thing each time it ran: every line, top to bottom. This module lets a program look at a value and choose what to do, so that some lines run only some of the time.

Before this, you can: give a value a name and change it; work out an expression by hand; print a value to see it.

By the end you will be able to say whether a comparison is True or False, say which lines of a program will run for a given value, and turn a rule written in words into code and test it at its edges.

Questions with yes-or-no answers

3 + 4 works out to a number. A comparison works out to one of two special values, True or False:

age = 16
print(age > 12)
print(age > 16)
print(age >= 16)
True
False
True

16 is not greater than 16, so the second line is False. It is greater than or equal to 16, so the third is True. Most mistakes with comparisons happen exactly there, at the value on the boundary.

Written Asks
a > b is a greater than b?
a < b is a less than b?
a >= b is a greater than or equal to b?
a <= b is a less than or equal to b?
a == b are they equal?
a != b are they different?

Text can be compared for equality too, and every character counts, including capitals:

print("go" == "go")
print("go" == "Go")
True
False

True and False are values like any other. They can be given a name, and it is common to do so:

age = 15
is_adult = age >= 18
print(is_adult)
False

Python worked out the comparison, got False, and stored that under is_adult. As in the last module, the name holds the answer, not the question.

One equals sign or two?

There are now two things that look alike:

Written Does
age = 16 stores 16 under the name age
age == 16 asks whether age is 16, and works out to True or False

One equals sign changes something. Two equals signs change nothing; they only ask. Using one where two are needed is so common that Python refuses to run the program and tells you which line:

age = 16
if age = 16:
    print("sixteen")
  File "your_program.py", line 2
    if age = 16:
       ^^^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?

Python even suggests the fix. (It also mentions :=, a different sign that this course does not use. You can ignore that part.)

if, and the lines that belong to it

temp = 30
print("checking")
if temp > 25:
    print("hot")
    print("drink water")
print("done")
checking
hot
drink water
done

if is followed by a comparison and a colon. The lines underneath that are indented, pushed in by four spaces, belong to the if. They run only when the comparison is True.

print("done") is not indented, so it does not belong to the if. It runs whatever the temperature is. Here is the same program on a cooler day:

temp = 20
print("checking")
if temp > 25:
    print("hot")
    print("drink water")
print("done")
checking
done

Python reached the if, worked out 20 > 25, got False, skipped the two indented lines and carried on with the next line that was not indented. The program did not stop. It only left something out.

Indentation is not decoration in Python. It is how you say which lines belong together.

Otherwise

Often there are two things to do, one for each answer. else holds the lines for when the comparison is False:

from scimigo import canvas, rectangle, circle

canvas(600, 400)
hour = 21
if hour >= 19:
    rectangle(0, 0, 600, 400, color="midnightblue")
    circle(470, 90, 35, color="lightyellow")
else:
    rectangle(0, 0, 600, 400, color="skyblue")
    circle(470, 90, 45, color="gold")
rectangle(0, 300, 600, 100, color="darkgreen")

Exactly one of the two indented groups runs, never both and never neither. else has no comparison of its own: it means "in every other case". The last line, the ground, is not indented, so it is drawn either way. Change hour to 9 and the first group is skipped and the second runs.

More than two cases

For three or more cases, put elif (short for "else if") between if and else:

size = 12
if size > 20:
    print("large")
elif size > 5:
    print("medium")
else:
    print("small")
medium

Python tries the comparisons from the top and runs the group under the first one that is True. Then it skips all the rest, without even looking at them.

That is why the order matters. size > 5 is also true of 40, but a 40 never gets that far, because size > 20 caught it first. If the two tests were the other way round, every large parcel would be called medium:

size = 40
if size > 5:
    print("medium")
elif size > 20:
    print("large")
else:
    print("small")
medium

The second test can never win. Anything greater than 20 is also greater than 5, and the first test takes it. When you write a chain, start from one end of the range and work towards the other.

Two tests at once

and, or and not join comparisons:

height = 130
has_ticket = False
print(height >= 120 and has_ticket)
print(height >= 120 or has_ticket)
print(not has_ticket)
False
True
True

and is True only when both sides are. or is True when at least one side is. not turns True into False and False into True.

left right left and right left or right
True True True True
True False False True
False True False True
False False False False

In everyday speech "or" often means one or the other but not both. In Python, or is also True when both sides are.

Testing a rule at its edges

A rule such as "under 5 go free" has an edge, and the cases that go wrong are the ones on it. Is a five-year-old free? The words say no. Whether your code says no depends on whether you wrote < or <=.

So when you write a comparison, try the value exactly on the boundary, and one on each side. For "under 5": try 4, 5 and 6. Three runs will tell you more than thirty in the middle of the range.

In the lab

You will predict which lines of a program run before running it, make a sky that changes with the hour, add a third colour to a signal lamp, and write a ticket-price rule that has to be right at every boundary.

Your turn

Now try it yourself

Predict what a program will do, run it, and step through it line by line. The checks tell you when your own code works.

Loading the lab…