A long traceback can make a small defect feel larger than it is. This exercise starts with a fictional parcel record, reduces the problem to one dictionary and repairs a mismatch between the agreed field name and the code. The aim is to preserve the failure while removing distractions. No real parcel data, user account or production log is needed.
Documentation boundary
Python’s traceback module provides tools to extract and format stack traces. extract_tb returns frame summaries from a traceback. The worked example inspects the final frame’s function name without depending on an exact full error-message string or a local filesystem path.
State the expected behaviour
The fictional data contract calls the quantity mass. One record has mass two; another has mass five. The desired total is seven. A faulty helper instead requests weight. Your first task is to describe the difference between expected and observed behaviour in one sentence. “The programme is broken” is less useful than naming the requested field and the field actually present in the fixture.
| Case | Input size | Expected observation | Purpose |
|---|---|---|---|
| Original failing helper | One record | Missing weight key | Retain defect |
| Minimal corrected input | One record | Mass 2 | Check field repair |
| Original two-record task | Two records | Total 7 | Restore context |
| Empty agreed input | Zero records | Total 0 | Boundary check |
A minimal case should still fail for the same reason. Do not “simplify” by adding a weight field, because that removes the very mismatch you need to investigate. Remove unrelated records and display formatting first. Keep the contract and the single failing lookup. Write down why the reduced record is sufficient to reproduce the observed exception.
Work through the failure and repair
import traceback
def wrong_mass(row):
return row["weight"]
minimal = {"mass": 2}
try:
wrong_mass(minimal)
except KeyError as error:
frames = traceback.extract_tb(error.__traceback__)
assert frames[-1].name == "wrong_mass"
assert error.args == ("weight",)
else:
raise AssertionError("expected the original failure")
def total_mass(rows):
return sum(row["mass"] for row in rows)
assert total_mass([minimal]) == 2
assert total_mass([{"mass": 2}, {"mass": 5}]) == 7
assert total_mass([]) == 0
print("minimal case2; original case7; empty case0")
The captured failure identifies wrong_mass as the final function and weight as the missing key. The corrected calculation uses mass, yielding two for the reduced record and seven for the two-record fixture. The empty-input result is zero under the stated summing contract. These observations provide a chain of evidence from reproduction to repair rather than just a claim that the latest run completed.
The corrected function does not silently accept every record shape. A record lacking mass would still violate its input contract. That is a separate validation question. Keep this debugging task narrow: repair the proven field mismatch, then decide whether a later exercise should add a schema check. Mixing several speculative repairs into one change makes it harder to know which change addressed the original failure.
Recognise a misleading quick fix
Replacing the failing lookup with a default zero can hide the defect. The programme might stop raising an exception while still returning the wrong total. Under this fixture, a total of zero is evidence of lost quantities, not success. Compare the numerical result with the expected seven after every proposed repair. An absence of exceptions is weaker evidence than agreement with the observable contract.
Another unhelpful reaction is to rewrite the whole calculation before isolating the failing expression. Preserve a small version of the original failure and change one assumption at a time. If you rename the fixture and the code simultaneously, you can accidentally create a new contract rather than repair the intended one. A short decision log should say which side was authoritative and why.
Hand over a reproducible diagnosis
Submit four items: the expected total, the one-record failing fixture, the identified lookup mismatch and the corrected results for all three success cases. Avoid including a screenshot that only shows “worked now”. Text inputs and assertions make the result independently checkable. Keep exception type and relevant key separate from any incidental path or line number shown by your editor.
For further practice, introduce a second record with a different misspelt key. Decide whether to normalise that source or reject it; do not assume the first debugging repair also solves inconsistent data. Write a new failing case and an explicit policy. This extension shows the boundary between diagnosing a code defect and deciding how to handle imperfect input records.
Questions for this exercise
Why inspect a traceback frame?
The traceback API exposes frame summaries, letting this exercise locate the final function without relying on a complete printed message.
Is returning zero a repair?
Only when zero matches the contract. Here replacing missing quantities with zero would conceal the expected total of seven.
What makes the case minimal?
One fictional record and one incorrect lookup are enough to preserve the original field-name mismatch.
Official documentation
Explore the Courses overview or use Contact for general enquiries. This is an original INTIAU editorial self-study exercise; no qualification is awarded.
Related guides
View the study diagram

