pint
pint copied to clipboard
Override units display order (1 kW·h displayed as 1 h·kW)
Let's consider this code
import pint as pt
# sets compact display mode
u = pt.UnitRegistry()
u.default_format = '~P'
# creates quantity
q = u.Quantity("1 kW * 1 h")
# this prints "1 h·kW", not "1 kW·h" as expected
print(q)
During the string conversion I believe the units are sorted alphabetically, in fact hour
comes before kilowatt
.
How can I override this behaviour to have it printed correctly as 1 kW·h
?
For now I am doing str(q).replace("h·kW", "kW·h")
but I am looking for a better solution, that may act globally and before string conversion.
Any suggestions? Thank you!
With latest version you may be able to with a custom format that sorts the units in unit as desired. https://pint.readthedocs.io/en/latest/user/formatting.html?highlight=format#custom-unit-format-types
It may be worth adding custom sorting as an example there.
Thank you! I have some ideas about how to do it. I will try
However, do you think it would be possible to use this to change only the order but not the format?
In other words: How to apply my custom order to all the existing possible formatting options? Compact, latex, etc.
I may find all the format specifiers and (programmatically) create a new updated format (with custom) for each one.
What do you think?
Il giorno mar 12 set 2023 alle 22:17 andrewgsavage @.***> ha scritto:
With latest version you may be able to with a custom format that sorts the units in unit as desired.
https://pint.readthedocs.io/en/latest/user/formatting.html?highlight=format#custom-unit-format-types
It may be worth adding custom sorting as an example there.
— Reply to this email directly, view it on GitHub https://github.com/hgrecco/pint/issues/1841#issuecomment-1716364476, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADDJSQEPDSWUTW2OYBH7TRDX2C7M7ANCNFSM6AAAAAA4DRK7NI . You are receiving this because you authored the thread.Message ID: @.***>
I do think it's pretty common to place time dimensions after all other dimensions (i.e., acceleration as m/s**2
or power as kW * h
), so just doing that one thing might solve most of the problems.
This is a very interesting point, however do you have any idea about how to implement this in pint?
Or maybe the library requires some sort of unit order customization functionality?
What about using a unit preprocessor
argument for the formatter function?
Code from pint/pint/formatting.py
@register_unit_format("L")
def format_latex(unit: UnitsContainer, registry: UnitRegistry, **options) -> str:
preprocessed = {rf"\mathrm{{{latex_escape(u)}}}": p for u, p in unit.items()}
formatted = formatter(
preprocessed.items(),
as_ratio=True,
single_denominator=True,
product_fmt=r" \cdot ",
division_fmt=r"\frac[{}][{}]",
power_fmt="{}^[{}]",
parentheses_fmt=r"\left({}\right)",
**options,
)
return formatted.replace("[", "{").replace("]", "}")
Xref (albeit to a partially closed-source answer): https://www.iso.org/obp/ui/#iso:std:iso:80000:%2D1:ed-1:v1:en
There is a long standing plan to move the formatting to Delegate (like the Parser) which is composed (not inherited). In this way, string formatting would be more decoupled and therefore easy to change..