- from __future__ import annotations
-
- from typing import final
-
- __all__ = ["Duration", "Seconds", "Minutes", "Hours"]
-
-
- class UnitMeta(type):
- _symbol: str
- _multiplier: float
-
- def __contains__[T](cls: type[Unit[T]], unit: Unit[T]) -> float:
- return unit._value * (cls._multiplier / unit._multiplier)
-
-
- class Unit[T](metaclass=UnitMeta):
- def __init_subclass__(cls, symbol: str, multiplier: float) -> None:
- cls._symbol = symbol
- cls._multiplier = multiplier
-
- def __init__(self, value: float):
- self._value = value
-
- def to_number(self, unit: type[Unit[T]]) -> float:
- return self._value * (self._multiplier / unit._multiplier)
-
- def __repr__(self) -> str:
- return f"{type(self).__name__}({self._value})"
-
- def __str__(self) -> str:
- return f"{self._value}{self._symbol}"
-
-
- @final
- class Seconds(Unit["Duration"], symbol="s", multiplier=1):
- pass
-
-
- @final
- class Minutes(Unit["Duration"], symbol="m", multiplier=60):
- pass
-
-
- @final
- class Hours(Unit["Duration"], symbol="h", multiplier=3600):
- pass
-
-
- Duration = Seconds | Minutes | Hours
-
-
- @final
- class Meters(Unit["Distance"], symbol="m", multiplier=1):
- pass
-
-
- Distance = Meters
-
-
- t: Duration = Minutes(10)
-
- # is there an error? | should there be? | my face
- print(t in Seconds) # no | no | :)
- print(t in Meters) # yes | yes | :)
- print(t in Duration) # no | yes | >:I
- print(t.to_number(Seconds)) # no | no | :)
- print(t.to_number(Meters)) # yes | yes | :)
- print(t.to_number(Duration)) # yes | yes | :)