Skip to content

← Data Modelling and Invariants step 6 of 25

Easy Primitives

Dataclasses: slots, frozen, order

Model a semantic version as a dataclass that is immutable, comparable and memory-lean, then use it to sort.

Define a dataclass Version with integer fields major, minor, patch, declared with all three of:

  • slots=True — no per-instance __dict__. Cuts memory substantially and turns a typo’d attribute assignment into an AttributeError instead of a silently-created new attribute.
  • frozen=True — assignment raises FrozenInstanceError. Also makes the class hashable, so instances work as dict keys and set members.
  • order=True — generates __lt__/__le__/__gt__/__ge__ comparing the fields as a tuple, in declaration order. This is why field order is a semantic decision, not a formatting one.

Then implement:

def solve(versions: list[list[int]]) -> list[str]:

It receives a list of [major, minor, patch] triples, and returns them sorted ascending, each formatted as "major.minor.patch".

The catch: slots=True and a field(default=...) on an inherited dataclass interact badly, and order=True compares every field including ones you may not want in the ordering — use field(compare=False) to exclude one. Neither bites here, but both are why these flags are opt-in.

Your submission must pass mypy --strict: every function and every field needs an annotation, and solve must actually return list[str].