Juan Reyero

magnitude - a Python Library for Computing with Physical Quantities

A physical quantity is a number with a unit, like 10 km/h. Units can be any of the SI units, plus a bunch of non-SI, bits, dollars, and any combination of them. They can include the standard SI prefixes. Magnitude can operate with physical quantities, parse their units, and print them. You don't have to worry about unit consistency or conversions; everything is handled transparently. By default output is done in basic SI units, but you can specify any output unit, as long as it can be reduced to the basic units of the physical quantity.

Download from googlecode

Alternatives

A couple of alternative libraries have been pointed out to me. I haven't tested them yet: my comments are based on looking at the documentation.

  • Unum looks well finished and is thoroughly documented. Good: allows you to define arbitrary units (magnitude doesn't; in the future it will support user-defined units as long as they are a combination of the base units). Bad: it looks like it doesn't handle prefixes, and it clutters your namespace with all its unit definitions (you end up with variables named M, S, etc. in your namespace).
  • Scalar looks very similar to Unum, maybe not as well documented. Looks like it has exactly the same problems and advantages, plus the ability of running with units disabled (which should be good for performance).
  • PhyisicalQuantities, part of ScientificPython, is very similar to magnitude. Same approach, essentially the same functionality, very similar API.

Examples

>>> from magnitude import mg
>>> print "10 m/s ** 2 ->", mg(10, 'm/s') ** 2
10 m/s ** 2 -> 100.0000 m2 / s2 
>>> print (mg(10, 'm') * 2 / (10, 'm/s2')).sqrt()
1.4142 s 
>>> tsq = mg(10, 'm') * 2 / (10, 'm/s2')
>>> print tsq ** 0.5
1.4142 s
    
>>> from magnitude import mg, output_precision
>>> print mg(1, "lightyear") / mg(1, "c")
>>> 31557600.0000 s
>>> y = mg(1, "lightyear") / (1, "c") 
>>> y.ounit("year")
<magnitude.magnitude instance at 0x81440>
>>> print y
1.0000 year
>>> yd = y.ounit('day')
>>> print yd
365.2500 day
>>> output_precision(0)
0
>>> print yd
365 day
    
>>> from magnitude import mg
>>> power = mg(100, 'kg') * (2, 'gravity') * (5, 'km/h')
>>> print power
2724.0694 m2 kg / s3 
>>> print power.ounit('mW')
2724069.4444 mW
>>> power.ounit('kW')
<magnitude.magnitude instance at 0x90f80>
>>> print  power
2.7241 kW

Units

All units are defined in as a combination of the base units: m, s, K, kg, A, mol, cd, $ and bit.

A list of all available units with their definition:

# Magnitudes for the base SI units
_mags'm'   = magnitude(1.0, m=1)
_mags's'   = magnitude(1.0, s=1)
_mags'K'   = magnitude(1.0, K=1)
_mags'kg'  = magnitude(1.0, kg=1)
_mags'A'   = magnitude(1.0, A=1)
_mags'mol' = magnitude(1.0, mol=1)
_mags'cd'  = magnitude(1.0, cd=1)
_mags'$'   = magnitude(1.0, dollar=1)
_mags'dollar' = magnitude(1.0, dollar=1)
_mags'bit' = magnitude(1.0, bit=1)

# Magnitudes for derived SI units _mags'rad' = magnitude(1.0) # radian _mags'sr' = magnitude(1.0) # steradian _mags'Hz' = magnitude(1.0, s=-1) # hertz _mags'g' = magnitude(1e-3, kg=1) # gram _mags'N' = magnitude(1.0, m=1, kg=1, s=-2) # newton _mags'Pa' = magnitude(1.0, m=-1, kg=1, s=-2) # pascal _mags'J' = magnitude(1.0, m=2, kg=1, s=-2) # joule _mags'W' = magnitude(1.0, m=2, kg=1, s=-3) # watt _mags'C' = magnitude(1.0, s=1, A=1) # coulomb _mags'V' = magnitude(1.0, m=2, kg=1, s=-3, A=-1) # volt _mags'F' = magnitude(1.0, m=-2, kg=-1, s=4, A=2) # farad, C/V _mags'ohm' = magnitude(1.0, m=2, kg=1, s=-3, A=-2) # ohm, V/A _mags'S' = magnitude(1.0, m=-2, kg=-1, s=3, A=2) # siemens, A/V, el cond. _mags'Wb' = magnitude(1.0, m=2, kg=1, s=-2, A=-1) # weber, V.s, mag. flux _mags'T' = magnitude(1.0, kg=1, s=-2, A=-1) # tesla, Wb/m2, mg flux dens. _mags'H' = magnitude(1.0, m=2, kg=1, s=-2, A=-2) # henry, Wb/A, induct. _mags'degC' = magnitude(1.0, K=1) # celsius, !! _mags'lm' = magnitude(1.0, cd=1) # lumen, cd.sr (=cd), luminous flux _mags'lux' = magnitude(1.0, m=-2, cd=1) # lux, lm/m2, illuminance _mags'Bq' = magnitude(1.0, s=-1) # becquerel, activity of a radionulide _mags'Gy' = magnitude(1.0, m=2, s=-2) # gray, J/kg, absorbed dose _mags'Sv' = magnitude(1.0, m=2, s=-2) # sievert, J/kg, dose equivalent _mags'kat' = magnitude(1.0, s=-1, mol=1) # katal, catalitic activity # Non-SI but almost: _mags'b' = magnitude(8.0, bit=1) # byte, note that B is Bel, as in dB # Funny magnitudes with strange names # length _mags"'" = magnitude(0.3048, m=1) # feet _mags'ft' = magnitude(0.3048, m=1) # feet _mags'inch' = magnitude(0.0254, m=1) # inch _mags'"' = magnitude(0.0254, m=1) # inch _mags'lightyear' = magnitude(2.99792458e8 * 365.25 * 86400, m=1)

# volume _mags'l' = magnitude(0.001, m=3)

# time # year is tropical year, "the mean interval between vernal # equinoxes. Differs from the sidereal year by 1 part in 26000 # due to precession of the earth about its rotational axis # combined with precession of the perihelion of the earth's orbit" # (from units.dat). _mags'year' = magnitude(31556925.974678401, s=1) _mags'day' = magnitude(86400, s=1) _mags'h' = magnitude(3600, s=1) _mags'min' = magnitude(60, s=1)

# Resolution _mags'dpi' = magnitude(1.0/0.0254, m=-1) _mags'lpi' = magnitude(1.0/0.0254, m=-1)

# Velocity _mags'ips' = magnitude(0.0254, m=1, s=-1) _mags'c' = magnitude(2.99792458e8, m=1, s=-1)

# Acceleration _mags'gravity' = magnitude(9.80665, m=1, s=-2)


Prefixes

They can be prepended to any unit specification, as in pl for picoliter or Pm for petameter.

_prefix = {'y': 1e-24,  # yocto
          'z': 1e-21,  # zepto
          'a': 1e-18,  # atto
          'f': 1e-15,  # femto
          'p': 1e-12,  # pico
          'n': 1e-9,   # nano
          'u': 1e-6,   # micro
          'm': 1e-3,   # mili
          'c': 1e-2,   # centi
          'd': 1e-1,   # deci
          'k': 1e3,    # kilo
          'M': 1e6,    # mega
          'G': 1e9,    # giga
          'T': 1e12,   # tera
          'P': 1e15,   # peta
          'E': 1e18,   # exa
          'Z': 1e21,   # zetta
          'Y': 1e24,   # yotta

          # Binary prefixes, approved by the International
          # Electrotechnical Comission in 1998.  Since then, kb means
          # 1000 bytes; for 1024 bytes use Kib (note the capital K in
          # the binary version, and the lower case for the b of byte,
          # see comment in byte definition below).
          'Ki': 1024,        # Kibi (<- kilo, 10^3)
          'Mi': 1048576,     # Mebi, 2^20 (<- mega, 10^6)
          'Gi': 1073741824,  # Gibi, 2^30 (<- giga, 10^9)
          'Ti': 1099511627776,       # Tebi, 2^40 (<- tera, 10^12)
          'Pi': 1125899906842624,    # Pebi, 2^50 (<- peta, 10^15)
          'Ei': 1152921504606846976  # Exbi, 2^60 (<- exa, 10^18)
          }