Menu

Programming Fundamentals

Condition-Controlled Iteration

Contents

  1. Condition-controlled iteration
  2. Stopping values
  3. Infinite loops

Condition-controlled iteration repeats a section of code while a condition is true, stopping once it becomes false. The condition is checked while the program is running, so the number of repeats is decided at run time rather than when the program is written.

Use it when you cannot know the number of repeats

Some jobs have a fixed size: seven days in a week, twelve questions in a quiz. When you already know the count, a count-controlled loop is the right tool. Many jobs are not like that, though. How many attempts a player needs, how many customers buy today, or how many values you add before the user types a stopping value all depend on what happens while the program runs. Guessing a maximum and using a fixed count goes wrong both ways: guess too low and the program gives up too early, guess too high and it loops pointlessly once the real work is done. A condition-controlled loop stops as soon as its condition becomes false, so it repeats only as many times as it is needed.

Where you meet it

  • asking again until the correct password is typed
  • a guessing game where the player keeps guessing until they are right or run out of attempts
  • adding up values until a stopping value is entered
  • a menu that reappears until the user chooses to quit
  • selling items while stock remains

Worked example

A snack machine keeps selling while there is stock left. The number of items loaded is typed in when the program runs, so the number of passes is not known until then.

stock = int(input("Items in machine: "))  # how many are loaded today
while stock > 0:                          # carry on while there is something to sell
    stock = stock - 1                     # one more item sold
    print("Item sold. Left:", stock)
print("Machine empty")

Output when the user types 3:

Items in machine: 3
Item sold. Left: 2
Item sold. Left: 1
Item sold. Left: 0
Machine empty

The condition is written as the reason to carry on — keep going while stock is above zero. Writing the stopping test on its own, such as stock == 0, would describe the same job backwards: the condition would be false at the start when stock is 3, so nothing would ever be sold.

A stopping value (also called a sentinel value) is a special input that ends a while loop. Instead of repeating a fixed number of times, the loop keeps going until the latest input matches that value. That only works if you compare the latest input with the stopping value in the loop condition, and take the input inside the loop so there is a new value on each pass.

For example, a school equipment desk logs borrowers until the librarian types -1. If the loop condition is while borrower != -1:, the exact value -1 makes the condition false, so the loop ends and -1 is not counted as a borrower. Written as a stopping condition, the test is borrower == -1, which becomes true exactly at the sentinel.

Combining a counter with a stopping value

A loop can also have a counter so it does not run too many times. Put the counter test and the stopping-value test in the same condition with and when both must still be true to carry on. The loop then ends when either the limit is reached or the stopping value is entered.

total = 0
count = 0
number = int(input("Enter a number, or 0 to finish: "))
while number != 0 and count < 4:  # stop on 0 or after four numbers
    total = total + number
    count = count + 1
    if count < 4:
        number = int(input("Enter a number, or 0 to finish: "))
print("Numbers added:", count)
print("Total:", total)

Output when the user types 6, 4, 0:

Enter a number, or 0 to finish: 6
Enter a number, or 0 to finish: 4
Enter a number, or 0 to finish: 0
Numbers added: 2
Total: 10

Choosing the comparison

The condition is the carry-on condition: it says what must be true for another pass, the opposite of the stopping condition. If the loop should stop the moment a value equals the sentinel, use != in the carry-on test so that exact value ends it. For a limit, use < if reaching the limit must stop the loop, or <= if the limit value must still be processed.

JobCarry-on conditionWhat ends the loop
Stop on sentinel 0while number != 0:0 is entered
Stop when score reaches 10while score < 10:score becomes 10
Process up to and including 10while score <= 10:score goes above 10

Use or only when the loop should carry on if either condition is true; it then ends when both are false. For example, a game could carry on while time remains or lives remain, stopping only when both are gone.

An infinite loop is a loop whose condition never becomes False, so the loop never ends. The program keeps repeating the same block and never moves on. In Python this almost always happens with a while loop.

Why it happens

  • Nothing in the body changes the values used in the condition. The test is asked again and again and always gets the same answer, so the loop can never stop. Forgetting the update line is the most common cause.
  • The update moves the value the wrong way. Starting at 0 and taking 1 away each pass never makes the test count < 10 false, because the value only gets smaller each time.
  • The condition is always true, such as while True:, which no line in the body can make false.

Making a while loop end

For a while loop to finish, something inside the body must change the values used in the condition, so that the condition can eventually become False. Those update lines are easy to forget, which is why they cause most infinite loops.

drinks = 6
while drinks > 0:
    print("Pouring a drink")
    drinks = drinks - 1  # this update lets the loop finish
print("Fridge empty")

Output:

Pouring a drink
Pouring a drink
Pouring a drink
Pouring a drink
Pouring a drink
Pouring a drink
Fridge empty

The variable drinks is tested in the condition and is reduced by 1 on every pass, so after six passes the test is False and the loop stops. Remove the line that subtracts 1 from drinks and the condition would stay True for ever, printing the same message with no end.

Also useful