In [7]:
class Modular:
    """
    Stores a number and does arithmetic modulo some given modulus parameter.
    """
    val: int
    modulus: int
    
    def __init__(self, val: int, modulus: int) -> None:
        self.val = val % modulus
        self.modulus = modulus
        
    def __repr__(self) -> str:
        return f"{self.val} (in %{self.modulus})"
    
    def compatible(self, y: Modular) -> None:
        assert self.modulus == y.modulus, "Moduli don't match"
    
    def __add__(self, y) -> Modular:
        self.compatible(y)
        return Modular((self.val + y.val) % self.modulus, self.modulus)
    
    def __sub__(self, y) -> Modular:
        self.compatible(y)
        return Modular((self.val - y.val) % self.modulus, self.modulus)
    
    def __mul__(self, y) -> Modular:
        self.compatible(y)
        return Modular((self.val * y.val) % self.modulus, self.modulus)
    
x = Modular(3, 5)
y = Modular(2, 5)
print(x * y * y)
2 (in %5)