A package that lets you define quantities with units, which can then be used in almost any numerical calculation in any programming language. Checks that calculations pass dimensional analysis, performs unit conversions, and defines physical constants.
This package implements units and dimensional analysis in an unconventional way that has the following unique advantages:
These great features come with the disadvantage that the interface is less slick than other unit packages. If you have a quantity with units, you cannot directly see what the units are. You are supposed to already know what the units are, and then the package will tell you whether you made a mistake. Even worse, you only get alerted to the mistake after running a calculation all the way through twice.
Therefore the package is not suggested for students exploring how units work. It is suggested for engineering and science professionals who want to make their code more self-documenting and self-debugging.
You can install from PyPI:
pip install numericalunits
At the top of the code you’re working on, write:
import numericalunits as nu nu.reset_units()
Unit errors, like trying to add a length to a mass, will not immediately announce themselves as unit errors. Instead, you need to run the whole calculation (including the reset_units() part) twice. If you get the same final answers both times, then congratulations, all your calculations are almost guaranteed to pass dimensional analysis! If you get different answers every time you run, then you made a unit error! It is up to you to figure out where and what the error is.
To assign a unit to a quantity, multiply by the unit, e.g. my_length = 100 * mm. (In normal text you would write “100 mm”, but unfortunately Python does not have “implied multiplication”.)
To express a dimensionful quantity in a certain unit, divide by that unit, e.g. when you see my_length / cm, you pronounce it “my_length expressed in cm”.
Example 1: What is 5 mL expressed in cubic nanometers?:
import numericalunits as nu nu.reset_units() x = 5 * nu.mL # "Read: x is equal to 5 milliliters" x / nu.nm**3 # "Read: x expressed in cubic nanometers is..." --> 5e21
Example 2: An electron is in a 1e5 V/cm electric field. What is its acceleration? (Express the answer in m/s^2.)
import numericalunits as nu nu.reset_units() efield = 1e5 * (nu.V / nu.cm) force = nu.e * efield # (nu.e is the elementary charge) accel = force / nu.me # (nu.me is the electron mass) accel / (nu.m / nu.s**2) # Answer --> 1.7588e18
Example 3: You measured a voltage as a function of the position of dial: 10 volts when the dial is at 1cm, 11 volts when the dial is at 2cm, etc. etc. Interpolate from this data to get the expected voltage when the dial is at 41mm, and express the answer in mV.
import numericalunits as nu nu.reset_units() from numpy import array from scipy.interpolate import interp1d voltage_data = array([[1 * nu.cm, 10 * nu.V], [2 * nu.cm, 11 * nu.V], [3 * nu.cm, 13 * nu.V], [4 * nu.cm, 16 * nu.V], [5 * nu.cm, 18 * nu.V]]) f = interp1d(voltage_data[:,0], voltage_data[:,1]) f(41 * nu.mm) / nu.mV # Answer --> 16200
Example 4: A unit mistake … what is 1 cm expressed in atmospheres?
import numericalunits as nu nu.reset_units() (1 * nu.cm) / nu.atm # --> a randomly-varying number # The answer randomly varies every time you run this, indicating that you # are violating dimensional analysis.
A complete set of independent base units (meters, kilograms, seconds, coulombs, kelvins) are defined as randomly-chosen positive floating-point numbers. All other units and constants are defined in terms of those. In a dimensionally-correct calculation, the units all cancel out, so the final answer is deterministic, not random. In a dimensionally-incorrect calculations, there will be random factors causing a randomly-varying final answer.
Includes a variety of common units, both SI and non-SI, everything from frequency to magnetic flux. Also includes common physical constants like Planck’s constant and the speed of light. Browse the source code to see a complete list. It is very easy to add in any extra units and constants that were left out.
For electromagnetism, all units are intended for use in SI formulas. If you plug them into cgs-gaussian electromagnetism formulas, or cgs-esu electromagnetism formulas, etc., you will get nonsense results.
The package does not keep track of “radians” as an independent unit assigned a random number. The reason is that the “radians” factor does not always neatly cancel out of formulas.
The package does not keep track of “moles” as an independent unit assigned a random number; instead mol is just a pure number (~6e23), like you would say “dozen”=12. That means: (1) gram/mol is exactly the same as amu, and Boltzmann constant is exactly the same as the ideal gas constant, and so on. (2) You should rarely need to use Avogadro’s number NA – it is just a synonym of mol (NA = mol ~ 6e23). Here are a few examples using moles:
import numericalunits as nu nu.reset_units() # There are eight copies of a protein inside a yeast nucleus of volume # 3 cubic microns. What is the concentration of the protein, in micromolar (uM)? (8. / (3 * nu.um**3)) / nu.uM # Answer --> 0.0044 # 5 kcal / mol is how many joules? (5. * nu.kcal / nu.mol) / nu.J # Answer --> 3.47e-20 # How many molecules are in 2.3 femtomoles? 2.3 * nu.fmol # Answer --> 1.39e9
The package cannot convert temperatures between Fahrenheit, Celsius, and kelvin. The reason is that these scales have different zeros, so the units cannot be treated as multiplicative factors. It is, however, possible to convert temperature intervals, via the units degCinterval (which is a synonym of kelvin, K) and degFinterval.