University of Free Knowledge
QA 76.73 · fol. 9

Following the Counter by Hand

Tracing a loop line by line in a table reveals how the counter grows and where an off-by-one boundary error slips in. · 11 min

A loop hides its work. It says repeat this, and the machine runs the body many times while you see only the final result. To predict what a loop does — or to find why it does the wrong thing — you slow it down and record every pass by hand. That record is called a trace (a row-by-row account of the program as it runs), and building one is the most reliable debugging skill in this whole course.

Guess before you learn

How many lines does this loop print? `` i = 1 while i <= 3: print(i) i = i + 1 ``

THE DEPTH DIAL — the same idea, younger or deeper
9–12

9–12

Tracing turns an invisible process into a table you can audit. Each row is the program's state at one moment: the counter, the condition's truth value, the output. Read the rows until the condition is False. Two choices set a loop's length: the counter's start value and the comparison in the test. Change <= to <, or start at 0 instead of 1, and the number of passes shifts by one. That single-step shift at the boundary is the off-by-one error, and a trace table exposes it at once.

trace

A row-by-row record of a program's state as it runs: one row per step, with columns for each variable that changes and for any output.

Why is this true?

Why does changing the test from i <= n to i < n change how many times the loop runs?

Because the test decides what happens at the boundary. With i <= n, the value n still passes and the body runs for it; with i < n, the value n is refused and the loop runs one fewer time. The endpoints are where the count is won or lost.

Trueloop backFalsestart: i = 1test: i <= n ?body: print(i)update: i = i + 1end
PLATE I One pass is test, then body, then update. The test guards the boundary.

Trace the counter: while i <= 4 — the steps fade as you master them

1
The body runs with i = 1, printing 1. Then i = i + 1 sets i to what?
i = 1 + 1
2
Test 2 <= 4 is True, so the body prints 2. After i = i + 1?
i = 2 + 1
3
Test 3 <= 4 is True, so the body prints 3. After i = i + 1?
i = 3 + 1
4
Test 4 <= 4 is True, so the body prints 4. After i = i + 1?
i = 4 + 1
5
Test 5 <= 4 is now False, so the loop stops. What was the last number printed?
printed: 1 2 3 4
Retrieval Gate — answer before you continue 0 / 4

1.Trace this loop. What is the value of i on the line right after the loop ends? `` i = 0 while i < 3: i = i + 1 ``

2.How many times does the body of this loop run? `` k = 5 while k > 0: k = k - 1 ``

3.Put these events in the order they happen during one pass of a while loop.

  1. Evaluate the loop's test
  2. If true, run the body once
  3. Update the counter inside the body
  4. Jump back to the test

4.A loop is meant to print the numbers 1 through 10. It is written i = 1, then while i < 10:. What actually happens?

Now watch the counter itself. If you plot the value it holds on each pass, you get a staircase: one even step per pass, ending on the last value the test allows. Sketching that staircase before you run the code is how you feel an off-by-one coming — the line either stops one step short or reaches one step too far.

Ink That Thinks — guess first; the answer draws itself.
For the loop i = 1; while i <= 4: print(i); i = i + 1, place a point for the value printed on pass 1, 2, 3, and 4 — commit your guesses in pencil first.

0123450246pass numbervalue of i printed
Tap to place each point.
PLATE II How the counter grows — guess in graphite, truth in ink.
PASSII <= 4 ?PRINTED11True122True233True344True455False— stop
PLATE III The full trace of a four-pass loop — the fifth row is where it stops.
Retrieval Gate — answer before you continue 0 / 4

1.What does this print? `` for i in range(1, 5): print(i) ``

2.How many numbers does range(2, 12) produce?

3.In one sentence, describe how to find the last value a counter reaches in a while loop without running the code.

4.A 100-meter fence has a post every 10 meters, including one at each end. How many posts are there?

That is the whole method: a trace table makes a loop's every step visible, and the counter's staircase shows exactly where it starts and stops. Next folio begins Unit IV — you will name a block of steps once and run it whenever you call it, which is the first real tool for keeping large programs traceable.

Practice — new ink and old, interleaved

1.Review from folio 1: in what order does the computer run a program's statements?

2.What is the last value i takes in for i in range(2, 6):?

3.Does this loop ever stop? `` n = 3 while n > 0: print(n) ``

4.How many times does the body run? `` for i in range(4): print('hi') ``

5.Order what one row of a trace table records, in the sequence you fill it in.

  1. the counter's value at the start of the pass
  2. the test's truth value
  3. the output produced
  4. the counter's value after updating

6.(2 < 3) and (3 < 2) evaluates to?

7.What does 3 < 5 and 5 < 4 evaluate to?

8.not (5 == 5) evaluates to?

9.Evaluate 7 + 3 * 2 under Python's precedence rules.

10.How many numbers does range(0, 20, 5) produce?

The Call Slip — search everything Ctrl·K / ⌘K