diff --git a/validate.py b/validate.py new file mode 100644 index 0000000..643cb63 --- /dev/null +++ b/validate.py @@ -0,0 +1,108 @@ +class Validator: + @classmethod + def check(cls, value): + return value + + +class Typed(Validator): + expected_type = object + + @classmethod + def check(cls, value): + if not isinstance(value, cls.expected_type): + raise TypeError(f"expected {cls.expected_type}") + return super().check(value) + + +class Integer(Typed): + expected_type = int + + +class Float(Typed): + expected_type = float + + +class String(Typed): + expected_type = str + + +class Positive(Validator): + @classmethod + def check(cls, value): + if value < 0: + raise ValueError("Expected >= 0") + return super().check(value) + + +class NonEmpty(Validator): + @classmethod + def check(cls, value): + if len(value) == 0: + return ValueError("Must be non-empty") + return super().check(value) + + +class PositiveInteger(Integer, Positive): + pass + + +class PositiveFloat(Float, Positive): + pass + + +class NonEmptyString(String, NonEmpty): + pass + + +class Stock: + _types = (str, int, float) + __slots__ = ["name", "_shares", "_price"] + + def __init__(self, name, shares, price): + self.name = name + self.shares = shares + self.price = price + + def __repr__(self): + return f"Stock({self.name!r}, {self.shares!r}, {self.price!r})" + + def __eq__(self, other): + if not isinstance(other, Stock): + return False + return (self.name, self.shares, self.price) == ( + other.name, + other.shares, + other.price, + ) + + @classmethod + def from_row(cls, row): + values = [func(val) for func, val in zip(cls._types, row)] + return cls(*values) + + @property + def cost(self): + return self.shares * self.price + + @property + def shares(self): + return self._shares + + @shares.setter + def shares(self, value): + PositiveInteger.check(value) + self._shares = value + + @property + def price(self): + return self._price + + @price.setter + def price(self, value): + PositiveFloat.check(value) + self._price = value + + def sell(self, num): + self.shares -= num + if self.shares < 0: + self.shares = 0