Condition-controlled loops: while
Looping until something changes, break, and loops that never end.
Do this lesson in the simulatorfor repeats a known number of times. A robot usually does not know in advance: drive until the wall is close, wait until the battery is charged. while repeats as long as a condition stays True. It is a condition-controlled loop.
while
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
while distance() > 30:
forward(40)
wait(0.1)
stop()
print("stopped", distance(), "cm from the wall")
Before every repeat, Python checks the condition. True: run the block again. False: leave the loop and carry on below it. Here the condition is "is the wall further than 30 cm?", so the robot creeps forward until it is not.
The wait(0.1) inside the block matters on a real robot. It gives the robot time to actually move before the next check, and it keeps the motors' safety timer happy: a real BugBot stops if it hears no drive command for half a second. Without it the loop would ask the sensor thousands of times a second for no benefit.
Counting with while
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
steps = 0
while distance() > 40:
forward(50, distance=5)
steps = steps + 1
print("took", steps, "steps of 5 cm")
This is count = count + 1 from lesson F1.6 doing its most common job: counting how many times a loop ran, when nobody knew beforehand.
Asking until the answer is right
while is also how a program keeps asking until it gets an answer it can use:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
answer = input("Shall I drive? (yes or no) ")
while answer != "yes" and answer != "no":
answer = input("Please type yes or no: ")
if answer == "yes":
forward(50, distance=20)
print("you said", answer)
Type maybe a few times, then yes. The loop only ends when the condition becomes False, which is when the answer is one of the two allowed words.
for or while?
Use for when you know how many times: four sides, ten steps. Use while when you will only know by looking: until the wall, until the answer is valid. You can write either with the other, but the right one reads better.
break: leave a loop early
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
for i in range(100):
forward(50, distance=5)
if distance() < 30:
print("wall! stopping after", i + 1, "steps")
break
led("red")
break jumps out of the loop immediately, whichever kind it is. Here the for could run 100 times but leaves as soon as the wall is close.
Loops that never end
A while whose condition never becomes False runs forever: an infinite loop. Run this one; the simulator stops it once it has printed far too much, but a real robot would carry on until its battery died:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
count = 0
while count < 5:
print("count is", count)
# count never changes, so this loop never ends
Fix it by adding count = count + 1 inside the block. Every while needs something inside it that will eventually make the condition False.
Sometimes a loop is meant to run forever: a robot that patrols until it is switched off is while True:. Then break is the only way out.
Predict, then run
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
n = 1
while n < 100:
print(n)
n = n * 2
print("finished with n =", n)
Task: creep to the wall
Use a while loop: while the wall is more than 25 cm away, drive 5 cm and print the distance. Stop inside the green band, without touching the wall.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
while distance() > 25:
forward(50, distance=5)
Challenges
- In creep to the wall, count the steps and print the count at the end.
- Write a loop that halves a number starting at 100 until it is below 1, printing each value.
- Use
breakto stop awhile True:loop when the robot has driven 50 cm, usingposition().