Representing and Comparing Objects · practice
Create a User-facing str()
Question("What does len('cat') return?", '3', 2) is the kind of detail a developer wants to see in a log.
It is not what you would show a learner taking the quiz. They want the prompt, and nothing else.
Python lets an
Two questions an object gets asked
Three lines, two different print used __str__. repr() used __repr__. The __repr__ for its contents.
The split is deliberate:
__repr__is for whoever is working on the program: informative and unambiguous, with a constructor-like form when that is practical.__str__is for whoever is using the program: readable, and free to leave things out.
__str__ here omits the answer entirely, which would be a terrible repr and is exactly right for text shown to someone about to answer the question.
For these classes, plain {question} also uses __str__. Adding !r, as in {question!r}, selects __repr__ instead.
Which output does print(f"Next: {question}") use?
What happens when you define only one
This is the part worth remembering, because it decides which
Define only __repr__, and str() falls back to it. Every display in the program improves at once:
Define only __str__, and there is no fallback in the other direction:
The list still shows the memory address, and so does every debugger, log line, and failed assertion.
When improving both developer and user displays, start with __repr__. Add __str__ when the readable form needs to differ.
Most classes never need __str__. A Response or a ScoreReport is not something you show a user directly, and giving them a __str__ that only repeats the repr is code with no reader.
Formatting belongs at the edge, mostly
Chapter 6 argued that presentation should stay out of domain classes. __str__ looks like it breaks that rule.
The distinction is __str__ answers “what is the plainest text form of this one object?” It should not know about ScoreReport or to the entry point, and they change far more often.
A useful test: if the string would change when the program moved to a web page, it does not belong in __str__.
The exercise
You are adding both methods across three classes, and deciding for each one whether a __str__ earns its place.
Task
Give each class the display
Question gets both: a repr reading Question('...', '...', 2), and a __str__ reading What does len('cat') return? (2 points), which never reveals the answer.
QuizAttempt gets both: a summary repr reading QuizAttempt(learner='Mina', response_count=2), and a __str__ reading Mina: 2 of 5 points.
Response gets a repr only, reading Response(given='3', earned=2). Its correctness and earned points are snapshots from when the answer arrived.
Run the program. The two lines printing a