When you know exactly how many times to repeat, you don’t need a condition — you need a counter. That’s the for loop, and it comes with one famous off-by-one trap.
Focus on what range() actually produces — that’s today’s
whole trap. Enrolled in our Runestone course? Open it from there so your progress counts.
Still in Programs. A while loop (3.1–3.2) runs
an unknown number of times — until a condition changes. A counting loop runs a
known number of times. Both are iteration; you pick the one that fits.
Python’s counting loop is
for i in range(...), and it hands you a counter i for free. The catch is
what range() actually counts — and it’s the source of the most famous
off-by-one error in programming.
for i in range(a, b) counts from a up to but not
including b. With one argument, range(b) starts at 0.
| Code | i takes the values | How many times |
|---|---|---|
| range(5) | 0, 1, 2, 3, 4 | 5 |
| range(1, 5) | 1, 2, 3, 4 | 4 |
| range(2, 8) | 2, 3, 4, 5, 6, 7 | 6 |
range(1, 5) does not include 5 — it
stops at 4. The end value is where it stops, not the last value it uses. To count the
values, subtract: b − a. It’s called a fencepost error because building a
10-foot fence with posts every foot needs 11 posts, not 10 — boundaries are easy to
miscount.
for i in range(1, 4): print(i)
REPEAT 3 TIMES { DISPLAY(i) /* you supply i */ }
Hover or tap a line to light its twin. The Python loop prints
1, 2, 3 — three passes. Note the difference: REPEAT n TIMES just
repeats; it does not give you a loop variable, so if you need a counter in
pseudocode you must create and update one yourself.
for loop when you know the count up front (“print the
7 times table,” “do this for every item”). Use a while loop when you
don’t (“keep asking until they type the password,” “save until you hit the
goal”). Same idea, different fit.
Set the start and stop and see exactly which values range() produces — and how
many. Watch what happens to the count when you change only the stop.
for loop or
REPEAT n TIMES.for loop updates each pass (the i in
for i in range(...)). REPEAT n TIMES has none unless you make one.range(1, 5) includes
5.Five questions. Write out the values range() produces before you count — that
kills the fencepost trap. Then pick your answer.
The off-by-one error is so common it has its own nickname among programmers. A loop that runs one time too many reads past the end of a list and crashes; one that runs one time too few silently skips the last item — the last customer, the last day, the last sensor reading. Neither announces itself.
These bugs have mispriced products, skipped the final frame of videos, and dropped the last record in reports. The whole defense is a habit you can build today: before trusting a loop, write out the exact values it visits and check the first and last one by hand. Boundaries are where the money leaks.
while loop handles unknown counts; the
for loop handles known ones.for loops shine when you walk through a list, one
element at a time.