Values are invisible, which is why broken programs feel like magic. Write every value down after every line and the magic turns into a table — with the bug sitting in one row of it.
The single most useful thing you can do when a program is wrong is to stop reading it and start being it — walk the steps by hand, one at a time, writing down what every value is after every line.
This is called tracing or a trace table, and it is the closest thing this subject has to a superpower. It is also, not coincidentally, a thing you will be asked to do on an exam with no computer in front of you.
Here is why it works. When you read code, your brain reads what you meant. It skims. It fills gaps — exactly the gaps from level one. When you trace, you cannot skim, because you have to write down an actual number after every single line. The line where your written number stops matching what you expected is the bug. Not near the bug. The bug.
Values are invisible. When a program misbehaves you are staring at text that does not move, trying to imagine numbers that are not written anywhere. Of course it feels impossible. Tracing makes the invisible thing visible, and the mystery mostly evaporates.
Before you press anything: read the six lines and write down what you think the answer will be. Put your guess in the box. Being wrong here is genuinely useful — it shows you exactly which line you misread.
Press step. A row appears for every line that runs. Step back if you lose the thread.
| step | line | total | count |
|---|
Watch the count column. It went 1, 2, 3, 4, 5, 6 — and the moment it hit 6, the answer to “is count 5 or less?” became no, and the program left the loop. Line 5 is the only reason this program ever finishes.
Now watch total: 0, 1, 3, 6, 10, 15. It never jumps. Every value is the one before it plus the current count. If you had traced a broken version, the first row where that pattern breaks would be the line to go and look at. That is debugging, and you already know how to do it.
Four columns, one row per line that runs. It looks slow. It is slow. It is also the difference between an answer and a guess, and graders give marks for the table itself — your course description lists “test/debug” as a named skill, and this is what that means before you own a debugger.
Read one line out loud. Only one. Then stop and wait. Do not read ahead, and do not explain what is about to happen.
After every line, say every value out loud and write it down. “total is 3, count is 3.” Every line. Even the boring ones.
Then change line 3 to “while count is 10 or less” and do it again — but predict the answer first. When your prediction and your table disagree, the table is right. That sentence will save you hours this semester.
Reading code shows you what you meant. Tracing shows you what it does.
Not near it. It. Debugging is mostly finding the first row that surprises you.
Guessing first turns a boring exercise into a test of what you actually believe.
Not recall — these are the shapes an exam actually uses. Every answer below was produced by compiling and running the code, so if you disagree with one, the compiler is the one to believe.
Have a real go before revealing. Being wrong here is worth more than being right in three weeks.
total starts at 0, count at 1. The loop adds count to total and then adds 1 to count, while count is 5 or less. What is total at the end?
And what is count when the loop finally stops?
You trace a broken program and row 7 is the first number that surprises you. Where is the bug?
← back to all 12 levels · stuck on anything? ask peter.