# Python quantities

February 4th, 2013 at 10:01 pm by Dr. Drang

I’ve been doing a lot of calculations in both SI and US Customary Units recently. Normally, I can do the conversions at the end of a set of calculations, and the venerable `units`

program works just fine for me. But in my current project, I need to show intermediate results in both sets of units and there’s just too much busy work in going back and forth between IPython, which I’m using as my calculator, and `units`

. After a bit of hunting, I found the Python `quantities`

module—it’s a bit more cumbersome than `units`

if you’re just doing a few conversions, but it’s much better if you’re doing a long series of calculations.

Before I get into `quantities`

, a word of warning: I’m going to be much less tolerant of SI-absolutist comments on this post than I was a month ago. I certainly prefer to work primarily in one system or the other, but that isn’t an option on this project, so comments that even vaguely suggest I shouldn’t be using US Customary Units will be deleted.

I installed `quantities`

via

```
sudo pip install quantities
```

and the installation went smoothly on both Lion and Mountain Lion. It’s built on NumPy, so if you don’t have that installed already, your installation may not be as trouble-free as mine was.

I’ve been importing `quantities`

this way:

```
In [1]: import quantities as q
```

This prevents the many, many unit names in `quantities`

from polluting my namespace, but gives me access to them with only a little extra typing.

The easiest way to define a variable with both a value and a unit is through multiplication by the unit:

```
In [2]: F = 525*q.lbf
In [3]: h = 3.15*q.inch
In [4]: w = 1.75*q.inch
In [5]: stress = F/(h*w)
In [6]: stress
Out[6]: array(95.23809523809524) * lbf/in**2
```

This example shows a couple of things to keep in mind if, like me, you do a lot of mechanics problems:

- Like
`units`

,`quantities`

thinks of pounds (`lb`

) as a unit of mass, not of force. For pounds as a force, use`lbf`

. The natural way to assign units of inches,

`in`

, doesn’t work, presumably because the`quantities`

developers didn’t want to risk a conflict with Python’s`in`

keyword. Oddly, though, if you ask to see a value in inches, the response*will*use`in`

:`In [7]: h Out[7]: array(3.15) * in`

Converting units is easy:

```
In [8]: stress.units = q.kPa
In [9]: stress
Out[9]: array(656.6435517303199) * kPa
```

From now on, `stress`

will be reported in kilopascals. If you want it back in US Customary Units,

```
In [10]: stress.units = q.psi
In [11]: stress
Out[11]: array(95.23809523809524) * psi
```

will do the trick. By the way, if you’re put off by the `array()`

stuff, just use `print`

:

```
In [12]: print stress
95.2380952381 psi
```

It’s a bit more typing, but the output is nicer.

What happens if you have a mixture of units? That depends. Although the documentation says that in ambiguous cases, `quantities`

doesn’t guess your intention, I find that sometimes it does.

```
In [13]: b = 36*q.mm
In [14]: h+b
Out[14]: array(4.567322834645669) * in
In [15]: b+h
Out[15]: array(116.01) * mm
```

Here, it’s obviously using the units of the first term to decide which one to use for the sum. But in this case,

```
In [18]: F/(b*h)
Out[18]: array(4.62962962962963) * lbf/(mm*in)
```

it decided not to decide. When there’s a mix of units of the same type like this, `simplified`

will unmix them, substituting the SI unit for each.

```
In [19]: F/(b*h).simplified
Out[19]: array(182268.88305628463) * lbf/m**2
```

As you can see, `simplified`

doesn’t change units that aren’t mixed, so the `lbf`

remains. If you prefer different default units, you can change them.

```
In [20]: q.set_default_units(length='mm')
In [21]: F/(b*h).simplified
Out[21]: array(0.18226888305628464) * lbf/mm**2
```

There are other `quantities`

tricks, which you can read about in the documentation, but this is a decent start.

Clark says:

February 5th, 2013 at 8:42 pm

That’s cool. I didn’t even know about that module. While I prefer metric the reality is that most of the measures I deal with are in classic units. Modules like this are a savior.

Yves Daoust says:

February 6th, 2013 at 2:50 am

I dream of a programming language that would natively support measurement units (be they predefined or user-definable).

That would allow implicit or explicit unit conversions but also, more importantly, checking the dimensional compatibility of expression.

Like:

float [m/s/s] a= 9.81 [m/s/s]; float [m/s] v0= 3 [m/s]; float [m] e= 0.5 * a * t * t + v0 * t + 3; - Dimension error: term ‘3’ should be in [m] !

Yves Daoust says:

February 6th, 2013 at 2:50 am

I dream of a programming language that would natively support measurement units (be they predefined or user-definable).

That would allow implicit or explicit unit conversions but also, more importantly, checking the dimensional compatibility of expressions.

Like:

float [m/s/s] a= 9.81 [m/s/s]; float [m/s] v0= 3 [m/s]; float [m] e= 0.5 * a * t * t + v0 * t + 3; - Dimension error: term ‘3’ should be in [m] !

Alex says:

February 6th, 2013 at 3:15 am

Strictly speaking, any strongly-typed language will let you create a library which enforces such things. Depending on the language, you may need a greater or lesser amount of boilerplate in the consuming code.

m0sa says:

February 6th, 2013 at 6:23 am

@Yves F# supports units of measure out of the box: http://blogs.msdn.com/b/andrewkennedy/archive/2008/09/02/units-of-measure-in-f-part-two-unit-conversions.aspx

Chris says:

February 6th, 2013 at 9:26 am

Another nice units module is Unum. I have been using it lately for mechanics problems as well. By default, mainly SI units are defined. But, it is easy to add whatever units you want.

http://home.scarlet.be/be052320/Unum.html

Dr. Drang says:

February 6th, 2013 at 8:16 pm

Chris, thanks for the link to Unum. I saw its name when I was searching for a units library, but I forgot to follow up on it. Looks every bit as capable as quantities, but I like having lots of units predefined.

Clark says:

February 7th, 2013 at 10:39 am

Only problem with quantities is that it has dependencies on NumPy which in turn requires Fortran. I was going to put it on my iPhone when I noticed that. I may give Unum a look.