diff --git a/units.py b/units.py new file mode 100644 index 0000000..9e8328a --- /dev/null +++ b/units.py @@ -0,0 +1,109 @@ +from enum import Enum, auto +from math import pi + + +class UnitClass(Enum): + NONE = auto() + LENGTH = auto() + SPEED = auto() + TIME = auto() + ANGLE = auto() + + +class Unit(Enum): + KM_H = auto(), UnitClass.SPEED + M_S = auto(), UnitClass.SPEED + KM = auto(), UnitClass.LENGTH + M = auto(), UnitClass.LENGTH + SEC = auto(), UnitClass.TIME + MIN = auto(), UnitClass.TIME + HOUR = auto(), UnitClass.TIME + DEG = auto(), UnitClass.ANGLE + RAD = auto(), UnitClass.ANGLE + NONE = auto(), UnitClass.NONE + + def __init__(self, v: int, cls: UnitClass): + self.cls: UnitClass = cls + + +class Value: + def __init__(self, value: float, unit: Unit): + self.value: float = value + self.unit: Unit = unit + + def convert(self, to_unit: Unit) -> "Value": + if self.unit == to_unit: + return self + + from_cls = self.unit.cls + to_cls = to_unit.cls + + if from_cls != to_cls: + raise ValueError(f"Cannot convert from {from_cls} to {to_cls}") + + cls = from_cls + + if cls == UnitClass.NONE: + to_value = self.value + + elif cls == UnitClass.LENGTH: + value = self.value + if self.unit == Unit.KM: + value *= 1000 + + to_value = value + + if to_unit == Unit.KM: + to_value /= 1000 + + elif cls == UnitClass.TIME: + value = self.value + if self.unit == Unit.MIN: + value *= 60 + elif self.unit == Unit.HOUR: + value *= 3600 + + to_value = value + + if to_unit == Unit.MIN: + to_value /= 60 + elif self.unit == Unit.HOUR: + to_value /= 3600 + + elif cls == UnitClass.SPEED: + value = self.value + if self.unit == Unit.KM_H: + value /= 3.6 + + to_value = value + + if to_unit == Unit.KM_H: + to_value *= 3.6 + + elif cls == UnitClass.ANGLE: + value = self.value + if self.unit == Unit.RAD: + value *= 180 / pi + + to_value = value + + if to_unit == Unit.RAD: + value *= pi / 180 + + else: + raise ValueError(f"Unknown unit class: {cls}") + + return Value(to_value, to_unit) + + def __repr__(self): + return f"{self.value} [{self.unit}]" + + +if __name__ == '__main__': + v1 = Value(765, Unit.KM_H) + print(v1) + print(v1.convert(Unit.M_S)) + + v2 = Value(120, Unit.SEC) + print(v2) + print(v2.convert(Unit.MIN)) \ No newline at end of file