CurriculumPython while Loops, break and continue for KidsBoundaries and every-path updates

Off-by-One Errors at the Edge of a Python while Loop

Off-by-one at the edge of a while loop — and the update that has to happen on EVERY branch, not just one.

Lesson 5 of 5PROAges 10+
See what PRO unlocks →

Boundaries and every-path updates

You know a while loop needs its condition updated every pass, or it never stops. Now for two subtler versions of the same idea.

checkpoint < 5 stops the INSTANT checkpoint reaches 5 — so 5 itself is never checked, and never printed.

checkpoint = 1
while checkpoint < 5:
    print("Checkpoint", checkpoint)
    checkpoint = checkpoint + 1

Output

Checkpoint 1
Checkpoint 2
Checkpoint 3
Checkpoint 4

Only 4 checkpoints printed, even though the story asked for 5. Swap < for <=, and 5 gets included too.

checkpoint = 1
while checkpoint <= 5:
    print("Checkpoint", checkpoint)
    checkpoint = checkpoint + 1

Output

Checkpoint 1
Checkpoint 2
Checkpoint 3
Checkpoint 4
Checkpoint 5

That's the boundary trap: < and <= look almost identical, but they disagree on exactly one value — the edge itself.

Now a different, sneakier version of s1's 'forgot to update' bug — one where only ONE branch forgets.

crates 1-5 move, but crate 4 is heavy and needs a different message. Watch what happens if ONLY the else branch updates crate.

crate = 1
while crate <= 5:
    if crate == 4:
        print("Heavy - using both claws")
    else:
        print("Crate", crate, "moved")
        crate = crate + 1

Crates 1, 2, 3 move fine — the else branch runs and updates crate every time. But the moment crate reaches 4, the if branch runs instead, and IT never updates crate. crate is stuck at 4 forever.

The loop doesn't stall on the very first pass this time — it runs perfectly for a while, which is exactly what makes this bug easy to miss just by reading the code once.

The fix: EVERY branch that can run needs its OWN update. Not just the branch you tested first.

crate = 1
while crate <= 5:
    if crate == 4:
        print("Heavy - using both claws")
        crate = crate + 1
    else:
        print("Crate", crate, "moved")
        crate = crate + 1

Output

Crate 1 moved
Crate 2 moved
Crate 3 moved
Heavy - using both claws
Crate 5 moved

Check your understanding

checkpoint = 1, and the loop uses while checkpoint < 5:. How many checkpoints get printed?

checkpoint = 1
while checkpoint < 5:
    print("Checkpoint", checkpoint)
    checkpoint = checkpoint + 1
  • 4 — checkpoints 1, 2, 3, 4, but never 5
  • 5 — checkpoints 1 through 5, all of them
  • It never stops, because checkpoint never reaches exactly 4

Why: 4 checkpoints — 1 through 4. checkpoint < 5 becomes False the moment checkpoint reaches 5, so 5 itself never gets printed. Using <= 5 instead would include it, since <= stays True right up to and including the boundary value.

crate = 1..5, and only the else branch has crate = crate + 1 — the if crate == 4: branch has none. What happens?

crate = 1
while crate <= 5:
    if crate == 4:
        print("Heavy - using both claws")
    else:
        print("Crate", crate, "moved")
        crate = crate + 1
  • Crates 1-3 move fine, then the loop gets stuck forever once crate reaches 4
  • The loop gets stuck immediately, on crate 1
  • Python automatically updates crate anyway, since it can tell the loop needs to progress

Why: Crates 1, 2, and 3 print and move normally, because they all take the else branch, which updates crate correctly. The bug only appears once crate reaches 4 and the if branch runs instead — that branch has no update at all, so crate is stuck at 4 and crate <= 5 stays True forever. EVERY branch that can run needs its own update, not just the one you happened to test first.

What you'll practice

The dragon checks checkpoints 1 through 5 — ALL FIVE, including checkpoint 5 itself. Fill in the condition so the loop includes 5, not stops one short of it.

Unlock this lesson with PRO →

More from this topic

Boundaries and every-path updates is one lesson inside Python while Loops, break and continue for Kids — see the full lesson order and what the whole topic covers.

View the full topic →