Channels ▼
RSS

Tools

Quantities and Units in Python


Pint allows you to define units as functions of other units with different alias names. Then, you can apply all the prefixes to the different units. This way, you just need to include the definition for meter with a meter alias and you can work with kilo-meter, kilo-metre, kilometer, kilometre, centi-meter, centi-metre, centimeter, and centimeter. The definitions file includes the kilo and centi prefixes and you can use them with and without a dash. Pint also supports plurals, so you can use both kilo-meter and kilo-meters. The prefixes and the units include abbreviations as alias names and you can use kmeter, kmeters, and km to specify kilo-meters.

The following lines show the decimal prefixes specified in the default_en.txt unit definitions file:

# decimal prefixes
yocto- = 1e-24 = y-
zepto- = 1e-21 = z-
atto- =  1e-18 = a-
femto- = 1e-15 = f-
pico- =  1e-12 = p-
nano- =  1e-9  = n-
micro- = 1e-6  = u-
milli- = 1e-3  = m-
centi- = 1e-2  = c-
deci- =  1e-1  = d-
deca- =  1e+1  = da-
hecto- = 1e2   = h-
kilo- =  1e3   = k-
mega- =  1e6   = M-
giga- =  1e9   = G-
tera- =  1e12  = T-
peta- =  1e15  = P-
exa- =   1e18  = E-
zetta- = 1e21  = Z-
yotta- = 1e24  = Y-

The base unit for length measurement is the meter. The following line defines the base unit with the category enclosed in square brackets ([]). All the length units will be compatible between them to perform arithmetic operations (you can sum meters to inches and Pint will perform the necessary unit conversions). Notice how simple it is to define many alias names for the unit by simply adding an equal sign and the alias name. In this case, meter has two alias names, m and metre.

meter = [length] = m = metre

The following lines define other length measures based on the meter and the prefixes. For example, an inch is equal to 2.54 multiplied by a centimeter and it includes four alias names: international_inch, inches, international_inches, and in. The foot is defined related to an inch. Both the mile and the yard are based on the foot and its plural alias name: feet.

inch = 2.54 * centimeter = international_inch = inches = international_inches = in
foot = 12 * inch = international_foot = ft = feet = international_foot = international_feet
mile = 5280 * foot = mi = international_mile
yard = 3 * feet = yd = international_yard

In the # EM section, you will find the electrical measurement units, including volt and ohm. The default definition for ohm doesn't include an alias.

volt = joule / coulomb = V
ohm = volt / ampere

You can easily modify the line that defines the ohm unit in default_en.txt to use O as an alias for ohm by replacing that line with the following one:

ohm = volt / ampere = O

Then, you need only add the following lines to import UnitRegistry from Pint and create an instance of UnitRegistry to start working with the different units.

from pint import UnitRegistry
ur = UnitRegistry()

Next, you need to follow two simple rules:

  • To assign a unit of measure to a value, multiply the value by the unit included in the UnitRegistry instance (ur). Pint will create an instance of the Quantity class (a subclass of _Quantity). The magnitude property will hold the specified value and the units property will include the units of measure decoded from the specified names. Remember that the names might be any of the alias names defined in the units definition file and the UnitRegistry must map them to the specific unit names.
  • To generate a new instance of the Quantity class with a value converted from its unit to a different unit, call the to method with the desired destination unit as a parameter.

You can read the following line of code as "assign 500 ohms to r1."

r1 = 500 * ur.ohms

If you call print(r1) the result will be 500 ohm. If you enter r1 in the Python Console, the result will be <Quantity(500, 'ohm')>. Thus, you can easily know the magnitudes and the related units.

You can read the following line of code as "display the value of r1 expressed in kilo-ohms."

print(r1.to(ur.kO))

The following line displays the value of r1 expressed in ohms, no matter the unit in which r1 has the value saved.

print(r1.to(ur.O))

The following code uses Pint to sum the values of r1 and r2. As happened with the other package, the code is self-documented; and with Pint, you can also check the units property and its dictionary to retrieve the units related to the magnitude value. Notice that ur['kO'] is equitalent to ur.kO and it is just another way of specifying the desired unit, providing it as a string. The r1_plus_r2 variable holds the result of the sum operation expressed in ohms and r1_plus_r2_kohms holds the result converted to kilo-ohms. Pint performs the necessary conversion to allow you to sum the values of r1 and r2.

from pint import UnitRegistry
ur = UnitRegistry()
r1 = 500 * ur.ohms
r2 = 5.2 * ur['kO']
r1_plus_r2 = r1 + r2
r1_plus_r2_kohms = r1_plus_r2.to(ur['kO'])

The following code uses Pint to sum four distance values expressed in four different units of measure: meters, miles, centimeters, and feet. Because Pint supports alias names and plurals for the units, I can use the appropriate names that make the code easier to read. The total_distance variable holds the total distance expressed in feet.

from pint import UnitRegistry
ur = UnitRegistry()
distance1 = 2500 * ur.meters
distance2 = 2 * ur.miles
distance3 = 3000 * ur.centimeters
distance4 = 3500 * ur.feet
total_distance = (distance1 + distance2 + distance3 + distance4).to(ur.feet)

Because total_distance is an instance of Quantity, if you want to work with just the value, you have to use total_distance.magnitude. You can perform certain operations with dimensionless values, such as multiplication and division. Pint will perform the operations and the unit of measure will be the same (feet).

total_distance_divided_by_2 = total_distance / 2
total_distance_multiplied_by_3 = total_distance * 3

However, Pint raises an exception when you try to perform a sum with a dimensionless value. For example, the following line generates a pint.unit.DimensionalityError exception with the following message: pint.unit.DimensionalityError: Cannot convert from 'foot' to 'dimensionless'. This way, Pint makes sure you don't make mistakes when you fail to specify the units of measure.

total_distance_plus_1 = total_distance + 1

Some operations with values that have the same unit of measure associated to them might produce a new unit of measure in the result. For example, if you calculate the surface of a rectangle with the width and length expressed in inches, the resulting Quantity instance (surface) will have a square inch (inch ** 2 in Pint) unit of measure as the result of the multiplication:

length = 50 * ur.inches
width = 100 * ur.inches
surface = length * width


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video