1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
Defining Quantities
===================
A quantity in Pint is the product of a unit and a magnitude.
Pint supports several different ways of defining physical quantities, including
a powerful string parsing system. These methods are largely interchangeable,
though you may **need** to use the constructor form under certain circumstances
(see :doc:`nonmult` for an example of where the constructor form is required).
By multiplication
-----------------
If you've read the :ref:`Tutorial`, you're already familiar with defining a
quantity by multiplying a ``Unit()`` and a scalar:
.. doctest::
>>> from pint import UnitRegistry
>>> ureg = UnitRegistry()
>>> ureg.meter
<Unit('meter')>
>>> 30.0 * ureg.meter
<Quantity(30.0, 'meter')>
This works to build up complex units as well:
.. doctest::
>>> 9.8 * ureg.meter / ureg.second**2
<Quantity(9.8, 'meter / second ** 2')>
Using the constructor
---------------------
In some cases it is useful to define :class:`Quantity() <pint.quantity.Quantity>`
objects using it's class constructor. Using the constructor allows you to
specify the units and magnitude separately.
We typically abbreviate that constructor as `Q_` to make it's usage less verbose:
.. doctest::
>>> Q_ = ureg.Quantity
>>> Q_(1.78, ureg.meter)
<Quantity(1.78, 'meter')>
As you can see below, the multiplication and constructor methods should produce
the same results:
.. doctest::
>>> Q_(30.0, ureg.meter) == 30.0 * ureg.meter
True
>>> Q_(9.8, ureg.meter / ureg.second**2)
<Quantity(9.8, 'meter / second ** 2')>
Quantity can be created with itself, if units is specified ``pint`` will try to convert it to the desired units.
If not, pint will just copy the quantity.
.. doctest::
>>> length = Q_(30.0, ureg.meter)
>>> Q_(length, 'cm')
<Quantity(3000.0, 'centimeter')>
>>> Q_(length)
<Quantity(30.0, 'meter')>
Using string parsing
--------------------
Pint includes a powerful parser for detecting magnitudes and units (with or
without prefixes) in strings. Calling the ``UnitRegistry()`` directly
invokes the parsing function ``UnitRegistry.parse_expression``:
.. doctest::
>>> 30.0 * ureg('meter')
<Quantity(30.0, 'meter')>
>>> ureg('30.0 meters')
<Quantity(30.0, 'meter')>
>>> ureg('3000cm').to('meters')
<Quantity(30.0, 'meter')>
The parsing function is also available to the ``Quantity()`` constructor and
the various ``.to()`` methods:
.. doctest::
>>> Q_('30.0 meters')
<Quantity(30.0, 'meter')>
>>> Q_(30.0, 'meter')
<Quantity(30.0, 'meter')>
>>> Q_('3000.0cm').to('meter')
<Quantity(30.0, 'meter')>
Or as a standalone method on the ``UnitRegistry``:
.. doctest::
>>> 2.54 * ureg.parse_expression('centimeter')
<Quantity(2.54, 'centimeter')>
It is fairly good at detecting compound units:
.. doctest::
>>> g = ureg('9.8 meters/second**2')
>>> g
<Quantity(9.8, 'meter / second ** 2')>
>>> g.to('furlongs/fortnight**2')
<Quantity(7.12770743e+10, 'furlong / fortnight ** 2')>
And behaves well when given dimensionless quantities, which are parsed into
their appropriate objects:
.. doctest::
>>> ureg('2.54')
2.54
>>> type(ureg('2.54'))
<class 'float'>
>>> Q_('2.54')
<Quantity(2.54, 'dimensionless')>
>>> type(Q_('2.54'))
<class 'pint.Quantity'>
.. note:: Pint's rule for parsing strings with a mixture of numbers and
units is that **units are treated with the same precedence as numbers**.
For example, the units of
.. doctest::
>>> Q_('3 l / 100 km')
<Quantity(0.03, 'liter * kilometer')>
may be unexpected at first but, are a consequence of applying this rule. Use
brackets to get the expected result:
.. doctest::
>>> Q_('3 l / (100 km)')
<Quantity(0.03, 'liter / kilometer')>
Special strings for NaN (Not a Number) and inf(inity) are also handled in a case-insensitive fashion.
Note that, as usual, NaN != NaN.
.. doctest::
>>> Q_('inf m')
<Quantity(inf, 'meter')>
>>> Q_('-INFINITY m')
<Quantity(-inf, 'meter')>
>>> Q_('nan m')
<Quantity(nan, 'meter')>
>>> Q_('NaN m')
<Quantity(nan, 'meter')>
.. note:: Since version 0.7, Pint **does not** use eval_ under the hood.
This change removes the `serious security problems`_ that the system is
exposed to when parsing information from untrusted sources.
.. _eval: http://docs.python.org/3/library/functions.html#eval
.. _`serious security problems`: http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
|