Debugging Loops and Tracing Execution
Iteration is the repeated execution of statements in a loop or recursive function, and understanding loop terminology is essential for writing correct loops.
Try it: Loop Tracer
How a Python for loop visits each item in turn, and how an accumulator variable (a total, a count, a best-so-far or a result list) changes on every iteration.
How it works
- Initialise the accumulator before the loop.
- Each iteration, the loop variable takes the next value from the list.
- An if inside the loop decides whether to update the accumulator.
- After the last item the loop ends and the accumulator holds the answer.
Default run (13 steps): values = [4, 9, 2, 7, 5]. Run the loop one statement at a time. … The loop has used every value. print(total) shows 27.
Simplified: A model of five fixed loop programs (sum, count, maximum, minimum, filter) run on your list — it steps the program exactly as Python would, but it does not run Python.
Loading the simulation…
Try it: Debug by Tracing Execution
How to debug a program that runs but gives the wrong answer: compare expected and actual output, trace the lines in the order they really run with a variable watch table (or an inserted debug print), find the first line where a value goes wrong, then choose a fix and re-run to check it.
How it works
- State the expected output from the specification, run the program and compare: a difference is the evidence you debug from.
- Trace in execution order, not file order: loops repeat lines, if/elif picks one branch, and the watch table records every variable before each line runs.
- An inserted print('debug: ...', value) shows the same state in the output; it must not change what the program itself prints.
- Look for the first place a value differs from what it should be (an off-by-one range, > instead of >=, a total reset inside the loop, two names for one list, a str from input()). Where the wrong value shows up is only the symptom.
- Change one thing with a reason, re-run, and compare again: a fix that makes an error disappear can still leave the output wrong.
Default run (14 steps): Sum 1..n: Add up the whole numbers from 1 to n (n included) and print the sum. Press Play to trace it line by line. … Finished, but the output is wrong: got sum of 1 to 5 is 10, expected sum of 1 to 5 is 15.
Simplified: The lab's own small Python interpreter runs fixed, hand-written programs (you pick the program, the fix and a value; your text is never executed). Every program the lab can show was run in CPython 3.12 and the lab reproduces its output, its traceback text and its line-by-line trace. Six short programs, one editable value each; input() receives the value you type in the lab. Lines starting with "debug:" are ignored when comparing the output with the expected output.
Loading the simulation…
Why Loop State Matters
A loop repeats a group of statements. Each repetition is an iteration. To debug a loop, do not look only at the statements inside the loop; track the values of the variables that determine what happens next. Initialization gives those variables starting values, the loop body uses or changes them, and an increment or decrement updates them for another possible iteration.
The Iteration Control Sequence
A useful tracing sequence has four parts. First, initialization assigns a starting value before the loop begins. Next, the loop condition is checked. If the condition allows another iteration, the loop body executes. Finally, an update changes one or more loop variables, and control returns to the condition. The same sequence repeats until the condition is false.
Counters and Accumulators
A counter and an accumulator both change during a loop, but they represent different ideas. A counter tracks how many times an event occurs. It increases by 1 or by another fixed amount on each iteration. An accumulator builds a running total by adding values that may vary from one iteration to the next. Many counters and accumulators begin at 0, although their purposes remain different.
| Variable role | What it represents | Typical update |
|---|---|---|
| Counter | How many times an event occurs | Increase by 1 or another fixed amount |
| Accumulator | A running total | Add a value that can vary by iteration |
The key difference is what the changing variable means.
A State Trace Across Iterations
Consider a loop with two variables. The counter starts at 0 and increases by 1 after each iteration. The accumulator also starts at 0, but it adds the changing values 4, 2, and 5. The table shows the state after each iteration. This is a generated example for practicing the tracing method.
| Point in execution | Counter | Accumulator | What changed |
|---|---|---|---|
| Before the loop | 0 | 0 | Both variables are initialized |
| After iteration 1 | 1 | 4 | The counter increases by 1; 4 is added |
| After iteration 2 | 2 | 6 | The counter increases by 1; 2 is added |
| After iteration 3 | 3 | 11 | The counter increases by 1; 5 is added |
A generated state trace separating fixed counting from changing-value accumulation.
Separating the Two Meanings
A loop processes three changing values: 4, 2, and 5. Track a counter and an accumulator, both initialized to 0.
- 1Initialize
Set the counter to 0 because no iterations have been completed, and set the accumulator to 0 because no values have been added.
- 2First iteration
Increase the counter by 1, giving 1. Add 4 to the accumulator, giving 4.
- 3Second iteration
Increase the counter by 1, giving 2. Add 2 to the accumulator, giving 6.
- 4Third iteration
Increase the counter by 1, giving 3. Add 5 to the accumulator, giving 11.
After three iterations, the counter is 3 and the accumulator is 11.
Recognizing Infinite Loops
An infinite loop occurs when the loop condition never becomes false. A common cause is a missing update: the variable used by the condition keeps its old value. Another cause is an incorrect update, such as changing the variable in a direction that does not move it toward the stopping condition. During debugging, identify the variable controlling the condition and check its value after every iteration.
Common mistake Using a loop variable before giving it a starting value.
What it looks likeThe variable that controls the loop has no initialization.
Why it failsThe loop begins without a defined starting state, making the loop's behavior unreliable.
Do this insteadInitialize each loop variable before the loop begins.
Common mistake Forgetting to update the variable that controls the condition.
What it looks likeThe loop body runs, but the controlling variable keeps the same value.
Why it failsThe condition can remain true indefinitely.
Do this insteadCheck that every iteration performs the required increment or decrement.
Common mistake Confusing an accumulator with a counter.
What it looks likeA variable intended to count events is updated by adding changing values.
Why it failsIts final value no longer represents the number of events.
Do this insteadUse a fixed update for a counter and varying additions for an accumulator.
Common mistake Updating in the wrong direction.
What it looks likeA decrement is used when the loop variable needs to increase toward the stopping condition.
Why it failsThe variable may move farther from the value that would make the condition false.
Do this insteadTrace the variable after each update and verify that it moves toward termination.
Practice the Trace
A loop starts a counter at 0 and an accumulator at 0. On each of four iterations, the counter increases by 1. The accumulator receives the values 3, 1, 4, and 2 in that order. Record the counter and accumulator after every iteration. Then explain which variable is the counter, which is the accumulator, and why the loop can stop after the fourth iteration.
Hints
- Write the initial state before any iteration: counter 0 and accumulator 0.
- Increase the counter by the same fixed amount on every iteration.
- Add one changing value to the accumulator on each iteration.
A loop variable begins at 5. After each iteration, it is supposed to move toward a condition that stops the loop at 0. Trace what you would inspect if the loop never stops: the initial value, the condition, the update, and the value after each iteration. Decide whether the likely issue is initialization, a missing update, or an update in the wrong direction.
Hints
- First identify the variable used by the stopping condition.
- Check whether its value changes after the loop body.
- Compare the direction of the update with the direction needed to reach 0.
Reliable Loop Tracing
- 1Write down the initialization value for every variable involved in the loop.
- 2Identify which variable controls whether another iteration occurs.
- 3Record the state before the first iteration and after each loop body execution.
- 4Separate fixed updates used by counters from varying additions used by accumulators.
- 5Verify that every update moves the controlling variable toward the condition becoming false.
Iteration means repeated execution. Initialization establishes the starting state, increments and decrements change variables by fixed amounts, counters measure occurrences, and accumulators build running totals from changing values. A loop is safe to continue only when its state changes in a direction that can eventually make its condition false. Tracing those state changes turns an unclear loop into a sequence of observable steps.
Key Takeaways
- Initialization assigns starting values before a loop begins.
- A counter tracks occurrences with a fixed update, while an accumulator builds a running total from varying values.
- An increment increases a variable and a decrement decreases it; both can update loop state.
- Tracing the value of a loop variable after every iteration reveals whether execution is progressing.
- A missing or incorrectly directed update can keep the loop condition true and cause an infinite loop.