Skip to content

Consistent str formatting (with units and transformed units) #63

@sadielbartholomew

Description

@sadielbartholomew

When a units object is transformed by some operation, such as at least (as tested) a 'power' operation or as the denominator in a division operation, the formatting of the units can change in form: originally, before if the operation it uses ** to indicate preceding exponents and spaces to delimit the unit components, then after it uses numbers straight after the unit symbol to indicate an exponent value, with dots to delimit the unit components, as illustrated:

>>> u = cfunits.Units("K m**2 kg**-1 s**-1")
>>> print(u)
K m**2 kg**-1 s**-1
>>> print(u**2)
m4.kg-2.s-2.K2
>>> # And the repr() includes the str() for this so similarly changes: <Units: K m**2 kg**-1 s**-1> -> <Units: m4.kg-2.s-2.K2>

Upon a little further investigation, any transform that is valid and produces new units seems to change the repr like above. So there is formatting inconsistency.

It seems the dot-delimited and symbol number form (e.g. m4.kg-2.s-2.K2) is the form that is returned by default, for example using that as the original form retains consistency:

>>> u = cfunits.Units("K.m2.kg-1.s-1")
>>> print(u)
K.m2.kg-1.s-1
>>> print(u**2)
m4.kg-2.s-2.K2

So it seems the issue boils down to (unless I am missing some related point/subtlety) alternative valid formatting, such as the space-delimited double-asterisk form, being an accepted way of inputting units that is rendered as entered when the unit was initialised.

Ideally, we can have consistent formatting for the units always, which would mean, as far as options go as far as I can see, that we either:

  • always represent units with consistent formatting from initiation: so u = cfunits.Units("K m**2 kg**-1 s**-1") would, when printed, instead return K.m2.kg-1.s-1 rather than the K m**2 kg**-1 s**-1 it returns now; or
  • have formatting preserved before and after operations, so whatever formatting style we have for the original, we use for the transformed version, so the same case of cfunits.Units("K m**2 kg**-1 s**-1") would, when squared, have its str() representation converted to conform with the original to m**4 kg**-2 s**-2 K**2.

As noticed from the quick summary Notebook of the CF Tools Training (https://github.com/NCAS-CMS/cf-tools-training/blob/master/new_course/quick_summary/cf_data_tools_summary.ipynb).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions