Coding problem · Medium · Language Idioms
Immutable Money Value Object (dataclasses)
Medium Language practicals Seen at Stripe, Wise, Revolut
Create a value object Money with a @dataclass:
- fields
amount_cents: intandcurrency: str; - immutable — assigning to a field raises
dataclasses.FrozenInstanceError; Money + Moneyreturns a newMoney; adding different currencies raisesValueError;str(Money(1999, "USD"))→"19.99 USD"(also negative:"-5.00 EUR");- instances sort by
amount_cents, thencurrency.
Hints
Hint 1
@dataclass(frozen=True, order=True) gives immutability, __eq__, __hash__ and ordering by field order.
Hint 2
Format with divmod(abs(cents), 100) and add the sign back.
Write and run your solution
Loading the editor… (JavaScript is required to run code in your browser.)
Solution and explanation
Show the solution
Time O(1) · Space O(1)
frozen=True makes instances immutable and hashable (safe as dict keys and in sets); order=True generates comparison methods using field order — here amount, then currency. Value objects like Money are compared by value, never by identity. Returning NotImplemented from __add__ for unknown types lets Python try the other operand and produce a proper TypeError.
Reference solution
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class Money:
amount_cents: int
currency: str
def __add__(self, other: "Money") -> "Money":
if not isinstance(other, Money):
return NotImplemented
if other.currency != self.currency:
raise ValueError(f"cannot add {other.currency} to {self.currency}")
return Money(self.amount_cents + other.amount_cents, self.currency)
def __str__(self) -> str:
units, cents = divmod(abs(self.amount_cents), 100)
sign = "-" if self.amount_cents < 0 else ""
return f"{sign}{units}.{cents:02d} {self.currency}"
Common mistakes
- Floats for money.
- Mutable value objects used as dict keys.
- Formatting negatives as
-0.-5.
Follow-up questions
- Add
__mul__for quantities and allocation without losing cents. - Use
Decimalfor currencies with 3 decimal places.