pythonunits-of-measurementpint

How to define and use percentage in Pint


I'm currently using Pint to handle units and unit conversions. This seems to work well for the units that are already defined in Pint, for example

>>> import pint
>>> ureg = pint.UnitRegistry()
>>> Q = ureg.Quantity
>>> a = Q(5, 'm/s')
>>> a
<Quantity(5, 'meter / second')>
>>> a.to('ft/s')
<Quantity(16.404199475065617, 'foot / second')>

I tried to define my own units, which represent percentage. As far as unit conversions go, a percentage is simply 100 times a dimensionless fraction, which is how I defined it.

>>> ureg.define('percent = dimensionless * 100 = pct')
>>> a = Q(5, 'pct')
>>> a
<Quantity(5, 'percent')>

However I cannot seem to convert back and forth between fraction ('dimensionless') and 'pct'.

>>> a.to('dimensionless')
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    a.to('dimensionless')
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\quantity.py", line 263, in to
    magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\quantity.py", line 231, in _convert_magnitude_not_inplace
    return self._REGISTRY.convert(self._magnitude, self._units, other)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 1026, in convert
    return self._convert(value, src, dst, inplace)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 1042, in _convert
    src_dim = self._get_dimensionality(src)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 813, in _get_dimensionality
    self._get_dimensionality_recurse(input_units, 1.0, accumulator)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 837, in _get_dimensionality_recurse
    self._get_dimensionality_recurse(reg.reference, exp2, accumulator)
  File "C:\Python35\python-3.5.1.amd64\lib\site-packages\pint\unit.py", line 835, in _get_dimensionality_recurse
    reg = self._units[self.get_name(key)]
KeyError: ''

What I'd essentially like to do is be able to convert between e.g. "0.73" and "73%". How can I define and use such a unit?


Solution

  • In pint>0.22, percent is supported out of the box:

    These do the expected thing:

    import pint
    ureg = pint.UnitRegistry()
    pint.__version__  # 0.22
    ureg.Quantity(1,'%')  # 1 percent
    ureg.Quantity(1,'').to('percent')  # 100.0 percent
    ureg.Quantity(100,'percent').to('')  # 1.0 dimensionless
    ureg.Quantity(1,"").to('%')  # 100.0 percent