Skip to content

Commit

Permalink
Refactored code, add new tests and avoid getting value from empty sca…
Browse files Browse the repository at this point in the history
…lar passing a unit
  • Loading branch information
arthursoprana committed Oct 14, 2019
1 parent 40779a0 commit e982896
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 18 deletions.
8 changes: 4 additions & 4 deletions src/barril/units/_quantity.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,9 @@ def GetUnit(self):

unit = property(GetUnit)

def IsEmpty(self):
return self == self._EMPTY_QUANTITY

def GetUnitName(self):
"""
:rtype: str
Expand Down Expand Up @@ -684,10 +687,7 @@ def Convert(self, value, to_unit):
)
except ComposedUnitError:
return self._unit_database.Convert(
self._category,
self._CreateUnitsWithJoinedExponentsString(),
to_unit,
value,
self._category, self._unit, to_unit, value
)

@classmethod
Expand Down
21 changes: 13 additions & 8 deletions src/barril/units/_scalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ._abstractvaluewithquantity import AbstractValueWithQuantityObject
from ._quantity import ObtainQuantity, Quantity
from .interfaces import IQuantity, IScalar
from .unit_database import InvalidQuantityTypeError, UnitDatabase
from .unit_database import InvalidQuantityTypeError, UnitDatabase, UnitsError

__all__ = ["Scalar"]

Expand Down Expand Up @@ -109,6 +109,10 @@ def GetAbstractValue(self, unit=None):
if unit is None:
return self._value
else:
if self._quantity.IsEmpty():
raise UnitsError(
"Unable to get value for empty quantity, unit should be None."
)
return self._quantity.ConvertScalarValue(self._value, unit)

GetValue = GetAbstractValue
Expand Down Expand Up @@ -238,34 +242,35 @@ def GetFormatted(self, unit=None, value_format=None):
)

# Compare --------------------------------------------------------------------------------------
def _GetValueInDefaultUnit(self):
def _GetValueInBaseUnit(self):
try:
if self._quantity.IsEmpty():
return self._value
return self.GetValue(
self._unit_database.GetDefaultUnit(self._quantity._category)
self._unit_database.GetBaseUnit(self._quantity._category)
)
except InvalidQuantityTypeError:
return self._value
return (self._value, self._quantity._unit)

def __eq__(self, other):
return (
type(self) is type(other)
and self._quantity._category == other._quantity._category
and self._GetValueInDefaultUnit() == other._GetValueInDefaultUnit()
and self._GetValueInBaseUnit() == other._GetValueInBaseUnit()
)

def AlmostEqual(self, other, precision):
return (
type(self) is type(other)
and self._quantity._category == other._quantity._category
and round(
self._GetValueInDefaultUnit() - other._GetValueInDefaultUnit(),
precision,
self._GetValueInBaseUnit() - other._GetValueInBaseUnit(), precision
)
== 0
)

def __hash__(self, *args, **kwargs):
return hash((self._quantity._category, self._GetValueInDefaultUnit()))
return hash((self._quantity._category, self._GetValueInBaseUnit()))

def __lt__(self, other):
if self.quantity_type != other.quantity_type:
Expand Down
8 changes: 6 additions & 2 deletions src/barril/units/_tests/test_empty_scalar.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from barril.units import Scalar
from barril.units.unit_database import InvalidQuantityTypeError
from barril.units.unit_database import InvalidQuantityTypeError, UnitsError
import pytest


Expand All @@ -18,10 +18,14 @@ def testEmptyScalar():
def testEmptyScalarWithInitialValue():
# An empty scalar doesn't have a category defined
scalar_1 = Scalar.CreateEmptyScalar(20.0)
scalar_2 = Scalar.CreateEmptyScalar(20.0)

assert scalar_1 == scalar_2
# When try to retrieve an empty scalar value using any unit a exception
# is being raised
with pytest.raises(InvalidQuantityTypeError):
with pytest.raises(
UnitsError, match="Unable to get value for empty quantity, unit should be None."
):
_ = scalar_1.GetValue("m")

assert scalar_1.GetUnit() == ""
1 change: 0 additions & 1 deletion src/barril/units/_tests/test_posc.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ def testDefaultCategories(unit_database_posc):
"self inductance per length",
"shear rate",
"status",
"thermodynamic temperature",
"volume per area",
"volume per length",
"volume per time per area",
Expand Down
14 changes: 14 additions & 0 deletions src/barril/units/_tests/test_posc_additional_units.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,17 @@ def testPerMicrometre(db):
assert approx(per_inch.GetValue()) == 25400
assert per_metre == units.Scalar("per length", 10 ** 6, "1/m")
assert per_inch == units.Scalar("per length", 25400.0, "1/in")


def testMassTemperaturePerMol(db):
value = units.Scalar("mass temperature per mol", 3.1415, "kg.K/mol")

assert value.GetValue("kg.K/mol") == approx(3.1415)
assert value.GetValue("kg.degC/mol") == approx(3.1415)
assert value.GetValue("g.K/mol") == approx(3.1415 * 1e3)
assert value.GetValue("g.degC/mol") == approx(3.1415 * 1e3)
assert value.GetValue("kg.K/kmol") == approx(3.1415 * 1e3)
assert value.GetValue("kg.degC/kmol") == approx(3.1415 * 1e3)
assert value.GetValue("kg.degF/mol") == approx(3.1415 * 9 / 5)
assert value.GetValue("g.degF/mol") == approx(3.1415 * 9 / 5 * 1e3)
assert value.GetValue("kg.degF/kmol") == approx(3.1415 * 9 * 1e3 / 5)
7 changes: 7 additions & 0 deletions src/barril/units/_tests/test_quantity.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,10 @@ def testDivision():
assert speed.GetUnit() == "m/s"
assert speed.unit == "m/s"
assert no_unit.GetUnit() == ""


def testEmptyQuantity():
quantity = Quantity.CreateEmpty()
assert quantity.IsEmpty()
assert quantity.GetUnit() == ""
assert quantity.GetQuantityType() == ""
21 changes: 20 additions & 1 deletion src/barril/units/_tests/test_scalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,10 @@ def testScalarCreationModes():
assert Scalar("length", 10, "m") == base
assert Scalar((10.0, "m")) == base

with pytest.raises(AssertionError):
with pytest.raises(
AssertionError,
match="If category and value are given, the unit must be specified too.",
):
Scalar("length", 1.0) # missing unit


Expand Down Expand Up @@ -633,6 +636,8 @@ class Fluid:


def testComparison():
from math import pi

a = Scalar(1, "m")
b = Scalar(100, "cm")
c = Scalar(99, "cm")
Expand All @@ -659,3 +664,17 @@ def testComparison():
a = Scalar(q, 1.0)
b = Scalar(q * q, 1.0)
assert {a, b, b / a} == {b, a}

for value in [0.0, pi, 0.33333333]:
a = Scalar("temperature", value, "degC")
b = Scalar("temperature", value * 1.8 + 32, "degF")
c = Scalar("temperature", value + 273.15, "K")

assert a <= b <= c and c <= b <= a


def testHashing():
m = Scalar(1, "m")
cm = Scalar(100, "cm")
assert m == cm
assert hash(m) == hash(cm)
4 changes: 2 additions & 2 deletions src/barril/units/posc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2665,7 +2665,7 @@ def FillUnitDatabaseWithPosc(db=None, fill_categories=True, override_categories=
"degF",
f_base_to_unit,
f_unit_to_base,
default_category="thermodynamic temperature",
default_category=None,
)
f_unit_to_base = MakeCustomaryToBase(0.0, 0.1761102, 1.0, 0.0)
f_base_to_unit = MakeBaseToCustomary(0.0, 0.1761102, 1.0, 0.0)
Expand Down Expand Up @@ -2755,7 +2755,7 @@ def FillUnitDatabaseWithPosc(db=None, fill_categories=True, override_categories=
"degR",
f_base_to_unit,
f_unit_to_base,
default_category="thermodynamic temperature",
default_category=None,
)
f_unit_to_base = MakeCustomaryToBase(0.0, 0.1, 1.0, 0.0)
f_base_to_unit = MakeBaseToCustomary(0.0, 0.1, 1.0, 0.0)
Expand Down

0 comments on commit e982896

Please sign in to comment.