Skip to content

Commit 69b7798

Browse files
author
Arthur Besen Soprana
committed
Fix division float over scalar and float over array
BARRIL-15 Add floor division support Add changelog Using CreateEmpty
1 parent fbcfac0 commit 69b7798

File tree

7 files changed

+83
-12
lines changed

7 files changed

+83
-12
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ UNRELEASED
44
* ``_foundation`` has been renamed to ``_util``, and a lot of functions which were not being
55
used anymore have been removed.
66
* Add new unit category mass temperature per mol (``kg.K/mol``).
7+
* Fix division `1.0 / a` where `a` is a `Scalar` or `Array` and also add support for floor
8+
division, i.e., operations like ``a // b`` where `a` and `b` are `Scalar` or `Array`
9+
(and combinations with `float` or `int`).
710

811
1.7.1 (2019-10-03)
912
------------------

src/barril/units/_array.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from oop_ext.interface._interface import ImplementsInterface
55

66
from ._abstractvaluewithquantity import AbstractValueWithQuantityObject
7-
from .interfaces import IArray
87
from ._quantity import Quantity
8+
from .interfaces import IArray
99

1010
__all__ = ["Array"]
1111

@@ -246,6 +246,9 @@ def __iter__(self):
246246
def __truediv__(self, other):
247247
return self._DoOperation(self, other, "Divide")
248248

249+
def __floordiv__(self, other):
250+
return self._DoOperation(self, other, "FloorDivide")
251+
249252
def __mul__(self, other):
250253
return self._DoOperation(self, other, "Multiply")
251254

@@ -256,6 +259,12 @@ def __sub__(self, other):
256259
return self._DoOperation(self, other, "Subtract")
257260

258261
# Right-Basic operators ------------------------------------------------------------------------
262+
def __rtruediv__(self, other):
263+
return self._DoOperation(other, self, "Divide")
264+
265+
def __rfloordiv__(self, other):
266+
return self._DoOperation(other, self, "FloorDivide")
267+
259268
def __rdiv__(self, other):
260269
return self._DoOperation(other, self, "Divide")
261270

src/barril/units/_scalar.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from oop_ext.interface._interface import ImplementsInterface
99

1010
from ._abstractvaluewithquantity import AbstractValueWithQuantityObject
11-
from .interfaces import IQuantity, IScalar
1211
from ._quantity import ObtainQuantity, Quantity
12+
from .interfaces import IQuantity, IScalar
1313
from .unit_database import UnitDatabase
1414

1515
__all__ = ["Scalar"]
@@ -269,7 +269,8 @@ def __lt__(self, other):
269269
def __rtruediv__(self, other):
270270
return self._DoOperation(other, self, "Divide", lambda a, b: a / b)
271271

272-
__rfloordiv__ = __rtruediv__
272+
def __rfloordiv__(self, other):
273+
return self._DoOperation(other, self, "FloorDivide", lambda a, b: a // b)
273274

274275
def __rmul__(self, other):
275276
return self._DoOperation(other, self, "Multiply", lambda a, b: a * b)
@@ -284,7 +285,8 @@ def __radd__(self, other):
284285
def __truediv__(self, other):
285286
return self._DoOperation(self, other, "Divide", lambda a, b: a / b)
286287

287-
__floordiv__ = __truediv__
288+
def __floordiv__(self, other):
289+
return self._DoOperation(self, other, "FloorDivide", lambda a, b: a // b)
288290

289291
def __mul__(self, other):
290292
return self._DoOperation(self, other, "Multiply", lambda a, b: a * b)
@@ -302,7 +304,8 @@ def __pow__(self, exponent):
302304
return result
303305

304306
def _DoOperation(self, p1, p2, operation, callback_operation):
305-
if IsNumber(p1):
307+
p1_is_number = IsNumber(p1)
308+
if p1_is_number and operation not in ["Divide", "FloorDivide"]:
306309
return self.__class__.CreateWithQuantity(
307310
self._quantity, callback_operation(p1, self._value)
308311
)
@@ -313,8 +316,19 @@ def _DoOperation(self, p1, p2, operation, callback_operation):
313316
)
314317

315318
unit_database = self._unit_database
316-
operation = getattr(unit_database, operation)
317-
q, v = operation(p1.GetQuantity(), p2.GetQuantity(), self._value, p2.value)
319+
operation_func = getattr(unit_database, operation)
320+
if p1_is_number:
321+
assert operation in [
322+
"Divide",
323+
"FloorDivide",
324+
], "Only operation Divide and FloorDivide allowed here!"
325+
q, v = operation_func(
326+
Quantity.CreateEmpty(), p2.GetQuantity(), p1, p2.value
327+
)
328+
else:
329+
q, v = operation_func(
330+
p1.GetQuantity(), p2.GetQuantity(), self._value, p2.value
331+
)
318332
return self.__class__.CreateWithQuantity(q, v)
319333

320334
def __reduce__(self):

src/barril/units/_tests/test_array.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import pytest
2-
from pytest import approx
3-
42
from collections import OrderedDict
53
from barril import units
64
from barril.units import Array, InvalidUnitError, ObtainQuantity, Quantity
5+
from pytest import approx
76

87

98
def testEmptyArray():
@@ -215,6 +214,24 @@ def testDivision(unit_database_len_time):
215214
assert calculated1 == s1 / s2
216215

217216

217+
def testFloorDivision():
218+
a = Array([3.5, 4.2], "m")
219+
b = Array([100.0, 100.0], "cm")
220+
assert approx((a // b).GetValues()) == [3.0, 4.0]
221+
assert approx((350 // b).GetValues("1/cm")) == [3.0, 3.0]
222+
assert approx((a // 1.0).GetValues("m")) == [3.0, 4.0]
223+
224+
225+
def testNumberOverArray():
226+
a = Array([2.0, 2.0], "m")
227+
b = Array([3.0, 3.0], "m")
228+
c = 1.0 / a
229+
230+
assert approx(c.GetValues("1/m")) == [0.5, 0.5]
231+
assert approx((3.0 / a).GetValues("1/m")) == [1.5, 1.5]
232+
assert b / a == b * 1 / a == b * (1 / a)
233+
234+
218235
def testNumberInteractions(unit_database_len_time):
219236
import numpy
220237

src/barril/units/_tests/test_derived_quantities.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ def testConvertionWithDerivedUnits(unit_database_len_time):
8181
# check division with cancelling units (and different categories)
8282
assert (empty, 1) == unit_database.Divide(m, m_city, 1, 1)
8383

84+
# floor division
85+
assert (m, 3.0) == unit_database.FloorDivide(cat_mix_m2, km_city, 3.5, 0.001)
86+
8487
# sum
8588
assert (m, 1 + 0.01) == unit_database.Sum(m, cm, 1, 1)
8689
assert (m, 2) == unit_database.Sum(m, m_city, 1, 1)

src/barril/units/_tests/test_scalar.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
"""
44

55
import pytest
6-
from pytest import approx
7-
86
from collections import OrderedDict
97
from barril import units
108
from barril.units import (
9+
ChangeScalars,
1110
InvalidOperationError,
1211
InvalidUnitError,
1312
ObtainQuantity,
1413
Quantity,
1514
Scalar,
16-
ChangeScalars,
1715
)
16+
from pytest import approx
1817

1918

2019
def testScalarInterface(unit_database_well_length):
@@ -319,6 +318,22 @@ def testDivision(unit_database_len_time):
319318
assert calculated1 == s1 / s2
320319

321320

321+
def testFloorDivision():
322+
a = Scalar(3.5, "m")
323+
b = Scalar(100.0, "cm")
324+
assert (a // b).GetValueAndUnit() == (3.0, "")
325+
assert (350 // b).GetValueAndUnit() == (3.0, "1/cm")
326+
assert (a // 1.0).GetValueAndUnit() == (3.0, "m")
327+
328+
329+
def testNumberOverScalar():
330+
a = Scalar(2.0, "m")
331+
b = Scalar(3.0, "m")
332+
assert (1.0 / a).GetValueAndUnit() == (0.5, "1/m")
333+
assert (3.0 / a).GetValueAndUnit() == (1.5, "1/m")
334+
assert b / a == b * 1 / a == b * (1.0 / a)
335+
336+
322337
def testPow(unit_database_len_time):
323338
s = Scalar(2, "s", "Time")
324339
spow = s ** 3

src/barril/units/unit_database.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,16 @@ def Divide(self, quantity1, quantity2, value1, value2):
12381238
quantity1, quantity2, value1, value2, lambda a, b: a - b, lambda a, b: a / b
12391239
)
12401240

1241+
def FloorDivide(self, quantity1, quantity2, value1, value2):
1242+
return self._DoOperationResultingInNewQuantity(
1243+
quantity1,
1244+
quantity2,
1245+
value1,
1246+
value2,
1247+
lambda a, b: a - b,
1248+
lambda a, b: a // b,
1249+
)
1250+
12411251
def Multiply(self, quantity1, quantity2, value1, value2):
12421252
"""
12431253
Multiplication with different quantities.

0 commit comments

Comments
 (0)