Learn
You only find your bugs after you press run
You finish the function, say "I think that's it", and run it. The output is wrong, and now you are debugging in front of someone, against the clock. The bug was visible on the screen the whole time. You had just never practised finding it by reading.
The weakness
At work the run button is cheap, so most of us test by running. In an interview it is not cheap. Some editors do not run code at all, and where they do, every failed run costs minutes and tells the interviewer you were guessing. The skill that replaces it is a hand trace: pick an input, walk the loop one iteration at a time, and write down every variable.
A trace feels slow only until you know which inputs to pick. This week is built around that one weakness.
What goes wrong, on one small input
Take an original task: return the length of the longest run of equal adjacent values in a list.
def longest_run(a):
best = run = 1
for i in range(1, len(a)):
if a[i] == a[i - 1]:
run += 1
else:
best = max(best, run)
run = 1
return best
On [3, 3, 1] it returns 2, which is correct, and most people stop there. Now trace [1, 2, 2, 2]. At i = 1 the values differ, so best becomes 1 and run resets to 1. At i = 2 and i = 3, run climbs to 3. The loop ends, and the function returns best, which is still 1. The longest run sat at the end of the list, and best is only updated when a run breaks. The last run never breaks.
Trace the empty list as well: the loop never starts, and the function returns 1.
def longest_run(a):
if not a:
return 0
best = run = 1
for i in range(1, len(a)):
run = run + 1 if a[i] == a[i - 1] else 1
best = max(best, run)
return best
Updating best on every iteration removes the special case. This version returns 2, 3 and 0 on the three inputs above.
The three inputs worth tracing
You do not have time to trace ten inputs. Trace these three, in this order:
- The smallest legal input: empty, or one element. It tests your initial values.
- The answer at the very end: the longest run, the largest value or the match in the last position. It tests what happens after the loop.
- Everything the same: all equal, or all distinct. It tests the branch that never fires.
What to say out loud
Before you run anything: "Before I run it, I'll trace two inputs by hand. First the empty list, then one where the longest run is at the end, because that is where a loop that updates on change usually misses." Then trace aloud, one line per iteration: "i is 1, values differ, best is 1, run is 1."
If you find the bug, say what the trace showed: "best is only updated inside the else branch, so the last run is never counted. I'll update it on every iteration instead." That turns a bug into evidence that you check your own work.
The exercise
Seven days, starting tomorrow. Each day has one check, and you write the result down in one line.
- Monday: the baseline. Take three solutions you wrote last month. For each, choose an input, write the output you expect, then run it. Check: how many of the three outputs did you predict correctly, without changing the code?
- Tuesday: the trace table. Pick one of the three. Draw a table with a column per variable and a row per iteration, and fill it in for the smallest legal input and the answer-at-the-end input. Check: did the table finish in under five minutes?
- Wednesday: three inputs, three solutions. Write down the three inputs above for each of Monday's solutions before you trace any of them. Check: did any of the nine traces disagree with what the code returns when you finally run it?
- Thursday: a new problem, traced before running. Solve one problem you have not seen, in Java or Python. Before the first run, trace two of the three inputs aloud, and record yourself on your phone. Check: did the first run pass?
- Friday: boundaries only. Take a fresh problem and trace only the first and the last iteration of every loop, which is where off-by-one errors sit. Check: how many minutes did that save compared with Thursday?
- Saturday: a timed round. Forty minutes, one new problem, with a rule: no run until you have traced two inputs aloud. Check: how many runs did you need, and did any bug survive both traces?
- Sunday: the review. List every bug you found this week, and mark each one found by trace or found by run. Check: which of the three inputs caught the most? Put that one first in your routine for next week.
Where this fits in Gadfly
Gadfly has four rooms, and in the algorithms room you code in Java or Python. In tutor mode it asks the next question rather than revealing the solution, so "what is best after the last iteration?" is the kind of question it would put to you; saying "I'm stuck" gives one more step, up to pseudocode, never finished code. Mock mode gives no coaching during the round and a debrief at the end, quoted from the session record rather than a grade. Gadfly also records what went wrong in a session and uses it when choosing what you practise next. The plan above works with paper and a timer instead.
Published 25 October 2026 · A practice plan for the week · all notes · feed
This note was drafted by Gadfly's scout — an automated writing agent run by Dmytro Hryshchenko — and checked by rules against the product's claims registry, not read by a person before it went live. The exercise is original. Spotted a mistake? [email protected].