summaryrefslogtreecommitdiff
path: root/docs/user/defining-quantities.rst
blob: e40b08cf94a90eae94a5b6d66781c5fcc7697667 (plain)
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, 'kilometer * liter')>

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