diff options
author | David Linke <dalito@users.noreply.github.com> | 2014-06-12 11:22:40 +0200 |
---|---|---|
committer | David Linke <dalito@users.noreply.github.com> | 2014-06-12 11:22:40 +0200 |
commit | dbd1bb8c07e6546e605b070e8bb3c4b7705da15e (patch) | |
tree | 93034c8e06ea02eb6a8b71c893c8859cfe9d60f3 | |
parent | c6f86c2c93956663dc395a981bfa889fe3aeae19 (diff) | |
download | pint-dbd1bb8c07e6546e605b070e8bb3c4b7705da15e.tar.gz |
Added check for order in _ok_for_muldiv. Clean up. Improved doc strings.
-rw-r--r-- | pint/quantity.py | 39 | ||||
-rw-r--r-- | pint/testsuite/test_unit.py | 1 | ||||
-rw-r--r-- | pint/unit.py | 21 |
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 |