While loops
Contents
While loops#
For
loops are a very valuable construct for repeating something when you already know how many times you will need to repeat (even if that is determined by some other variable). However, we often wish to repeat until a condition is no longer satisfied. For example, we might summarise the process of debugging as “while there are still bugs in the program, fix a bug!”
Python offers the while
loop for this purpose. It has the following form:
while <condition>:
things to do while the condition is True
Python will first evaluate the condition. If it is True
, then the loop body will be run. The condition will then be checked again, and if it is True
the loop body will be run again. This continues until the condition evaluates to False
.
Here’s an example:
x = 0.9
i = 0
while x != 0.5:
x = 2*x*(1-x)
i += 1 # increment i manually, as we're not using a for-loop
print(f"after {i} iterations, x = {x}")
after 1 iterations, x = 0.17999999999999997
after 2 iterations, x = 0.29519999999999996
after 3 iterations, x = 0.41611392
after 4 iterations, x = 0.4859262511644672
after 5 iterations, x = 0.49960385918742867
after 6 iterations, x = 0.49999968614491325
after 7 iterations, x = 0.49999999999980305
after 8 iterations, x = 0.5
Note that the condition isn’t checked inside the loop body, so Python won’t break the loop halfway through the loop body if the condition becomes False
. Because of this, if we rearranged the statements in the loop body, we would get a different final number printed:
x = 0.9
i = 0
while x != 0.5:
print(f"after {i} iterations, x = {x}")
i += 1
x = 2*x*(1-x)
after 0 iterations, x = 0.9
after 1 iterations, x = 0.17999999999999997
after 2 iterations, x = 0.29519999999999996
after 3 iterations, x = 0.41611392
after 4 iterations, x = 0.4859262511644672
after 5 iterations, x = 0.49960385918742867
after 6 iterations, x = 0.49999968614491325
after 7 iterations, x = 0.49999999999980305
In the example below, we have a turtle draw a spiral from the centre until it reaches a bounding box 150 units away from the centre.
from mobilechelonian import Turtle
import numpy as np
# the centre coordinate is (200, 200)
centre = 200
# create a turtle caled Terry
terry = Turtle()
terry.speed(10)
# we need a variable to keep track of the angle to turn to make the spiral
i = 1
# Loop until terry is 150 away from the centre in the x or y direction.
# np.abs computes the absolute value of its argument, so we are testing the if the difference
# between centre and posX is < 150, and the difference between centre and posY is < 150.
while (np.abs(centre - terry.posX) < 150) and (np.abs(centre - terry.posY) < 150):
# move forward a small amount to approximate a curve
terry.forward(5)
# The angle terry turns should get smaller as he goes to obtain a spiral
# so turn by 360/i, then increase i.
# There are many other choices that would also make a spiral.
terry.left(360/i)
i = i + 1
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Input In [3], in <cell line: 1>()
----> 1 from mobilechelonian import Turtle
2 import numpy as np
4 # the centre coordinate is (200, 200)
ModuleNotFoundError: No module named 'mobilechelonian'
Infinite loops#
There is a danger lurking in while
loops: what happens if the condition never becomes False
? Python will simply keep running the loop body forever. This is called an infinite loop, and is one of the common causes of programs freezing or crashing. Whenever you write a while
loop, you should consider how you know it will eventually finish, i.e. how you know that the condition will eventually be false. It is literally impossible for Python to decide whether a general while
loop will terminate, and so it is up to you as the programmer!
Proving that a while
loop will terminate often requires some mathematical insight.
If you run into an infinite loop (or simply a loop which is taking too long to terminate), you can stop Python executing your code by clicking the “stop” button in the menu beside the “Run” button.
Break
ing out of loops#
There are two common alternatives used to break out of while loops. The first is the break
statement. When this is encountered in a loop, Python will immediately stop executing the loop and go to the next line in the code. If you have nested loops, break
will only break out of the inner-most loop that contains the break
statement.
In the example below, a break
statement is used to exit a while
loop when the user inputs the correct number. We’ll discuss user input more in the final worksheet. If you execute the following cell, Python will get “stuck” in the loop and you will have to exit using the “stop” button in the menu bar, or by guessing the correct number. The technique used in this example - using while True
to keep looping and processing user input - is called an “event loop” and lies at the heart of any program you can interact with continuously, like office software or games.
import random
# This program implements a guessing game where numbers are
# read in from the user in order to guess an answer known to the
# computer
# First set the answer to be a random number between 0 and 100
answer = random.randint(0, 100)
# Explain in words what the user needs to do:
print("Guess a number between 0 and 100 - I only stop when you get it right!")
# Start a while loop which only exits if the user guesses the number correctly
while True:
# This line reads in a guess from the user:
guess = int(input(">"))
# Next see whether the guess is too small, too large or right:
if guess < answer:
print("Higher")
elif guess > answer:
print("Lower")
else:
# If we get here the answer is right
print("Correct! Congratulations.")
# If the answer is right exit the loop
break
print("Come back and play again soon!")
Guess a number between 0 and 100 - I only stop when you get it right!
>30
Higher
>60
Higher
>80
Lower
>70
Higher
>75
Lower
>72
Lower
>71
Correct! Congratulations.
Come back and play again soon!
Break
statements can also be used in for
loops. They are often used when you are searching for an object with some property, and there is no reason to keep doing work once you have found it.
# Sets i to be the first integer between 100 and 200 which is divisible by 47.
# There are better ways of doing this!
for i in range(100, 201):
if i % 47 == 0:
# if we break now, the variable i will keep its current value
break
print(f"the first multiple of 47 between 100 and 200 is {i}")
the first multiple of 47 between 100 and 200 is 141
The other standard way of breaking loops applies if the loop is contained in a function. Since a return
statement immediately stops the function from being run and returns the control flow to where it was called from, it also breaks out of any loop in the function.