Every while loop needs a path toward stopping — condition-controlled repetition, initialization, update steps, sentinels, validation, and safe loop design
In Chapter 7, you learned that loops are how programs repeat work without repeating code. You studied the idea of iteration, counters, accumulators, and the difference between definite and indefinite repetition. You saw that loops have bodies, that loop variables change, and that tracing a loop step by step is the key to understanding it.
Now it is time to meet Python's first loop structure: the while loop.
The while loop is Python's tool for condition-controlled repetition. It keeps running as long as a condition is true, and it stops when that condition becomes false. This makes it the natural choice whenever you do not know in advance how many times a loop should run.
A while loop is powerful precisely because it is flexible. It can run once, ten times, or a thousand times depending on what happens while it runs. But that flexibility comes with a responsibility: you must design your while loop so that it always has a clear, reliable path toward stopping. A loop that never stops is not a useful program. It is a problem.
This chapter teaches you how while loops work, how to design them carefully, how to trace them accurately, how to avoid infinite loops, and how to use them for realistic programming tasks: counting, validating input, using sentinel values, and building the number guessing game mini-project at the end.
By the end of this chapter, you should be able to:
while loop and predict its behavior by tracing the condition, body, and update step.break and continue appropriately, and explain the risks of overusing them.while loop using a structured, step-by-step approach.while Loop DoesCondition-controlled repetition; the check-run-update rhythm; tracing iterations; reading while loopsbreak and continue at an Introductory LevelExiting a loop immediately; skipping to the next iteration; the while True with break pattern; risks of overusewhile LoopsA six-step design process; identifying condition variables; testing boundary valueswhile Loop DoesA while loop runs a block of code repeatedly, checking a condition before each repetition. If the condition is True, the loop body runs. When the body finishes, the condition is checked again. If it is still True, the body runs again. This continues until the condition becomes False, at which point the loop ends and the program moves on to the next statement after the loop.
Here is the general structure:
while condition:
# loop body
# (this block runs as long as condition is True)
And here is a simple example:
count = 1
while count <= 3:
print(count)
count = count + 1
print("Done.")
1 2 3 Done.
Let's trace this carefully, because tracing is the most important skill for understanding loops.
Before the loop starts: count = 1
Iteration 1: The condition count <= 3 is checked. 1 <= 3 is True. The body runs: print(1) displays 1. Then count = count + 1 updates count to 2.
Iteration 2: The condition is checked again. 2 <= 3 is True. The body runs: print(2) displays 2. Then count becomes 3.
Iteration 3: The condition is checked. 3 <= 3 is True. The body runs: print(3) displays 3. Then count becomes 4.
Iteration 4 check: The condition is checked. 4 <= 3 is False. The loop ends. Execution moves to print("Done.").
Every while loop follows this same rhythm: check the condition — run the body — update — check again.
The condition is tested before the body runs each time. This means if the condition starts out False, the loop body never runs at all:
count = 10
while count <= 3:
print(count)
count = count + 1
print("Loop finished without running.")
Loop finished without running.
The condition 10 <= 3 is immediately False, so the body is skipped entirely.
while LoopsWhen you read a while loop, ask yourself four questions before you trace it:
If you can answer all four questions, you can usually trace the loop correctly. If you cannot find the update step, the loop will probably run forever.
A loop condition is a Boolean expression — the same kind of expression you learned about in Chapter 5. It evaluates to either True or False. The loop continues as long as the condition is True.
Loop conditions often compare a variable to a limit:
temperature > 100 score < 60 attempts <= 3 response != "quit"
They can also use compound conditions with and or or:
while score < 100 and attempts > 0:
...
And they can use the value of any expression that produces a Boolean result.
A well-written loop condition is:
False through normal execution.A poorly written condition is often the source of infinite loops and logic errors. If your loop runs more or fewer times than expected, checking the condition is a good first debugging step.
while count < 10:True.while running:while response != "quit":while number < 0:You will use all of these patterns in this chapter.
Every while loop depends on at least one variable in its condition. Before the loop starts, that variable must have a value. This is called initialization.
If you forget to initialize a variable before a loop, Python will raise a NameError because the variable does not exist yet when the condition is first checked:
while count <= 5: # NameError: count is not defined
print(count)
count = count + 1
The fix is simple: initialize the variable before the loop.
count = 1 # initialization
while count <= 5:
print(count)
count = count + 1
Where you initialize a variable determines what value the loop starts with, and that affects how many times it runs and what it produces.
Consider the difference between these two programs:
# Version A total = 0 count = 1 while count <= 5: total = total + count count = count + 1 print(total) # 15 (1 + 2 + 3 + 4 + 5)
# Version B total = 0 count = 0 # starts at 0, not 1 while count <= 5: total = total + count count = count + 1 print(total) # 15 (0 + 1 + 2 + 3 + 4 + 5 = 15)
Wait — both give 15 here. What about this:
# Version C total = 0 count = 2 # starts at 2 while count <= 5: total = total + count count = count + 1 print(total) # 14 (2 + 3 + 4 + 5)
The starting value of count changes the result. Initialization matters.
When a loop depends on user input, initialization often requires an initial value that forces the loop to run at least once. This is a common pattern:
response = "" # initialize to empty string, not "quit"
while response != "quit":
response = input("Enter a command (or 'quit' to stop): ")
print(f"You entered: {response}")
If response had been initialized to "quit", the loop would never run. The initialization value is chosen deliberately to let the loop begin.
Initialization gets a variable ready before the loop. But the loop will run forever unless something changes inside the body so the condition can eventually become False. That change is called the update step.
The update step is one of the most important parts of any while loop. Without it, the condition never changes, and the loop runs forever.
The most basic update is incrementing a counter:
count = 1
while count <= 5:
print(count)
count = count + 1 # update: count grows each iteration
You can also decrement:
count = 5
while count >= 1:
print(count)
count = count - 1 # update: count shrinks each iteration
Accumulators change with each iteration by adding, multiplying, or combining values:
total = 0
number = 1
while number <= 10:
total = total + number
number = number + 1
print(f"Sum from 1 to 10: {total}") # 55
Sometimes the update step is not arithmetic — it is reading new input. The new value from input() is what changes the condition variable:
response = ""
while response != "quit":
response = input("Enter command: ")
# response is updated by the user's input each time
The update step must be inside the loop body. If you put it outside, the loop variable never changes during the loop:
count = 1
while count <= 3:
print(count)
# count = count + 1 <-- if this were here, infinite loop!
count = count + 1 # this runs only after the loop ends
The update must also be reachable. If the update is inside an if statement that rarely runs, the loop may run much longer than expected.
An infinite loop is a loop whose condition never becomes False. It runs forever until the program is forcibly stopped.
Infinite loops are one of the most common beginner mistakes with while loops, and they happen in predictable ways.
Missing update:
count = 1
while count <= 5:
print(count)
# forgot to update count — loops forever printing 1
Update that never reaches the stopping condition:
count = 1
while count <= 5:
print(count)
count = count - 1 # count goes 1, 0, -1, -2, ... never reaches > 5
Condition that can never be False:
while True:
print("Hello") # this runs forever
while True: is sometimes used intentionally with an explicit break inside — see Section 8.8. But an unconditional while True: with no exit path is an infinite loop.
Wrong variable being updated:
count = 1
total = 0
while count <= 5:
total = total + count
total = total + 1 # updating total instead of count — count never changes
If your program appears to hang or print forever, you are probably in an infinite loop. Press Ctrl+C in the terminal to interrupt the program. Python will display a KeyboardInterrupt message.
Before running a while loop, ask yourself:
If you can answer yes to all four, you are unlikely to create an infinite loop.
When in doubt, trace the first few iterations on paper. If the condition variable is moving in the right direction, the loop will eventually stop. If the variable stays the same or moves in the wrong direction, you have found your bug.
A sentinel value is a special value used to signal the end of input. When the user enters the sentinel, the loop stops.
Sentinel-controlled loops are useful when you do not know in advance how many items the user will enter. You keep asking for input until the user provides the sentinel.
total = 0
entry = input("Enter a number (or 'done' to finish): ")
while entry != "done":
number = float(entry)
total = total + number
entry = input("Enter a number (or 'done' to finish): ")
print(f"Total: {total}")
Enter a number (or 'done' to finish): 10 Enter a number (or 'done' to finish): 25 Enter a number (or 'done' to finish): 8 Enter a number (or 'done' to finish): done Total: 43.0
The sentinel here is the string "done". When the user types "done", the condition entry != "done" becomes False and the loop ends.
A good sentinel value is something that cannot be confused with a real data value. If you are collecting integers, 0 makes a poor sentinel (zero might be a real answer). The word "done" or -1 in a context where negatives are impossible works better.
| Sentinel | Best Used When |
|---|---|
"done", "quit", "stop", "exit" | Collecting text input |
-1 | Collecting non-negative integer input |
0 | Collecting input where zero is not a valid value |
Notice the structure in the example above: the first input() call happens before the loop, and then the same input() call happens at the end of the loop body. This is the standard sentinel loop pattern:
read first value
while value is not the sentinel:
process the value
read the next value
This ensures the condition is checked before any processing, so the sentinel itself is never processed as a real value.
One of the most practical uses of while loops is input validation: repeatedly asking the user for input until they provide something acceptable.
Without validation, programs break easily. A user might type a letter when the program expects a number, or type a negative number when only positive numbers make sense.
age = int(input("Enter your age: "))
while age < 0 or age > 120:
print("That is not a valid age. Please try again.")
age = int(input("Enter your age: "))
print(f"Your age is {age}.")
This loop keeps running as long as the input is invalid. Once the user provides a valid age (0 through 120), the condition becomes False and the loop ends.
score = int(input("Enter a score (0 to 100): "))
while score < 0 or score > 100:
print("Score must be between 0 and 100.")
score = int(input("Enter a score (0 to 100): "))
print(f"Score accepted: {score}")
answer = input("Continue? (yes/no): ").lower()
while answer != "yes" and answer != "no":
print("Please type yes or no.")
answer = input("Continue? (yes/no): ").lower()
if answer == "yes":
print("Continuing...")
else:
print("Stopping.")
Note the .lower() call — this converts whatever the user types to lowercase so that "Yes", "YES", "yes" all match.
A validation loop should:
An alternative pattern initializes the variable to an invalid value that forces the loop to run at least once:
age = -1 # deliberately invalid initial value
while age < 0 or age > 120:
age = int(input("Enter your age: "))
print(f"Your age is {age}.")
This version always asks at least once and keeps asking until the input is valid. Both patterns work; choose whichever reads more clearly.
break and continue at an Introductory LevelPython provides two special statements for controlling loops: break and continue. They are useful tools, but beginners should use them carefully because they can make loops harder to trace.
break: Exit the Loop ImmediatelyThe break statement causes the loop to stop immediately, regardless of the condition. Execution jumps to the first statement after the loop.
count = 1
while count <= 10:
if count == 5:
break # stop the loop when count reaches 5
print(count)
count = count + 1
print("Loop ended.")
1 2 3 4 Loop ended.
The loop would normally run up to 10, but break stops it at 5.
break Is Usefulbreak is most naturally used inside a while True: loop where you want to keep running until some condition inside the body is met:
while True:
response = input("Enter a command (or 'quit' to stop): ")
if response == "quit":
break
print(f"You entered: {response}")
print("Goodbye.")
The loop runs forever by design — the condition True never becomes False. The only way out is the break statement inside the body.
This pattern reads well: "keep going until you decide to stop." It is a clean approach for menu-driven programs and command loops.
continue: Skip to the Next IterationThe continue statement skips the rest of the current loop body and returns to the condition check. The loop does not stop — it just moves on to the next iteration without finishing the current one.
count = 0
while count < 6:
count = count + 1
if count == 3:
continue # skip the rest when count is 3
print(count)
1 2 4 5 6
The value 3 is skipped because when count == 3, the continue statement sends the loop back to the condition check before print(count) runs.
continue Carefullycontinue can be confusing because it jumps over code. Make sure the update step (like count = count + 1) happens before the continue if the loop condition depends on that variable. Otherwise, you could accidentally create an infinite loop:
count = 0
while count < 6:
if count == 3:
continue # PROBLEM: count never gets updated when count == 3
print(count)
count = count + 1 # this is skipped when count == 3
This creates an infinite loop because when count is 3, the loop skips the update, checks the condition (3 < 6 is still True), runs again, sees count == 3, skips the update again — forever.
The fix: move the update before the continue:
count = 0
while count < 6:
count = count + 1
if count == 3:
continue
print(count)
break and continue are valid Python, but overusing them can make loops hard to follow. For many situations, you can redesign the loop condition or the if statement to avoid them entirely. When break and continue genuinely make the code clearer, use them. When they are being used to patch a poorly designed loop, consider restructuring instead.
while LoopsA safe while loop is one that:
Designing safe while loops is a skill that improves with practice. Here is a structured approach.
number <= 0numberTrue so the loop will run at least once, or that matches the actual starting state of the problem.Initialization choices for Step 3:
number = -1 # forces the loop to run at least once
or:
number = int(input("Enter a positive number: ")) # read first value before loop
And the loop body for Step 4:
while number <= 0:
print("Please enter a positive number.")
number = int(input("Enter a positive number: "))
# Safe loop: collect a positive integer
number = int(input("Enter a positive number: "))
while number <= 0:
print("That is not positive. Please try again.")
number = int(input("Enter a positive number: "))
print(f"Thank you. You entered {number}.")
Trace with inputs -3, 0, 5:
| Input | Condition Checked | Result |
|---|---|---|
| -3 | -3 <= 0 | True — print error, read again |
| 0 | 0 <= 0 | True — print error, read again |
| 5 | 5 <= 0 | False — loop ends, print result |
Loop bugs are among the most frustrating in programming because they can cause programs to run forever, skip values, process values incorrectly, or terminate too early. This section shows the most common loop bugs and how to fix them.
# Buggy version count = 1 while count <= 5: print(count) # forgot count = count + 1
count = 1
while count <= 5:
print(count)
count = count + 1
# Buggy version count = 1 while count <= 5: print(count) count = count - 1 # moving away from the stopping condition
count = 1
while count <= 5:
print(count)
count = count + 1
# Intended to print 1 through 5 count = 1 while count < 5: # should be <= 5 print(count) count = count + 1
< to <=. This is one of the most common subtle bugs. Trace the last iteration to check: when count is 5, should the loop run? If yes, the condition must be <= 5.while count <= 5:
# Intended to sum 1 through 10 total = 0 count = 0 # starts at 0, adding 0 in first iteration while count <= 10: total = total + count count = count + 1 print(total) # prints 55, which happens to be correct here # but if problem said "1 through 10", starting at 0 adds nothing
Whether this is a bug depends on the problem. Trace the first iteration and confirm the starting state is what you intended.
response = input("Enter 'quit' to stop: ")
while response != "Quit": # case mismatch — user types "quit", not "Quit"
print(f"You entered: {response}")
response = input("Enter 'quit' to stop: ")
while response.lower() != "quit":
entry = input("Enter a number or 'done': ")
while entry != "done":
number = float(entry)
entry = input("Enter a number or 'done': ")
total = total + number # BUG: this line is inside the loop but processes
# entry's new value, which might be "done"
number, before reading the next entry.while entry != "done":
number = float(entry)
total = total + number
entry = input("Enter a number or 'done': ")
For each program below, trace the execution by filling in the table. Then write the complete output.
count = 10
while count > 6:
print(count)
count = count - 2
print("Done")
| Iteration | count (start) | Condition | count (end) | Output |
|---|---|---|---|---|
| Check 1 | 10 | 10 > 6 → True | — | — |
| Body 1 | 10 | — | 8 | 10 |
| Check 2 | 8 | 8 > 6 → True | — | — |
| Body 2 | 8 | — | 6 | 8 |
| Check 3 | 6 | 6 > 6 → False | — | — |
Complete output:
10 8 Done
Trace this program and write the output.
total = 0
number = 1
while number <= 4:
total = total + number
number = number + 1
print(total)
| Iteration | number | total (before) | total (after) | number (after) |
|---|---|---|---|---|
| 1 | 1 | 0 | 1 | 2 |
| 2 | 2 | 1 | 3 | 3 |
| 3 | 3 | 3 | 6 | 4 |
| 4 | 4 | 6 | 10 | 5 |
Condition check: 5 <= 4 → False. Loop ends.
Output:
10
Trace this program. Describe what it does in plain English.
word = "hello"
index = 0
while index < len(word):
print(word[index])
index = index + 1
(Hint: word[0] is "h", word[1] is "e", and so on. len("hello") is 5.)
Trace this program. What is the final value of product?
product = 1
factor = 1
while factor <= 5:
product = product * factor
factor = factor + 1
print(product)
What does this program print? Be careful — trace every step.
x = 2
while x < 50:
x = x * 2
print(x)
Write a condition for each situation described. Do not write a complete loop — just write the condition expression.
a. Continue while temperature is above 98.6.
b. Continue while attempts is less than or equal to 3.
c. Continue while response is not equal to "yes" and not equal to "no".
d. Continue while balance is greater than 0 and withdrawals is fewer than 10.
e. Continue while name is an empty string.
For each condition, describe what kind of values would keep the loop running and what value would stop it.
a. while score < 70:
b. while entry != "quit":
c. while count > 0 and found == False:
d. while True:
Identify the error in each loop condition, then write the corrected condition.
a. A loop intended to run while count is less than 10:
while count > 10:
b. A loop intended to stop when the user types "done":
while response == "done":
c. A loop intended to run while age is between 0 and 18:
while age >= 0 or age <= 18:
Write a complete program that asks the user to enter a number between 1 and 10. If the number is outside that range, display an error and ask again. When the number is valid, display: "Valid input: [number]".
Write a program that asks the user to enter a temperature in degrees Celsius. The program should keep asking until the user enters a number between -273.15 (absolute zero) and 1000. When valid, display the temperature in a sentence.
Write a program that asks the user to enter a password. The password must be at least 8 characters long. If it is too short, display "Password must be at least 8 characters." and ask again. When the password is long enough, display "Password accepted.".
Write a program that asks the user for a positive odd number. The number must be greater than zero, and it must be odd (not divisible by 2). Keep asking until both conditions are satisfied.
(Hint: a number n is odd if n % 2 != 0.)
Rewrite the following program so it validates the input before proceeding, using a while loop:
# Original version (no validation)
age = int(input("Enter age (1-120): "))
print(f"In 10 years, you will be {age + 10}.")
Each program below contains one or more bugs. Identify the bug, explain what it causes, and write the corrected version.
count = 1
while count <= 5:
print(count)
count = count + 1
print("Finished")
total = 0
number = 10
while number > 0:
total = total + number
number = number + 1 # bug here
print(total)
response = input("Enter 'quit' to stop: ")
while response != "Quit":
print(f"Command: {response}")
response = input("Enter 'quit' to stop: ")
entry = input("Enter a number or 'done': ")
total = 0
while entry != "done":
entry = input("Enter a number or 'done': ")
total = total + float(entry) # bug: what happens when entry is "done"?
print(f"Total: {total}")
count = 1
while count != 10:
print(count)
count = count + 2 # count goes 1, 3, 5, 7, 9, 11...
Explain why this is an infinite loop. Write a corrected version that prints odd numbers from 1 to 9.
Write a program that asks the user to enter a positive integer. Then count down from that number to 1 and display "Liftoff!" when finished.
Enter a starting number: 5 5 4 3 2 1 Liftoff!
Write a program that repeatedly asks the user to enter a number. Keep a running total. When the user types "done", display the total. Do not count "done" as a number.
Write a program that asks the user to enter test scores one at a time. The user types -1 as the sentinel to stop. Calculate and display the average of the scores entered. (Do not include -1 in the average.)
Ask the user to enter a positive integer. Then display the multiplication table for that number from 1 through 10.
Enter a number: 7 7 x 1 = 7 7 x 2 = 14 ... 7 x 10 = 70
Ask the user to enter a positive integer. Count how many digits it has using a while loop. (Do not convert it to a string — use division.)
(Hint: Divide the number by 10 repeatedly until it reaches 0. Each division removes one digit.)
Write a program that displays this menu:
1. Say hello 2. Say goodbye 3. Quit
Keep showing the menu and responding to choices until the user chooses 3. If the user enters something other than 1, 2, or 3, display "Invalid choice." and show the menu again.
You will write a complete number guessing game program. The program picks a secret number, lets the player guess, gives hints, and tracks the number of attempts.
randint function — the instructions below explain how.)"Too low. Try again." — if the guess is below the secret number"Too high. Try again." — if the guess is above the secret number"Correct! You got it in [n] guesses." — if the guess matchesrandintThe random module is part of Python's standard library. For now, you only need this one line at the top of your program:
import random
And this line to generate a random number between 1 and 100 (inclusive):
secret = random.randint(1, 100)
You will learn much more about the random module in Chapter 15 and Chapter 24. For this project, just use it as a tool.
Here is one way to organize your program. Fill in the logic:
import random
secret = random.randint(1, 100)
attempts = 0
print("I have chosen a number between 1 and 100.")
print("Try to guess it!")
guess = int(input("Your guess: "))
attempts = attempts + 1
while guess != secret:
if guess < secret:
print("Too low. Try again.")
else:
print("Too high. Try again.")
guess = int(input("Your guess: "))
attempts = attempts + 1
print(f"Correct! You got it in {attempts} guesses.")
Once the basic version works, try adding:
"Play again? (yes/no)". If the player says yes, start a new game.Before you share your game, test these situations:
while loop check before each iteration? What happens when that check produces False?while loop condition is False before the loop ever runs, how many times does the loop body execute?break do? In what situation is it most naturally useful?continue do? Why must you be careful about where the update step is when using continue?while True: with a break inside. Is this an infinite loop? Explain.while loop.Chapter 9 introduces the for loop — Python's tool for count-controlled and sequence-based repetition.
Where a while loop is driven by a condition, a for loop is driven by a sequence: a range of numbers, a string of characters, or later a list of values. The for loop handles the counting and stopping automatically, without requiring you to manage a counter variable manually.
You will learn how range() generates sequences of numbers, how to count up and count down, how to iterate over the characters of a string, how to compute totals and averages with a for loop, and how to choose between for and while for a given problem.
After Chapter 9, you will have both major loop structures available. The key question — for or while? — will be answered: use for when you know the sequence in advance, and use while when the number of iterations depends on conditions that change during the loop.