Review
Reconstruct the path from a crash or wrong result through location, relevant state, first broken assumption, policy, repair, and regression verification.
Begin with the Symptom
A program can fail in two broad ways. It can stop and show a traceback, or it can finish and produce an answer that does not follow from the intended rules. Both cases call for evidence before editing.
Keep the exact input that exposed the problem. Run the unchanged program once more when that is safe and practical. Record what it printed, where it stopped, or which result was wrong. This gives later changes something concrete to compare against.
Follow Evidence Backward
For a traceback, begin with the final exception line and then find the deepest relevant frame in your code. The failing expression tells us where Python could not continue. It does not always tell us where the cause began.
Inspect the state immediately before that expression:
- the value and type being used;
- the current loop position and intermediate totals;
- the length of a sequence or the keys in a dictionary;
- the arguments and local values in the current function call.
Then trace the first unsuitable value or broken relationship backward. Remove temporary diagnostic output after the repair has been checked.
Treat a Wrong Answer as a Trace
A plausible number is not evidence that a calculation is correct. Work through one small case by hand, then compare the expected and actual state after each step. The first row where they differ is more useful than the final difference.
For the readings [18.0, None, 24.0], the available total is 42.0, the
available count is 2, and the mean is 21.0. Dividing by the three list
positions produces 14.0. The first bad state appears when count increases
for None. The wrong denominator and final answer are later consequences.
Choose the Program's Policy
Finding the cause does not by itself decide what the program should do. Four different policies appear in this chapter:
| Situation | Policy |
|---|---|
| No legitimate reading is available | Return None as the stated result |
| A caller supplies impossible threshold order | Raise ValueError near that boundary |
| Internal counters violate a rule the program relies on | Assert the invariant where it can first break |
| Numeric text can predictably be invalid and the program has a stated response | Catch that specific conversion failure in a narrow handler |
These choices are not interchangeable. An assertion is not input validation, and a broad exception handler is not a repair.
Reduce, Repair, and Keep the Check
When a failure is buried in a larger input, remove one unrelated part and run again. Keep the reduction only if the same operation still fails for the same reason. A new exception is a different experiment, not a successful reduction.
Reduction makes the cause easier to see; repair changes the cause. After the small case works, apply the repair to the real program and rerun the original input. Keep a regression check that would fail if the same defect returned.
The complete method is therefore:
symptom
→ location
→ relevant state
→ first broken assumption
→ policy
→ repair
→ regression check