← Back to the Introduction to Computer Science outline The Course Maker
← Introduction to Computer Science outline
Week 5 · Chapter

Chapter 5 — Loops I: The while Loop

Introduction to Computer Science Free sample edition

The module's primary reading · ~35–45 minutes · Objective 4 (write while loops and for loops over range(), using counters, accumulators, nested loops, and break, and recognize and repair an infinite loop and an off-by-one error) · Read it first this week; the lecture, the slides, the tutorial, the quiz, and the Coding Lab all build on it.


In plain language

So far every program you wrote ran each line once, from top to bottom, and stopped. This week your programs learn to repeat. A while loop (a block of code that runs again and again for as long as a test comes out True) lets one short program count days, add up totals, or keep trying until something works. You will learn to predict three things about every loop: what it prints, how many times it repeats, and where its counter (a name that goes up by one each time around) ends. You will also learn to spot a loop that never stops, and how to stop it.

Why you already care about this

A friend sets a goal of 10000 steps a day. Each walk around the park adds 2500 steps to her phone's count, and she keeps walking until the count reaches the goal. She never writes out "walk, walk, walk, walk." She follows one rule: while the count is under 10000, take another walk. After 4 walks the count reads 10000 and she stops.

That one rule is a loop. It has a test (is the count under the goal?), a body (take a walk, add 2500), and a way to end (the test eventually fails). Your reading log from Weeks 1 through 4 has the same shape: 45 pages read, a goal of 300 pages, and 30 pages a day. How many days until the goal? This week the program answers that for you, and the answer it prints holds a small surprise that teaches the whole week.

This chapter teaches you to write a while loop, to trace it pass by pass, to count and total with it, to catch the one-character mistake that runs a loop one time too many or too few, and to stop a loop that runs forever.

By the end of this chapter you will be able to:

  • write a while loop and say what its condition, its body, and one pass are;
  • explain why the reading log's loop stops at 315 pages, past its goal of 300;
  • set up a counter and an accumulator before a loop and predict their final values;
  • choose between < and <= in a loop condition and fix an off-by-one error;
  • recognize an infinite loop, stop it, and repair it;
  • leave a while True loop with break, and check a chatbot's claim about a loop by running it.

Carry this line with you: the test runs at the top of each pass — never in the middle.

Where we are

  • Already covered: Week 1 taught you to predict what a line prints, run it, and read an error from its last line. Week 2 gave values names and showed reassignment. Week 3 read typed input and built output with f-strings. Week 4 taught the comparison operators, True and False, and the if statement.
  • This week: the while loop, counters and accumulators, < versus <= and the off-by-one error, infinite loops, and break.
  • How they connect: a loop's condition is a Week 4 comparison such as pages_read < goal, and every pass uses Week 2's reassignment, pages_read = pages_read + 30, to change a value.
  • Where we're going next: Week 6, Loops II, adds the for loop and range(), which count the passes for you, and nested loops.

Two earlier ideas carry most of the weight this week. From Week 2: the line days = days + 1 reads "days gets the old value of days plus 1," so the name on the left ends up holding a new value. From Week 4: a comparison such as 285 < 300 produces True or False, and an if runs its indented lines only when its condition is True. A while line looks like an if line, but it keeps coming back. Spend extra time on Sections 2 and 3; every loop you write for the rest of the course depends on them.

1. Repeat with while: the body runs again while the test is True

A cook adding salt to a pot follows a rule: taste it; while it is still bland, add a pinch and taste again. The cook does not decide in advance how many pinches. The test decides, one pinch at a time. Python's while loop works the same way.

A while loop is a statement that repeats its indented body for as long as its condition is True, checking that condition once at the top of every pass and never in the middle of one.

Three more words describe its parts.

  • The loop condition is the Boolean expression written after the keyword while; Python tests it before each pass and stops repeating the first time it comes out False.
  • The loop body is the indented lines under a while line, which Python runs from top to bottom on every pass before it returns to test the condition again.
  • A pass is one complete run through a loop's body, from its first indented line to its last; a loop that ran five times made five passes.

Worked example — days to the reading goal. The reading log starts with 45 pages read, a goal of 300 pages, and a pace of 30 pages a day. Predict both printed lines before you read the output.

goal = 300
pages_read = 45
days = 0
while pages_read < goal:
    pages_read = pages_read + 30
    days = days + 1
print(days)
print(pages_read)

Output

9
315

Here is how Python got there.

  1. Lines 1 to 3 set the starting values: 300, 45, and 0.
  2. Line 4 tests pages_read < goal. 45 is less than 300, so the test is True and the body runs.
  3. The body adds 30 pages and 1 day. Then Python goes back up to line 4 and tests again.
  4. That repeats until the test comes out False. Then Python skips the body and runs the two print lines.

The loop made 9 passes, so days is 9. Why 9? The pages still needed are 300 − 45 = 255, and 255 ÷ 30 = 8.5. Eight days fall short, so a ninth day is needed. In words: at 30 pages a day, you reach the goal on day 9. The second line, 315, is the surprise; Section 2 explains it.

To see each pass, add one print inside the body. This copy of the program prints the day and the running total after each pass.

goal = 300
pages_read = 45
days = 0
while pages_read < goal:
    pages_read = pages_read + 30
    days = days + 1
    print(days, pages_read)

Output

1 75
2 105
3 135
4 165
5 195
6 225
7 255
8 285
9 315

The table below lines up each pass with the test that let it run.

Each pass of the reading-log loop: the test before the pass and the totals after it
Pass pages_read before the test Test result days after the pass pages_read after the pass
1 45 True 1 75
2 75 True 2 105
3 105 True 3 135
4 135 True 4 165
5 165 True 5 195
6 195 True 6 225
7 225 True 7 255
8 255 True 8 285
9 285 True 9 315
(no pass) 315 False 9 315

Worked example — the step counter. Here is the walk from the opening, as an illustrative program.

steps = 0
walks = 0
while steps < 10000:
    steps = steps + 2500
    walks = walks + 1
print(walks)
print(steps)

Output

4
10000

After 4 walks the count is 4 × 2500 = 10000. The test 10000 < 10000 is False, so the loop stops exactly on the goal. In words: this loop lands on its target because 2500 divides 10000 evenly; the reading log's pace of 30 does not divide 255 evenly.

Misconception check. Students often think a while line runs its body once, the way an if line does. That is tempting, because the two lines look alike: a keyword, a condition, a colon, and an indented block. But an if runs its block at most once, while a while goes back to its condition after every pass and runs the block again as long as the condition stays True. The cure: after the last line of a loop body, put your finger back on the while line, not on the next line down.

In practice (your tools). Paste the reading-log program into Python Tutor at pythontutor.com and click Next one step at a time. Watch the arrow jump from the last body line back up to the while line, and watch pages_read and days change in the frames panel on every pass. The Python Language Reference on docs.python.org describes the loop in section 8.2, The while statement.

Memory hook: a while line is an if line that keeps coming back.

2. Check at the top only: why the log overshoots to 315

A bus driver checks the time only when the bus pulls into a stop. If the shift ends while the bus is between stops, the driver still finishes the drive to the next stop before checking again. A while loop checks its condition in the same way: only at one spot, the top.

The reading log's goal is 300, yet the loop stopped at 315. Nothing went wrong. The loop did exactly what you wrote.

Worked example — the overshoot. Use the pass table from Section 1.

  1. After 8 passes, the total is 45 + 8 × 30 = 285.
  2. Python goes to the top and tests 285 < 300. That is True, so the ninth pass runs.
  3. The ninth pass adds 30: 285 + 30 = 315.
  4. Python goes to the top and tests 315 < 300. That is False, so the loop ends.

The final total is 315 − 300 = 15 pages past the goal. In words: the loop asked "are we there yet?" only before each pass, and on day 9 one more full day carried the total past the goal.

Worked example — the print that happens anyway. This short loop starts at 3, adds 1, and then prints. Predict every line.

count = 3
while count < 5:
    count = count + 1
    print(count)

Output

4
5

Pass 1: the test 3 < 5 is True; count becomes 4, and 4 prints. Pass 2: the test 4 < 5 is True; count becomes 5, and 5 prints. The 5 printed even though 5 < 5 is False, because Python had already passed the test at the top of that pass. Only then does it go back up, test 5 < 5, get False, and stop.

A loop can also make zero passes. Here is the reading log for a reader who has already met the goal (an illustrative starting value of 300).

goal = 300
pages_read = 300
days = 0
while pages_read < goal:
    pages_read = pages_read + 30
    days = days + 1
print(days)
print(pages_read)

Output

0
300

The very first test, 300 < 300, is False, so the body never runs. days stays 0 and pages_read stays 300.

Misconception check. Students often think a loop checks its condition in the middle of the body and stops the instant the condition turns False. That is tempting, because in everyday speech "while" means "during the time that." But Python tests the condition only at the top of each pass. Once a pass starts, every line of the body runs, even if the condition has already turned False partway through. The cure: when you trace a loop, test the condition only when your finger is on the while line.

In practice (your tools). Run the count = 3 loop in your free browser Python runner, then swap the two body lines so print(count) comes first and run again. Predict the new output before you press Run; this time it prints 3 and 4. Moving one line changed what printed, because the test did not move.

Memory hook: the test runs at the top of each pass — never in the middle.

3. Count and total: counters, accumulators, and the final value

A cashier totalling a grocery receipt keeps two numbers in mind: how many items have been scanned and the running total so far. Both start at zero before the first item, and both change with every item. Loops keep those same two kinds of numbers.

A counter is a name that gets a starting value before a loop and goes up by one on every pass, so its value tells you how many passes have run.

An accumulator is a name that starts at a value such as 0 before a loop and collects a running total, with each pass adding the current amount to it.

Python has a shorthand for "add to a name." += is the augmented assignment operator, a shorthand that adds the value on its right to the name on its left and stores the sum back in that name, so count += 1 means count = count + 1.

count = 1
count += 1
print(count)

Output

2

Worked example — the sum of 1 to 5. The counter n walks through 1, 2, 3, 4, and 5, and the accumulator total collects them. Predict the printed line.

total = 0
n = 1
while n <= 5:
    total += n
    n += 1
print(total)

Output

15

The table traces each pass. Each row shows the values at the top of the pass and at the end of it.

Each pass of the sum-of-1-to-5 loop: n and total before and after
Pass n at the test Is n at most 5? total after the pass n after the pass
1 1 True 1 2
2 2 True 3 3
3 3 True 6 4
4 4 True 10 5
5 5 True 15 6
(no pass) 6 False 15 6

In words: the loop added 1 + 2 + 3 + 4 + 5 = 15, and it made 5 passes. Notice the last row. When the loop ended, n was 6, not 5.

For every loop, predict three things: what it prints, how many passes it makes, and the counter's final value. Here is the pinned counter program from the course's predict-the-output set.

count = 1
while count <= 5:
    count = count + 1
print(count)

Output

6

It made 5 passes, one for each of 1, 2, 3, 4, and 5. The counter ends one past 5, the last value that passed the test, so it prints 6. In words: a counter stops on the first value that fails the test, never on the last value that passed it.

Worked example — the pledge walk. An illustrative charity walk on campus pledges 5 dollars for lap 1, 10 for lap 2, and so on, 5 dollars more for each lap. Walkers do 4 laps.

total = 0
lap = 1
while lap <= 4:
    total += lap * 5
    lap += 1
print(total)
print(lap)

Output

50
5

The pledges are 5, 10, 15, and 20 dollars, and 5 + 10 + 15 + 20 = 50. The counter lap ends at 5, one past 4.

Misconception check. Students often think the counter of while count <= 5 ends at 5, because 5 is the last number in the condition. That is tempting, but the loop can stop only by failing its test, and 5 passes the test 5 <= 5. So the body runs once more, count becomes 6, and only 6 <= 5 is False. The cure: the counter's final value is the first value that fails the test, one past the last value that passed.

In practice (your tools). Paste the sum-of-1-to-5 program into Python Tutor and step through it. Before each click, say aloud the next values of n and total, then check the frames panel. A tracing table like the one above, filled in before you run, is the habit the quizzes and Coding Labs ask for.

Memory hook: start it before, change it inside, read it after.

4. Test the edge: less than versus less than or equal to

A doorman counting guests into a room for 5 people must decide: does the 5th guest get in? "Fewer than 5" turns the 5th away. "Up to 5" lets the 5th in. One word changes the count by one. In a loop, one character does the same.

An off-by-one error is a logic mistake in which a loop runs one pass too many or one pass too few, most often because a condition uses less than where it needed less than or equal to, or the reverse.

Worked example — two loops, one character apart. Both loops start at 1 and add 1 each pass. Predict how many lines each prints.

count = 1
while count < 5:
    print(count)
    count += 1
print(count)

Output

1
2
3
4
5
count = 1
while count <= 5:
    print(count)
    count += 1
print(count)

Output

1
2
3
4
5
6

Read them carefully. Inside the first loop, with <, the body printed 1, 2, 3, and 4, four lines from four passes; the fifth line, 5, is the print after the loop showing the counter's final value. Inside the second loop, with <=, the body printed 1, 2, 3, 4, and 5, five lines from five passes; the last line, 6, is the counter after the loop. In words: < 5 stops before 5, and <= 5 includes it.

Worked example — the microwave countdown. An illustrative kitchen timer should show 3, 2, 1 and then announce it is ready.

seconds = 3
while seconds > 0:
    print(seconds)
    seconds = seconds - 1
print("Ready")

Output

3
2
1
Ready

Now suppose the condition were written seconds > 1 by mistake.

seconds = 3
while seconds > 1:
    print(seconds)
    seconds = seconds - 1
print("Ready")

Output

3
2
Ready

The 1 never shows, because 1 > 1 is False. That is an off-by-one error in the "one too few" direction. The program ran with no error message, so only a careful trace or a run with your eyes on the output catches it.

Misconception check. Students often think < n and <= n give the same number of passes, since both "go up to n." That is tempting, but they differ on exactly one value: n itself. count < 5 is False when count is 5, and count <= 5 is True. The cure: test the edge. Ask, "When the counter equals the number in the condition, does the body run?" and write down the last value you expect to print before you run the loop.

In practice (your tools). In your browser runner, run the count < 5 loop, change < to <=, and run it again. Count the printed lines both times. When a loop prints one line too many or too few, look first at the comparison in the while line, then at the counter's starting value.

Memory hook: test the edge: does the body run when the counter equals the limit?

5. Stop a runaway: infinite loops and how to end them

A dog chasing its own tail never catches it, because every step it takes moves the tail too. A loop can be stuck the same way: the body runs, but nothing it does ever moves the condition toward False.

An infinite loop is a loop whose condition never becomes False because nothing in its body moves it toward the stop, so the program keeps running until someone stops it by hand.

Worked example — the missing update. This loop was meant to print 1 to 5, but its author forgot one line. Do not run it until you have read how to stop it.

count = 1
while count <= 5:
    print(count)

When this program runs, it prints 1 on one line, then 1 again, then 1 again, and it never stops on its own. Here is why: count starts at 1, and nothing in the body changes it, so the test 1 <= 5 is True on every pass. The computer is not broken. It is doing exactly what you wrote, over and over.

To stop a running program, press Ctrl+C, the key press that interrupts a running program in a terminal, the usual way to stop an infinite loop; browser editors offer a Stop button that does the same job. After you stop it, the cure is the update line the body forgot.

count = 1
while count <= 5:
    print(count)
    count += 1

Output

1
2
3
4
5

Now each pass moves count one step toward 6, and the test 6 <= 5 ends the loop.

An update can also move the wrong way. In this illustrative savings jar, the owner meant to add 10 dollars each week until the jar holds at least 100.

balance = 50
while balance < 100:
    balance = balance - 10

This loop never ends. The minus sign sends balance to 40, then 30, then 20, farther from 100 on every pass, so balance < 100 stays True forever. Changing - to + repairs it.

Misconception check. Students often think a program that keeps running with no output, or with the same line over and over, means the computer or the website is broken. That is tempting, because nothing on the page explains what is happening. But a stuck program almost always means an infinite loop: the computer is doing exactly what the code says. The cure: stop it with Ctrl+C or the Stop button, then ask one question of the loop body, "Which line moves the condition toward False?" If no line does, add one.

In practice (your tools). In your free browser Python runner, the editor's Stop button ends a program that will not stop; in a terminal, Ctrl+C does the same job. Run the missing-update loop once on purpose, watch the 1s pile up, and press Stop. Then add count += 1 as the last body line and run it again. Before you run any loop, find the line that changes the counter.

Memory hook: every loop needs a line that moves it toward the stop.

6. Leave from the middle: while True, break, and checking a chatbot

A person searching a drawer for a key does not know in advance how many things to pick up. The rule is: keep picking things up, and the moment you find the key, stop. The stopping test sits in the middle of the search, not at the start. Python writes that rule with while True and break.

break is the keyword that ends the loop it sits in at once, skipping the rest of the body, so Python carries on with the first line after the loop.

while True is a loop header whose condition can never turn False on its own, used on purpose when a break inside the body decides when the repeating stops.

Worked example — the first square past 50. This is the pinned program from the course's language-guarantees set. It looks for the first whole number whose square is greater than 50.

n = 1
while True:
    if n * n > 50:
        print(n)
        break
    n = n + 1

Output

8

Trace it. When n is 7, the test checks 7 × 7 = 49, and 49 is not greater than 50, so n becomes 8. On the next pass the test checks 8 × 8 = 64, which is greater than 50, so the program prints 8 and break ends the loop. In words: the first whole number whose square passes 50 is 8.

Worked example — the board game. In an illustrative board game, a token moves 3 squares each turn, and play stops as soon as the token passes square 10.

position = 0
turns = 0
while True:
    position = position + 3
    turns = turns + 1
    if position > 10:
        break
print(turns, position)

Output

4 12

After 4 turns the token is on square 4 × 3 = 12, the first position past 10, and the break sends Python to the print line.

Python also has a related keyword, continue, which skips to the next pass instead of leaving the loop. It comes later in the course; this week you only need its name.

Worked example — checking a chatbot's claim. Suppose you ask a chatbot what the pinned counter program from Section 3 prints, and it answers 5, explaining that the loop "counts up to 5." That sounds reasonable. Your job is to check it, not to believe it.

count = 1
while count <= 5:
    count = count + 1
print(count)

Output

6

The run printed 6. The chatbot reported the last value that passed the test instead of the first value that failed it. You caught it by running four lines, which is the habit this course grades. When you want the official word on break, the Python Tutorial's section 4.4 on docs.python.org is where it is written down.

Misconception check. Students often think while True is always a bug, because Section 5 showed that a loop that never turns False runs forever. That is tempting, but while True is a planned loop when the body holds a break that the program is sure to reach. The pinned program reaches its break at n = 8. The cure: for every while True, point to the break and to the line that moves the program toward it.

In practice (your tools). Ask your approved chatbot what the pinned counter program prints, and write its prediction down. Then run the four lines in your browser runner and compare. Paste the first-square program into Python Tutor and step forward until the arrow lands on break; on the next click it jumps out of the loop.

Honesty note: this chapter covers only the while loop. Python's other loop, for, often counts passes more neatly, and it comes next week.

Caveat: every loop in this chapter uses small whole numbers chosen so you can trace it by hand. Real programs loop thousands of times, and the habits of a trace table, testing the edge, and finding the update line are what make that safe.

Pause and choose one of these to think about before you read on:

  • (a) Think of a routine you repeat until something is done, such as rinsing a dish until it is clean or saving until you can buy something. What is its test, what is its body, and what moves it toward the stop?
  • (b) Think of a time a count you made came out one too many or one too few, such as counting fence posts or days on a trip. Which edge did you count wrong, and how would a test-the-edge check have caught it?

Memory hook: while True needs a break you are sure to reach.

Key terms

  • while loop — A statement that repeats its indented body for as long as its condition is True, checking that condition once at the top of every pass and never in the middle of one. (first used: 1. Repeat with while: the body runs again while the test is True)
  • loop condition — The Boolean expression written after the keyword while; Python tests it before each pass and stops repeating the first time it comes out False. (first used: 1. Repeat with while: the body runs again while the test is True)
  • loop body — The indented lines under a while line, which Python runs from top to bottom on every pass before it returns to test the condition again. (first used: 1. Repeat with while: the body runs again while the test is True)
  • pass — One complete run through a loop's body, from its first indented line to its last; a loop that ran five times made five passes. (first used: 1. Repeat with while: the body runs again while the test is True)
  • counter — A name that gets a starting value before a loop and goes up by one on every pass, so its value tells you how many passes have run. (first used: 3. Count and total: counters, accumulators, and the final value)
  • accumulator — A name that starts at a value such as 0 before a loop and collects a running total, with each pass adding the current amount to it. (first used: 3. Count and total: counters, accumulators, and the final value)
  • += — The augmented assignment operator, a shorthand that adds the value on its right to the name on its left and stores the sum back in that name, so count += 1 means count = count + 1. (first used: 3. Count and total: counters, accumulators, and the final value)
  • off-by-one error — A logic mistake in which a loop runs one pass too many or one pass too few, most often because a condition uses less than where it needed less than or equal to, or the reverse. (first used: 4. Test the edge: less than versus less than or equal to)
  • infinite loop — A loop whose condition never becomes False because nothing in its body moves it toward the stop, so the program keeps running until someone stops it by hand. (first used: 5. Stop a runaway: infinite loops and how to end them)
  • Ctrl+C — The key press that interrupts a running program in a terminal, the usual way to stop an infinite loop; browser editors offer a Stop button that does the same job. (first used: 5. Stop a runaway: infinite loops and how to end them)
  • break — The keyword that ends the loop it sits in at once, skipping the rest of the body, so Python carries on with the first line after the loop. (first used: 6. Leave from the middle: while True, break, and checking a chatbot)
  • while True — A loop header whose condition can never turn False on its own, used on purpose when a break inside the body decides when the repeating stops. (first used: 6. Leave from the middle: while True, break, and checking a chatbot)

Summary

  • A while loop repeats its body for as long as its condition is True.
  • The condition is tested only at the top of each pass, so a loop can carry a total past its goal.
  • Give a counter or an accumulator its starting value before the loop; count += 1 adds 1.
  • For every loop, predict what it prints, how many passes it makes, and the counter's final value.
  • A counter ends on the first value that fails the test, one past the last value that passed.
  • < and <= differ on one value; test the edge to catch an off-by-one error.
  • A loop with no update that moves it toward the stop is an infinite loop; stop it with Ctrl+C or the Stop button.
  • while True is safe when the body holds a break the program is sure to reach.

Check your understanding

Work these before looking at the answers — they are ungraded, and the answers (with reasoning) are at the bottom of the page.

  1. A water-bottle program starts with cups = 0 and runs while cups < 7: with the body cups = cups + 2, then print(cups) after the loop. What prints, and how many passes did the loop make?
  2. A running-track program starts with lap = 1, runs while lap <= 8: with the body lap += 1, and then prints lap. What prints, and why is it not 8?
  3. A bus app should print the stop numbers 1 to 6. Its loop starts at stop = 1, runs while stop < 6:, prints stop, and adds 1. How many stop numbers print, which one is missing, and what one-character fix repairs it?
  4. A game hands out 4 stars per try. The program starts with tries = 0, then runs while True: with the body tries += 1 followed by if tries * 4 > 18: and break, and prints tries after the loop. What prints?

Answers (worked reasoning — read after attempting)

  1. It prints 8, after 4 passes. The tests run at 0, 2, 4, and 6, all less than 7, so the body adds 2 four times: 0 + 4 × 2 = 8. The next test, 8 < 7, is False. Like the reading log, the loop carried the total past the limit, because the test runs only at the top of each pass.
  2. It prints 9. The loop runs for lap values 1 through 8, which is 8 passes. On the pass where lap is 8, the test 8 <= 8 is still True, so the body runs and lap becomes 9. Only 9 <= 8 is False. The counter ends one past the last value that passed.
  3. Five stop numbers print, 1 through 5, and 6 is missing. When stop is 6, the test 6 < 6 is False, so the body never prints 6. Changing < to <= repairs it, because 6 <= 6 is True. This is an off-by-one error in the "one too few" direction.
  4. It prints 5. After try 4, the test checks 4 × 4 = 16, which is not greater than 18, so the loop goes on. After try 5, it checks 5 × 4 = 20, which is greater than 18, so break ends the loop and print(tries) prints 5.

Next up in this module: the Readings & Resources page, the lecture tutorial, the practice set, and the quiz — and next week, the for loop and range() count the passes for you and add nested loops.

Built with The Course Maker · samples.thecoursemaker.com