Trace tables
Following an algorithm line by line, and tracing to find a logic error.
Covers OCR J277 2.1.2 Designing, creating and refining algorithms · AQA 8525 3.1.1 Representing algorithms · Edexcel 1CP2 1.2.4 The output of an algorithm
Do this lesson in the simulatorPrint it: worksheet (PDF) · answers (PDF) · as a web page
Guide: Trace tables explained
A program that runs without an error can still be wrong. To find out what an algorithm really does, programmers trace it: follow it line by line, by hand, writing down the value of every variable each time it changes. A trace table is where you write it down. It is how you check an algorithm before trusting it, and how exams test whether you understand one.
A first trace
total = 0
for i in range(1, 5):
total = total + i * 2
print(total)
One column per variable, plus a column for output. A new row every time something changes:
| i | total | output |
|---|---|---|
| 0 | ||
| 1 | 2 | |
| 2 | 6 | |
| 3 | 12 | |
| 4 | 20 | |
| 20 |
Work through it yourself on paper first, then run the program to check:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
total = 0
for i in range(1, 5):
total = total + i * 2
print(total)
Let the program trace itself
Adding a print inside the loop makes the program write its own trace table. This is exactly how programmers debug:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
x = 1
y = 10
print("x", "y")
while x < y:
x = x * 2
y = y - 1
print(x, y)
print("finished with x =", x)
Before you run it, trace it on paper. When does the loop stop, and why? Then run it and compare row by row. The first row where your table and the program disagree is where your understanding and the algorithm part company.
The Debug button does the same job on screen: it stops at each line and shows the variables as they change.
You do not even need the print. trace() fills in the table for you: name the variables, in quotes, and it writes a new row every time one of them changes, with the number of the line that changed it. Here it is on the program at the top of the page:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
# watch i and total: a new row every time one of them changes
trace("i", "total")
total = 0
for i in range(1, 5):
total = total + i * 2
print(total)
Line 8 is the for line, where i changes, and line 9 is where total changes, so each time round the loop takes two rows. The table at the top of the page puts both on one row. The values are the same and in the same order, and either layout earns the marks when it matches the table the question gives you. Use trace() to check your own tables, after you have done them by hand.
Tracing to find a bug
This program should give the average of five distance readings, 40, 35, 30, 25 and 20, which is 30. It prints something else:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
readings = [40, 35, 30, 25, 20]
for i in range(len(readings)):
total = 0
total = total + readings[i]
print("average:", total / len(readings))
It prints average: 4.0. No error message, so this is a logic error. A trace shows it straight away:
| i | readings[i] | total |
|---|---|---|
| 0 | 40 | 40 |
| 1 | 35 | 35 |
| 2 | 30 | 30 |
total never grows. It goes back to 0 every time round, because total = 0 is inside the loop. By the end, total holds only the last reading, 20, and 20 divided by 5 is 4.0.
Tracing a robot
The robot's position can go in a trace table too. Predict where this program leaves the robot, then run it:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
side = 10
for i in range(3):
forward(60, distance=side)
right(60, distance=side)
side = side + 5
print("at", position())
| i | side before the drives | moved up | moved right |
|---|---|---|---|
| 0 | 10 | 10 | 10 |
| 1 | 15 | 15 | 15 |
| 2 | 20 | 20 | 20 |
So it should end 45 cm up and 45 cm right. The robot's own report will be close but not exact, because a real (or simulated) robot drifts a little.
Task: trace and fix
Fix the average program so it prints average: 30.0. Keep a trace: inside the loop, print a line i=<i> total=<total> each time round, so the program shows its own trace table.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
readings = [40, 35, 30, 25, 20]
for i in range(len(readings)):
total = 0
total = total + readings[i]
print("average:", total / len(readings))
Challenges
- Trace
n = 27thenwhile n != 1: if n is even, n = n // 2, else n = 3 * n + 1for the first six rows. Then run it to see how long it really takes. - Write a trace table for the parking sensor's loop, with the distance, the gap and the beep count.
- Swap the two lines inside the
xandyloop above. Trace it again before running. Does it still stop?
Past paper questions on this
Real exam questions that test this, each worked through with a program you can run.
- AQA 8525 June 2023 Paper 1, Question 5: Trace a flowchart with a loop 3 marks
- AQA 8525 June 2022 Paper 1, Question 10: Trace a REPEAT UNTIL loop with DIV, then compare it with WHILE 8 marks
- OCR J277 June 2025 Paper 2, Question 6(d): Trace a loop that totals an array, then refine it 7 marks
- OCR J277 June 2024 Paper 2, Question 9(b): Trace an if, elseif, else algorithm that scores a javelin throw 4 marks
- OCR J277 June 2023 Paper 2, Question 1(b) to (d): An assignment, the arithmetic operators, and a do until trace table 7 marks
- Edexcel 1CP2 June 2022 Paper 1, Question 5: Computational thinking: a search that stops early, the strawberry trace table, a flowchart 18 marks