Chapter 10

while loops — running while a condition holds

Repeating the same work, how infinite loops happen and how to stop them, break and continue, and asking again until the input is valid.

35 minPython 3.12
  1. 1Encounter
  2. 2Understand
  3. 3Worked
  4. 4Predict
  5. 5Apply
  6. 6Stretch

The problem we are solving

In the last mission we learned to catch bad input — when someone types twenty, the program can say "that is not a number".

But what does it do after saying so? It stops. The person has to run the whole program again. No real software behaves that way — it asks again, and keeps asking until it gets a valid answer.

That is what loops are for: doing the same work repeatedly, as long as it is needed. Today we learn while, which runs as long as a condition stays true.

There is also a new experience waiting for you today: a program that will not stop, with text racing down the terminal. Nothing to be afraid of — you will learn how to stop it in the same breath.

By the end of this mission you can

  • Write a while loop and say when it will stop
  • Recognise why infinite loops happen, and stop one with Ctrl + C
  • Accumulate a sum or a count inside a loop
  • Use break and continue in the right places
  • Keep asking until the input is valid

Prerequisites: Making decisions — if, elif, else.


The simplest loop

python
count = 3

while count > 0:
    print(count)
    count = count - 1

print("Go")
text
3
2
1
Go

The shape looks just like an if — condition, colon, indented block. There is one difference, and it is everything: an if checks the condition once; a while checks it again every time the block finishes.

What the program above did:

  1. count is 3. The condition 3 > 0 is true → the block ran, printed 3, count became 2
  2. Condition again: 2 > 0 is true → printed 2, count became 1
  3. Condition again: 1 > 0 is true → printed 1, count became 0
  4. Condition again: 0 > 0 is false → the loop ended and execution moved on

Every working while loop has three parts, and needs all three:

  • A starting value — before the loop (count = 3)
  • A condition — when to keep going (count > 0)
  • A change — something inside that will eventually make the condition false (count = count - 1)

Infinite loops

It is worth seeing what happens when the third part is missing:

python
count = 3

while count > 0:
    print(count)

This prints 3 forever. count never changes, so count > 0 never becomes false.

How to stop it: press Ctrl + C in the terminal. It halts immediately and shows something like this:

text
Traceback (most recent call last):
  File "D:\python-lab\lesson-10\loop.py", line 4, in <module>
    print(count)
KeyboardInterrupt

KeyboardInterrupt means you stopped it yourself. That is not a bug in your code, it is your decision.

Infinite loops are part of learning. Every programmer has written one, and still does. There is nothing to fear — knowing Ctrl + C reduces it to a minor annoyance. When writing a loop, just ask yourself once: "how will this condition become false?" If you cannot answer, the loop will not stop.

Accumulating

The most common job for a loop is building something up — a sum, a count, the largest value seen:

python
total = 0
number = 1

while number <= 5:
    total = total + number
    number = number + 1

print("Sum of 1 to 5:", total)
text
Sum of 1 to 5: 15

total is called an accumulator — the container you gather into. Note that it starts outside the loop, at 0. Starting it inside would reset it every pass, leaving only the last number at the end.

break — leave right now

break ends the loop immediately, whatever the condition says:

python
number = 1

while number <= 100:
    if number % 7 == 0:
        print("First multiple of 7:", number)
        break
    number = number + 1
text
First multiple of 7: 7

The condition said to run up to 100, but the work was finished the moment 7 appeared — so there was no point going round another 93 times.

break also makes possible a pattern that turns out to be very useful — writing True as the condition and leaving from the right place inside:

python
while True:
    answer = input("Type 'quit' to exit: ").strip().lower()
    if answer == "quit":
        print("Goodbye")
        break
    print(f"You typed: {answer}")
text
Type 'quit' to exit: hello
You typed: hello
Type 'quit' to exit: QUIT
Goodbye

while True means "run forever", so a break inside is mandatory — otherwise it is an infinite loop.

continue — skip this pass

continue does not end the loop; it skips the rest of the block and goes straight to the next pass:

python
number = 0

while number < 10:
    number = number + 1
    if number % 2 == 0:
        continue
    print(number)
text
1
3
5
7
9

For every even number continue ran, so the print was skipped.

There is a trap in writing continue. If the line that advances the condition (number = number + 1) sits after the continue, then continue skips it — and the loop is stuck there forever. That is why the increment comes first in the code above. Whenever you use continue, check that order.

At last: asking until the input is valid

This is the thing we have been waiting two missions for:

python
while True:
    raw = input("Your age: ").strip()
    if raw.isdigit():
        age = int(raw)
        break
    print("Please type a whole number, digits only.")

print(f"Thank you. Age recorded as {age}.")
text
Your age: twenty
Please type a whole number, digits only.
Your age: 22.5
Please type a whole number, digits only.
Your age: 22
Thank you. Age recorded as 22.

This is the pattern you will use for the rest of your working life: loop forever, validate inside, break when it is good, print a message and go round again when it is not. The program no longer collapses on bad input, and the person does not have to start over.


A complete example

shopping.py:

python
# Keep taking item prices until the user is done, then summarise
total = 0.0
item_count = 0

print("Enter item prices. Type 'done' to finish.")

while True:
    entry = input("Price: ").strip().lower()

    if entry == "done":
        break

    if entry == "":
        print("  Nothing typed — try again.")
        continue

    # Accept only digits and at most one decimal point
    if entry.replace(".", "", 1).isdigit():
        price = float(entry)
        total = total + price
        item_count = item_count + 1
        print(f"  Added {price:.2f}. Running total {total:.2f}")
    else:
        print(f"  '{entry}' is not a price. Try again.")

print()
if item_count == 0:
    print("No items were entered.")
else:
    average = total / item_count
    print(f"Items   : {item_count}")
    print(f"Total   : {total:.2f}")
    print(f"Average : {average:.2f}")
text
Enter item prices. Type 'done' to finish.
Price: 120
  Added 120.00. Running total 120.00
Price: abc
  'abc' is not a price. Try again.
Price: 85.5
  Added 85.50. Running total 205.50
Price: done

Items   : 2
Total   : 205.50
Average : 102.75

Three things work together here, and all three are today's material:

  • break — leaving the loop when the person types done
  • continue — skipping the rest and asking again on an empty line
  • Accumulators — total and item_count both start outside the loop and grow inside

Give a thought to why that final if item_count == 0 is needed. If someone types done immediately without entering anything, item_count is 0, and total / item_count would break the program with a ZeroDivisionError. Before using anything a loop accumulated, ask the question every time: "did it accumulate anything at all?"


When it breaks

The program will not stop, text is racing past Press Ctrl + C. Then check that the loop body contains the line that advances the condition, and that it is not sitting after a continue.

The loop never ran at all The condition was already false. Compare the starting value against the condition — while count > 0 starting from count = 0 never enters.

It runs one time too many or too few < and <= got mixed up. while n < 5 runs four times (1, 2, 3, 4); while n <= 5 runs five.

IndentationError: expected an indented block after 'while' statement The line after the while was not indented.

NameError after the loop — the variable is unknown The variable was only created inside the loop, and if the loop never ran, it was never created. Give any variable you need after the loop a starting value before it.

The total is wrong at the end of the loop Check whether the accumulator is being initialised inside the loop. The total = 0 line has to be outside it.