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
|
"""
pint.formatter
~~~~~~~~~~~~~~
Format units for pint.
:copyright: 2016 by Pint Authors, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from __future__ import annotations
from collections.abc import Iterable
from numbers import Number
from .delegates.formatter._format_helpers import (
_PRETTY_EXPONENTS, # noqa: F401
)
from .delegates.formatter._format_helpers import (
formatter as fh_formatter, # noqa: F401
)
from .delegates.formatter._format_helpers import (
pretty_fmt_exponent as _pretty_fmt_exponent, # noqa: F401
)
from .delegates.formatter._spec_helpers import (
_BASIC_TYPES, # noqa: F401
FORMATTER, # noqa: F401
REGISTERED_FORMATTERS,
extract_custom_flags, # noqa: F401
remove_custom_flags, # noqa: F401
)
from .delegates.formatter._spec_helpers import (
parse_spec as _parse_spec, # noqa: F401
)
from .delegates.formatter._spec_helpers import (
split_format as split_format, # noqa: F401
)
# noqa
from .delegates.formatter._to_register import register_unit_format # noqa: F401
# Backwards compatiblity stuff
from .delegates.formatter.latex import (
_EXP_PATTERN, # noqa: F401
latex_escape, # noqa: F401
matrix_to_latex, # noqa: F401
ndarray_to_latex, # noqa: F401
ndarray_to_latex_parts, # noqa: F401
siunitx_format_unit, # noqa: F401
vector_to_latex, # noqa: F401
)
def formatter(
items: Iterable[tuple[str, Number]],
as_ratio: bool = True,
single_denominator: bool = False,
product_fmt: str = " * ",
division_fmt: str = " / ",
power_fmt: str = "{} ** {}",
parentheses_fmt: str = "({0})",
exp_call: FORMATTER = "{:n}".format,
sort: bool = True,
) -> str:
"""Format a list of (name, exponent) pairs.
Parameters
----------
items : list
a list of (name, exponent) pairs.
as_ratio : bool, optional
True to display as ratio, False as negative powers. (Default value = True)
single_denominator : bool, optional
all with terms with negative exponents are
collected together. (Default value = False)
product_fmt : str
the format used for multiplication. (Default value = " * ")
division_fmt : str
the format used for division. (Default value = " / ")
power_fmt : str
the format used for exponentiation. (Default value = "{} ** {}")
parentheses_fmt : str
the format used for parenthesis. (Default value = "({0})")
exp_call : callable
(Default value = lambda x: f"{x:n}")
sort : bool, optional
True to sort the formatted units alphabetically (Default value = True)
Returns
-------
str
the formula as a string.
"""
if sort is False:
items = tuple(items)
else:
items = sorted(items)
if not items:
return ""
numerator = [(key, value) for key, value in items if value >= 0]
denominator = [(key, value) for key, value in items if value < 0]
return fh_formatter(
numerator=numerator,
denominator=denominator,
as_ratio=as_ratio,
single_denominator=single_denominator,
product_fmt=product_fmt,
division_fmt=division_fmt,
power_fmt=power_fmt,
parentheses_fmt=parentheses_fmt,
exp_call=exp_call,
)
def format_unit(unit, spec: str, registry=None, **options):
# registry may be None to allow formatting `UnitsContainer` objects
# in that case, the spec may not be "Lx"
if not unit:
if spec.endswith("%"):
return ""
else:
return "dimensionless"
if not spec:
spec = "D"
if registry is None:
_formatter = REGISTERED_FORMATTERS.get(spec, None)
else:
try:
_formatter = registry.formatter._formatters[spec]
except Exception:
_formatter = registry.formatter._formatters.get(spec, None)
if _formatter is None:
raise ValueError(f"Unknown conversion specified: {spec}")
return _formatter.format_unit(unit)
|