PythiloLesson 4 of 15 · progress kept in this browser

Entities and value objects

A value object is defined by its values: two amounts of 2.50 EUR are interchangeable. Make it immutable, validate it when it is created, and give it operations that return new values.

from dataclasses import dataclass

@dataclass(frozen=True)
class Money:
    cents: int
    currency: str

    def __add__(self, other):
        if other.currency != self.currency:
            msg = "currencies differ"
            raise ValueError(msg)
        total = self.cents + other.cents
        return Money(total, self.currency)

print(Money(250, "EUR") + Money(100, "EUR"))

An entity is defined by identity: a customer who changes their name is still the same customer. Compare entities by their id alone, and let the other attributes change.

class Customer:
    def __init__(self, cid, name):
        self.cid, self.name = cid, name

    def __eq__(self, other):
        return (isinstance(other, Customer)
                and other.cid == self.cid)

    def __hash__(self):
        return hash(self.cid)

a = Customer(7, "Ada")
print(a == Customer(7, "Ada Lovelace"))

Keep money in whole cents: floats cannot hold most decimal amounts exactly.

Your task

Write a frozen dataclass Money(cents, currency) that raises ValueError for negative cents or a currency that is not three capital letters, adds only to the same currency (else ValueError), and has split(n) returning n amounts that add up to the original, differ by at most one cent, largest first. Write an entity Account(number, owner) whose balance starts at Money(0, "EUR"), with deposit(money) and equality and hashing by number only.