Monday, June 10, 2013

quantities and units

[UPDATED 2013-07-24] add buckingham.py

Main Contenders

Looking at doing calculations with units? Let's see what's out there. Start by doing a quick Google search with Python + Units. The first site that looks like a match is Python Units.

Python units 0.06

  • Last updated: 2013-2-25
  • Download: PyPI
  • Documentation: None [1]
  • Repository: Bitbucket
  • Last commit: 2013-02-24
  • Owner: Aran Donohue
Then there's a few SO hits and some personal blog entries similar to pp. Python Quantities seems to be a recurring theme.

Python quantities 0.10.1

A little further down is new contender called Pint.

Python Pint 0.2

With some digging a few more packages pop up. A relative newcomer is Python-numericalunits.

Python numericalunits 1.11

  • Last updated: 2013-02-21
  • Download: PyPI
  • Documentation: None [1]
  • Repository: Github
  • Last commit: 2013-02-22
  • Owner: Steve Byrnes
One package that was really hard to find, only saw it in a SO post was Unum.

Python Unum 4.1.1

  • Last updated: 2010-06-19
  • Download: PyPI
  • Documentation: linked to from here
  • Repository: Bitbucket
  • Last commit: 2012-03-25
  • Owners: Chris MacLeod, Pierre Denis

Others

There are probably several others, but I think these are the main contenders. I found some by using search within PyPI, eg: magnitude-0.9.1  (c. 2007). Several are listed in this SO question including buckingham.py. Finally, DimPy (c. 2008) just randomly appeared way down the list when I Googled how to add a new unit to quantities, which is possible, but not well documented.
>>> US_cent = pq.UnitCurrency('cent', 1, u_symbol=u'¢')
>>> US_dollar = pq.UnitCurrency('dollar', 100 * US_cent,
                                'cent', u_symbol=u'$')
>>> cost = 10 * US_cent / pq.kWh
>>> print cost

SciPy.constants

I think it's important to note that SciPy does have many physical constants and conversion-factors to SI units. In fact it's a bit disappointing to see such a flagrant violation of the DRY principle with numerous physical constants and CODATA files floating around. But SciPy does not really have a good representation of units and a framework for using units in calculations.

Usage

Most of the packages are the same, multiplication by the units, creates a new class instance of the units. Here a snippet from Pint's documentation:
>>> distance = 24.0 * ureg.meter
>>> print(distance)
24.0 meter
>>> time = 8.0 * ureg.second
>>> print(time)
8.0 second
>>> speed = distance / time
>>> print(speed)
3.0 meter / second
The exception to this pattern is Python-units which uses a call to create objects.
>>> meters = unit('m')
>>> distance = meters(10)
Python-quantities is the only package with dependencies; it depends on NumPy, which really doesn't matter to me. Pint also supports NumPy arrays, which is important.

Snap Decision

Difficult to compare and decide without trying them all out. Who has time for that? So I think unit and numericalunits are both to undocumented for my taste. Unum looks like it is unsupported and/or not active anymore. That leaves Pint and quantities. Pint looks really slick, I like their design principles and it looks like their 0.3 release is coming out soon. It looks like quantities has been around for a while, there are both positive and  negative reviews, although to be fair that post about temperature conversions from C to F is the main reason SciPy doesn't have support for units conversions although it does have a great constants class with units. So I think I'll try quantities first, but keep my eye on Pint too. I hope to have a part II with some comparisons between these two soon.

Footnote

[1] There is some documentation for both units and numericalunits on their PyPI sites.
Fork me on GitHub