109 lines
2.5 KiB
Python
109 lines
2.5 KiB
Python
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)) |