4

Say I have an arbitrary Pint quantity q. Is there a way to display its units in symbol short form, instead of as a full-length word?

In other words, how would I code unit_symbol() such that it returns "m", not "meter"; "kg" not "kilogram"; etc.? Is there a way to retrieve the short-form unit symbol that is synonym with the quantity's current unit?

import pint 
ureg = pint.UnitRegistry()
Q_ = ureg.Quantity

def unit_symbol(q: pint.Quantity) -> str:
    # Intended to return "m", not "meter"
    # "kg" not "kilogram"
    # etc.
    # ???
    return q.units  # returns long-form unit, "meter", "kilogram" etc. :-(
    
q = Q_(42, ureg.m)
print(unit_symbol(q))  # "meter"... whereas I would like "m"

The above obviously fails to achieve this; it returns the long-form unit.

Jean-François Corbett
  • 37,420
  • 30
  • 139
  • 188

3 Answers3

5

You can use '~' as a spec for the unit formatting:

q = Q_(42, "m") / Q_(1, "second")

print(format(q, '~'))  # 42.0 m / s
print(format(q.u, '~'))  # m / s

This feature is apparently undocumented, but can be inferred from the source code for Unit.__format__ (search for "~" on that page to quickly navigate to the relevant piece of code).

fuglede
  • 17,388
  • 2
  • 54
  • 99
  • It's documented [here](https://pint.readthedocs.io/en/stable/formatting.html#modifiers). – chepner Jan 07 '22 at 18:23
  • Yep, looks like it was [added recently](https://github.com/hgrecco/pint/commit/6175d5f38b0381ccbf3ede2d0de9df0a432baaf3#diff-b0f48e0028fe333d96f1dd9b4390e13e32482a4531593f28ec176801a5d6e436) – fuglede Jan 09 '22 at 07:32
2

Use ureg.default_format = '~' if you want the short notation by default. These are also valid options for short units: ~L (LaTeX), ~H (HTML) and ~P (Pretty print).

B. Willems
  • 80
  • 1
  • 7
1

I found UnitRegistry.get_symbol(),

ureg.get_symbol(str(q.units))  # "m"

but it seems a bit clunky: converting unit to string, then parsing that string again...

Also this fails for composite units e.g.

q = Q_(42, "m") / Q_(1, "second")
ureg.get_symbol(str(q.units))  
# UndefinedUnitError: 'meter / second' is not defined in the unit registry
Jean-François Corbett
  • 37,420
  • 30
  • 139
  • 188