Skip to content

Commit 7dc5283

Browse files
Support constants in arithmetic FormulaEngine operations
Signed-off-by: Matthias Wende <[email protected]>
1 parent 207d96a commit 7dc5283

File tree

1 file changed

+38
-16
lines changed

1 file changed

+38
-16
lines changed

src/frequenz/sdk/timeseries/_formula_engine/_formula_engine.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
from ..._internal._asyncio import cancel_and_await
3131
from .. import Sample, Sample3Phase
32-
from .._quantities import QuantityT
32+
from .._quantities import Quantity, QuantityT
3333
from ._formula_steps import (
3434
Adder,
3535
Averager,
@@ -231,7 +231,7 @@ async def _stop(self) -> None:
231231

232232
def __add__(
233233
self,
234-
other: _GenericEngine | _GenericHigherOrderBuilder,
234+
other: _GenericEngine | _GenericHigherOrderBuilder | QuantityT,
235235
) -> _GenericHigherOrderBuilder:
236236
"""Return a formula builder that adds (data in) `other` to `self`.
237237
@@ -246,7 +246,7 @@ def __add__(
246246
return self._higher_order_builder(self, self._create_method) + other # type: ignore
247247

248248
def __sub__(
249-
self, other: _GenericEngine | _GenericHigherOrderBuilder
249+
self, other: _GenericEngine | _GenericHigherOrderBuilder | QuantityT
250250
) -> _GenericHigherOrderBuilder:
251251
"""Return a formula builder that subtracts (data in) `other` from `self`.
252252
@@ -261,7 +261,7 @@ def __sub__(
261261
return self._higher_order_builder(self, self._create_method) - other # type: ignore
262262

263263
def __mul__(
264-
self, other: _GenericEngine | _GenericHigherOrderBuilder
264+
self, other: _GenericEngine | _GenericHigherOrderBuilder | float
265265
) -> _GenericHigherOrderBuilder:
266266
"""Return a formula builder that multiplies (data in) `self` with `other`.
267267
@@ -276,7 +276,7 @@ def __mul__(
276276
return self._higher_order_builder(self, self._create_method) * other # type: ignore
277277

278278
def __truediv__(
279-
self, other: _GenericEngine | _GenericHigherOrderBuilder
279+
self, other: _GenericEngine | _GenericHigherOrderBuilder | float
280280
) -> _GenericHigherOrderBuilder:
281281
"""Return a formula builder that divides (data in) `self` by `other`.
282282
@@ -740,7 +740,11 @@ def __init__(
740740
self._steps: deque[
741741
tuple[
742742
TokenType,
743-
FormulaEngine[QuantityT] | FormulaEngine3Phase[QuantityT] | str,
743+
FormulaEngine[QuantityT]
744+
| FormulaEngine3Phase[QuantityT]
745+
| QuantityT
746+
| float
747+
| str,
744748
]
745749
] = deque()
746750
self._steps.append((TokenType.COMPONENT_METRIC, engine))
@@ -754,12 +758,12 @@ def _push(
754758

755759
@overload
756760
def _push(
757-
self, oper: str, other: _CompositionType3Phase
761+
self, oper: str, other: _CompositionType3Phase | QuantityT | float
758762
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
759763
...
760764

761765
def _push(
762-
self, oper: str, other: _CompositionType
766+
self, oper: str, other: _CompositionType | QuantityT | float
763767
) -> (
764768
HigherOrderFormulaBuilder[QuantityT]
765769
| HigherOrderFormulaBuilder3Phase[QuantityT]
@@ -771,6 +775,19 @@ def _push(
771775
# pylint: disable=protected-access
772776
if isinstance(other, (FormulaEngine, FormulaEngine3Phase)):
773777
self._steps.append((TokenType.COMPONENT_METRIC, other))
778+
elif isinstance(other, (Quantity, float)):
779+
match oper:
780+
case "+" | "-":
781+
if not isinstance(other, Quantity):
782+
raise RuntimeError(
783+
f"A Quantity must be provided for addition or subtraction to {other}"
784+
)
785+
case "*" | "/":
786+
if not isinstance(other, (float, int)):
787+
raise RuntimeError(
788+
f"A float must be provided for scalar multiplication to {other}"
789+
)
790+
self._steps.append((TokenType.CONSTANT, other))
774791
elif isinstance(other, _BaseHOFormulaBuilder):
775792
self._steps.append((TokenType.OPER, "("))
776793
self._steps.extend(other._steps)
@@ -791,12 +808,12 @@ def __add__(
791808

792809
@overload
793810
def __add__(
794-
self, other: _CompositionType3Phase
811+
self, other: _CompositionType3Phase | QuantityT
795812
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
796813
...
797814

798815
def __add__(
799-
self, other: _CompositionType
816+
self, other: _CompositionType | QuantityT
800817
) -> (
801818
HigherOrderFormulaBuilder[QuantityT]
802819
| HigherOrderFormulaBuilder3Phase[QuantityT]
@@ -821,13 +838,13 @@ def __sub__(
821838

822839
@overload
823840
def __sub__(
824-
self, other: _CompositionType3Phase
841+
self, other: _CompositionType3Phase | QuantityT
825842
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
826843
...
827844

828845
def __sub__(
829846
self,
830-
other: _CompositionType,
847+
other: _CompositionType | QuantityT,
831848
) -> (
832849
HigherOrderFormulaBuilder[QuantityT]
833850
| HigherOrderFormulaBuilder3Phase[QuantityT]
@@ -852,13 +869,13 @@ def __mul__(
852869

853870
@overload
854871
def __mul__(
855-
self, other: _CompositionType3Phase
872+
self, other: _CompositionType3Phase | float
856873
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
857874
...
858875

859876
def __mul__(
860877
self,
861-
other: _CompositionType,
878+
other: _CompositionType | float,
862879
) -> (
863880
HigherOrderFormulaBuilder[QuantityT]
864881
| HigherOrderFormulaBuilder3Phase[QuantityT]
@@ -883,13 +900,13 @@ def __truediv__(
883900

884901
@overload
885902
def __truediv__(
886-
self, other: _CompositionType3Phase
903+
self, other: _CompositionType3Phase | float
887904
) -> HigherOrderFormulaBuilder3Phase[QuantityT]:
888905
...
889906

890907
def __truediv__(
891908
self,
892-
other: _CompositionType,
909+
other: _CompositionType | float,
893910
) -> (
894911
HigherOrderFormulaBuilder[QuantityT]
895912
| HigherOrderFormulaBuilder3Phase[QuantityT]
@@ -935,6 +952,11 @@ def build(
935952
elif typ == TokenType.OPER:
936953
assert isinstance(value, str)
937954
builder.push_oper(value)
955+
elif typ == TokenType.CONSTANT:
956+
assert isinstance(value, (Quantity, float))
957+
builder.push_constant(
958+
value.base_value if isinstance(value, Quantity) else value
959+
)
938960
return builder.build()
939961

940962

0 commit comments

Comments
 (0)