Snippet content copied to clipboard.
Are you sure to delete this snippet? No, don't delete
  1. from __future__ import annotations
  2. from typing import final
  3. __all__ = ["Duration", "Seconds", "Minutes", "Hours"]
  4. class UnitMeta(type):
  5. _symbol: str
  6. _multiplier: float
  7. def __contains__[T](cls: type[Unit[T]], unit: Unit[T]) -> float:
  8. return unit._value * (cls._multiplier / unit._multiplier)
  9. class Unit[T](metaclass=UnitMeta):
  10. def __init_subclass__(cls, symbol: str, multiplier: float) -> None:
  11. cls._symbol = symbol
  12. cls._multiplier = multiplier
  13. def __init__(self, value: float):
  14. self._value = value
  15. def to_number(self, unit: type[Unit[T]]) -> float:
  16. return self._value * (self._multiplier / unit._multiplier)
  17. def __repr__(self) -> str:
  18. return f"{type(self).__name__}({self._value})"
  19. def __str__(self) -> str:
  20. return f"{self._value}{self._symbol}"
  21. @final
  22. class Seconds(Unit["Duration"], symbol="s", multiplier=1):
  23. pass
  24. @final
  25. class Minutes(Unit["Duration"], symbol="m", multiplier=60):
  26. pass
  27. @final
  28. class Hours(Unit["Duration"], symbol="h", multiplier=3600):
  29. pass
  30. Duration = Seconds | Minutes | Hours
  31. @final
  32. class Meters(Unit["Distance"], symbol="m", multiplier=1):
  33. pass
  34. Distance = Meters
  35. t: Duration = Minutes(10)
  36. # is there an error? | should there be? | my face
  37. print(t in Seconds) # no | no | :)
  38. print(t in Meters) # yes | yes | :)
  39. print(t in Duration) # no | yes | >:I
  40. print(t.to_number(Seconds)) # no | no | :)
  41. print(t.to_number(Meters)) # yes | yes | :)
  42. print(t.to_number(Duration)) # yes | yes | :)

Edit this Snippet