Utility · use it before asking for help
Troubleshoot by layer
Classes add their own family of errors, and the good news is that almost all of them announce themselves with one of about six exact messages. Learn the messages once and OOP debugging becomes pattern-matching.
Find the layer that failed
Symptom table
Messages quoted as Python prints them; match yours, then apply the fix. Bottom line of the traceback first, as always.
| Symptom / exact message | Layer | Most likely cause | What to do |
|---|---|---|---|
TypeError: ReactionLog.add() takes 1 positional argument but 2 were given | B | def add(ms):, the method's self is missing, so your one argument lands in its slot plus one | First parameter of every method is self: def add(self, ms): |
NameError: name 'times' is not defined, inside a method | B | Attribute used without its self. prefix | self.times; bare names are locals, and this one does not exist |
AttributeError: 'ReactionLog' object has no attribute 'times' | B | __init__ misspelled (one underscore, _init_, or __int__), so it never ran; or the attribute is created only on some paths | Exactly __init__, two underscores each side; create every attribute there, unconditionally |
TypeError: __init__() missing 1 required positional argument: 'player' | C | Constructed without the facts the blueprint demands: ReactionLog() | Pass them: ReactionLog("Sam"); help(ReactionLog) lists what construction needs |
Prints <bound method ReactionLog.best of ...> instead of a number | C | Method referenced, not called: log.best without parentheses | log.best(); parentheses are the "do it" operator |
| Button pressed, nothing ever happens, no error at all | C | when_pressed = self.press() with parentheses: ran once at construction, assigned None as the callback | Assign the method itself: when_pressed = self.press |
NameError: name 'ReactionLog' is not defined | C | Forgot the import from your module, or used the class above its definition in the same file | from reactionlog import ReactionLog, or define before use |
ModuleNotFoundError: No module named 'reactionlog' | C | File name and import name differ, or Python launched from another directory | Import names the file minus .py, exactly; cd ~/iot/week6 first, ls to confirm |
| Two instances mysteriously share one list of times | B | The attribute was created in the class body, not in __init__, so it belongs to the blueprint | See the shared-state trap below |
| Mode says one thing, hardware shows another | A | Some code path changes state outside the method that owns the rules | Route every change through the transition method; the encapsulation section is the design fix |
| Everything constructs, logic just wrong | D | Not an OOP fault at all | Week 5's trace table on the failing method, then its ladder; a method traces like any function, with a self column |
The shared-state trap
The one class bug that produces no message, only wrong behaviour, so it gets its own section:
# WRONG: the list lives on the blueprint, shared by every instance
class ReactionLog:
times = []
def add(self, ms):
self.times.append(ms)
# RIGHT: __init__ gives each instance its own list
class ReactionLog:
def __init__(self):
self.times = []
In the wrong version, sam.add(431) shows up in ana.times too: a name assigned directly in the class body is a class attribute, one object attached to the blueprint itself, which every instance sees. Class attributes have honest uses (a constant shared by design), but mutable per-instance state is never one of them. The rule that prevents the trap outright: every attribute an instance owns is created in __init__, through self. The two-players ladder rung is where this bug loves to appear; now it cannot.
Before you ask for help
- Which layer (A to D) you got stuck at, and why you ruled out the ones to its left.
- For A: the capsule sketch, and which state has no clear owner.
- For B: the class definition, plus the exact message's bottom line.
- For C: the constructing or calling line, side by side with what
help(YourClass)says it wants. - For D: the trace table or the evidence Week 4's list asks for.