Formatting Variables with uncertainties¶
Printing¶
Numbers with uncertainties can be printed conveniently:
>>> print(x)
0.200+/-0.010
The resulting form can generally be parsed back with
ufloat_fromstr()
(except for the LaTeX form).
The nominal value and the uncertainty always have the same precision: this makes it easier to compare them.
Standard formats¶
More control over the format can be obtained (in Python 2.6+)
through the usual format()
method of strings:
>>> print('Result = {:10.2f}'.format(x))
Result = 0.20+/- 0.01
All the float format specifications are accepted, except those
with the n
format type. In particular, a fill character, an
alignment option, a sign or zero option, a width, or the %
format
type are all supported.
The usual float formats with a precision retain their original
meaning (e.g. .2e
uses two digits after the decimal point): code
that works with floats produces similar results when running with
numbers with uncertainties.
Precision control¶
It is possible to control the number of significant digits of the
uncertainty by adding the precision modifier u
after the
precision (and before any valid float format type like f
, e
,
the empty format type, etc.):
>>> print('1 significant digit on the uncertainty: {:.1u}'.format(x))
1 significant digit on the uncertainty: 0.20+/-0.01
>>> print('3 significant digits on the uncertainty: {:.3u}'.format(x))
3 significant digits on the uncertainty: 0.2000+/-0.0100
>>> print('1 significant digit, exponent notation: {:.1ue}'.format(x))
1 significant digit, exponent notation: (2.0+/-0.1)e-01
>>> print('1 significant digit, percentage: {:.1u%}'.format(x))
1 significant digit, percentage: (20+/-1)%
When uncertainties
must choose the number of significant
digits on the uncertainty, it uses the Particle
Data Group rounding
rules (these rules keep the number of digits small, which is
convenient for reading numbers with uncertainties, and at the same
time prevent the uncertainty from being displayed with too few
digits):
>>> print('Automatic number of digits on the uncertainty: {}'.format(x))
Automatic number of digits on the uncertainty: 0.200+/-0.010
>>> print(x)
0.200+/-0.010
Custom options¶
uncertainties
provides even more flexibility through custom
formatting options. They can be added at the end of the format string:
P
for pretty-printing:>>> print('{:.2e}'.format(x)) (2.00+/-0.10)e-01 >>> print(u'{:.2eP}'.format(x)) (2.00±0.10)×10⁻¹
The pretty-printing mode thus uses “±”, “×” and superscript exponents.
S
for the shorthand notation:>>> print('{:+.1uS}'.format(x)) # Sign, 1 digit for the uncertainty, shorthand +0.20(1)
In this notation, the digits in parentheses represent the uncertainty on the last digits of the nominal value.
L
for a LaTeX output:>>> print(x*1e7) (2.00+/-0.10)e+06 >>> print('{:L}'.format(x*1e7)) # Automatic exponent form, LaTeX \left(2.00 \pm 0.10\right) \times 10^{6}
p
is for requiring that parentheses be always printed around the …±… part (without enclosing any exponent or trailing “%”, etc.). This can for instance be useful so as to explicitly factor physical units:>>> print('{:p} kg'.format(x)) # Adds parentheses (0.200+/-0.010) kg >>> print("{:p} kg".format(x*1e7)) # No parentheses added (exponent) (2.00+/-0.10)e+06 kg
These custom formatting options can be combined (when meaningful).
Details¶
A common exponent is automatically calculated if an exponent is needed for the larger of the nominal value (in absolute value) and the uncertainty (the rule is the same as for floats). The exponent is generally factored, for increased legibility:
>>> print(x*1e7)
(2.00+/-0.10)e+06
When a format width is used, the common exponent is not factored:
>>> print('Result = {:10.1e}'.format(x*1e-10))
Result = 2.0e-11+/- 0.1e-11
(Using a (minimal) width of 1 is thus a way of forcing exponents to not be factored.) Thanks to this feature, each part (nominal value and standard deviation) is correctly aligned across multiple lines, while the relative magnitude of the error can still be readily estimated thanks to the common exponent.
An uncertainty which is exactly zero is always formatted as an integer:
>>> print(ufloat(3.1415, 0))
3.1415+/-0
>>> print(ufloat(3.1415e10, 0))
(3.1415+/-0)e+10
>>> print(ufloat(3.1415, 0.0005))
3.1415+/-0.0005
>>> print('{:.2f}'.format(ufloat(3.14, 0.001)))
3.14+/-0.00
>>> print('{:.2f}'.format(ufloat(3.14, 0.00)))
3.14+/-0
All the digits of a number with uncertainty are given in its representation:
>>> y = ufloat(1.23456789012345, 0.123456789)
>>> print(y)
1.23+/-0.12
>>> print(repr(y))
1.23456789012345+/-0.123456789
>>> y
1.23456789012345+/-0.123456789
Global formatting¶
It is sometimes useful to have a consistent formatting across multiple parts of a program. Python’s string.Formatter class allows one to do just that. Here is how it can be used to consistently use the shorthand notation for numbers with uncertainties:
class ShorthandFormatter(string.Formatter):
def format_field(self, value, format_spec):
if isinstance(value, uncertainties.UFloat):
return value.format(format_spec+'S') # Shorthand option added
# Special formatting for other types can be added here (floats, etc.)
else:
# Usual formatting:
return super(ShorthandFormatter, self).format_field(
value, format_spec)
frmtr = ShorthandFormatter()
print(frmtr.format("Result = {0:.1u}", x)) # 1-digit uncertainty
prints with the shorthand notation: Result = 0.20(1)
.
Customizing the pretty-print and LaTeX outputs¶
The pretty print and LaTeX outputs themselves can be customized.
For example, the pretty-print representation of numbers with uncertainty can
display multiplication with a centered dot (⋅) instead of the default symbol
(×), like in (2.00±0.10)⋅10⁻¹
; this is easily done through the global
setting uncertainties.core.MULT_SYMBOLS["pretty-print"] = "⋅"
.
Beyond this multiplication symbol, the “±” symbol, the parentheses and the
exponent representations can also be customized globally. The details can be
found in the documentation of uncertainties.core.format_num()
.