Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

string formatting guide #1375

Merged
merged 24 commits into from
Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Pint Changelog
- Fix default format for Measurement class (Issue #1300)
- Fix parsing of pretty units with same exponents but different sign. (Issue #1360)
- Convert the application registry to a wrapper object (Issue #1365)
- Add documentation for the string format options (Issue #1357, #1375)

### Breaking Changes

Expand Down
14 changes: 13 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
"sphinx.ext.mathjax",
"matplotlib.sphinxext.plot_directive",
"nbsphinx",
"IPython.sphinxext.ipython_directive",
"IPython.sphinxext.ipython_console_highlighting",
Comment on lines +45 to +46
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like the ipython sphinx extension a lot (I think it's cleaner than the doctest directive). If desired, I can also open a new PR converting our current use of the doctest directive (and code blocks, where appropriate) to that, which might allow us to use pytest to run the doctests in the docstrings.

]

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -109,6 +111,10 @@
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []

# -- Options for extensions ----------------------------------------------------
# napoleon
napoleon_preprocess_types = True


# -- Options for HTML output ---------------------------------------------------

Expand Down Expand Up @@ -321,7 +327,13 @@


# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {"http://docs.python.org/": None}
intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
"numpy": ("https://numpy.org/doc/stable", None),
"matplotlib": ("https://matplotlib.org/stable/", None),
"dask": ("https://docs.dask.org/en/latest", None),
"sparse": ("https://sparse.pydata.org/en/latest/", None),
}

# -- Doctest configuration -----------------------------------------------------

Expand Down
111 changes: 111 additions & 0 deletions docs/formatting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
.. _formatting:
.. currentmodule:: pint


.. ipython:: python
:suppress:

import pint


String formatting
=================
The conversion of :py:class:`Unit` and :py:class:`Quantity` objects to strings (e.g.
through the :py:class:`str` builtin or f-strings) can be customized using :ref:`format
specifications <formatspec>`. The basic format is:

.. code-block:: none

[magnitude format][modifier][unit format]

where each part is optional and the order of these is arbitrary.

In case any part (except the modifier) is omitted, the corresponding value in
:py:attr:`Quantity.default_format` or :py:attr:`Unit.default_format` is filled in. If
that is not set (it evaluates to ``False``), :py:attr:`UnitRegistry.default_format` is
used. If both are not set, the global default of ``"D"`` and the magnitude's default
format are used instead.

.. note::

Modifiers may be used without specifying any format: ``"~"`` is a valid format
specification.


Unit Format Specifications
--------------------------
The :py:class:`Unit` class ignores the magnitude format part, and the unit format
consists of just the format type.

Let's look at some examples:

.. ipython:: python

ureg = pint.UnitRegistry()
u = ureg.kg * ureg.m / ureg.s ** 2

f"{u:P}" # using the pretty format
f"{u:~P}" # short pretty
f"{u:P~}" # also short pretty

# default format
u.default_format
ureg.default_format
str(u) # default: default
f"{u:~}" # default: short default
ureg.default_format = "C" # registry default to compact
str(u) # default: compact
f"{u}" # default: compact
u.default_format = "P"
f"{u}" # default: pretty
u.default_format = "" # TODO: switch to None
ureg.default_format = "" # TODO: switch to None
Comment on lines +61 to +62
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this PR is merged before #1371, I can do that there

f"{u}" # default: default

Unit Format Types
-----------------
``pint`` comes with a variety of unit formats:

======= =============== ======================================================================
Spec Name Example
======= =============== ======================================================================
``D`` default ``kilogram * meter / second ** 2``
``P`` pretty ``kilogram·meter/second²``
``H`` HTML ``kilogram meter/second<sup>2</sup>``
``L`` latex ``\frac{\mathrm{kilogram} \cdot \mathrm{meter}}{\mathrm{second}^{2}}``
``Lx`` latex siunitx ``\si[]{\kilo\gram\meter\per\second\squared}``
``C`` compact ``kilogram*meter/second**2``
======= =============== ======================================================================

Quantity Format Specifications
------------------------------
The magnitude format is forwarded to the magnitude (for a unit-spec of ``H`` the
magnitude's ``_repr_html_`` is called).

Let's look at some more examples:

.. ipython:: python

q = 1e-6 * u

# modifiers
f"{q:~P}" # short pretty
f"{q:~#P}" # compact short pretty
f"{q:P#~}" # also compact short pretty

# additional magnitude format
f"{q:.2f~#P}" # short compact pretty with 2 float digits
f"{q:#~}" # short compact default

Quantity Format Types
---------------------
There are no special quantity formats yet.

Modifiers
---------
======== =================================================== ================================
Modifier Meaning Example
======== =================================================== ================================
``~`` Use the unit's symbol instead of its canonical name ``kg·m/s²`` (``f"{u:~P}"``)
``#`` Call :py:meth:`Quantity.to_compact` first ``1.0 m·mg/s²`` (``f"{q:#~P}"``)
======== =================================================== ================================
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ User Guide
getting
tutorial
defining-quantities
formatting
numpy
nonmult
log_units
Expand Down
2 changes: 2 additions & 0 deletions requirements_docs.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sphinx
ipython
matplotlib
nbsphinx
Expand All @@ -7,6 +8,7 @@ pandas==1.2.4
pint-pandas
jupyter_client
ipykernel
ipython
graphviz
xarray
pooch
Expand Down