`pyqn`

is a Python 3 package for handling physical quantities with names, values, uncertainties and units. It is hosted on github and is available as free software under the GPL-v3 open source licence.

The units of a physical quantity are represented by a `Units`

object, which has methods for deducing the dimensions of a set of units and for calculating conversion factors between units. The simplest `Units`

, expressed as a string are simply the commonly-used unit symbols such as `m`

(metre), `Pa`

(pascal), `Å`

(Ångstrom), and `Hz`

(hertz). Click here for a full list of recognised units.

These simple units can carry any of the SI prefixes between `y`

(yocto, 10^{-24}) and `Y`

(yotta, 10^{+24}). For example, `nm`

(nanometres), `kg`

(kilograms), `GHz`

(gigahertz), and `μs`

(microseconds). Note that unit strings are represented as unicode strings encoded as UTF-8 throughout the `pyqn`

package. They can be raised to any integer power by placing the exponent to the right of the unit symbol, as in `J2`

(joules squared) and `cm-1`

(inverse centimetres). Note that no exponentiation operator such as `^`

or `**`

is used.

Units are combined by indicating multiplication by a period ('.') and division by a solidus ('/'). Note that a maximum of one units division is supported, and parentheses are not implemented (yet). Some examples are: `g.mol-1`

(grams per mole), `kg.m.s-2`

(kilogram metres per second per second) and `V/m`

(volts per metre). Different `Units`

objects can be further combined using the usual Python mathematical operators, `*`

and `/`

:

```
In [1]: from pyqn.units import Units
In [2]: u1 = Units('km')
In [3]: u2 = Units('hr')
In [4]: u3 = u1/u2
In [5]: print(u3)
km.hr-1
```

Units can be converted from one system to another using the `conversion`

method to return the conversion factor, only if both systems have the same dimensions:

```
In [6]: u4 = Units('m/s')
In [7]: u3.conversion(u4) # OK: can convert from km/hr to m/s
Out[7]: 0.2777777777777778
In [8]: u3.conversion(u2) # Oops: can't convert from km/hr to m!
...
UnitsError: Failure in units conversion: units km.hr-1[L.T-1] and hr[T] have
different dimensions
```

The `conversion`

method also accepts a string argument so the valid conversion above is equivalent to:

```
In [9]: u3.conversion('m/s')
Out[9]: 0.2777777777777778
```

It is also possible to convert between units without creating a `Units`

object at all, using the convenience method `convert`

:

```
In [10]: from pyqn.units import convert
In [11]: convert('km/hr', 'm/s')
Out[11]: 0.2777777777777778
In [12]: 299792458 * convert('m/s', 'fur/ftn')
Out[12]: 1802617499785.2542 # speed of light in furlongs per fortnight
```

The `Quantity`

class, found in the `pyqn.quantity`

module, provides a simple representation of physical quantities with a name, value, units, uncertainty and description.

The complete initialization method for Quantity objects allows one to set the Quantity's plain-text name (`name`

), LaTeX representation (`latex`

), HTML representation (`html`

), value (`value`

, a floating-point number), units (`units`

, either a text string to be parsed, or a `Units`

object), uncertainty (`sd`

, expressed as a 1σ standard deviation), and description or definition (`definition`

). For example,

```
Mr = Quantity ('M_EtOH',
r'$M_\mathrm{EtOH}$',
'<em>M</em><sub>EtOH</sub>',
44.01,
'g.mol-1',
0.012,
'molar mass of ethanol')
```

It is not necessary to set all (or any) of these attributes:

```
k = Quantity(name='k', value=2300., units='N/m',
definition='N2 bond force constant')
```

pyqn will do its best to parse a plain text string into a Quantity object. Quantity names are assigned in this string with `name =`

, uncertainties given as an integer value in parentheses at the appropriate significant figure after the value, and units as a string separated from the value/sd by whitespace. Scientific notation is supported with the exponent denoted by one of `e`

, `E`

, `d`

or `D`

). For example,

```
Mr = Quantity.parse('Mr = 44.010(12) g.mol-1')
k = Quantity.parse('k = 2.3e3 N/m')
x = Quantity.parse('400')
```

In addition to the usual `__str__()`

method, which returns a string representation of the `Quantity`

object with its name and units (if defined), there is also a method, `as_str()`

, which takes boolean arguments, `b_name`

, `b_sd`

and `b_units`

to control which of the `Quantity`

's name, uncertainty and units should be output in the returned string. For example,

```
>>> g = Quantity.parse('g = 9.818(7) m.s-2')
>>> print(g.as_str()) # by default, output name, sd and units
g = 9.818(7) m.s-2
>>> print(g.as_str(b_sd=False))
g = 9.818 m.s-2
>>> print(g.as_str(b_name=False, b_sd=False))
9.818 m.s-2
```

`Quantity`

objects support simple algebra (addition, subtraction, multiplication and division). Errors (*i.e.* standard deviation uncertainties) are propagated, but assumed to be uncorrelated. Note that addition and subtraction can only be carried out with `Quantity`

operands with the same units (not just the same dimensions). For example,

```
>>> DeltaH = Quantity.parse('DeltaH = 47.15(4) kJ.mol-1')
>>> T = Quantity(name='T', units='K', value=298., sd=0.5)
>>> DeltaS = DeltaH / T # DeltaS now has units kJ.K-1.mol-1
>>> DeltaS.convert_units_to('J.K-1.mol-1')
>>> print(DeltaS.as_str())
158.22(30) J.K-1.mol-1
```