Trace tables explained

How to complete a trace table for GCSE Computer Science: a column per variable, the output, and a new row when a value changes. Watch a robot program print its own trace table as it runs, then try six practice questions with answers.

Guidefree, runs in your browser

A trace table is a record of what a program does, step by step. You pretend to be the computer. You go through the algorithm one line at a time and write down the value of each variable every time it changes. It is how you work out what an algorithm outputs, what it is for, and where it goes wrong, without running it. That is why trace table questions come up so often in GCSE Computer Science exams.

On this page each demo is a robot program that prints its own trace table as it runs, one row at a time. Trace the program on paper first. Then press Run and check your table against the real one, row by row. The first row where they differ is the line you misread.

What a trace table is for

A trace by hand is also called a dry run. You use one to:

  • find the output of an algorithm for some given input;
  • work out the purpose of an algorithm: what it is for;
  • find a logic error, where the program runs but gives the wrong answer.

A computer does not get bored or guess. A trace makes you work in the same way. You cannot skip a step because you think you know what happens next.

How to lay out a trace table

  1. Draw a column for every variable, plus a column for the output. Some questions add a column for a condition, such as count <= 3. Write true or false in it.
  2. Write the starting values on the first row.
  3. Go through the algorithm one line at a time, in the order the computer runs it.
  4. Write a value only when it changes. Leave the cell empty when it stays the same.
  5. At a loop, check the condition every time round, and write the result.

Here is a short algorithm to try it on.

speed = 10
FOR i = 1 TO 3
    speed = speed + 5
ENDFOR
OUTPUT speed

There are two common ways to lay out the rows. The first puts each change on its own row. It is the layout our GCSE lesson on trace tables teaches, because it keeps the exact order things changed in.

i speed output
10
1
15
2
20
3
25
25

The second puts one row for each time round the loop, with the values at the end of that pass.

i speed output
10
1 15
2 20
3 25
25

Both show the same values in the same order. Mark schemes give the marks for the right values in the right order, and usually accept either layout. If the question gives you a table, fill it in the way it is drawn. If it gives you a blank space, one change per row is the safe choice.

FOR i = 1 TO 3 includes 3, so the loop runs three times. Python's range(1, 4) does the same job, because range stops before its second number.

Make a program print its trace table

A program can keep its own trace table. Every demo below starts with this small function:

def row(*cells):
    # print one row of the trace table
    print("".join(f"{str(c):>10}" for c in cells))

row prints each value it is given in a space 10 characters wide, lined up on the right, so the columns line up. row("step", "total") prints the headings. row(step, total) prints the values. An empty string, "", leaves a cell blank. Each demo calls row once for the headings, once for the starting values, and once each time round the loop. It also plots one variable, so you can see its values as a line.

Tracing a FOR loop

The robot drives forward four times. Each move is 5 cm longer than the one before: 5, 10, 15, then 20 cm. total adds up how far it has gone. Trace it on paper before you press Run.

The robot drives 5, 10, 15 and 20 cm, and prints a row of its trace table after each move. total ends at 50 cm.
The program
from bugbot import *
connect()

def row(*cells):
    # print one row of the trace table
    print("".join(f"{str(c):>10}" for c in cells))

# change the numbers and press Run
total = 0
row("step", "total", "output")
row("", total)
for step in range(1, 5):
    forward(50, distance=step * 5)
    total = total + step * 5
    row(step, total)
    plot("total", total)
row("", "", total)
Put this demo on your own site

Paste it into a school website, Moodle, Google Sites or a blog. More options on the embed page.

It prints:

      step     total    output
                   0
         1         5
         2        15
         3        30
         4        50
                            50

The first row has only the starting value of total. step has no value yet, because the loop has not started. range(1, 5) gives 1, 2, 3 and 4, so there are four rows for the loop. The last row holds the output, 50, on its own. The chart of total climbs in steps that get bigger: 5, 15, 30, 50. Change step * 5 to step * 10, trace it again, then run it to check.

Tracing a WHILE loop

A WHILE loop checks its condition before each pass. If the condition is false the first time, the body never runs at all. Here the robot drives towards a wall 10 cm at a time, for as long as the gap in front of it is more than 20 cm. gap is a real reading from the distance sensor on the front of the robot, rounded to a whole number.

The robot starts 61 cm from the wall and drives 10 cm at a time while the gap is more than 20 cm. It makes 5 moves and stops 10 cm from the wall.
The program
from bugbot import *
connect()

def row(*cells):
    # print one row of the trace table
    print("".join(f"{str(c):>10}" for c in cells))

# change the numbers and press Run
moves = 0
gap = round(distance())
row("moves", "gap", "gap > 20", "output")
row(moves, gap, gap > 20)
plot("gap", gap)
while gap > 20:
    forward(50, distance=10)
    moves = moves + 1
    gap = round(distance())
    row(moves, gap, gap > 20)
    plot("gap", gap)
row("", "", "", moves)
Put this demo on your own site

Paste it into a school website, Moodle, Google Sites or a blog. More options on the embed page.

It prints:

     moves       gap  gap > 20    output
         0        61      True
         1        51      True
         2        41      True
         3        30      True
         4        21      True
         5        10     False
                                       5

Python prints True and False. In an exam you would write true and false. Three things to see in this table:

  • The condition column says what the check found with the values on that row. The loop only stops on the row where it says False.
  • The robot stops 10 cm from the wall, not 20. At 21 cm the condition is still true, so the loop runs once more and the robot drives another 10 cm. The trace table shows exactly why.
  • The gap does not always fall by exactly 10. From 41 it falls to 30. A real robot never moves exactly 10 cm. A trace by hand assumes the program's numbers are exact, so for a robot it is a prediction, and the real table is the check.

Tracing selection: an IF inside a loop

An IF statement runs one branch or the other, never both. Give the condition its own column, and the trace shows which branch ran on each pass. This robot takes big 15 cm steps while the wall is more than 30 cm away, then small 5 cm steps.

While the gap is more than 30 cm the robot moves 15 cm at a time. Once it is 30 cm or less, it moves 5 cm at a time, and ends 5 cm from the wall.
The program
from bugbot import *
connect()

def row(*cells):
    # print one row of the trace table
    print("".join(f"{str(c):>10}" for c in cells))

# change the numbers and press Run
row("step", "gap", "gap > 30", "move")
for step in range(1, 7):
    gap = round(distance())
    if gap > 30:
        move = 15
    else:
        move = 5
    row(step, gap, gap > 30, move)
    plot("move", move)
    forward(50, distance=move)
print("gap at the end:", round(distance()))
Put this demo on your own site

Paste it into a school website, Moodle, Google Sites or a blog. More options on the embed page.

It prints:

      step       gap  gap > 30      move
         1        66      True        15
         2        50      True        15
         3        35      True        15
         4        20     False         5
         5        15     False         5
         6        10     False         5
gap at the end: 5

Read down the condition column. It is true for three passes and false for three, and the move column changes on the same row. The chart of move is a step down from 15 to 5. Try changing 30 to 40 and trace it again first. Which row does the condition turn false on now?

Finding an error with a trace table

This program should drive the robot four steps of 10 cm, which is 40 cm. It runs without an error message, but it prints 30. The program runs and gives the wrong answer, so this is a logic error. A trace table finds it.

The program should move 40 cm in four steps. The trace shows count starting at 1, so the check count < 4 is false after only three moves, and moved ends at 30.
The program
from bugbot import *
connect()

def row(*cells):
    # print one row of the trace table
    print("".join(f"{str(c):>10}" for c in cells))

# should drive 4 steps of 10 cm: 40 cm
count = 1
moved = 0
row("count", "moved", "count < 4", "output")
row(count, moved, count < 4)
while count < 4:
    forward(50, distance=10)
    moved = moved + 10
    count = count + 1
    row(count, moved, count < 4)
    plot("moved", moved)
row("", "", "", moved)
print("the robot is at", position())
Put this demo on your own site

Paste it into a school website, Moodle, Google Sites or a blog. More options on the embed page.

It prints:

     count     moved count < 4    output
         1         0      True
         2        10      True
         3        20      True
         4        30     False
                                      30
the robot is at (-0.3, 30.1)

There are only three rows where the robot moved. count starts at 1, and the check count < 4 is false as soon as count reaches 4. The robot's own position agrees: it went 30 cm forward. There are two ways to fix it: start count at 0, or change the check to count <= 4. Try the first. Change count = 1 to count = 0 and trace it before you run it. You should get one more row, with count at 4 and moved at 40, and the robot ends at (-0.6, 40.0).

This is the most common kind of bug in a loop: it runs one time too many or too few. Always check the condition at the boundary, < against <=, and the starting value of the counter.

Let the computer fill in the table: trace()

Writing row calls by hand is fine for one program. For any other, the BugBot simulator has a trace table generator built in. Put trace() near the top with the names of the variables to watch, in quotes, and every time one of them changes it prints a new row: the number of the line that changed it, and the new value.

trace() watching count and total prints a row every time one of them changes, headed by the line that changed it. The loop runs three times and the output is 6.
The program
from bugbot import *
connect()

trace("count", "total")    # the computer fills in the trace table

# change the numbers and press Run
total = 0
count = 1
while count <= 3:
    forward(50, distance=count * 5)
    total = total + count
    count = count + 1
    plot("total", total)
print("output:", total)
Put this demo on your own site

Paste it into a school website, Moodle, Google Sites or a blog. More options on the embed page.

It prints:

line   count   total
   7               0
   8       1
  11               1
  12       2
  11               3
  12       3
  11               6
  12       4
output: 6

Each row is one change, and only the value that changed is written, exactly as the method above says. Line 11 is total = total + count and line 12 is count = count + 1, so you can see the loop take its turns: total, then count, three times, until count is 4 and count <= 3 is false. Write trace("count", "total", every="row") instead and every row shows both values, which is the layout some questions give you.

To trace any program: do the trace by hand first, then add one trace(...) line and run it to check. It works on the programs in the practice questions below, once they are written in Python. In the BugBot lessons, the Debug button does a similar job on screen: it stops at each line and shows the variables as they change.

Mistakes that lose marks

  • Missing the last check. A WHILE loop always ends with a check that is false. That check is a row.
  • Running the body before the check. A WHILE loop tests first. If the condition starts false, the body never runs.
  • Off by one. FOR i = 1 TO 4 runs four times, including 4. Python's range(1, 4) runs three times, and stops before 4.
  • Two changes on one row, when the table is laid out as one row per change.
  • A variable reset inside the loop when it should be set once, before it.
  • Integer division. 7 DIV 2 is 3, and 7 MOD 2 is 1. In Python they are 7 // 2 and 7 % 2.
  • Output written wrongly. Write exactly what is printed. OUTPUT "fast" prints fast, without the quote marks.

Practice questions

Try each one on paper before you look at the answers below. The algorithms use a plain pseudocode like the exam boards' own. Lists start at index 0. FOR i = 0 TO 4 includes 4, so it runs five times.

Question 1: a FOR loop

speed = 3
FOR i = 1 TO 3
    speed = speed * 2 - i
ENDFOR
OUTPUT speed

Complete a trace table with the columns i, speed and output.

Question 2: a WHILE loop

A robot makes trips until its battery is too low.

battery = 100
trips = 0
WHILE battery >= 30
    battery = battery - 25
    trips = trips + 1
ENDWHILE
OUTPUT trips

Complete a trace table with the columns battery, trips, battery >= 30 and output.

Question 3: an IF inside a loop

The robot has taken five distance readings, in cm.

readings = [35, 12, 48, 9, 20]
near = 0
FOR i = 0 TO 4
    IF readings[i] < 15 THEN
        near = near + 1
    ENDIF
ENDFOR
OUTPUT near

Complete a trace table with the columns i, readings[i], readings[i] < 15, near and output.

Question 4: output inside a loop

gap = 50
WHILE gap > 0
    IF gap > 20 THEN
        gap = gap - 20
        OUTPUT "fast"
    ELSE
        gap = gap - 10
        OUTPUT "slow"
    ENDIF
ENDWHILE

Complete a trace table with the columns gap and output.

Question 5: find the error

This algorithm should output the largest reading. It does not.

readings = [18, 42, 7, 30]
biggest = 0
FOR i = 0 TO 3
    IF readings[i] < biggest THEN
        biggest = readings[i]
    ENDIF
ENDFOR
OUTPUT biggest

Complete a trace table with the columns i, readings[i], biggest and output. State the output, explain the error, and give the fix.

Question 6: its purpose

DIV is whole number division: 13 DIV 2 is 6.

n = 13
count = 0
WHILE n > 0
    n = n DIV 2
    count = count + 1
ENDWHILE
OUTPUT count

Complete a trace table with the columns n, count, n > 0 and output. Then say what the algorithm does.

Answers

These use one row each time round the loop. Question 2 is also shown with one row per change, so you can compare the layouts.

Question 1. The output is 13.

i speed output
3
1 5
2 8
3 13
13

Question 2. The output is 3. After the third trip the battery is 25, the check is false, and the loop ends.

battery trips battery >= 30 output
100 0 true
75 1 true
50 2 true
25 3 false
3

The same trace with one row per change:

battery trips battery >= 30 output
100 0
75 true
1
50 true
2
25 true
3
false 3

Question 3. The output is 2. near only changes on the rows where the condition is true.

i readings[i] readings[i] < 15 near output
0
0 35 false
1 12 true 1
2 48 false
3 9 true 2
4 20 false
2

Question 4. The output is fast, fast, slow, on three lines. When gap reaches 0, the check gap > 0 is false and the loop ends.

gap output
50
30 fast
10 fast
0 slow

Question 5. The output is 0. biggest never changes, because no reading is less than 0.

i readings[i] biggest output
0
0 18
1 42
2 7
3 30
0

The comparison is the wrong way round. It should be IF readings[i] > biggest THEN. With that fix, biggest becomes 18, then 42, and the output is 42.

Question 6. The output is 4.

n count n > 0 output
13 0 true
6 1 true
3 2 true
1 3 true
0 4 false
4

The algorithm counts how many binary digits n needs. 13 in binary is 1101, which is 4 digits. Each DIV 2 removes one binary digit from the right.

Questions

What is a trace table?

A table for following an algorithm by hand. It has a column for each variable and one for the output. You go through the algorithm a line at a time and write down each new value as it changes, so you can see what the algorithm does.

How do you complete a trace table?

Write the starting values on the first row. Then follow the algorithm one line at a time, in the order the computer would. Each time a variable changes, write its new value in its column. At every loop, check the condition and write the result. Write the output exactly as it would appear.

What is a trace table used for?

To find the output of an algorithm, to work out what an algorithm is for, and to find logic errors: mistakes where the program runs but gives the wrong answer. Programmers use the same idea to test an algorithm before they trust it.

What is a dry run?

Running an algorithm in your head or on paper, without a computer. A trace table is where you write a dry run down.

Do you start a new row every time a value changes?

That is the safest layout, and the one our GCSE lesson teaches. Many tables use one row each time round a loop instead. Mark schemes usually accept either, as long as the values are right and in the right order. If the question gives you a table, follow its layout.

Do you need to write a value if it has not changed?

No. Leave the cell empty. Write a value only when it changes, unless the question tells you otherwise.

How do you trace a WHILE loop?

Check the condition before each pass, using the values at that moment, and write true or false. If it is true, trace the body. If it is false, the loop ends. Always include the last check, the one that is false.

Can a trace table find syntax errors?

No. A syntax error stops a program from running at all, and the computer tells you where it is. A trace table is for logic errors, where the program runs but gives the wrong answer. The row where your table first differs from what you expected points to the line that is wrong.

Is there a trace table generator?

Every demo on this page is one. The row function prints a row of the trace table each time it is called, so any Python program can print its own. Copy it into your own program, trace it by hand first, then run it and compare.

Are trace tables on the GCSE Computer Science specification?

Yes, on all three main boards. OCR J277 includes them in designing, creating and refining algorithms (2.1.2). AQA 8525 asks you to use them to find the output, the purpose and the errors in an algorithm (3.1.1). Pearson Edexcel 1CP2 asks you to find the output of an algorithm and to use trace tables to do it (1.2.4). Our GCSE lessons F5.4 Trace tables and F13.2 Trace tables cover them, and A15.3 Trace tables and hand-tracing goes on to A level.

Learn it step by step

These lessons build the same ideas one at a time, each with tasks the simulator marks.

  1. F5.4 Trace tables Algorithms, GCSE
  2. F13.2 Trace tables Exam preparation, GCSE
  3. A15.3 Trace tables and hand-tracing Exam preparation, A level
Open the lessons