summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Linke <dalito@users.noreply.github.com>2014-06-12 11:22:40 +0200
committerDavid Linke <dalito@users.noreply.github.com>2014-06-12 11:22:40 +0200
commitdbd1bb8c07e6546e605b070e8bb3c4b7705da15e (patch)
tree93034c8e06ea02eb6a8b71c893c8859cfe9d60f3
parentc6f86c2c93956663dc395a981bfa889fe3aeae19 (diff)
downloadpint-dbd1bb8c07e6546e605b070e8bb3c4b7705da15e.tar.gz
Added check for order in _ok_for_muldiv. Clean up. Improved doc strings.
-rw-r--r--pint/quantity.py39
-rw-r--r--pint/testsuite/test_unit.py1
-rw-r--r--pint/unit.py21
3 files changed, 41 insertions, 20 deletions
diff --git a/pint/quantity.py b/pint/quantity.py
index 0cdb4c5..35c864c 100644
--- a/pint/quantity.py
+++ b/pint/quantity.py
@@ -56,30 +56,34 @@ def _check(q1, other):
return False
-def _only_multiplicative_units(q):
- """Check if the quantity has non-multiplicative units.
+def _is_multiplicative(q): # renamed from _only_multiplicative_units
+ """Check if the Quantity object has only multiplicative units.
"""
+ # XXX Turn this into a method/property of _Quantity?
return not _get_non_multiplicative_units(q)
def _get_non_multiplicative_units(q):
- """Check if the quantity has a unit with non-zero offset
+ """Return a list of the of non-multiplicative units of the Quantity object
"""
+ # XXX Turn this into a method/property of _Quantity?
offset_units = [unit for unit in q.units.keys()
if not q._REGISTRY._units[unit].is_multiplicative]
return offset_units
def _get_delta_units(q):
- """Check if the quantity has a delta_unit
+ """Return list of delta units ot the Quantity object
"""
+ # XXX Turn this into a method/property of _Quantity? a class mathod?
delta_units = [u for u in q.units.keys() if u.startswith("delta_")]
return delta_units
def _has_compatible_delta(q, unit):
- """"Check if quantity has a delta_unit that is compatible with unit
+ """"Check if Quantity object has a delta_unit that is compatible with unit
"""
+ # XXX Turn this into a method/property of _Quantity?
deltas = _get_delta_units(q)
if 'delta_' + unit in deltas:
return True
@@ -92,11 +96,12 @@ def _has_compatible_delta(q, unit):
def _ok_for_muldiv(q, no_offset_units=None):
- """Checks if quantity q can be multiplied with or divided
+ """Checks if Quantity object can be multiplied or divided
:q: quantity object that is checked
:no_offset_units: number of offset units in q
"""
+ # XXX Turn this into a method/property of _Quantity?
is_ok = True
if no_offset_units is None:
no_offset_units = len(_get_non_multiplicative_units(q))
@@ -108,7 +113,9 @@ def _ok_for_muldiv(q, no_offset_units=None):
if (len(q.units) == 1
and not q._REGISTRY.autoconvert_offset_to_baseunit):
is_ok = False
- # XXX check also for order?
+ if (q.units[0] != 1
+ and not q._REGISTRY.autoconvert_offset_to_baseunit):
+ is_ok = False
return is_ok
@@ -665,6 +672,13 @@ class _Quantity(object):
other_magnitude = _to_magnitude(other, self.force_ndarray)
except TypeError:
return NotImplemented
+
+ no_offset_units_self = len(_get_non_multiplicative_units(self))
+ if not _ok_for_muldiv(self, no_offset_units_self):
+ raise OffsetUnitCalculusError(self.units, '')
+ elif no_offset_units_self == 1 and len(self.units) == 1:
+ self = self.to_base_units()
+
return self.__class__(other_magnitude / self._magnitude, 1 / self._units)
def __rfloordiv__(self, other):
@@ -672,6 +686,13 @@ class _Quantity(object):
other_magnitude = _to_magnitude(other, self.force_ndarray)
except TypeError:
return NotImplemented
+
+ no_offset_units_self = len(_get_non_multiplicative_units(self))
+ if not _ok_for_muldiv(self, no_offset_units_self):
+ raise OffsetUnitCalculusError(self.units, '')
+ elif no_offset_units_self == 1 and len(self.units) == 1:
+ self = self.to_base_units()
+
return self.__class__(other_magnitude // self._magnitude, 1 / self._units)
__div__ = __truediv__
@@ -687,7 +708,7 @@ class _Quantity(object):
except TypeError:
return NotImplemented
else:
- if not _only_multiplicative_units(self):
+ if not _is_multiplicative(self):
self.ito_base_units()
self._magnitude **= _to_magnitude(other, self.force_ndarray)
self._units **= other
@@ -700,7 +721,7 @@ class _Quantity(object):
return NotImplemented
else:
new_self = self
- if not _only_multiplicative_units(self):
+ if not _is_multiplicative(self):
new_self = self.to_base_units()
magnitude = new_self._magnitude ** _to_magnitude(other, self.force_ndarray)
diff --git a/pint/testsuite/test_unit.py b/pint/testsuite/test_unit.py
index 9228f59..c0f4602 100644
--- a/pint/testsuite/test_unit.py
+++ b/pint/testsuite/test_unit.py
@@ -595,7 +595,6 @@ class TestErrors(BaseTestCase):
class TestConvertWithOffset(QuantityTestCase, ParameterizedTestCase):
-
# The dicts in convert_with_offset are used to create a UnitsContainer.
# We create UnitsContainer to avoid any auto-conversion of units.
convert_with_offset = [
diff --git a/pint/unit.py b/pint/unit.py
index a699947..77523e5 100644
--- a/pint/unit.py
+++ b/pint/unit.py
@@ -118,7 +118,8 @@ class OffsetUnitCalculusError(ValueError):
self.extra_msg = extra_msg
def __str__(self):
- msg = ("Ambiguous operation with offset unit ('{0}', '{1}')."
+ msg = ("Ambiguous operation with offset unit (%s)." %
+ ', '.join(['%s' % u for u in [self.units1, self.units2] if u])
+ self.extra_msg)
return msg.format(self.units1, self.units2)
@@ -467,8 +468,8 @@ class UnitRegistry(object):
:type on_redefintion: str
"""
- def __init__(self, filename='', force_ndarray=False, default_as_delta=True,
- autoconvert_offset_to_baseunit=False,
+ def __init__(self, filename='', force_ndarray=False, default_as_delta=True,
+ autoconvert_offset_to_baseunit=False,
on_redefinition='warn'):
self.Quantity = build_quantity_class(self, force_ndarray)
self.Measurement = build_measurement_class(self, force_ndarray)
@@ -511,11 +512,11 @@ class UnitRegistry(object):
#: When performing a multiplication of units, interpret
#: non-multiplicative units as their *delta* counterparts.
self.default_as_delta = default_as_delta
-
- # Determines if quantities with offset units are converted to their
+
+ # Determines if quantities with offset units are converted to their
# base units on multiplication and division.
self.autoconvert_offset_to_baseunit = autoconvert_offset_to_baseunit
-
+
if filename == '':
self.load_definitions('default_en.txt', True)
elif filename is not None:
@@ -1034,7 +1035,7 @@ class UnitRegistry(object):
raise DimensionalityError(
src, dst, src_dim, dst_dim,
extra_msg=' - more than one offset unit.')
-
+
# validate that offset unit is not used in multiplicative context
if ((len(src_offset_units) == 1 and len(src) > 1)
or (len(dst_offset_units) == 1 and len(dst) > 1)
@@ -1042,7 +1043,7 @@ class UnitRegistry(object):
raise DimensionalityError(
src, dst, src_dim, dst_dim,
extra_msg=' - offset unit used in multiplicative context.')
-
+
# Validate that order of offset unit is not above one.
if src_offset_units:
if src_offset_units[0][1] > 1:
@@ -1171,7 +1172,7 @@ class UnitRegistry(object):
cname = self.get_name(name)
if not cname:
continue
- if as_delta and (many or (not many and abs(value) != 1)):
+ if as_delta and (many or (not many and value != 1)):
definition = self._units[cname]
if not definition.is_multiplicative:
cname = 'delta_' + cname
@@ -1195,7 +1196,7 @@ class UnitRegistry(object):
unknown = set()
for toknum, tokval, _, _, _ in gen:
if toknum == NAME:
- # TODO: Integrate math better, Replace eval
+ # TODO: Integrate math better, Replace eval, make as_delta-aware
if tokval == 'pi' or tokval in values:
result.append((toknum, tokval))
continue