From 51d06142f920ce88e45918784e7180a440711d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jules=20Ch=C3=A9ron?= Date: Sun, 20 Feb 2022 21:10:41 +0100 Subject: [PATCH] Update documentation - Rework of configuration with new sphinx_book_theme - Use ipython directive where necessary - Add theme to requirements_docs.txt - Start using autosummarry - Fix doctests - Add sphinx design to requirements - Add overview & panels in home page - Update footer with `Pint Developers` - Fix docstrings - Use string imports in __all__ in __init__.py --- docs/_static/index_api.svg | 26 ++ docs/_static/index_contribute.svg | 21 ++ docs/_static/index_getting_started.svg | 18 + docs/_static/index_user_guide.svg | 18 + docs/_static/style.css | 45 +++ docs/_themes/.gitignore | 3 - docs/_themes/LICENSE | 37 -- docs/_themes/README | 31 -- docs/_themes/flask/layout.html | 30 -- docs/_themes/flask/relations.html | 20 -- docs/_themes/flask/static/flasky.css_t | 395 --------------------- docs/_themes/flask/static/small_flask.css | 70 ---- docs/_themes/flask/theme.conf | 10 - docs/_themes/flask_theme_support.py | 89 ----- docs/advanced_guides.rst | 14 + docs/{developers_reference.rst => api.rst} | 8 +- docs/conf.py | 239 ++++--------- docs/{ => dev}/contributing.rst | 4 +- docs/{ => dev}/pint-convert.rst | 44 ++- docs/getting.rst | 58 --- docs/getting_started.rst | 50 +++ docs/index.rst | 198 +++-------- docs/{ => user}/angular_frequency.rst | 2 +- docs/{ => user}/contexts.rst | 0 docs/{ => user}/currencies.rst | 0 docs/{ => user}/defining-quantities.rst | 0 docs/{ => user}/defining.rst | 0 docs/user/ecosystem.rst | 11 + docs/{ => user}/faq.rst | 0 docs/{ => user}/formatting.rst | 0 docs/user/index.rst | 20 ++ docs/{ => user}/log_units.rst | 0 docs/{ => user}/measurement.rst | 0 docs/{ => user}/nonmult.rst | 0 docs/{ => user}/numpy.ipynb | 0 docs/user/overview.rst | 116 ++++++ docs/{ => user}/performance.rst | 60 ++-- docs/{ => user}/pitheorem.rst | 0 docs/{ => user}/plotting.rst | 0 docs/{ => user}/serialization.rst | 0 docs/{ => user}/systems.rst | 4 +- docs/{ => user}/tutorial.rst | 0 docs/{ => user}/wrapping.rst | 4 +- pint/facets/context/__init__.py | 2 +- pint/facets/context/registry.py | 76 ++-- pint/facets/formatting/__init__.py | 2 +- pint/facets/group/__init__.py | 2 +- pint/facets/measurement/__init__.py | 2 +- pint/facets/nonmultiplicative/__init__.py | 2 +- pint/facets/numpy/__init__.py | 2 +- pint/facets/plain/__init__.py | 22 +- pint/facets/plain/quantity.py | 4 +- pint/facets/system/__init__.py | 2 +- requirements_docs.txt | 3 + 54 files changed, 593 insertions(+), 1171 deletions(-) create mode 100644 docs/_static/index_api.svg create mode 100644 docs/_static/index_contribute.svg create mode 100644 docs/_static/index_getting_started.svg create mode 100644 docs/_static/index_user_guide.svg create mode 100644 docs/_static/style.css delete mode 100644 docs/_themes/.gitignore delete mode 100644 docs/_themes/LICENSE delete mode 100644 docs/_themes/README delete mode 100644 docs/_themes/flask/layout.html delete mode 100644 docs/_themes/flask/relations.html delete mode 100644 docs/_themes/flask/static/flasky.css_t delete mode 100644 docs/_themes/flask/static/small_flask.css delete mode 100644 docs/_themes/flask/theme.conf delete mode 100644 docs/_themes/flask_theme_support.py create mode 100644 docs/advanced_guides.rst rename docs/{developers_reference.rst => api.rst} (93%) rename docs/{ => dev}/contributing.rst (97%) rename docs/{ => dev}/pint-convert.rst (75%) delete mode 100644 docs/getting.rst create mode 100644 docs/getting_started.rst rename docs/{ => user}/angular_frequency.rst (96%) rename docs/{ => user}/contexts.rst (100%) rename docs/{ => user}/currencies.rst (100%) rename docs/{ => user}/defining-quantities.rst (100%) rename docs/{ => user}/defining.rst (100%) create mode 100644 docs/user/ecosystem.rst rename docs/{ => user}/faq.rst (100%) rename docs/{ => user}/formatting.rst (100%) create mode 100644 docs/user/index.rst rename docs/{ => user}/log_units.rst (100%) rename docs/{ => user}/measurement.rst (100%) rename docs/{ => user}/nonmult.rst (100%) rename docs/{ => user}/numpy.ipynb (100%) create mode 100644 docs/user/overview.rst rename docs/{ => user}/performance.rst (77%) rename docs/{ => user}/pitheorem.rst (100%) rename docs/{ => user}/plotting.rst (100%) rename docs/{ => user}/serialization.rst (100%) rename docs/{ => user}/systems.rst (95%) rename docs/{ => user}/tutorial.rst (100%) rename docs/{ => user}/wrapping.rst (99%) diff --git a/docs/_static/index_api.svg b/docs/_static/index_api.svg new file mode 100644 index 000000000..ceb5be6af --- /dev/null +++ b/docs/_static/index_api.svg @@ -0,0 +1,26 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/docs/_static/index_contribute.svg b/docs/_static/index_contribute.svg new file mode 100644 index 000000000..24a29f328 --- /dev/null +++ b/docs/_static/index_contribute.svg @@ -0,0 +1,21 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/docs/_static/index_getting_started.svg b/docs/_static/index_getting_started.svg new file mode 100644 index 000000000..2afbbe1de --- /dev/null +++ b/docs/_static/index_getting_started.svg @@ -0,0 +1,18 @@ + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/docs/_static/index_user_guide.svg b/docs/_static/index_user_guide.svg new file mode 100644 index 000000000..d70b3d73d --- /dev/null +++ b/docs/_static/index_user_guide.svg @@ -0,0 +1,18 @@ + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/docs/_static/style.css b/docs/_static/style.css new file mode 100644 index 000000000..b2bc297d6 --- /dev/null +++ b/docs/_static/style.css @@ -0,0 +1,45 @@ +@import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap'); + +body { + font-family: 'Open Sans', sans-serif; +} + +h1 { + font-family: "Lato", sans-serif; +} + +pre, code { + font-size: 100%; + line-height: 155%; +} + +/* Main page overview cards */ + +.sd-card { + border-radius: 0; + padding: 30px 10px 20px 10px; + margin: 10px 0px; +} + +.sd-card .sd-card-header { + text-align: center; +} + +.sd-card .sd-card-header .sd-card-text { + margin: 0px; +} + +.sd-card .sd-card-img-top { + height: 52px; + width: 52px; + margin-left: auto; + margin-right: auto; +} + +.sd-card .sd-card-header { + border: none; + color: #150458 !important; + font-size: var(--pst-font-size-h5); + font-weight: bold; + padding: 2.5rem 0rem 0.5rem 0rem; +} diff --git a/docs/_themes/.gitignore b/docs/_themes/.gitignore deleted file mode 100644 index 66b6e4c2f..000000000 --- a/docs/_themes/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.pyc -*.pyo -.DS_Store diff --git a/docs/_themes/LICENSE b/docs/_themes/LICENSE deleted file mode 100644 index 8daab7ee6..000000000 --- a/docs/_themes/LICENSE +++ /dev/null @@ -1,37 +0,0 @@ -Copyright (c) 2010 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms of the theme, with or -without modification, are permitted provided that the following conditions -are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - -* The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -We kindly ask you to only use these themes in an unmodified manner just -for Flask and Flask-related products, not for unrelated projects. If you -like the visual style and want to use it for your own projects, please -consider making some larger changes to the themes (such as changing -font faces, sizes, colors or margins). - -THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/docs/_themes/README b/docs/_themes/README deleted file mode 100644 index b3292bdff..000000000 --- a/docs/_themes/README +++ /dev/null @@ -1,31 +0,0 @@ -Flask Sphinx Styles -=================== - -This repository contains sphinx styles for Flask and Flask related -projects. To use this style in your Sphinx documentation, follow -this guide: - -1. put this folder as _themes into your docs folder. Alternatively - you can also use git submodules to check out the contents there. -2. add this to your conf.py: - - sys.path.append(os.path.abspath('_themes')) - html_theme_path = ['_themes'] - html_theme = 'flask' - -The following themes exist: - -- 'flask' - the standard flask documentation theme for large - projects -- 'flask_small' - small one-page theme. Intended to be used by - very small addon libraries for flask. - -The following options exist for the flask_small theme: - - [options] - index_logo = '' filename of a picture in _static - to be used as replacement for the - h1 in the index.rst file. - index_logo_height = 120px height of the index logo - github_fork = '' repository name on github for the - "fork me" badge diff --git a/docs/_themes/flask/layout.html b/docs/_themes/flask/layout.html deleted file mode 100644 index 4c79a9ad2..000000000 --- a/docs/_themes/flask/layout.html +++ /dev/null @@ -1,30 +0,0 @@ -{%- extends "basic/layout.html" %} -{%- block extrahead %} - {{ super() }} - {% if theme_touch_icon %} - - {% endif %} - -{% endblock %} -{%- block relbar2 %} - {% if theme_github_fork %} - Fork me on GitHub - {% endif %} -{% endblock %} -{% block header %} - {{ super() }} - {% if pagename == 'index' %} -
- {% endif %} -{% endblock %} -{%- block footer %} - - {% if pagename == 'index' %} -
- {% endif %} -{%- endblock %} diff --git a/docs/_themes/flask/relations.html b/docs/_themes/flask/relations.html deleted file mode 100644 index ed433fad2..000000000 --- a/docs/_themes/flask/relations.html +++ /dev/null @@ -1,20 +0,0 @@ - -

Related Topics

- -{%- endfor %} -{%- if prev %} -

- Previous
- {{ prev.title }} -

-{%- endif %} -{%- if next %} -

- Next
- {{ next.title }} -

-{%- endif %} diff --git a/docs/_themes/flask/static/flasky.css_t b/docs/_themes/flask/static/flasky.css_t deleted file mode 100644 index 4f7830864..000000000 --- a/docs/_themes/flask/static/flasky.css_t +++ /dev/null @@ -1,395 +0,0 @@ -/* - * flasky.css_t - * ~~~~~~~~~~~~ - * - * :copyright: Copyright 2010 by Armin Ronacher. - * :license: Flask Design License, see LICENSE for details. - */ - -{% set page_width = '940px' %} -{% set sidebar_width = '220px' %} - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: 'Georgia', serif; - font-size: 17px; - background-color: white; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - width: {{ page_width }}; - margin: 30px auto 0 auto; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 {{ sidebar_width }}; -} - -div.sphinxsidebar { - width: {{ sidebar_width }}; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #ffffff; - color: #3E4349; - padding: 0 30px 0 30px; -} - -img.floatingflask { - padding: 0 0 10px 10px; - float: right; -} - -div.footer { - width: {{ page_width }}; - margin: 20px auto 30px auto; - font-size: 14px; - color: #888; - text-align: right; -} - -div.footer a { - color: #888; -} - -div.related { - display: none; -} - -div.sphinxsidebar a { - color: #444; - text-decoration: none; - border-bottom: 1px dotted #999; -} - -div.sphinxsidebar a:hover { - border-bottom: 1px solid #999; -} - -div.sphinxsidebar { - font-size: 14px; - line-height: 1.5; -} - -div.sphinxsidebarwrapper { - padding: 18px 10px; -} - -div.sphinxsidebarwrapper p.logo { - padding: 0 0 20px 0; - margin: 0; - text-align: center; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: 'Garamond', 'Georgia', serif; - color: #444; - font-size: 24px; - font-weight: normal; - margin: 0 0 5px 0; - padding: 0; -} - -div.sphinxsidebar h4 { - font-size: 20px; -} - -div.sphinxsidebar h3 a { - color: #444; -} - -div.sphinxsidebar p.logo a, -div.sphinxsidebar h3 a, -div.sphinxsidebar p.logo a:hover, -div.sphinxsidebar h3 a:hover { - border: none; -} - -div.sphinxsidebar p { - color: #555; - margin: 10px 0; -} - -div.sphinxsidebar ul { - margin: 10px 0; - padding: 0; - color: #000; -} - -div.sphinxsidebar input { - border: 1px solid #ccc; - font-family: 'Georgia', serif; - font-size: 1em; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #004B6B; - text-decoration: underline; -} - -a:hover { - color: #6D4100; - text-decoration: underline; -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Garamond', 'Georgia', serif; - font-weight: normal; - margin: 30px 0px 10px 0px; - padding: 0; -} - -{% if theme_index_logo %} -div.indexwrapper h1 { - text-indent: -999999px; - background: url({{ theme_index_logo }}) no-repeat center center; - height: {{ theme_index_logo_height }}; -} -{% endif %} - -div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } -div.body h2 { font-size: 180%; } -div.body h3 { font-size: 150%; } -div.body h4 { font-size: 130%; } -div.body h5 { font-size: 100%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #ddd; - padding: 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - color: #444; - background: #eaeaea; -} - -div.body p, div.body dd, div.body li { - line-height: 1.4em; -} - -div.admonition { - background: #fafafa; - margin: 20px -30px; - padding: 10px 30px; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; -} - -div.admonition tt.xref, div.admonition a tt { - border-bottom: 1px solid #fafafa; -} - -dd div.admonition { - margin-left: -60px; - padding-left: 60px; -} - -div.admonition p.admonition-title { - font-family: 'Garamond', 'Georgia', serif; - font-weight: normal; - font-size: 24px; - margin: 0 0 10px 0; - padding: 0; - line-height: 1; -} - -div.admonition p.last { - margin-bottom: 0; -} - -div.highlight { - background-color: white; -} - -dt:target, .highlight { - background: #FAF3E8; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre, tt { - font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; - font-size: 0.9em; -} - -img.screenshot { -} - -tt.descname, tt.descclassname { - font-size: 0.95em; -} - -tt.descname { - padding-right: 0.08em; -} - -img.screenshot { - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils { - border: 1px solid #888; - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils td, table.docutils th { - border: 1px solid #888; - padding: 0.25em 0.7em; -} - -table.field-list, table.footnote { - border: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -table.footnote { - margin: 15px 0; - width: 100%; - border: 1px solid #eee; - background: #fdfdfd; - font-size: 0.9em; -} - -table.footnote + table.footnote { - margin-top: -15px; - border-top: none; -} - -table.field-list th { - padding: 0 0.8em 0 0; -} - -table.field-list td { - padding: 0; -} - -table.footnote td.label { - width: 0px; - padding: 0.3em 0 0.3em 0.5em; -} - -table.footnote td { - padding: 0.3em 0.5em; -} - -dl { - margin: 0; - padding: 0; -} - -dl dd { - margin-left: 30px; -} - -blockquote { - margin: 0 0 0 30px; - padding: 0; -} - -ul, ol { - margin: 10px 0 10px 30px; - padding: 0; -} - -pre { - background: #eee; - padding: 7px 30px; - margin: 15px -30px; - line-height: 1.3em; -} - -dl pre, blockquote pre, li pre { - margin-left: -60px; - padding-left: 60px; -} - -dl dl pre { - margin-left: -90px; - padding-left: 90px; -} - -tt { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ -} - -tt.xref, a tt { - background-color: #FBFBFB; - border-bottom: 1px solid white; -} - -a.reference { - text-decoration: none; - border-bottom: 1px dotted #004B6B; -} - -a.reference:hover { - border-bottom: 1px solid #6D4100; -} - -a.footnote-reference { - text-decoration: none; - font-size: 0.7em; - vertical-align: top; - border-bottom: 1px dotted #004B6B; -} - -a.footnote-reference:hover { - border-bottom: 1px solid #6D4100; -} - -a:hover tt { - background: #EEE; -} diff --git a/docs/_themes/flask/static/small_flask.css b/docs/_themes/flask/static/small_flask.css deleted file mode 100644 index 1c6df309e..000000000 --- a/docs/_themes/flask/static/small_flask.css +++ /dev/null @@ -1,70 +0,0 @@ -/* - * small_flask.css_t - * ~~~~~~~~~~~~~~~~~ - * - * :copyright: Copyright 2010 by Armin Ronacher. - * :license: Flask Design License, see LICENSE for details. - */ - -body { - margin: 0; - padding: 20px 30px; -} - -div.documentwrapper { - float: none; - background: white; -} - -div.sphinxsidebar { - display: block; - float: none; - width: 102.5%; - margin: 50px -30px -20px -30px; - padding: 10px 20px; - background: #333; - color: white; -} - -div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, -div.sphinxsidebar h3 a { - color: white; -} - -div.sphinxsidebar a { - color: #aaa; -} - -div.sphinxsidebar p.logo { - display: none; -} - -div.document { - width: 100%; - margin: 0; -} - -div.related { - display: block; - margin: 0; - padding: 10px 0 20px 0; -} - -div.related ul, -div.related ul li { - margin: 0; - padding: 0; -} - -div.footer { - display: none; -} - -div.bodywrapper { - margin: 0; -} - -div.body { - min-height: 0; - padding: 0; -} diff --git a/docs/_themes/flask/theme.conf b/docs/_themes/flask/theme.conf deleted file mode 100644 index 0b3d313e9..000000000 --- a/docs/_themes/flask/theme.conf +++ /dev/null @@ -1,10 +0,0 @@ -[theme] -inherit = basic -stylesheet = flasky.css -pygments_style = flask_theme_support.FlaskyStyle - -[options] -index_logo = '' -index_logo_height = 120px -touch_icon = -github_fork = hgrecco/pint diff --git a/docs/_themes/flask_theme_support.py b/docs/_themes/flask_theme_support.py deleted file mode 100644 index 64e249963..000000000 --- a/docs/_themes/flask_theme_support.py +++ /dev/null @@ -1,89 +0,0 @@ -# flasky extensions. flasky pygments style based on tango style -from pygments.style import Style -from pygments.token import ( - Comment, - Error, - Generic, - Keyword, - Literal, - Name, - Number, - Operator, - Other, - Punctuation, - String, - Whitespace, -) - - -class FlaskyStyle(Style): - background_color = "#f8f8f8" - default_style = "" - - styles = { - # No corresponding class for the following: - # Text: "", # class: '' - Whitespace: "underline #f8f8f8", # class: 'w' - Error: "#a40000 border:#ef2929", # class: 'err' - Other: "#000000", # class 'x' - Comment: "italic #8f5902", # class: 'c' - Comment.Preproc: "noitalic", # class: 'cp' - Keyword: "bold #004461", # class: 'k' - Keyword.Constant: "bold #004461", # class: 'kc' - Keyword.Declaration: "bold #004461", # class: 'kd' - Keyword.Namespace: "bold #004461", # class: 'kn' - Keyword.Pseudo: "bold #004461", # class: 'kp' - Keyword.Reserved: "bold #004461", # class: 'kr' - Keyword.Type: "bold #004461", # class: 'kt' - Operator: "#582800", # class: 'o' - Operator.Word: "bold #004461", # class: 'ow' - like keywords - Punctuation: "bold #000000", # class: 'p' - # because special names such as Name.Class, Name.Function, etc. - # are not recognized as such later in the parsing, we choose them - # to look the same as ordinary variables. - Name: "#000000", # class: 'n' - Name.Attribute: "#c4a000", # class: 'na' - to be revised - Name.Builtin: "#004461", # class: 'nb' - Name.Builtin.Pseudo: "#3465a4", # class: 'bp' - Name.Class: "#000000", # class: 'nc' - to be revised - Name.Constant: "#000000", # class: 'no' - to be revised - Name.Decorator: "#888", # class: 'nd' - to be revised - Name.Entity: "#ce5c00", # class: 'ni' - Name.Exception: "bold #cc0000", # class: 'ne' - Name.Function: "#000000", # class: 'nf' - Name.Property: "#000000", # class: 'py' - Name.Label: "#f57900", # class: 'nl' - Name.Namespace: "#000000", # class: 'nn' - to be revised - Name.Other: "#000000", # class: 'nx' - Name.Tag: "bold #004461", # class: 'nt' - like a keyword - Name.Variable: "#000000", # class: 'nv' - to be revised - Name.Variable.Class: "#000000", # class: 'vc' - to be revised - Name.Variable.Global: "#000000", # class: 'vg' - to be revised - Name.Variable.Instance: "#000000", # class: 'vi' - to be revised - Number: "#990000", # class: 'm' - Literal: "#000000", # class: 'l' - Literal.Date: "#000000", # class: 'ld' - String: "#4e9a06", # class: 's' - String.Backtick: "#4e9a06", # class: 'sb' - String.Char: "#4e9a06", # class: 'sc' - String.Doc: "italic #8f5902", # class: 'sd' - like a comment - String.Double: "#4e9a06", # class: 's2' - String.Escape: "#4e9a06", # class: 'se' - String.Heredoc: "#4e9a06", # class: 'sh' - String.Interpol: "#4e9a06", # class: 'si' - String.Other: "#4e9a06", # class: 'sx' - String.Regex: "#4e9a06", # class: 'sr' - String.Single: "#4e9a06", # class: 's1' - String.Symbol: "#4e9a06", # class: 'ss' - Generic: "#000000", # class: 'g' - Generic.Deleted: "#a40000", # class: 'gd' - Generic.Emph: "italic #000000", # class: 'ge' - Generic.Error: "#ef2929", # class: 'gr' - Generic.Heading: "bold #000080", # class: 'gh' - Generic.Inserted: "#00A000", # class: 'gi' - Generic.Output: "#888", # class: 'go' - Generic.Prompt: "#745334", # class: 'gp' - Generic.Strong: "bold #000000", # class: 'gs' - Generic.Subheading: "bold #800080", # class: 'gu' - Generic.Traceback: "bold #a40000", # class: 'gt' - } diff --git a/docs/advanced_guides.rst b/docs/advanced_guides.rst new file mode 100644 index 000000000..cc2c495af --- /dev/null +++ b/docs/advanced_guides.rst @@ -0,0 +1,14 @@ +Advanced Guides +=============== + +.. toctree:: + :maxdepth: 2 + :hidden: + + user/performance + user/serialization + user/defining + user/wrapping + user/measurement + user/pitheorem + user/currencies diff --git a/docs/developers_reference.rst b/docs/api.rst similarity index 93% rename from docs/developers_reference.rst rename to docs/api.rst index 19ce3cb7d..6ac269e4d 100644 --- a/docs/developers_reference.rst +++ b/docs/api.rst @@ -1,12 +1,8 @@ =================== -Developer reference +API reference =================== -All Modules -=========== - -.. automodule:: pint - :members: +.. currentmodule:: pint .. automodule:: pint.babel_names :members: diff --git a/docs/conf.py b/docs/conf.py index 4f0dfa64c..ee74481f8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,12 +12,7 @@ # serve to show the default. import datetime - -try: - from importlib.metadata import version -except ImportError: - # Backport for Python < 3.8 - from importlib_metadata import version +from importlib.metadata import version # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -33,6 +28,7 @@ # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ "sphinx.ext.autodoc", + "sphinx.ext.autosummary", "sphinx.ext.autosectionlabel", "sphinx.ext.doctest", "sphinx.ext.intersphinx", @@ -42,8 +38,10 @@ "sphinx.ext.mathjax", "matplotlib.sphinxext.plot_directive", "nbsphinx", + "sphinx_copybutton", "IPython.sphinxext.ipython_directive", "IPython.sphinxext.ipython_console_highlighting", + "sphinx_design", ] # Add any paths that contain templates here, relative to this directory. @@ -75,136 +73,78 @@ release = version this_year = datetime.date.today().year -copyright = "%s, %s" % (this_year, author) - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' +copyright = f"2012-{this_year}, Pint Developers" -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. exclude_patterns = ["_build"] -# The reST default role (used for this markup: `text`) to use for all documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False +# Napoleon configurations -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# -- Options for extensions ---------------------------------------------------- -# napoleon +napoleon_google_docstring = False +napoleon_numpy_docstring = True +napoleon_use_param = False +napoleon_use_rtype = False napoleon_preprocess_types = True +napoleon_type_aliases = { + # general terms + "sequence": ":term:`sequence`", + "iterable": ":term:`iterable`", + "callable": ":py:func:`callable`", + "dict_like": ":term:`dict-like `", + "path-like": ":term:`path-like `", + "mapping": ":term:`mapping`", + "file-like": ":term:`file-like `", + # stdlib type aliases + "timedelta": "~datetime.timedelta", + "datetime": "~datetime.datetime", + "string": ":class:`string `", + "Path": "~pathlib.Path", + # numpy terms + "array_like": ":term:`array_like`", + "array-like": ":term:`array-like `", + "scalar": ":term:`scalar`", + "array": ":term:`array`", + "hashable": ":term:`hashable `", + # objects without namespace: pint + "Quantity": "~pint.Quantity", + "Unit": "~pint.Unit", + "UnitsContainer": "~pint.UnitsContainer", + # objects without namespace: numpy + "ndarray": "~numpy.ndarray", + "MaskedArray": "~numpy.ma.MaskedArray", + "dtype": "~numpy.dtype", +} -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# html_theme = 'default' -html_theme = "flask" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] -html_theme_path = ["_themes"] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None +html_theme = "sphinx_book_theme" -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None +html_theme_options = { + "repository_url": "https://github.com/hgrecco/pint", + "repository_branch": "master", + "use_repository_button": True, + "use_issues_button": True, + "extra_navbar": "", + "navbar_footer_text": "", +} -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None +html_logo = "_static/logo-full.jpg" -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True +html_css_files = ["style.css"] # Custom sidebar templates, maps document names to template names. # html_sidebars = {} -html_sidebars = { - "index": ["sidebarintro.html", "sourcelink.html", "searchbox.html"], - "**": [ - "sidebarlogo.html", - "localtoc.html", - "relations.html", - "sourcelink.html", - "searchbox.html", - ], -} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# plain URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file plain name for HTML help builder. +# html_sidebars = { +# "index": ["sidebarintro.html", "sourcelink.html", "searchbox.html"], +# "**": [ +# "sidebarlogo.html", +# "localtoc.html", +# "relations.html", +# "sourcelink.html", +# "searchbox.html", +# ], +# } + +# Output file base name for HTML help builder. htmlhelp_basename = "pintdoc" @@ -225,26 +165,6 @@ ("index", "pint.tex", "pint Documentation", "Hernan E. Grecco", "manual") ] -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - # -- Options for manual page output -------------------------------------------- @@ -291,45 +211,12 @@ epub_publisher = author epub_copyright = copyright -# The language of the text. It defaults to the language option -# or en if the language is not set. -# epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -# epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# epub_identifier = '' - -# A unique identification for the text. -# epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -# epub_cover = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# epub_pre_files = [] - -# HTML files shat should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# epub_post_files = [] - -# A list of files that should not be packed into the epub file. -# epub_exclude_files = [] - -# The depth of the table of contents in toc.ncx. -# epub_tocdepth = 3 - -# Allow duplicate toc entries. -# epub_tocdup = True - # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { "python": ("https://docs.python.org/3/", None), "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), "matplotlib": ("https://matplotlib.org/stable/", None), "dask": ("https://docs.dask.org/en/latest", None), "sparse": ("https://sparse.pydata.org/en/latest/", None), diff --git a/docs/contributing.rst b/docs/dev/contributing.rst similarity index 97% rename from docs/contributing.rst rename to docs/dev/contributing.rst index bf275dd5d..10e6f5a90 100644 --- a/docs/contributing.rst +++ b/docs/dev/contributing.rst @@ -6,7 +6,7 @@ Contributing to Pint Pint uses (and thanks): - github_ to host the code -- travis_ to test all commits and PRs. +- `github actions`_ to test all commits and PRs. - coveralls_ to monitor coverage test coverage - readthedocs_ to host the documentation. - `bors-ng`_ as a merge bot and therefore every PR is tested before merging. @@ -134,7 +134,7 @@ features that work best as an extension package versus direct inclusion in Pint .. _`issue tracker`: https://github.com/hgrecco/pint/issues .. _`bors-ng`: https://github.com/bors-ng/bors-ng .. _`github docs`: https://help.github.com/articles/closing-issues-via-commit-messages/ -.. _travis: https://travis-ci.com/ +.. _`github actions`: https://docs.github.com/en/actions .. _coveralls: https://coveralls.io/ .. _readthedocs: https://readthedocs.org/ .. _pre-commit: https://pre-commit.com/ diff --git a/docs/pint-convert.rst b/docs/dev/pint-convert.rst similarity index 75% rename from docs/pint-convert.rst rename to docs/dev/pint-convert.rst index 8d548f8cf..dbb0804f4 100644 --- a/docs/pint-convert.rst +++ b/docs/dev/pint-convert.rst @@ -6,38 +6,52 @@ Command-line script The script `pint-convert` allows a quick conversion to a target system or between arbitrary compatible units. -By default, `pint-convert` converts to SI units:: +By default, `pint-convert` converts to SI units: + +.. code-block:: console $ pint-convert 225lb 225 pound = 102.05828325 kg -use the `--sys` argument to change it:: +use the `--sys` argument to change it: + +.. code-block:: console $ pint-convert --sys US 102kg 102 kilogram = 224.871507429 lb -or specify directly the target units:: +or specify directly the target units: + +.. code-block:: console $ pint-convert 102kg lb 102 kilogram = 224.871507429 lb -The input quantity can contain expressions:: +The input quantity can contain expressions: + +.. code-block:: console $ pint-convert 7ft+2in 7.166666666666667 foot = 2.1844 m -in some cases parentheses and quotes may be needed:: +in some cases parentheses and quotes may be needed: + +.. code-block:: console $ pint-convert "225lb/(7ft+2in)" 31.3953488372093 pound / foot = 46.7214261353 kg/m -If a number is omitted, 1 is assumed:: +If a number is omitted, 1 is assumed: + +.. code-block:: console $ pint-convert km mi 1 kilometer = 0.621371192237 mi The default precision is 12 significant figures, it can be changed with `-p`, -but note that the accuracy may be affected by floating-point errors:: +but note that the accuracy may be affected by floating-point errors: + +.. code-block:: console $ pint-convert -p 3 mi 1 mile = 1.61e+03 m @@ -46,7 +60,9 @@ but note that the accuracy may be affected by floating-point errors:: 1 light_year = 9460730472580.80078125 km Some contexts are automatically enabled, allowing conversion between not fully -compatible units:: +compatible units: + +.. code-block:: console $ pint-convert 540nm 540 nanometer = 5.4e-07 m @@ -59,7 +75,9 @@ compatible units:: With the `uncertainties` package, the experimental uncertainty in the physical constants is considered, and the result is given in compact notation, with the -uncertainty in the last figures in parentheses:: +uncertainty in the last figures in parentheses: + +.. code-block:: console $ pint-convert Eh eV 1 hartree = 27.21138624599(5) eV @@ -73,13 +91,17 @@ and the maximum number of uncertainty digits (`-u`, 2 by default):: $ pint-convert -p 20 -u 4 Eh eV 1 hartree = 27.21138624598847(5207) eV -The uncertainty can be disabled with `-U`):: +The uncertainty can be disabled with `-U`): + +.. code-block:: console $ pint-convert -p 20 -U Eh eV 1 hartree = 27.211386245988471444 eV Correlations between experimental constants are also known, and taken into -account. Use `-C` to disable it:: +account. Use `-C` to disable it: + +.. code-block:: console $ pint-convert --sys atomic m_p 1 proton_mass = 1836.15267344(11) m_e diff --git a/docs/getting.rst b/docs/getting.rst deleted file mode 100644 index 0afcea354..000000000 --- a/docs/getting.rst +++ /dev/null @@ -1,58 +0,0 @@ -.. _getting: - -Installation -============ - -Pint has no dependencies except Python_ itself. In runs on Python 3.8+. - -You can install it (or upgrade to the latest version) using pip_:: - - $ pip install -U pint - -That's all! You can check that Pint is correctly installed by starting up python, and importing Pint: - -.. code-block:: python - - >>> import pint - >>> pint.__version__ # doctest: +SKIP - -Or running the test suite: - -.. code-block:: python - - >>> pint.test() - -.. note:: If you have an old system installation of Python and you don't want to - mess with it, you can try `Anaconda CE`_. It is a free Python distribution by - Continuum Analytics that includes many scientific packages. To install pint - from the conda-forge channel instead of through pip use:: - - $ conda install -c conda-forge pint - - -Getting the code ----------------- - -You can also get the code from PyPI_ or GitHub_. You can either clone the public repository:: - - $ git clone git://github.com/hgrecco/pint.git - -Download the tarball:: - - $ curl -OL https://github.com/hgrecco/pint/tarball/master - -Or, download the zipball:: - - $ curl -OL https://github.com/hgrecco/pint/zipball/master - -Once you have a copy of the source, you can embed it in your Python package, or install it into your site-packages easily:: - - $ python setup.py install - - -.. _easy_install: http://pypi.python.org/pypi/setuptools -.. _Python: http://www.python.org/ -.. _pip: http://www.pip-installer.org/ -.. _`Anaconda CE`: https://store.continuum.io/cshop/anaconda -.. _PyPI: https://pypi.python.org/pypi/Pint/ -.. _GitHub: https://github.com/hgrecco/pint diff --git a/docs/getting_started.rst b/docs/getting_started.rst new file mode 100644 index 000000000..cae31c686 --- /dev/null +++ b/docs/getting_started.rst @@ -0,0 +1,50 @@ +Getting Started +=============== + +The getting started guide aims to get you using pint productively as quickly as possible. + + + +Installation +------------ + +Pint has no dependencies except Python itself. In runs on Python 3.8+. + +.. grid:: 2 + + .. grid-item-card:: Prefer pip? + + **pint** can be installed via pip from `PyPI `__. + + ++++++++++++++++++++++ + + .. code-block:: bash + + pip install pint + + .. grid-item-card:: Working with conda? + + **pint** is part of the `Conda-Forge `__ + channel and can be installed with Anaconda or Miniconda: + + ++++++++++++++++++++++ + + .. code-block:: bash + + conda install -c conda-forge pint + + +That's all! You can check that Pint is correctly installed by starting up python, and importing Pint: + +.. code-block:: python + + >>> import pint + >>> pint.__version__ # doctest: +SKIP + +.. toctree:: + :maxdepth: 2 + :hidden: + + user/overview + user/tutorial + user/faq diff --git a/docs/index.rst b/docs/index.rst index a0aa97244..9a65f433c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,168 +3,86 @@ Pint: makes units easy ====================== -.. image:: _static/logo-full.jpg - :alt: Pint: **physical quantities** - :class: floatingflask +**Useful links**: +`Code Repository `__ | +`Issues `__ | +`Discussions `__ -Pint is a Python package to define, operate and manipulate **physical quantities**: -the product of a numerical value and a unit of measurement. It allows -arithmetic operations between them and conversions from and to different units. -It is distributed with a `comprehensive list of physical units, prefixes and constants`_. -Due to its modular design, you can extend (or even rewrite!) the complete list -without changing the source code. It supports a lot of numpy mathematical -operations **without monkey patching or wrapping numpy**. -It has a complete test coverage. It runs in Python 3.8+ with no other -dependencies. It is licensed under a `BSD 3-clause style license`_. +.. grid:: 1 1 2 2 + :gutter: 2 -It is extremely easy and natural to use: + .. grid-item-card:: + :img-top: _static/index_getting_started.svg + :link: getting_started + :link-type: doc -.. code-block:: python + Getting Started + ^^^^^^^^^^^^^^^ - >>> import pint - >>> ureg = pint.UnitRegistry() - >>> 3 * ureg.meter + 4 * ureg.cm - + New to Pint? Check out the getting started guides. They contain an + introduction to Pint's main concepts and links to additional tutorials. -and you can make good use of numpy if you want: + .. grid-item-card:: + :img-top: _static/index_user_guide.svg + :link: user/index + :link-type: doc -.. code-block:: python + User Guide + ^^^^^^^^^^ - >>> import numpy as np - >>> [3, 4] * ureg.meter + [4, 3] * ureg.cm - - >>> np.sum(_) - + The user guide provides in-depth information on the + key concepts of Pint with useful background information and explanation. -See the :ref:`Tutorial` for more help getting started. + .. grid-item-card:: + :img-top: _static/index_api.svg + :link: api + :link-type: doc -Quick Installation ------------------- + API reference + ^^^^^^^^^^^^^ -To install Pint, simply: + The reference guide contains a detailed description of the pint API. + The reference describes how the methods work and which parameters can + be used. It assumes that you have an understanding of the key concepts. -.. code-block:: bash + .. grid-item-card:: + :img-top: _static/index_contribute.svg + :link: dev/contributing + :link-type: doc - $ pip install pint + Developer guide + ^^^^^^^^^^^^^^^ -or utilizing conda, with the conda-forge channel: + Saw a typo in the documentation? Want to improve existing functionalities? + The contributing guidelines will guide you through the process of improving + Pint. -.. code-block:: bash - - $ conda install -c conda-forge pint - -and then simply enjoy it! - -(See :ref:`Installation ` for more detail.) - - -Design principles ------------------ - -Although there are already a few very good Python packages to handle physical -quantities, no one was really fitting my needs. Like most developers, I -programmed Pint to scratch my own itches. - -**Unit parsing**: prefixed and pluralized forms of units are recognized without -explicitly defining them. In other words: as the prefix *kilo* and the unit -*meter* are defined, Pint understands *kilometers*. This results in a much -shorter and maintainable unit definition list as compared to other packages. - -**Standalone unit definitions**: units definitions are loaded from a text file -which is simple and easy to edit. Adding and changing units and their -definitions does not involve changing the code. - -**Advanced string formatting**: a quantity can be formatted into string using -`PEP 3101`_ syntax. Extended conversion flags are given to provide symbolic, -LaTeX and pretty formatting. Unit name translation is available if Babel_ is -installed. - -**Free to choose the numerical type**: You can use any numerical type -(``fraction``, ``float``, ``decimal``, ``numpy.ndarray``, etc). NumPy_ is not -required, but is supported. - -**Awesome NumPy integration**: When you choose to use a NumPy_ ndarray, its methods and -ufuncs are supported including automatic conversion of units. For example -``numpy.arccos(q)`` will require a dimensionless ``q`` and the units of the output -quantity will be radian. - -**Uncertainties integration**: transparently handles calculations with -quantities with uncertainties (like 3.14±0.01) meter via the `uncertainties -package`_. - -**Handle temperature**: conversion between units with different reference -points, like positions on a map or absolute temperature scales. - -**Dependency free**: it depends only on Python and its standard library. It interacts with other packages -like numpy and uncertainties if they are installed - -**Pandas integration**: The `pint-pandas`_ package makes it possible to use Pint with Pandas. -Operations on DataFrames and between columns are units aware, providing even more convenience for users -of Pandas DataFrames. For full details, see the `pint-pandas Jupyter notebook`_. - - -When you choose to use a NumPy_ ndarray, its methods and -ufuncs are supported including automatic conversion of units. For example -``numpy.arccos(q)`` will require a dimensionless ``q`` and the units -of the output quantity will be radian. - - -User Guide ----------- .. toctree:: - :maxdepth: 1 + :maxdepth: 2 + :hidden: + :caption: For users - getting - tutorial - defining-quantities - formatting - numpy - nonmult - log_units - angular_frequency - wrapping - plotting - serialization - pitheorem - contexts - measurement - defining - performance - systems - currencies - pint-convert - -More information ----------------- + Getting started + User Guide + Advanced topics + user/ecosystem + api .. toctree:: :maxdepth: 1 + :hidden: + :caption: For developers - developers_reference - contributing - faq - - -One last thing --------------- - -.. epigraph:: - - The MCO MIB has determined that the root cause for the loss of the MCO spacecraft was the failure to use metric units in the coding of a ground software file, “Small Forces,” used in trajectory models. Specifically, thruster performance data in English units instead of metric units was used in the software application code titled SM_FORCES (small forces). The output from the SM_FORCES application code as required by a MSOP Project Software Interface Specification (SIS) was to be in metric units of Newtonseconds (N-s). Instead, the data was reported in English units of pound-seconds (lbf-s). The Angular Momentum Desaturation (AMD) file contained the output data from the SM_FORCES software. The SIS, which was not followed, defines both the format and units of the AMD file generated by ground-based computers. Subsequent processing of the data from AMD file by the navigation software algorithm therefore, underestimated the effect on the spacecraft trajectory by a factor of 4.45, which is the required conversion factor from force in pounds to Newtons. An erroneous trajectory was computed using this incorrect data. - - `Mars Climate Orbiter Mishap Investigation Phase I Report` - `PDF `_ - + dev/contributing + dev/pint-convert +.. toctree:: + :maxdepth: 1 + :hidden: + :caption: Community -.. _`comprehensive list of physical units, prefixes and constants`: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt -.. _`uncertainties package`: https://pythonhosted.org/uncertainties/ -.. _`NumPy`: http://www.numpy.org/ -.. _`PEP 3101`: https://www.python.org/dev/peps/pep-3101/ -.. _`Babel`: http://babel.pocoo.org/ -.. _`pint-pandas`: https://github.com/hgrecco/pint-pandas -.. _`pint-pandas Jupyter notebook`: https://github.com/hgrecco/pint-pandas/blob/master/notebooks/pint-pandas.ipynb -.. _`BSD 3-clause style license`: https://github.com/hgrecco/pint/blob/master/LICENSE + GitHub repository + StackOverflow diff --git a/docs/angular_frequency.rst b/docs/user/angular_frequency.rst similarity index 96% rename from docs/angular_frequency.rst rename to docs/user/angular_frequency.rst index 5636135a4..beebb92c7 100644 --- a/docs/angular_frequency.rst +++ b/docs/user/angular_frequency.rst @@ -16,7 +16,7 @@ By default, pint treats angle quantities as `dimensionless`, so allows conversio >>> frequency.to('Hz') -pint follows the convetions of SI. The SI BIPM Brochure (Bureau International des Poids et Mesures) states: +pint follows the conventions of SI. The SI BIPM Brochure (Bureau International des Poids et Mesures) states: .. note:: diff --git a/docs/contexts.rst b/docs/user/contexts.rst similarity index 100% rename from docs/contexts.rst rename to docs/user/contexts.rst diff --git a/docs/currencies.rst b/docs/user/currencies.rst similarity index 100% rename from docs/currencies.rst rename to docs/user/currencies.rst diff --git a/docs/defining-quantities.rst b/docs/user/defining-quantities.rst similarity index 100% rename from docs/defining-quantities.rst rename to docs/user/defining-quantities.rst diff --git a/docs/defining.rst b/docs/user/defining.rst similarity index 100% rename from docs/defining.rst rename to docs/user/defining.rst diff --git a/docs/user/ecosystem.rst b/docs/user/ecosystem.rst new file mode 100644 index 000000000..7610fd019 --- /dev/null +++ b/docs/user/ecosystem.rst @@ -0,0 +1,11 @@ +Ecosystem +========= + +Here is a list of known projects, packages and integrations using pint. + + +Pint integrations: +------------------ + +- `pint-pandas `_ Pandas integration +- `pint-xarray `_ Xarray integration diff --git a/docs/faq.rst b/docs/user/faq.rst similarity index 100% rename from docs/faq.rst rename to docs/user/faq.rst diff --git a/docs/formatting.rst b/docs/user/formatting.rst similarity index 100% rename from docs/formatting.rst rename to docs/user/formatting.rst diff --git a/docs/user/index.rst b/docs/user/index.rst new file mode 100644 index 000000000..8fd9c357e --- /dev/null +++ b/docs/user/index.rst @@ -0,0 +1,20 @@ +User Guide +========== + +In this user guide, you will find detailed descriptions and +examples that describe many common tasks that you can accomplish with pint. + + +.. toctree:: + :maxdepth: 2 + :hidden: + + defining-quantities + formatting + nonmult + log_units + angular_frequency + contexts + systems + numpy + plotting diff --git a/docs/log_units.rst b/docs/user/log_units.rst similarity index 100% rename from docs/log_units.rst rename to docs/user/log_units.rst diff --git a/docs/measurement.rst b/docs/user/measurement.rst similarity index 100% rename from docs/measurement.rst rename to docs/user/measurement.rst diff --git a/docs/nonmult.rst b/docs/user/nonmult.rst similarity index 100% rename from docs/nonmult.rst rename to docs/user/nonmult.rst diff --git a/docs/numpy.ipynb b/docs/user/numpy.ipynb similarity index 100% rename from docs/numpy.ipynb rename to docs/user/numpy.ipynb diff --git a/docs/user/overview.rst b/docs/user/overview.rst new file mode 100644 index 000000000..cd639aaa3 --- /dev/null +++ b/docs/user/overview.rst @@ -0,0 +1,116 @@ +What is Pint ? +============== + +.. .. image:: _static/logo-full.jpg +.. :alt: Pint: **physical quantities** +.. :class: float-right + +Pint is a Python package to define, operate and manipulate **physical quantities**: +the product of a numerical value and a unit of measurement. It allows +arithmetic operations between them and conversions from and to different units. + +It is distributed with a `comprehensive list of physical units, prefixes and constants`_. +Due to its modular design, you can extend (or even rewrite!) the complete list +without changing the source code. It supports a lot of numpy mathematical +operations **without monkey patching or wrapping numpy**. + +It has a complete test coverage. It runs in Python 3.8+ with no other +dependencies. It is licensed under a `BSD 3-clause style license`_. + +It is extremely easy and natural to use: + +.. code-block:: python + + >>> import pint + >>> ureg = pint.UnitRegistry() + >>> 3 * ureg.meter + 4 * ureg.cm + + +and you can make good use of numpy if you want: + +.. code-block:: python + + >>> import numpy as np + >>> [3, 4] * ureg.meter + [4, 3] * ureg.cm + + >>> np.sum(_) + + +See the :ref:`Tutorial` for more help getting started. + + + + +Design principles +----------------- + +Although there are already a few very good Python packages to handle physical +quantities, no one was really fitting my needs. Like most developers, I +programmed Pint to scratch my own itches. + +**Unit parsing**: prefixed and pluralized forms of units are recognized without +explicitly defining them. In other words: as the prefix *kilo* and the unit +*meter* are defined, Pint understands *kilometers*. This results in a much +shorter and maintainable unit definition list as compared to other packages. + +**Standalone unit definitions**: units definitions are loaded from a text file +which is simple and easy to edit. Adding and changing units and their +definitions does not involve changing the code. + +**Advanced string formatting**: a quantity can be formatted into string using +`PEP 3101`_ syntax. Extended conversion flags are given to provide symbolic, +LaTeX and pretty formatting. Unit name translation is available if Babel_ is +installed. + +**Free to choose the numerical type**: You can use any numerical type +(``fraction``, ``float``, ``decimal``, ``numpy.ndarray``, etc). NumPy_ is not +required, but is supported. + +**Awesome NumPy integration**: When you choose to use a NumPy_ ndarray, its methods and +ufuncs are supported including automatic conversion of units. For example +``numpy.arccos(q)`` will require a dimensionless ``q`` and the units of the output +quantity will be radian. + +**Uncertainties integration**: transparently handles calculations with +quantities with uncertainties (like 3.14±0.01) meter via the `uncertainties +package`_. + +**Handle temperature**: conversion between units with different reference +points, like positions on a map or absolute temperature scales. + +**Dependency free**: it depends only on Python and its standard library. It interacts with other packages +like numpy and uncertainties if they are installed + +**Pandas integration**: The `pint-pandas`_ package makes it possible to use Pint with Pandas. +Operations on DataFrames and between columns are units aware, providing even more convenience for users +of Pandas DataFrames. For full details, see the `pint-pandas Jupyter notebook`_. + + +When you choose to use a NumPy_ ndarray, its methods and +ufuncs are supported including automatic conversion of units. For example +``numpy.arccos(q)`` will require a dimensionless ``q`` and the units +of the output quantity will be radian. + +One last thing +-------------- + + + The MCO MIB has determined that the root cause for the loss of the MCO spacecraft was the failure to use metric units in the coding of a ground software file, “Small Forces,” used in trajectory models. Specifically, thruster performance data in English units instead of metric units was used in the software application code titled SM_FORCES (small forces). The output from the SM_FORCES application code as required by a MSOP Project Software Interface Specification (SIS) was to be in metric units of Newtonseconds (N-s). Instead, the data was reported in English units of pound-seconds (lbf-s). The Angular Momentum Desaturation (AMD) file contained the output data from the SM_FORCES software. The SIS, which was not followed, defines both the format and units of the AMD file generated by ground-based computers. Subsequent processing of the data from AMD file by the navigation software algorithm therefore, underestimated the effect on the spacecraft trajectory by a factor of 4.45, which is the required conversion factor from force in pounds to Newtons. An erroneous trajectory was computed using this incorrect data. + + `Mars Climate Orbiter Mishap Investigation Phase I Report` + `PDF `_ + + +License +------- + +.. literalinclude:: ../../LICENSE + +.. _`comprehensive list of physical units, prefixes and constants`: https://github.com/hgrecco/pint/blob/master/pint/default_en.txt +.. _`uncertainties package`: https://pythonhosted.org/uncertainties/ +.. _`NumPy`: http://www.numpy.org/ +.. _`PEP 3101`: https://www.python.org/dev/peps/pep-3101/ +.. _`Babel`: http://babel.pocoo.org/ +.. _`pint-pandas`: https://github.com/hgrecco/pint-pandas +.. _`pint-pandas Jupyter notebook`: https://github.com/hgrecco/pint-pandas/blob/master/notebooks/pint-pandas.ipynb +.. _`BSD 3-clause style license`: https://github.com/hgrecco/pint/blob/master/LICENSE diff --git a/docs/performance.rst b/docs/user/performance.rst similarity index 77% rename from docs/performance.rst rename to docs/user/performance.rst index 1dbd27d98..d7b8a0cd5 100644 --- a/docs/performance.rst +++ b/docs/user/performance.rst @@ -11,51 +11,53 @@ Pint can impose a significant performance overhead on computationally-intensive Use magnitudes when possible ---------------------------- -It's significantly faster to perform mathematical operations on magnitudes (even though your'e still using pint to retrieve them from a quantity object). +It's significantly faster to perform mathematical operations on magnitudes (even though you're still using pint to retrieve them from a quantity object). -.. doctest:: +.. ipython:: + :verbatim: - In [1]: from pint import UnitRegistry + In [1]: from pint import UnitRegistry - In [2]: ureg = UnitRegistry() + In [2]: ureg = UnitRegistry() - In [3]: q1 =ureg('1m') + In [3]: q1 = ureg('1m') - In [5]: q2=ureg('2m') + In [5]: q2 = ureg('2m') - In [6]: %timeit (q1-q2) - 100000 loops, best of 3: 7.9 µs per loop + In [6]: %timeit (q1 - q2) + 8.24 us +- 44.5 ns per loop (mean +- std. dev. of 7 runs, 100,000 loops each) - In [7]: %timeit (q1.magnitude-q2.magnitude) - 1000000 loops, best of 3: 356 ns per loop + In [7]: %timeit (q1.magnitude - q2.magnitude) + 214 ns +- 2.39 ns per loop (mean +- std. dev. of 7 runs, 1,000,000 loops each) This is especially important when using pint Quantities in conjunction with an iterative solver, such as the `brentq method`_ from scipy: -.. doctest:: +.. ipython:: + :verbatim: In [1]: from scipy.optimize import brentq In [2]: def foobar_with_quantity(x): - # find the value of x that equals q2 - - # assign x the same units as q2 - qx = ureg(str(x)+str(q2.units)) - - # compare the two quantities, then take their magnitude because - # brentq requires a dimensionless return type - return (qx - q2).magnitude + ...: # find the value of x that equals q2 + ...: + ...: # assign x the same units as q2 + ...: qx = ureg(str(x)+str(q2.units)) + ...: + ...: # compare the two quantities, then take their magnitude because + ...: # brentq requires a dimensionless return type + ...: return (qx - q2).magnitude In [3]: def foobar_with_magnitude(x): - # find the value of x that equals q2 - - # don't bother converting x to a quantity, just compare it with q2's magnitude - return x - q2.magnitude + ...: # find the value of x that equals q2 + ...: + ...: # don't bother converting x to a quantity, just compare it with q2's magnitude + ...: return x - q2.magnitude In [4]: %timeit brentq(foobar_with_quantity,0,q2.magnitude) - 1000 loops, best of 3: 310 µs per loop + 286 us +- 9.05 us per loop (mean +- std. dev. of 7 runs, 1,000 loops each) In [5]: %timeit brentq(foobar_with_magnitude,0,q2.magnitude) - 1000000 loops, best of 3: 1.63 µs per loop + 1.14 us +- 21.3 ns per loop (mean +- std. dev. of 7 runs, 1,000,000 loops each) Bear in mind that altering computations like this **loses the benefits of automatic unit conversion**, so use with care. @@ -63,7 +65,7 @@ A safer method: wrapping ------------------------ A better way to use magnitudes is to use pint's wraps decorator (See :ref:`wrapping`). By decorating a function with wraps, you pass only the magnitude of an argument to the function body according to units you specify. As such this method is safer in that you are sure the magnitude is supplied in the correct units. -.. doctest:: +.. ipython:: In [1]: import pint @@ -72,11 +74,11 @@ A better way to use magnitudes is to use pint's wraps decorator (See :ref:`wrapp In [3]: import numpy as np In [4]: def f(x, y): - return (x - y) / (x + y) * np.log(x/y) + ...: return (x - y) / (x + y) * np.log(x/y) In [5]: @ureg.wraps(None, ('meter', 'meter')) - def g(x, y): - return (x - y) / (x + y) * np.log(x/y) + ...: def g(x, y): + ...: return (x - y) / (x + y) * np.log(x/y) In [6]: a = 1 * ureg.meter diff --git a/docs/pitheorem.rst b/docs/user/pitheorem.rst similarity index 100% rename from docs/pitheorem.rst rename to docs/user/pitheorem.rst diff --git a/docs/plotting.rst b/docs/user/plotting.rst similarity index 100% rename from docs/plotting.rst rename to docs/user/plotting.rst diff --git a/docs/serialization.rst b/docs/user/serialization.rst similarity index 100% rename from docs/serialization.rst rename to docs/user/serialization.rst diff --git a/docs/systems.rst b/docs/user/systems.rst similarity index 95% rename from docs/systems.rst rename to docs/user/systems.rst index d4a175d93..5a1c27b32 100644 --- a/docs/systems.rst +++ b/docs/user/systems.rst @@ -1,7 +1,7 @@ .. _systems: -Different Unit Systems (and default units) -========================================== +Dealing with unit systems +========================= Pint Unit Registry has the concept of system, which is a group of units diff --git a/docs/tutorial.rst b/docs/user/tutorial.rst similarity index 100% rename from docs/tutorial.rst rename to docs/user/tutorial.rst diff --git a/docs/wrapping.rst b/docs/user/wrapping.rst similarity index 99% rename from docs/wrapping.rst rename to docs/user/wrapping.rst index d04b0ba1d..21d8177c3 100644 --- a/docs/wrapping.rst +++ b/docs/user/wrapping.rst @@ -145,7 +145,7 @@ the extra outputs. For example, given the NREL SOLPOS calculator that outputs solar zenith, azimuth and air mass, the following wrapper assumes no units for airmass -.. doctest:: +.. code-block:: python @ureg.wraps(('deg', 'deg'), ('deg', 'deg', 'millibar', 'degC')) def solar_position(lat, lon, press, tamb, timestamp): @@ -232,7 +232,7 @@ To avoid the conversion of an argument or return value, use None Checking dimensionality -======================= +----------------------- When you want pint quantities to be used as inputs to your functions, pint provides a wrapper to ensure units are of correct type - or more precisely, they match the expected dimensionality of the physical quantity. diff --git a/pint/facets/context/__init__.py b/pint/facets/context/__init__.py index 61685a217..db2843648 100644 --- a/pint/facets/context/__init__.py +++ b/pint/facets/context/__init__.py @@ -15,4 +15,4 @@ from .objects import Context from .registry import ContextRegistry -__all__ = [ContextDefinition, Context, ContextRegistry] +__all__ = ["ContextDefinition", "Context", "ContextRegistry"] diff --git a/pint/facets/context/registry.py b/pint/facets/context/registry.py index 5483554d1..4290e3e0f 100644 --- a/pint/facets/context/registry.py +++ b/pint/facets/context/registry.py @@ -259,48 +259,47 @@ def disable_contexts(self, n: int = None) -> None: @contextmanager def context(self, *names, **kwargs) -> ContextManager[Context]: """Used as a context manager, this function enables to activate a context - which is removed after usage. + which is removed after usage. - Parameters - ---------- - *names : - name(s) of the context(s). - **kwargs : - keyword arguments for the contexts. + Parameters + ---------- + *names : name(s) of the context(s). + **kwargs : keyword arguments for the contexts. - Examples - -------- - Context can be called by their name: + Examples + -------- + Context can be called by their name: - import pint.facets.context.objects >>> import pint - >>> ureg = pint.UnitRegistry() - >>> ureg.add_context(pint.facets.context.objects.Context('one')) - >>> ureg.add_context(pint.facets.context.objects.Context('two')) - >>> with ureg.context('one'): - ... pass + >>> import pint.facets.context.objects + >>> import pint + >>> ureg = pint.UnitRegistry() + >>> ureg.add_context(pint.facets.context.objects.Context('one')) + >>> ureg.add_context(pint.facets.context.objects.Context('two')) + >>> with ureg.context('one'): + ... pass - If a context has an argument, you can specify its value as a keyword argument: + If a context has an argument, you can specify its value as a keyword argument: - >>> with ureg.context('one', n=1): - ... pass + >>> with ureg.context('one', n=1): + ... pass - Multiple contexts can be entered in single call: + Multiple contexts can be entered in single call: - >>> with ureg.context('one', 'two', n=1): - ... pass + >>> with ureg.context('one', 'two', n=1): + ... pass - Or nested allowing you to give different values to the same keyword argument: + Or nested allowing you to give different values to the same keyword argument: - >>> with ureg.context('one', n=1): - ... with ureg.context('two', n=2): - ... pass + >>> with ureg.context('one', n=1): + ... with ureg.context('two', n=2): + ... pass - A nested context inherits the defaults from the containing context: + A nested context inherits the defaults from the containing context: - >>> with ureg.context('one', n=1): - ... # Here n takes the value of the outer context - ... with ureg.context('two'): - ... pass + >>> with ureg.context('one', n=1): + ... # Here n takes the value of the outer context + ... with ureg.context('two'): + ... pass """ # Enable the contexts. self.enable_contexts(*names, **kwargs) @@ -318,7 +317,7 @@ def with_context(self, name, **kwargs) -> Callable[[F], F]: """Decorator to wrap a function call in a Pint context. Use it to ensure that a certain context is active when - calling a function:: + calling a function. Parameters ---------- @@ -330,14 +329,13 @@ def with_context(self, name, **kwargs) -> Callable[[F], F]: Returns ------- - callable - the wrapped function. + callable: the wrapped function. - Example - ------- - >>> @ureg.with_context('sp') - ... def my_cool_fun(wavelength): - ... print('This wavelength is equivalent to: %s', wavelength.to('terahertz')) + Examples + -------- + >>> @ureg.with_context('sp') + ... def my_cool_fun(wavelength): + ... print('This wavelength is equivalent to: %s', wavelength.to('terahertz')) """ def decorator(func): diff --git a/pint/facets/formatting/__init__.py b/pint/facets/formatting/__init__.py index f9c8c8227..e3f43816e 100644 --- a/pint/facets/formatting/__init__.py +++ b/pint/facets/formatting/__init__.py @@ -13,4 +13,4 @@ from .objects import FormattingQuantity, FormattingUnit from .registry import FormattingRegistry -__all__ = [FormattingQuantity, FormattingUnit, FormattingRegistry] +__all__ = ["FormattingQuantity", "FormattingUnit", "FormattingRegistry"] diff --git a/pint/facets/group/__init__.py b/pint/facets/group/__init__.py index d9d1606f4..e1fad043d 100644 --- a/pint/facets/group/__init__.py +++ b/pint/facets/group/__init__.py @@ -14,4 +14,4 @@ from .objects import Group from .registry import GroupRegistry -__all__ = [GroupDefinition, Group, GroupRegistry] +__all__ = ["GroupDefinition", "Group", "GroupRegistry"] diff --git a/pint/facets/measurement/__init__.py b/pint/facets/measurement/__init__.py index 83454dc4f..21539dcd5 100644 --- a/pint/facets/measurement/__init__.py +++ b/pint/facets/measurement/__init__.py @@ -13,4 +13,4 @@ from .objects import Measurement, MeasurementQuantity from .registry import MeasurementRegistry -__all__ = [Measurement, MeasurementQuantity, MeasurementRegistry] +__all__ = ["Measurement", "MeasurementQuantity", "MeasurementRegistry"] diff --git a/pint/facets/nonmultiplicative/__init__.py b/pint/facets/nonmultiplicative/__init__.py index 56b8710f9..cbba4100c 100644 --- a/pint/facets/nonmultiplicative/__init__.py +++ b/pint/facets/nonmultiplicative/__init__.py @@ -18,5 +18,5 @@ from .registry import NonMultiplicativeRegistry __all__ = [ - NonMultiplicativeRegistry, + "NonMultiplicativeRegistry", ] diff --git a/pint/facets/numpy/__init__.py b/pint/facets/numpy/__init__.py index 9e0d4d54d..aad9508bc 100644 --- a/pint/facets/numpy/__init__.py +++ b/pint/facets/numpy/__init__.py @@ -12,4 +12,4 @@ from .registry import NumpyRegistry -__all__ = [NumpyRegistry] +__all__ = ["NumpyRegistry"] diff --git a/pint/facets/plain/__init__.py b/pint/facets/plain/__init__.py index 50669327f..604cb42d4 100644 --- a/pint/facets/plain/__init__.py +++ b/pint/facets/plain/__init__.py @@ -1,6 +1,6 @@ """ pint.facets.plain - ~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~ Base implementation for registry, units and quantities. @@ -22,14 +22,14 @@ from .registry import PlainRegistry __all__ = [ - PlainUnit, - PlainQuantity, - PlainRegistry, - AliasDefinition, - DefaultsDefinition, - DimensionDefinition, - PrefixDefinition, - ScaleConverter, - UnitDefinition, - UnitsContainer, + "PlainUnit", + "PlainQuantity", + "PlainRegistry", + "AliasDefinition", + "DefaultsDefinition", + "DimensionDefinition", + "PrefixDefinition", + "ScaleConverter", + "UnitDefinition", + "UnitsContainer", ] diff --git a/pint/facets/plain/quantity.py b/pint/facets/plain/quantity.py index 5e4f33ddb..d4c1a55ed 100644 --- a/pint/facets/plain/quantity.py +++ b/pint/facets/plain/quantity.py @@ -618,9 +618,9 @@ def to_compact(self, unit=None) -> PlainQuantity[_MagnitudeType]: >>> import pint >>> ureg = pint.UnitRegistry() >>> (200e-9*ureg.s).to_compact() - + >>> (1e-2*ureg('kg m/s^2')).to_compact('N') - + """ if not isinstance(self.magnitude, numbers.Number): diff --git a/pint/facets/system/__init__.py b/pint/facets/system/__init__.py index 3e0450733..e95098bd9 100644 --- a/pint/facets/system/__init__.py +++ b/pint/facets/system/__init__.py @@ -14,4 +14,4 @@ from .objects import System from .registry import SystemRegistry -__all__ = [SystemDefinition, System, SystemRegistry] +__all__ = ["SystemDefinition", "System", "SystemRegistry"] diff --git a/requirements_docs.txt b/requirements_docs.txt index 7e90fd219..683292c2d 100644 --- a/requirements_docs.txt +++ b/requirements_docs.txt @@ -15,3 +15,6 @@ dask[complete] setuptools>=41.2 Serialize pygments>=2.4 +sphinx-book-theme==0.3.3 +sphinx_copybutton +sphinx_design