Skip to content

Commit

Permalink
Documentation and code cleanups
Browse files Browse the repository at this point in the history
Incorporate more code review feedback and fix some doc issues.

Signed-off-by: Michael Tiemann <[email protected]>
  • Loading branch information
MichaelTiemannOSC committed Oct 22, 2023
1 parent 1d7327a commit eae6856
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 21 deletions.
24 changes: 22 additions & 2 deletions docs/getting/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,26 @@ a ``Quantity()`` object.
``Quantity()`` objects also work well with NumPy arrays, which you can
read about in the section on :doc:`NumPy support <numpy>`.

Some units are compound, such as [energy], which is stated in terms of
[mass] * [length]**2 / [time]**2. Earlier versions of Pint would sort unit names
alphabetically by default, leading to different orderings of units (old behavior):

>>> "{:P}".format(pint.Quantity('1 pound * ft**2 * second**-2'))
'1.0 foot²·pound/second²'
>>> "{:P}".format(pint.Quantity('1 kg * cm**2 * second**-2'))
'1.0 centimeter²·kilogram/second²'

Now by default it sorts by dimensions as proposed by ISO 80000, with [mass]
coming before [length], which also comes before [time]. The dimension order
can be changed in the registry (`dim_order` in `defaults`):

>>> "{:P}".format(pint.Quantity('1 pound * ft**2 * second**-2'))
'1.0 pound·foot²/second²'
>>> "{:P}".format(pint.Quantity('1 kg * cm**2 * second**-2'))
'1.0 kilogram·centimeter²/second²'



Converting to different units
-----------------------------

Expand Down Expand Up @@ -180,11 +200,11 @@ but otherwise keeping your unit definitions intact.
>>> volume = 10*ureg.cc
>>> mass = density*volume
>>> print(mass)
14.0 cubic_centimeter * gram / centimeter ** 3
14.0 gram * cubic_centimeter / centimeter ** 3
>>> print(mass.to_reduced_units())
14.0 gram
>>> print(mass)
14.0 cubic_centimeter * gram / centimeter ** 3
14.0 gram * cubic_centimeter / centimeter ** 3
>>> mass.ito_reduced_units()
>>> print(mass)
14.0 gram
Expand Down
1 change: 1 addition & 0 deletions pint/default_en.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
@defaults
group = international
system = mks
# This default order for sorting dimensions was described in the proposed ISO 80000 specification.
dim_order = [ "[substance]", "[mass]", "[current]", "[luminosity]", "[length]", "[]", "[time]", "[temperature]", ]
@end

Expand Down
33 changes: 14 additions & 19 deletions pint/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import re
import warnings
from typing import Callable, Any, TYPE_CHECKING, TypeVar, List, Optional, Tuple, Union
from collections import OrderedDict
from collections.abc import Iterable
from numbers import Number

Expand Down Expand Up @@ -189,6 +188,7 @@ def wrapper(func):

@register_unit_format("P")
def format_pretty(unit: UnitsContainer, registry: UnitRegistry, **options) -> str:
breakpoint()
return formatter(
unit.items(),
as_ratio=True,
Expand Down Expand Up @@ -223,18 +223,15 @@ def latex_escape(string: str) -> str:
def format_latex(unit: UnitsContainer, registry: UnitRegistry, **options) -> str:
# Lift the sorting by dimensions b/c the preprocessed units are unrecognizeable
sorted_units = dim_sort(unit.items(), registry)
preprocessed_list = [
preprocessed = [
(
rf"\mathrm{{{latex_escape(u)}}}",
p,
)
for u, p in sorted_units
]
preprocessed = OrderedDict()
for k, v in preprocessed_list:
preprocessed[k] = v
formatted = formatter(
preprocessed.items(),
preprocessed,
as_ratio=True,
single_denominator=True,
product_fmt=r" \cdot ",
Expand Down Expand Up @@ -311,7 +308,7 @@ def format_compact(unit: UnitsContainer, registry: UnitRegistry, **options) -> s


def dim_sort(items: Iterable[Tuple[str, Number]], registry: UnitRegistry):
"""Sort a list of units by dimensional order.
"""Sort a list of units by dimensional order (from `registry._defaults['dim_order']`).
Parameters
----------
Expand All @@ -332,17 +329,16 @@ def dim_sort(items: Iterable[Tuple[str, Number]], registry: UnitRegistry):
"""
if registry is None or len(items) <= 1:
return items
# if len(items) == 2 and items[0][1] * items[1][1] < 0:
# return items
ret_dict = dict()
for name, value in items:
cname = registry.get_name(name)
dim_order = registry._defaults["dim_order"]
for unit_name, unit_exponent in items:
cname = registry.get_name(unit_name)
if not cname:
continue
cname_dims = registry.get_dimensionality(cname)
if len(cname_dims) == 0:
cname_dims = {"[]": None}
dim_types = iter(registry._defaults["dim_order"])
dim_types = iter(dim_order)
while True:
try:
dim = next(dim_types)
Expand All @@ -351,20 +347,17 @@ def dim_sort(items: Iterable[Tuple[str, Number]], registry: UnitRegistry):
ret_dict[dim] = list()
ret_dict[dim].append(
(
name,
value,
unit_name,
unit_exponent,
)
)
break
except StopIteration:
raise KeyError(
f"Unit {name} (aka {cname}) has no recognized dimensions"
f"Unit {unit_name} (aka {cname}) has no recognized dimensions"
)

ret = sum(
[ret_dict[dim] for dim in registry._defaults["dim_order"] if dim in ret_dict],
[],
)
ret = sum([ret_dict[dim] for dim in dim_order if dim in ret_dict], [])
return ret


Expand Down Expand Up @@ -417,6 +410,8 @@ def formatter(
True to sort the units dimentionally (Default value = False).
When dimensions have multiple units, sort by "most significant dimension" the unit contains
When both `sort` and `sort_dims` are True, sort alphabetically within sorted dimensions
ISO 80000 and other sources guide on how dimensions shoule be ordered; the user
can set their preference in the registry.
registry : UnitRegistry, optional
The registry to use if `sort_dims` is True
Expand Down

0 comments on commit eae6856

Please sign in to comment.