0%

Dataclasses and Value Objects · practice

Build Alternative Constructors

A class normally has one way in: call it with the fields its constructor expects. Real data often arrives in another useful shape.

Try it

The class receives itself

@classmethod passes the class as the first . Convention names it cls.

cls(...) constructs through whichever class received the call. Hard-coding Duration(...) appears equivalent now, but an inherited constructor would then build the wrong class.

What is cls inside from_seconds?

Name meaningful ways in

An alternative constructor should name a recognizable source or use case:

@classmethod
def one_minute(cls):
    return cls(1, 0)

Configuration classes benefit too:

@classmethod
def untimed(cls, title):
    return cls(title, time_limit=0)

The caller reads the intention instead of repeating a collection of magic values.

Use an ordinary constructor for the general case and a class for a genuinely named route into the same valid . The exercise builds four such routes. Helpers that construct nothing are a separate decision for the next lesson.

Task

Add four alternative constructors using @classmethod.

Question.from_dict(record) reads "prompt", "answer", and "points". Question.simple(prompt, answer) builds a one-point question.

QuizConfig.practice(title) uses a pass mark of 0.5. QuizConfig.final_exam(title) uses 0.8 and a time limit of 3600.

Every must construct through cls(...), not by naming its class. The ordinary constructors keep their __post_init__ validation, so every alternative route must reject the same invalid values.