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 5
  • PRO
  • Ages 10+
  • 3 hands-on levels
See what PRO unlocksA one-time $49.99 purchase. Topics 1–3 are free.

The dragon explains

Boundaries and every-path updates

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

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

    example.pyPython 3
    checkpoint = 1while checkpoint < 5:    print("Checkpoint", checkpoint)    checkpoint = checkpoint + 1
    OutputCheckpoint 1 Checkpoint 2 Checkpoint 3 Checkpoint 4
  3. The dragon: Only 4 checkpoints printed, even though the story asked for 5. Swap < for <=, and 5 gets included too.

    example.pyPython 3
    checkpoint = 1while checkpoint <= 5:    print("Checkpoint", checkpoint)    checkpoint = checkpoint + 1
    OutputCheckpoint 1 Checkpoint 2 Checkpoint 3 Checkpoint 4 Checkpoint 5
  4. The dragon: That's the boundary trap: < and <= look almost identical, but they disagree on exactly one value — the edge itself.

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

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

    example.pyPython 3
    crate = 1while crate <= 5:    if crate == 4:        print("Heavy - using both claws")    else:        print("Crate", crate, "moved")        crate = crate + 1
  7. The dragon: 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.

  8. The dragon: 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.

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

    example.pyPython 3
    crate = 1while crate <= 5:    if crate == 4:        print("Heavy - using both claws")        crate = crate + 1    else:        print("Crate", crate, "moved")        crate = crate + 1
    OutputCrate 1 moved Crate 2 moved Crate 3 moved Heavy - using both claws Crate 5 moved

Quick check

Check your understanding

Say your answer out loud before reading the marked one. Every wrong option is a mistake real beginners make.

  1. Question 1 of 2

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

    question.pyPython 3
    checkpoint = 1while checkpoint < 5:    print("Checkpoint", checkpoint)    checkpoint = checkpoint + 1
    • 4 — checkpoints 1, 2, 3, 4, but never 5Correct
    • 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.

  2. Question 2 of 2

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

    question.pyPython 3
    crate = 1while 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 4Correct
    • 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.

In the game

What you'll practice

Three levels in the game: one guided first try with the shape of the answer already there, then two to solve on your own.

  1. 1

    GuidedYour first try

    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.

  2. +2

    PracticeTwo more, on your own

This lesson is part of PRO.

PRO is a one-time $49.99 purchase, no subscription, and unlocks this whole topic along with everything else. Topics 1–3 are free, start to finish.

Unlock this lesson with PRO

Stuck three times? The game offers the answer — unasked.