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))