Subjects ยท Computer Science & Data
Computer Science & Data: Error cataloguing for bugs
Keep a bug log that turns dozens of unrelated- looking failures into three or four wrong beliefs about how your tools work.
What you'll be able to do: Keep a bug log that turns dozens of unrelated- looking failures into three or four wrong beliefs about how your tools work.
Why this is the highest-value document a programmer can keep
Bugs cluster by concept, not by symptom. One misunderstanding, about scope, about mutation, about when something is evaluated, generates failures across completely different files, weeks apart, that look like separate incidents.
You will not notice that from inside. Each bug is urgent, gets fixed, and is forgotten. The pattern only exists across time, and working memory does not span three weeks.
The log externalises it. And in programming the entries are unusually good, because the evidence is exact: you have the code, the input, the expected output, and the actual output. No other subject gives you a record that precise.
The format
WHAT HAPPENED: the symptom, precisely
WHAT I EXPECTED: and why
WHAT WAS TRUE: the actual behaviour
WHAT I BELIEVED: the model I was running that made my expectation reasonable
HOW I FOUND IT: the move that located it
Two fields here that the general method doesn't have.
"What I believed" is, as always, the one everybody skips and the one that makes the log worth keeping. "Off-by-one in the loop" is a symptom. "I believed range(n) includes n" is a belief, and it's also about to cause a slicing bug and a boundary condition bug that you won't connect to this one.
"How I found it" is specific to this subject and unusually valuable. Over time it's a record of which debugging moves actually work for you, and it's the raw material for the flowchart in article 05. Most people discover they find bugs the same three ways and have never noticed.
The clusters that recur
Almost every beginner log collapses into a handful of these:
- Reference versus value. Assignment doesn't copy. Generates aliasing bugs, mutable default arguments, and surprising list behaviour.
- Scope and shadowing. Which name refers to what, where.
- Off-by-one and boundaries. Inclusive versus exclusive, empty collections, single-element cases.
- Evaluation timing. Lazy versus eager, closures capturing variables rather than values, async ordering.
- Type coercion. Silent conversions, truthiness, null-versus-missing.
- State that outlives what you thought. Module-level state, notebook cells run out of order, caches.
- Floating point. Equality comparisons, accumulation.
- Character encoding. Which shows up as one weird bug every six months forever.
Each is one belief producing many symptoms. A student with thirty entries usually has four or five of these, and naming them ends whole categories of bug.
The weekly analysis
Here are this week's bug log entries. Don't summarise them. Tell me what single misunderstanding about how the language or system works would explain the most of them, and which entries it doesn't cover.
And the one specific to this subject:
Looking at "how I found it" across my entries: what are my actual debugging moves, in order of how often they work? What move am I not using that would have found several of these faster?
That second question turns the log into deliberate practice on debugging itself, which nothing else in a programming education does.
Across the subject
Beginner programming. Reference-versus-value and scope dominate. Naming them explicitly ends the majority of confusing bugs.
Data analysis. Notebook state and silent type coercion. The log will show that half the bugs are "cells run out of order", which is a workflow fix rather than a knowledge fix.
SQL. Nulls in joins, and aggregate-versus-row confusion. Two beliefs, many wrong result sets.
ML. Leakage, shape mismatches, and train/test contamination. Log leakage incidents specially, they're the ones that make results look better, so nothing prompts you to look.
Concurrency. Shared mutable state and assumed ordering. Usually one belief about atomicity.
Systems and deployment. Environment differences and implicit dependencies, The "how I found it" field matters most here, because the moves are different.
Pitfalls
- Logging symptoms. "It crashed" is not an entry.
- Skipping "what I believed". Makes the log a list of fixed bugs, which is what version control already is.
- Logging every typo. Only log confident-and-wrong, plus repeats.
- Never analysing. A diary. Book the weekly review.
- Not using "how I found it". It's the only systematic feedback on your debugging procedure you will ever get.
- The tell: three months of entries and you can't name a belief about your tools that changed.
Try this today
Take the last three bugs you fixed. Write the five fields for each, especially the fourth.
Then ask what those three beliefs have in common. In programming the answer is frequently "they're the same belief", and it's usually about copying or about when things are evaluated.