Coverage for backend/pinch_service/OpenPinch/src/classes/value.py: 43%
81 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-06 23:27 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-06 23:27 +0000
1from pint import UnitRegistry
2from ..lib.schema import ValueWithUnit
4ureg = UnitRegistry()
5Q_ = ureg.Quantity
8class Value:
9 def __init__(self, data=None, unit: str = None):
10 if data is None:
11 self._quantity = Q_(0)
12 elif isinstance(data, ValueWithUnit):
13 self._quantity = Q_(data.value, data.units)
14 try:
15 self._quantity.to(unit)
16 except:
17 pass
18 else:
19 self._quantity = Q_(data, unit) if unit else Q_(data)
21 @property
22 def value(self):
23 return self._quantity.magnitude
25 @value.setter
26 def value(self, data):
27 self._quantity = Q_(data, self.unit)
29 @property
30 def unit(self):
31 return format(self._quantity.units, "~").replace("°","deg").replace(" ","")
33 @unit.setter
34 def unit(self, unit_str):
35 self._quantity = Q_(self.value, unit_str)
37 def to(self, new_unit: str) -> "Value":
38 return Value(self._quantity.to(new_unit).magnitude, new_unit)
40 def __str__(self):
41 return f"{self.value} {self.unit}"
43 def __repr__(self):
44 return f"Value({self.value}, {repr(self.unit)})"
46 def __float__(self):
47 return float(self.value)
49 def __int__(self):
50 return int(self.value)
52 def __round__(self, ndigits=None):
53 return round(self.value, ndigits)
55 def __eq__(self, other):
56 try:
57 if isinstance(other, (int, float)):
58 return self._quantity.magnitude == other
59 return self._quantity == self._to_quantity(other)
60 except Exception:
61 return False
63 def __lt__(self, other):
64 return self._quantity < self._to_quantity(other)
66 def __le__(self, other):
67 return self._quantity <= self._to_quantity(other)
69 def __gt__(self, other):
70 return self._quantity > self._to_quantity(other)
72 def __ge__(self, other):
73 return self._quantity >= self._to_quantity(other)
75 def __add__(self, other):
76 return self._from_quantity(self._quantity + self._to_quantity(other))
78 def __radd__(self, other):
79 return self + other
81 def __sub__(self, other):
82 return self._from_quantity(self._quantity - self._to_quantity(other))
84 def __rsub__(self, other):
85 return self._from_quantity(self._to_quantity(other) - self._quantity)
87 def __mul__(self, other):
88 return self._from_quantity(self._quantity * self._to_quantity(other))
90 def __rmul__(self, other):
91 return self * other
93 def __truediv__(self, other):
94 return self._from_quantity(self._quantity / self._to_quantity(other))
96 def __rtruediv__(self, other):
97 return self._from_quantity(self._to_quantity(other) / self._quantity)
99 def _to_quantity(self, other):
100 if isinstance(other, Value):
101 return other._quantity
102 return Q_(other)
104 def _from_quantity(self, qty):
105 return Value(qty.magnitude, format(qty.units, "~"))
107 def to_dict(self):
108 return {"value": self.value, "unit": self.unit}
110 @classmethod
111 def from_dict(cls, data):
112 return cls(data["value"], data.get("unit"))
115# @pd.api.extensions.register_series_accessor("as_value")
116# class ValueAccessor:
117# def __init__(self, series):
118# self.series = series
120# def to(self, unit):
121# return self.series.apply(lambda v: v.to(unit))