Welcome to ‘Just SI Units’ documentation!

justunits handles (SI-) units within string occurrences. The module’s justunits tasks are limited to the interchangeability of different unit formatting styles. This module focus just on units, it does not provide unit conversion or anything related to such a topic. It’s purpose is to provide an entry point for a future unit conversion within another module.

A trash panda.

justunits major purpose can be shown with 2 graphs. It’s first purpose is to provide a support for different value/attribute and unit separation styles, which can occur within text files.

Note

The current development state of this project is `alpha`. It’s published for a first stress test of 2 major functions.

Towards the beta

  • naming of modules, classes and methods will change, since the final wording is not done.

  • Code inspections are not finished.

  • The documentation is broad or incomplete.

  • Testing is not complete, as it is added during the first test phase. At this state mostly doctests are applied at class or function level.

digraph separators {
  layout=twopi;
  ranksep=1.5;
  node [shape=plaintext fontsize=11] {
   a [label="'length in mm'"];
   b [label="'length_in_mm'"];
   c [label="'length [mm]'"];
   d [label="'length_[mm]'"];
   e [label="'length#mm'"];
   f [label="'length mm'"];
   g [label="'length_mm'"];
   }

  justunits [shape=circle];

  justunits -> a, b, c, d, e, f, g [dir="both"];

}

Figure 1: Supported separations between an attribute/value and a unit.

The second purpose is to detect SI-units and support 4 major layouts emphasising utf8 with superscripts using a dot as a separator.

graph grid {
  node [shape=plaintext width=1.8 fontsize=11] {
    a [label="kg/(s²⋅K)⋅m²"];
    b [label="kg⋅s⁻²⋅K⁻¹⋅m²"];
    c [label="kg/(s^2*K)*m^2"];
    d [label="kg*s^-2*K^-1*m^2"];
  }

  node [shape=boxed width=1.5] {
     slashed; power [label="by power"];
  }

  node [shape=boxed width=1] {
     utf8; ascii
  }

    a -- d
    c -- b

    slashed -- a -- c
    power -- b -- d

    rank=same {slashed power}
    rank=same {utf8 -- a -- b}
    rank=same {ascii -- c -- d}
}

Figure 2: Unit representations supported by justunits.


Installation

Install the latest release from pip.

$ pip install justunits

Basic Usage

Styling

You might want to set your desired attribute unit and unit style flavor first or just keep the preset defaults. See all supported unit styles.

>>> import justunits
>>> from justunits import AttributeUnitSeparators, UnitStyle
>>> justunits.set_default_attribute_unit_separator(AttributeUnitSeparators.WHITESPACE_BOXED)
>>> justunits.set_default_unit_style(UnitStyle.FINE_SLASHED_SUPERSCRIPT)

Reformatting

Attribute/value-unit pairs come in many different, justifiable forms. Either they are demanded by preexisting file format definitions or depend on the context of information transfer. Transferring different formats depicted in figure 1.

>>> import justunits
>>> from justunits import AttributeUnitSeparators, UnitStyle, UnitDividingStyle
>>> justunits.reformat_unit("pressure#kg*m^-1*s^-2")
'pressure [kg/(m⋅s²)]'

Change just the separator in between attribute and unit.

>>> justunits.reformat_unit(
...     "pressure#kg*m^-1*s^-2",
...     target_format=AttributeUnitSeparators.WHITESPACE_IN
... )
'pressure in kg/(m⋅s²)'

Or make custom combinations. Missing definitions will be replaced by defaults.

>>> boxed_fine_powered = (
...     AttributeUnitSeparators.WHITESPACE_BOXED | UnitDividingStyle.BY_POWER
... )
>>> justunits.reformat_unit(
...     "pressure#kg*m^-1*s^-2",
...     target_format=boxed_fine_powered
... )
'pressure [kg⋅m⁻¹⋅s⁻²]'

Splitting

You may come across one of these exemplary formats and want to split attributes/values from units from further processing.

Header of a csv file:

time[s],energy[J],torque[Nm]
0.0,0.0,0.0
...

Attributes with units in text files:

...
height_mm = 1.0
width_mm = 2.0
...

Or values with units in text files:

...
height = 1.0 mm
width = 2.0 mm
...
split_unit_text

Splitting attributes/values from units preserving text. The function justunits.split_unit_text() provides a splitting whenever a unit detection is not desired.

>>> justunits.split_unit_text("heat capacity[kg/(s^−2*K^-1)*m^2]")
('heat capacity', 'kg/(s^−2*K^-1)*m^2')

>>> justunits.split_unit_text("1.23 apples")
('1.23', 'apples')
split_unit

justunits.split_unit() provides the main feature of detecting units in the process of splitting.

>>> attribute_name, any_units = justunits.split_unit("pressure#kg*m^-1*s^-2")
>>> attribute_name
'pressure'

The unit text is converted into an iterable DerivedUnit-Object containing all detected
(and unknown units).

>>> any_units
(AUnit(kg 'kilogram' mass, 1e+03g), AUnit(m 'meter' length; power=-1), AUnit(s 'second' time; power=-2))

>>> [str(unit) for unit in any_units]
['kg', 'm^-1.0', 's^-2.0']
split_unit converting attribute/value

It is also possible to convert the split values by converting them with a Callable[[str], Any]`.

>>> justunits.split_unit("1.23 apples", converter=float)
(1.23, (UnknownUnit('apples'),))

Be aware that using a conversion function any exception will not be caught.

>>> justunits.split_unit("1.23 apples", converter=int)
Traceback (most recent call last):
...
ValueError: invalid literal for int() with base 10: '1.23'

This is intentional as the purpose of the converters result depends on your choice. Either catch a related exception or take different solutions.

>>> justunits.split_unit("1.23 apples", converter=lambda x: int(float(x)))
(1, (UnknownUnit('apples'),))

Joining

justunits.join() The counterpart of splitting attributes/values-unit pairs joins

>>> pressure = justunits.from_string("kg/(m*s^2)")
>>> justunits.join_unit("pressure", pressure)
'pressure [kg/(m⋅s²)]'

>>> from justunits import AttributeUnitSeparators
>>> justunits.join_unit(
...     "pressure", pressure, target_format=AttributeUnitSeparators.WHITESPACE_IN
... )
'pressure in kg/(m⋅s²)'

Unit styles of justunits

The formatting of units is sectioned into the separation of attribute/value-unit pairs and the styling of the units themself.

Defaults

justunits formats by these default definitions.

justunits.DEFAULT_ATTRIBUTE_UNIT_SEPARATOR = AttributeUnitSeparators.WHITESPACE_IN

The style separating attributes/values from units.

justunits.DEFAULT_ALLOWED_SEPARATORS = AttributeUnitSeparators.None

By default only 5 of 7 supported attribute unit separator are taken into account as the absolute certain separation of an single underline or whitespace separated unit is ambiguous, without limiting the results to the content of the unit library. Such a behaviour may be implemented in future releases, if it turns out to be necessary.

justunits.DEFAULT_POWER_STYLE = UnitPowerStyle.SUPERSCRIPT

The default style how powers are represented.

justunits.DEFAULT_DIVIDING_STYLE = UnitDividingStyle.SLASHED

The default style how unit fractions are represented.

justunits.DEFAULT_SEPARATION_STYLE = UnitSeparationStyle.DOT

The default style by which character units are separated.

justunits.DEFAULT_UNIT_STYLE = UnitPowerStyle.None

The default unit style composed of power-, dividing- and separation-style.

Seperation of attribute/value and unit

AttributeUnitSeparators.WHITESPACE_BOXED = 1

Leads to ‘attribute [unit]’

AttributeUnitSeparators.UNDERLINE_BOXED = 2

Leads to ‘attribute_[unit]’

AttributeUnitSeparators.WHITESPACE_IN = 4

Leads to ‘attribute in unit’

AttributeUnitSeparators.UNDERLINED_IN = 8

Leads to ‘attribute_in_unit’

AttributeUnitSeparators.HASH_SIGN = 16

Leads to ‘attribute#unit’

AttributeUnitSeparators.SINGLE_UNDERLINE = 32

Leads to ‘attribute_unit’

AttributeUnitSeparators.SINGLE_WHITESPACE = 64

Leads to ‘attribute unit’

Styling of just units

Unit power style
UnitPowerStyle.SUPERSCRIPT = 256

Leads to superscripting powers like a⁻¹

UnitPowerStyle.CARET = 512

Powers are represented in ascii compatible like a^-1

Style of divisions
UnitDividingStyle.SLASHED = 1024

Units are divided by a forward slash like a/b.

UnitDividingStyle.BY_POWER = 2048

Divisions of units is represented using powers like a/b being a⋅b⁻¹.

Seperation in between units
UnitSeparationStyle.DOT = 4096

Units are separated using a dot operator like a⋅b

UnitSeparationStyle.ASTERISK = 8192

Units are separated by an asterisk like a*b being ascii compatible.

Complete unit styles
UnitStyle.SIMPLE_ASCII = 9728

Results into ‘kg/(s^2*K)*m^2’

UnitStyle.TOTAL_POWER_ASCII = 10752

Results into ‘kg*s^-2*K^-1*m^2’

UnitStyle.FINE_SLASHED_SUPERSCRIPT = 5376

Results into ‘kg/(s²⋅K)⋅m²’

UnitStyle.FINE_POWERED_SUPERSCRIPT = 6400

Results into ‘kg⋅s⁻²⋅K⁻¹⋅m²’

API reference

justunits

justunits.DerivedUnit(*sub_units)

param *sub_units

justunits.AttributeUnitSeparators(value)

An enumeration.

justunits.BaseSiUnits()

justunits.BareUnit(symbol, name, quantity)

param symbol

justunits.create_unit(symbol, name, quantity)

Creates a basic unit of your liking.

justunits.from_string(unit_text)

param unit_text

justunits.join_unit(attribute, unit[, …])

Joins attribute and unit using one of six separators.

justunits.Prefix(symbol, name, decimal)

Create new instance of Prefix(symbol, name, decimal)

justunits.prefix_base_unit(base_unit, …)

param base_unit

justunits.reformat_unit(text[, …])

Reformats a attribute/value-unit pair to a targeted format.

justunits.register_unit(unit)

justunits.reset_unit_library()

Resets the unit library to the default definition.

justunits.set_default_attribute_unit_separator(…)

Sets the default separator in between attribute/value and unit.

justunits.set_default_unit_style(unit_style)

Sets the default unit style.

justunits.SiPrefixes()

justunits.SiUnits()

justunits.split_unit(text[, …])

Splits an attribute/value with a trailing unit.

justunits.split_unit_text(text[, …])

Splits an attribute/value with a trailing unit text.

justunits.to_string(unit[, unit_style])

Creates a string represenation of units.

justunits.UnitDividingStyle(value)

An enumeration.

justunits.UnitPowerStyle(value)

An enumeration.

justunits.UnitSeparationStyle(value)

An enumeration.

justunits.UnitStyle(value)

An enumeration.

justunits.UnknownUnit(unit_text, …)

The unknown unit appears for cases in which text could not be resolved to units known by the current runtime library.

justunits.AUnit

justunits.AUnit(raw_unit, prefix, power, …)

A unit represents just a single unit like meter ‘m’ and second ‘s’.

justunits.AUnit.switch_power()

The unit’s power is multiplied by -1.

justunits.AUnit.power

The units power.

justunits.AUnit.width

Width (length) of the unit’s symbol (including any prefix).

justunits.AUnit.first_letter

The symbols first letter.

justunits.AUnit.symbol

The unit’s symbol including any prefix.

justunits.AUnit.name

The units name.

justunits.AUnit.quantity

The quantity the unit stands for.

justunits.AUnit.base_symbol

The unit’s symbol without any prefix.

justunits.AUnit.prefix_symbol

The symbol of the unit’s prefix, if carrying one.

justunits.AUnit.with_power(power)

Returns a unit based on this unit’s base unit with the requested power.

justunits.AUnit.with_prefix(prefix)

Returns a unit based on this unit’s base unit with the requested prefix.

justunits.AUnit.without_prefix()

The base unit with the current power.

justunits.AUnit.bare()

A unit based on this unit’s base unit solely.

justunits.AUnit.to_raw_parts()

Returns:

justunits.AUnit.UNIT_TYPE

Indices and tables