From 41830395554e01f53143e1ddf89b799c24743780 Mon Sep 17 00:00:00 2001 From: Arthur Besen Soprana Date: Mon, 7 Oct 2019 19:12:23 -0300 Subject: [PATCH] Add floor division support --- src/barril/units/_array.py | 6 ++++-- src/barril/units/_scalar.py | 13 +++++++++---- src/barril/units/_tests/test_array.py | 13 +++++++++++-- src/barril/units/_tests/test_derived_quantities.py | 3 +++ src/barril/units/_tests/test_scalar.py | 8 ++++++++ src/barril/units/unit_database.py | 10 ++++++++++ 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/barril/units/_array.py b/src/barril/units/_array.py index cecb0c4..fc190fe 100644 --- a/src/barril/units/_array.py +++ b/src/barril/units/_array.py @@ -246,7 +246,8 @@ def __iter__(self): def __truediv__(self, other): return self._DoOperation(self, other, "Divide") - __floordiv__ = __truediv__ + def __floordiv__(self, other): + return self._DoOperation(self, other, "FloorDivide") def __mul__(self, other): return self._DoOperation(self, other, "Multiply") @@ -261,7 +262,8 @@ def __sub__(self, other): def __rtruediv__(self, other): return self._DoOperation(other, self, "Divide") - __rfloordiv__ = __rtruediv__ + def __rfloordiv__(self, other): + return self._DoOperation(other, self, "FloorDivide") def __rdiv__(self, other): return self._DoOperation(other, self, "Divide") diff --git a/src/barril/units/_scalar.py b/src/barril/units/_scalar.py index f1eca8f..4b73759 100644 --- a/src/barril/units/_scalar.py +++ b/src/barril/units/_scalar.py @@ -269,7 +269,8 @@ def __lt__(self, other): def __rtruediv__(self, other): return self._DoOperation(other, self, "Divide", lambda a, b: a / b) - __rfloordiv__ = __rtruediv__ + def __rfloordiv__(self, other): + return self._DoOperation(other, self, "FloorDivide", lambda a, b: a // b) def __rmul__(self, other): return self._DoOperation(other, self, "Multiply", lambda a, b: a * b) @@ -284,7 +285,8 @@ def __radd__(self, other): def __truediv__(self, other): return self._DoOperation(self, other, "Divide", lambda a, b: a / b) - __floordiv__ = __truediv__ + def __floordiv__(self, other): + return self._DoOperation(self, other, "FloorDivide", lambda a, b: a // b) def __mul__(self, other): return self._DoOperation(self, other, "Multiply", lambda a, b: a * b) @@ -303,7 +305,7 @@ def __pow__(self, exponent): def _DoOperation(self, p1, p2, operation, callback_operation): p1_is_number = IsNumber(p1) - if p1_is_number and operation != "Divide": + if p1_is_number and operation not in ["Divide", "FloorDivide"]: return self.__class__.CreateWithQuantity( self._quantity, callback_operation(p1, self._value) ) @@ -316,7 +318,10 @@ def _DoOperation(self, p1, p2, operation, callback_operation): unit_database = self._unit_database operation_func = getattr(unit_database, operation) if p1_is_number: - assert operation == "Divide", "Only operation Divide allowed here!" + assert operation in [ + "Divide", + "FloorDivide", + ], "Only operation Divide and FloorDivide allowed here!" q, v = operation_func( p2.GetQuantity(), p2.GetQuantity() * p2.GetQuantity(), p1, p2.value ) diff --git a/src/barril/units/_tests/test_array.py b/src/barril/units/_tests/test_array.py index 5034c55..b0b3491 100644 --- a/src/barril/units/_tests/test_array.py +++ b/src/barril/units/_tests/test_array.py @@ -214,12 +214,21 @@ def testDivision(unit_database_len_time): assert calculated1 == s1 / s2 +def testFloorDivision(): + a = Array([3.5, 4.2], "m") + b = Array([100.0, 100.0], "cm") + assert approx((a // b).GetValues()) == [3.0, 4.0] + assert approx((350 // b).GetValues("1/cm")) == [3.0, 3.0] + assert approx((a // 1.0).GetValues("m")) == [3.0, 4.0] + + def testNumberOverArray(): a = Array([2.0, 2.0], "m") b = Array([3.0, 3.0], "m") c = 1.0 / a - assert c.GetValues("1/m") == [0.5, 0.5] - assert (3.0 / a).GetValues("1/m") == [1.5, 1.5] + + assert approx(c.GetValues("1/m")) == [0.5, 0.5] + assert approx((3.0 / a).GetValues("1/m")) == [1.5, 1.5] assert b / a == b * 1 / a == b * (1 / a) diff --git a/src/barril/units/_tests/test_derived_quantities.py b/src/barril/units/_tests/test_derived_quantities.py index 9aeb053..01affdf 100644 --- a/src/barril/units/_tests/test_derived_quantities.py +++ b/src/barril/units/_tests/test_derived_quantities.py @@ -81,6 +81,9 @@ def testConvertionWithDerivedUnits(unit_database_len_time): # check division with cancelling units (and different categories) assert (empty, 1) == unit_database.Divide(m, m_city, 1, 1) + # floor division + assert (m, 3.0) == unit_database.FloorDivide(cat_mix_m2, km_city, 3.5, 0.001) + # sum assert (m, 1 + 0.01) == unit_database.Sum(m, cm, 1, 1) assert (m, 2) == unit_database.Sum(m, m_city, 1, 1) diff --git a/src/barril/units/_tests/test_scalar.py b/src/barril/units/_tests/test_scalar.py index ca5c5a5..07f675e 100644 --- a/src/barril/units/_tests/test_scalar.py +++ b/src/barril/units/_tests/test_scalar.py @@ -318,6 +318,14 @@ def testDivision(unit_database_len_time): assert calculated1 == s1 / s2 +def testFloorDivision(): + a = Scalar(3.5, "m") + b = Scalar(100.0, "cm") + assert (a // b).GetValueAndUnit() == (3.0, "") + assert (350 // b).GetValueAndUnit() == (3.0, "1/cm") + assert (a // 1.0).GetValueAndUnit() == (3.0, "m") + + def testNumberOverScalar(): a = Scalar(2.0, "m") b = Scalar(3.0, "m") diff --git a/src/barril/units/unit_database.py b/src/barril/units/unit_database.py index dcd371a..5229420 100644 --- a/src/barril/units/unit_database.py +++ b/src/barril/units/unit_database.py @@ -1238,6 +1238,16 @@ def Divide(self, quantity1, quantity2, value1, value2): quantity1, quantity2, value1, value2, lambda a, b: a - b, lambda a, b: a / b ) + def FloorDivide(self, quantity1, quantity2, value1, value2): + return self._DoOperationResultingInNewQuantity( + quantity1, + quantity2, + value1, + value2, + lambda a, b: a - b, + lambda a, b: a // b, + ) + def Multiply(self, quantity1, quantity2, value1, value2): """ Multiplication with different quantities.