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
>>> 30.0 * ureg.meter
This works to build up complex units as well:
.. doctest::
>>> 9.8 * ureg.meter / ureg.second**2
Using the constructor
---------------------
In some cases it is useful to define :class:`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)
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 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')
>>> Q_(length)
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:
.. doctest::
>>> 30.0 * ureg('meter')
>>> ureg('30.0 meters')
>>> ureg('3000cm').to('meters')
The parsing function is also available to the ``Quantity()`` constructor and
the various ``.to()`` methods:
.. doctest::
>>> Q_('30.0 meters')
>>> Q_(30.0, 'meter')
>>> Q_('3000.0cm').to('meter')
Or as a standalone method on the ``UnitRegistry``:
.. doctest::
>>> 2.54 * ureg.parse_expression('centimeter')
It is fairly good at detecting compound units:
.. doctest::
>>> g = ureg('9.8 meters/second**2')
>>> g
>>> g.to('furlongs/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'))
>>> Q_('2.54')
>>> type(Q_('2.54'))
.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')
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)')
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')
>>> Q_('-INFINITY m')
>>> Q_('nan m')
>>> Q_('NaN m')
.. 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