else, elif and Boolean operators
Choosing between outcomes, and joining conditions with and, or and not.
Do this lesson in the simulatorif runs a block or skips it. Most decisions have more than one outcome: do this, otherwise do that; or pick one of several. This lesson adds else and elif, and shows how to join conditions together with and, or and not.
else: what to do otherwise
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if distance() > 60:
led("green")
print("plenty of room")
else:
led("red")
print("not much room")
print("decided")
else: has its own block. Exactly one of the two blocks runs: the if block when the condition is True, the else block when it is False. Never both, never neither.
Compare with two separate ifs from the last lesson: those could both run, or neither. if/else is for when the outcomes are opposites.
elif: several choices
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
forward(50, distance=35)
d = distance()
if d < 20:
led("red")
print("stop")
elif d < 40:
led("orange")
print("careful")
else:
led("green")
print("go")
print("wall in", d, "cm")
elif is short for "else if". Python checks the conditions from the top, runs the block of the first one that is True, and skips all the rest. So the order matters: d < 20 must come before d < 40, or a distance of 15 would be called "careful" instead of "stop".
Predict which block runs for d equal to 10, 30 and 50. Then change the 35 in the drive to 5 and to 50 and check.
Joining conditions: and, or, not
These are the Boolean operators. and needs both sides True. or needs at least one. not flips the answer:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
d = distance()
b = battery()
print("clear and charged:", d > 30 and b > 20)
print("clear or charged:", d > 30 or b > 20)
print("not clear:", not d > 30)
The whole set of answers fits in a truth table:
| A | B | A and B | A or B | not A |
|---|---|---|---|---|
| False | False | False | False | True |
| False | True | False | True | True |
| True | False | False | True | False |
| True | True | True | True | False |
In a program, a joined condition goes straight into an if:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if distance() > 30 and battery() > 20:
print("safe to drive")
forward(50, distance=20)
else:
print("staying put")
Checking a range
"Between 20 and 40" is two conditions joined with and:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
d = distance()
if d >= 20 and d <= 40:
print("in the parking zone")
else:
print("outside the zone:", d)
Python also lets you write it as 20 <= d <= 40, the way you would in maths.
Task: traffic light
Drive 15 cm, then read the distance and set the LED: red and print stop if the wall is under 20 cm away; orange and careful if under 40; green and go otherwise. The wall is placed so that the right answer is orange, but write all three branches.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
forward(50, distance=15)
d = distance()
if d < 20:
led("red")
print("stop")
Task: safe to go?
If the way ahead is clear (more than 50 cm), print clear and drive 40 cm forward into the green zone. Otherwise print blocked and do not move.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if distance() > 50:
print("clear")
Challenges
- Add a fourth colour for "very far" (over 80 cm) to the traffic light. Where must its condition go?
- Only drive if the battery is above 50 as well, using
and. - Rewrite safe-to-go so the
blockedcase comes first, usingnot.