diff --git a/CHANGES b/CHANGES index 61af9bdce..888e06117 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,7 @@ Pint Changelog - Fixed crash when some specific combinations of contexts were enabled (Issue #1112, Thanks Guido Imperiale) - Added support for checking prefixed units using `in` keyword (Issue #1086) +- Updated many examples in the documentation to reflect Pint's current behavior 0.12 (2020-05-29) diff --git a/docs/contexts.rst b/docs/contexts.rst index 27cb6abc2..9f75c9fdb 100644 --- a/docs/contexts.rst +++ b/docs/contexts.rst @@ -55,11 +55,15 @@ Contexts can be also enabled for blocks of code using the `with` statement: If you need a particular context in all your code, you can enable it for all -operations with the registry:: +operations with the registry + +.. doctest:: >>> ureg.enable_contexts('sp') -To disable the context, just call:: +To disable the context, just call + +.. doctest:: >>> ureg.disable_contexts() @@ -69,17 +73,23 @@ Enabling multiple contexts You can enable multiple contexts: +.. doctest:: + >>> q.to('Hz', 'sp', 'boltzmann') This works also using the `with` statement: +.. doctest:: + >>> with ureg.context('sp', 'boltzmann'): ... q.to('Hz') or in the registry: +.. doctest:: + >>> ureg.enable_contexts('sp', 'boltzmann') >>> q.to('Hz') @@ -88,6 +98,8 @@ If a conversion rule between two dimensions appears in more than one context, the one in the last context has precedence. This is easy to remember if you think that the previous syntax is equivalent to nest contexts: +.. doctest:: + >>> with ureg.context('sp'): ... with ureg.context('boltzmann') : ... q.to('Hz') @@ -106,7 +118,7 @@ calculate, for example, the wavelength in water of a laser which on air is 530 n >>> wl = 530. * ureg.nm >>> f = wl.to('Hz', 'sp') >>> f.to('nm', 'sp', n=1.33) - + Contexts can also accept Pint Quantity objects as parameters. For example, the 'chemistry' context accepts the molecular weight of a substance (as a Quantity @@ -135,7 +147,7 @@ context and the parameters that you wish to set. ... def f(wl): ... return wl.to('Hz').magnitude >>> f(wl) - 398.496240602 + 425297855014895.6 This decorator can be combined with **wraps** or **check** decorators described in @@ -194,14 +206,16 @@ functions. For example: ... lambda ureg, x: x * ureg.speed_of_light) >>> ureg.add_context(c) >>> ureg("1 s").to("km", "ab") - 299792.458 kilometer + It is also possible to create anonymous contexts without invoking add_context: +.. doctest:: + >>> c = pint.Context() - ... + >>> c.add_transformation('[time]', '[length]', lambda ureg, x: x * ureg.speed_of_light) >>> ureg("1 s").to("km", c) - 299792.458 kilometer + Using contexts for unit redefinition ------------------------------------ diff --git a/docs/contributing.rst b/docs/contributing.rst index a7c7e41c0..d5c870330 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -32,6 +32,38 @@ Pint uses `bors-ng` as a merge bot and therefore every PR is tested before mergi In any case, feel free to use the `issue tracker`_ to discuss ideas for new features or improvements. +Setting up your environment +--------------------------- + +If you're contributing to this project for the fist time, you can set up your +environment on Linux or OSX with the following commands:: + + $ git clone git@github.com:hgrecco/pint.git + $ cd pint + $ python -m virtualenv venv + $ source venv/bin/activate + $ pip install -e . + $ pip install -r requirements_docs.txt + +Running tests and building documentation +---------------------------------------- + +To run the test suite, invoke pytest from the ``pint`` directory:: + + $ cd pint + $ pytest + +To run the doctests, invoke Sphinx's doctest module from the ``docs`` directory:: + + $ cd docs + $ make doctest + +To build the documentation, invoke Sphinx from the ``docs`` directory:: + + $ cd docs + $ make html + + .. _github: http://github.com/hgrecco/pint .. _`issue tracker`: https://github.com/hgrecco/pint/issues .. _`bors-ng`: https://github.com/bors-ng/bors-ng diff --git a/docs/defining.rst b/docs/defining.rst index fd5c2d456..43344bcaf 100644 --- a/docs/defining.rst +++ b/docs/defining.rst @@ -112,7 +112,7 @@ Let's add a dog_year (sometimes written as dy) equivalent to 52 (human) days: # We create a quantity based on that unit and we convert to years. >>> lassie_lifespan = Q_(10, 'year') >>> print(lassie_lifespan.to('dog_years')) - 70.23888438100961 dog_year + 70.240384... dog_year Note that we have used the name `dog_years` even though we have not defined the plural form as an alias. Pint takes care of that, so you don't have to. @@ -132,7 +132,7 @@ Same for aliases and derived dimensions: .. doctest:: >>> ureg.define('@alias meter = metro = metr') - >>> ureg.define('[hypervolume] = [length ** 4]') + >>> ureg.define('[hypervolume] = [length] ** 4') .. warning:: diff --git a/docs/developers_reference.rst b/docs/developers_reference.rst index 157732805..b4a48891f 100644 --- a/docs/developers_reference.rst +++ b/docs/developers_reference.rst @@ -111,4 +111,4 @@ Pint :members: .. automodule:: pint.testsuite.test_util - :members: \ No newline at end of file + :members: diff --git a/docs/getting.rst b/docs/getting.rst index db3b2ebf9..a883175cb 100644 --- a/docs/getting.rst +++ b/docs/getting.rst @@ -11,10 +11,10 @@ You can install it (or upgrade to the latest version) using pip_:: That's all! You can check that Pint is correctly installed by starting up python, and importing pint: -.. testcode:: +.. code-block:: - >>> import pint # doctest: +SKIP - >>> pint.__version__ # doctest: +SKIP + >>> import pint + >>> pint.__version__ .. 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 @@ -25,7 +25,9 @@ That's all! You can check that Pint is correctly installed by starting up python You can check the installation with the following command: - >>> pint.test() # doctest: +SKIP +.. code-block:: + + >>> pint.test() On Arch Linux, you can alternatively install Pint from the Arch User Repository diff --git a/docs/measurement.rst b/docs/measurement.rst index 12facfb20..78e80083d 100644 --- a/docs/measurement.rst +++ b/docs/measurement.rst @@ -54,7 +54,7 @@ Mathematical operations with Measurements, return new measurements following the .. doctest:: >>> print(2 * book_length) - (40.0 +/- 4.0) centimeter + (40 +/- 4) centimeter >>> width = (10 * ureg.centimeter).plus_minus(1) >>> print('{:.02f}'.format(book_length + width)) (30.00 +/- 2.24) centimeter diff --git a/docs/nonmult.rst b/docs/nonmult.rst index 4d792c1f4..a649d2ad1 100644 --- a/docs/nonmult.rst +++ b/docs/nonmult.rst @@ -14,30 +14,24 @@ kelvin and rankine abbreviated as degF, degC, degK, and degR. For example, to convert from celsius to fahrenheit: -.. testsetup:: - - from pint import UnitRegistry - ureg = UnitRegistry() - ureg.default_format = '.3f' - Q_ = ureg.Quantity - .. doctest:: - >>> from pint import UnitRegistry - >>> ureg = UnitRegistry() - >>> Q_ = ureg.Quantity - >>> home = Q_(25.4, ureg.degC) - >>> print(home.to('degF')) - 77.7200004 degF + >>> from pint import UnitRegistry + >>> ureg = UnitRegistry() + >>> ureg.default_format = '.3f' + >>> Q_ = ureg.Quantity + >>> home = Q_(25.4, ureg.degC) + >>> print(home.to('degF')) + 77.720 degree_Fahrenheit or to other kelvin or rankine: .. doctest:: >>> print(home.to('kelvin')) - 298.55 kelvin + 298.550 kelvin >>> print(home.to('degR')) - 537.39 degR + 537.390 degree_Rankine Additionally, for every non-multiplicative temperature unit in the registry, there is also a *delta* counterpart to specify @@ -48,18 +42,18 @@ is different). .. doctest:: - >>> increase = 12.3 * ureg.delta_degC - >>> print(increase.to(ureg.kelvin)) - 12.3 kelvin - >>> print(increase.to(ureg.delta_degF)) - 22.14 delta_degF + >>> increase = 12.3 * ureg.delta_degC + >>> print(increase.to(ureg.kelvin)) + 12.300 kelvin + >>> print(increase.to(ureg.delta_degF)) + 22.140 delta_degree_Fahrenheit Subtraction of two temperatures given in offset units yields a *delta* unit: .. doctest:: >>> Q_(25.4, ureg.degC) - Q_(10., ureg.degC) - + You can add or subtract a quantity with *delta* unit and a quantity with offset unit: @@ -67,9 +61,9 @@ offset unit: .. doctest:: >>> Q_(25.4, ureg.degC) + Q_(10., ureg.delta_degC) - + >>> Q_(25.4, ureg.degC) - Q_(10., ureg.delta_degC) - + If you want to add a quantity with absolute unit to one with offset unit, like here @@ -94,7 +88,7 @@ or convert the absolute unit to a *delta* unit: .. doctest:: >>> Q_(10., ureg.degC) + heating_rate.to('delta_degC/min') * Q_(30, ureg.min) - + In contrast to subtraction, the addition of quantities with offset units is ambiguous, e.g. for *10 degC + 100 degC* two different result are reasonable @@ -108,7 +102,7 @@ Quantities with *delta* units are multiplicative: >>> speed = 60. * ureg.delta_degC / ureg.min >>> print(speed.to('delta_degC/second')) - 1.0 delta_degC / second + 1.000 delta_degree_Celsius / second However, multiplication, division and exponentiation of quantities with offset units is problematic just like addition. Pint (since version 0.6) @@ -125,7 +119,7 @@ to be explicitly created: ... OffsetUnitCalculusError: Ambiguous operation with offset unit (degC). >>> Q_(25.4, ureg.degC) - + As an alternative to raising an error, pint can be configured to work more relaxed via setting the UnitRegistry parameter *autoconvert_offset_to_baseunit* @@ -139,20 +133,24 @@ to true. In this mode, pint behaves differently: >>> ureg = UnitRegistry(autoconvert_offset_to_baseunit = True) >>> T = 25.4 * ureg.degC >>> T - + * Before all other multiplications, all divisions and in case of exponentiation [#f1]_ involving quantities with offset-units, pint will convert the quantities with offset units automatically to the corresponding base unit before performing the operation. +.. doctest:: + >>> 1/T - + >>> T * 10 * ureg.meter You can change the behaviour at any time: +.. doctest:: + >>> ureg.autoconvert_offset_to_baseunit = False >>> 1/T Traceback (most recent call last): @@ -165,28 +163,28 @@ is found in a multiplicative context. For example, here: .. doctest:: >>> print(ureg.parse_units('degC/meter')) - delta_degC / meter + delta_degree_Celsius / meter but not here: .. doctest:: >>> print(ureg.parse_units('degC')) - degC + degree_Celsius You can override this behaviour: .. doctest:: >>> print(ureg.parse_units('degC/meter', as_delta=False)) - degC / meter + degree_Celsius / meter Note that the magnitude is left unchanged: .. doctest:: >>> Q_(10, 'degC/meter') - + To define a new temperature, you need to specify the offset. For example, this is the definition of the celsius and fahrenheit:: diff --git a/docs/pitheorem.rst b/docs/pitheorem.rst index a2513d506..cd3716528 100644 --- a/docs/pitheorem.rst +++ b/docs/pitheorem.rst @@ -73,7 +73,7 @@ There are 3 fundamental physical units in this equation: time, mass, and length, ... 'M': '[mass]', ... 'L': '[length]', ... 'g': '[acceleration]'}) - [{'T': 2.0, 'g': 1.0, 'L': -1.0}] + [{'T': 2.0, 'L': -1.0, 'g': 1.0}] which means that the dimensionless quantity is: diff --git a/docs/serialization.rst b/docs/serialization.rst index 1ebd24552..aa4872836 100644 --- a/docs/serialization.rst +++ b/docs/serialization.rst @@ -10,10 +10,6 @@ deserialize the object. The easiest way to do this is by converting the quantity to a string: -.. testsetup:: * - - import pint - .. doctest:: >>> import pint @@ -74,15 +70,19 @@ with the magnitude and the units: >>> to_serialize = duration.to_tuple() >>> print(to_serialize) - (24.2, (('year', 1.0),)) + (24.2, (('year', 1),)) And then you can just pickle that: +.. doctest:: + >>> import pickle >>> serialized = pickle.dumps(to_serialize, -1) To unpickle, just +.. doctest:: + >>> loaded = pickle.loads(serialized) >>> ureg.Quantity.from_tuple(loaded) @@ -97,6 +97,8 @@ numerical type such as `numpy.ndarray`). Using the serialize_ package you can load and read from multiple formats: +.. doctest:: + >>> from serialize import dump, load, register_class >>> register_class(ureg.Quantity, ureg.Quantity.to_tuple, ureg.Quantity.from_tuple) >>> dump(duration, 'output.yaml') @@ -113,6 +115,3 @@ Using the serialize_ package you can load and read from multiple formats: .. _hdf5: http://www.h5py.org/ .. _PyTables: http://www.pytables.org .. _dill: https://pypi.python.org/pypi/dill - - - diff --git a/docs/systems.rst b/docs/systems.rst index 7c095c5d3..f209ab5da 100644 --- a/docs/systems.rst +++ b/docs/systems.rst @@ -5,6 +5,8 @@ Different Unit Systems (and default units) Pint Unit Registry has the concept of system, which is a group of units +.. doctest:: + >>> import pint >>> ureg = pint.UnitRegistry(system='mks') >>> ureg.default_system @@ -12,18 +14,24 @@ Pint Unit Registry has the concept of system, which is a group of units This has an effect in the base units. For example: +.. doctest:: + >>> q = 3600. * ureg.meter / ureg.hour >>> q.to_base_units() But if you change to cgs: +.. doctest:: + >>> ureg.default_system = 'cgs' >>> q.to_base_units() or more drastically to: +.. doctest:: + >>> ureg.default_system = 'imperial' >>> '{:.3f}'.format(q.to_base_units()) '1.094 yard / second' @@ -36,12 +44,16 @@ or more drastically to: You can also use system to narrow down the list of compatible units: +.. doctest:: + >>> ureg.default_system = 'mks' >>> ureg.get_compatible_units('meter') frozenset({, }) or for imperial units: +.. doctest:: + >>> ureg.default_system = 'imperial' >>> ureg.get_compatible_units('meter') frozenset({, , , , , , }) @@ -49,19 +61,25 @@ or for imperial units: You can check which unit systems are available: +.. doctest:: + >>> dir(ureg.sys) - ['US', 'cgs', 'imperial', 'mks'] + ['Planck', 'SI', 'US', 'atomic', 'cgs', 'imperial', 'mks'] Or which units are available within a particular system: +.. doctest:: + >>> dir(ureg.sys.imperial) ['UK_hundredweight', 'UK_ton', 'acre_foot', 'cubic_foot', 'cubic_inch', 'cubic_yard', 'drachm', 'foot', 'grain', 'imperial_barrel', 'imperial_bushel', 'imperial_cup', 'imperial_fluid_drachm', 'imperial_fluid_ounce', 'imperial_gallon', 'imperial_gill', 'imperial_peck', 'imperial_pint', 'imperial_quart', 'inch', 'long_hunderweight', 'long_ton', 'mile', 'ounce', 'pound', 'quarter', 'short_hunderdweight', 'short_ton', 'square_foot', 'square_inch', 'square_mile', 'square_yard', 'stone', 'yard'] Notice that this give you the opportunity to choose within units with colliding names: +.. doctest:: + >>> (1 * ureg.sys.imperial.pint).to('liter') - + >>> (1 * ureg.sys.US.pint).to('liter') - + >>> (1 * ureg.sys.US.pint).to(ureg.sys.imperial.pint) - + diff --git a/docs/tutorial.rst b/docs/tutorial.rst index 474fa2a5e..b49c56414 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -10,16 +10,11 @@ Converting Quantities Pint has the concept of Unit Registry, an object within which units are defined and handled. You start by creating your registry: +.. doctest:: + >>> from pint import UnitRegistry >>> ureg = UnitRegistry() -.. testsetup:: * - - from pint import UnitRegistry - ureg = UnitRegistry() - Q_ = ureg.Quantity - - If no parameter is given to the constructor, the unit registry is populated with the default list of units and prefixes. You can now simply use the registry in the following way: @@ -62,7 +57,7 @@ convert quantities to the unit of choice: .. doctest:: >>> speed.to(ureg.inch / ureg.minute ) - + This method returns a new object leaving the original intact as can be seen by: @@ -78,9 +73,9 @@ use the `ito` method: >>> speed.ito(ureg.inch / ureg.minute ) >>> speed - + >>> print(speed) - 7086.614173228345 inch / minute + 7086.6141... inch / minute If you ask Pint to perform an invalid conversion: @@ -103,7 +98,7 @@ human-readable. >>> print(frequency) 193414489032258.03 hertz >>> print(frequency.to_compact()) - 193.41448903225802 terahertz + 193.414489032... terahertz There are also methods 'to_base_units' and 'ito_base_units' which automatically convert to the reference units with the correct dimensionality: @@ -114,12 +109,12 @@ convert to the reference units with the correct dimensionality: >>> print(height) 5.75 foot >>> print(height.to_base_units()) - 1.7526 meter + 1.752... meter >>> print(height) 5.75 foot >>> height.ito_base_units() >>> print(height) - 1.7526 meter + 1.752... meter There are also methods 'to_reduced_units' and 'ito_reduced_units' which perform a simplified dimensional reduction, combining units with the same dimensionality @@ -131,11 +126,11 @@ but otherwise keeping your unit definitions intact. >>> volume = 10*ureg.cc >>> mass = density*volume >>> print(mass) - 14.0 cc * gram / centimeter ** 3 + 14.0 cubic_centimeter * gram / centimeter ** 3 >>> print(mass.to_reduced_units()) 14.0 gram >>> print(mass) - 14.0 cc * gram / centimeter ** 3 + 14.0 cubic_centimeter * gram / centimeter ** 3 >>> mass.ito_reduced_units() >>> print(mass) 14.0 gram @@ -280,7 +275,7 @@ Strings containing values can be parsed using the ``ureg.parse_pattern`` functio >>> input_string = '10 feet 10 inches' >>> pattern = '{feet} feet {inch} inches' >>> ureg.parse_pattern(input_string, pattern) - [10.0 , 10.0 ] + [, ] To search for multiple matches, set the ``many`` parameter to ``True``. The following example also demonstrates how the parser is able to find matches in amongst filler characters: @@ -289,7 +284,7 @@ To search for multiple matches, set the ``many`` parameter to ``True``. The foll >>> input_string = '10 feet - 20 feet ! 30 feet.' >>> pattern = '{feet} feet' >>> ureg.parse_pattern(input_string, pattern, many=True) - [[10.0 ], [20.0 ], [30.0 ]] + [[], [], []] The full power of regex can also be employed when writing patterns: @@ -298,7 +293,7 @@ The full power of regex can also be employed when writing patterns: >>> input_string = "10` - 20 feet ! 30 ft." >>> pattern = r"{feet}(`| feet| ft)" >>> ureg.parse_pattern(input_string, pattern, many=True) - [[10.0 ], [20.0 ], [30.0 ]] + [[], [], []] *Note that the curly brackets (``{}``) are converted to a float-matching pattern by the parser.* @@ -329,6 +324,7 @@ Pint supports float formatting for numpy arrays as well: .. doctest:: + >>> import numpy as np >>> accel = np.array([-1.1, 1e-6, 1.2505, 1.3]) * ureg['meter/second**2'] >>> # float formatting numpy arrays >>> print('The array is {:.2f}'.format(accel)) @@ -350,8 +346,8 @@ Pint also supports 'f-strings'_ from python>=3.6 : The str is 1.3 m / s ** 2 >>> print(f'The str is {accel:~.3e}') The str is 1.300e+00 m / s ** 2 - >>> print(f'The str is {accel:~H}') - The str is 1.3 m/s² + >>> print(f'The str is {accel:~H}') # HTML format (displays well in Jupyter) + The str is \[1.3\ m/{s}^{2}\] But Pint also extends the standard formatting capabilities for unicode and LaTeX representations: @@ -365,9 +361,9 @@ LaTeX representations: >>> # Latex print >>> 'The latex representation is {:L}'.format(accel) 'The latex representation is 1.3\\ \\frac{\\mathrm{meter}}{\\mathrm{second}^{2}}' - >>> # HTML print + >>> # HTML print - good for Jupyter notebooks >>> 'The HTML representation is {:H}'.format(accel) - 'The HTML representation is 1.3 meter/second2' + 'The HTML representation is \\[1.3\\ meter/{second}^{2}\\]' If you want to use abbreviated unit names, prefix the specification with `~`: @@ -390,6 +386,7 @@ The formatting specs (ie 'L', 'H', 'P') can be used with Python string 'formatti syntax'_ for custom float representations. For example, scientific notation: .. doctest:: + >>> 'Scientific notation: {:.3e~L}'.format(accel) 'Scientific notation: 1.300\\times 10^{0}\\ \\frac{\\mathrm{m}}{\\mathrm{s}^{2}}' @@ -400,15 +397,16 @@ Pint also supports the LaTeX siunitx package: >>> accel = 1.3 * ureg['meter/second**2'] >>> # siunitx Latex print >>> print('The siunitx representation is {:Lx}'.format(accel)) - The siunitx representation is \SI{1.3}{\meter\per\second\squared} + The siunitx representation is \SI[]{1.3}{\meter\per\second\squared} >>> accel = accel.plus_minus(0.2) >>> print('The siunitx representation is {:Lx}'.format(accel)) - The siunitx representation is \SI{1.3 +- 0.2}{\meter\per\second\squared} + The siunitx representation is \SI{1.30 +- 0.20}{\meter\per\second\squared} Additionally, you can specify a default format specification: .. doctest:: + >>> accel = 1.3 * ureg['meter/second**2'] >>> 'The acceleration is {}'.format(accel) 'The acceleration is 1.3 meter / second ** 2' >>> ureg.default_format = 'P' @@ -425,6 +423,8 @@ Finally, if Babel_ is installed you can translate unit names to any language You can also specify the format locale at the registry level either at creation: +.. doctest:: + >>> ureg = UnitRegistry(fmt_locale='fr_FR') or later: @@ -437,6 +437,7 @@ and by doing that, string formatting is now localized: .. doctest:: + >>> accel = 1.3 * ureg['meter/second**2'] >>> str(accel) '1.3 mètre par seconde²' >>> "%s" % accel @@ -451,14 +452,18 @@ Using Pint in your projects If you use Pint in multiple modules within your Python package, you normally want to avoid creating multiple instances of the unit registry. The best way to do this is by instantiating the registry in a single place. For -example, you can add the following code to your package `__init__.py`:: +example, you can add the following code to your package `__init__.py` + +.. code-block:: from pint import UnitRegistry ureg = UnitRegistry() Q_ = ureg.Quantity -Then in `yourmodule.py` the code would be:: +Then in `yourmodule.py` the code would be + +.. code-block:: from . import ureg, Q_ @@ -466,7 +471,9 @@ Then in `yourmodule.py` the code would be:: my_speed = Q_(20, 'm/s') If you are pickling and unplicking Quantities within your project, you should -also define the registry as the application registry:: +also define the registry as the application registry + +.. code-block:: from pint import UnitRegistry, set_application_registry ureg = UnitRegistry() diff --git a/docs/wrapping.rst b/docs/wrapping.rst index 8a0be35d9..d04b0ba1d 100644 --- a/docs/wrapping.rst +++ b/docs/wrapping.rst @@ -13,19 +13,19 @@ requires you to provide numerical values in certain units: .. testsetup:: * - import math - G = 9.806650 - def pendulum_period(length): - return 2*math.pi*math.sqrt(length/G) + import math + G = 9.806650 + def pendulum_period(length): + return 2*math.pi*math.sqrt(length/G) - def pendulum_period2(length, swing_amplitude): - pass + def pendulum_period2(length, swing_amplitude): + pass - def pendulum_period_maxspeed(length, swing_amplitude): - pass + def pendulum_period_maxspeed(length, swing_amplitude): + pass - def pendulum_period_error(length): - pass + def pendulum_period_error(length): + pass .. doctest:: @@ -47,6 +47,7 @@ You could wrap this function to use Quantities instead: >>> from pint import UnitRegistry >>> ureg = UnitRegistry() + >>> Q_ = ureg.Quantity >>> def mypp_caveman(length): ... return pendulum_period(length.to(ureg.meter).magnitude) * ureg.second @@ -55,7 +56,7 @@ and: .. doctest:: >>> mypp_caveman(100 * ureg.centimeter) - + Pint provides a more convenient way to do this: @@ -71,7 +72,7 @@ Or in the decorator format: ... def mypp(length): ... return pendulum_period(length) >>> mypp(100 * ureg.centimeter) - + `wraps` takes 3 input arguments: @@ -94,7 +95,7 @@ the input arguments assigned to units must be a Quantities. .. doctest:: >>> mypp(1. * ureg.meter) - + >>> mypp(1.) Traceback (most recent call last): ... @@ -106,9 +107,9 @@ To enable using non-Quantity numerical values, set strict to False`. >>> mypp_ns = ureg.wraps(ureg.second, ureg.meter, False)(pendulum_period) >>> mypp_ns(1. * ureg.meter) - + >>> mypp_ns(1.) - + In this mode, the value is assumed to have the correct units. @@ -142,7 +143,9 @@ Or if the function has multiple outputs: If there are more return values than specified units, ``None`` is assumed for 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:: +airmass + +.. doctest:: @ureg.wraps(('deg', 'deg'), ('deg', 'deg', 'millibar', 'degC')) def solar_position(lat, lon, press, tamb, timestamp): @@ -166,18 +169,17 @@ arguments: ... d = .5 * g * t**2 ... t = sqrt(2 * d / g) ... """ - ... t = sqrt(2 * height / gravity) + ... t = math.sqrt(2 * height / gravity) ... if verbose: print(str(t) + " seconds to fall") ... return t ... >>> lunar_module_height = Q_(22, 'feet') + Q_(11, 'inches') >>> calculate_time_to_fall(lunar_module_height, verbose=True) 1.1939473204801092 seconds to fall - - >>> + >>> moon_gravity = Q_(1.625, 'm/s^2') - >>> tcalculate_time_to_fall(lunar_module_height, moon_gravity) - + >>> calculate_time_to_fall(lunar_module_height, gravity=moon_gravity) + Specifying relations between arguments @@ -199,6 +201,8 @@ has the unit of `x` squared (`A**2`) You can use more than one label: +.. doctest:: + >>> @ureg.wraps('=A**2*B', ('=A', '=A*B', '=B')) ... def some_function(x, y, z): ... pass diff --git a/pint/context.py b/pint/context.py index 6a54301c9..f82bb1397 100644 --- a/pint/context.py +++ b/pint/context.py @@ -63,22 +63,24 @@ class Context: ------- >>> from pint.util import UnitsContainer + >>> from pint import Context, UnitRegistry + >>> ureg = UnitRegistry() >>> timedim = UnitsContainer({'[time]': 1}) >>> spacedim = UnitsContainer({'[length]': 1}) - >>> def f(time): + >>> def time_to_len(ureg, time): ... 'Time to length converter' ... return 3. * time >>> c = Context() - >>> c.add_transformation(timedim, spacedim, f) - >>> c.transform(timedim, spacedim, 2) - 6 - >>> def f(time, n): + >>> c.add_transformation(timedim, spacedim, time_to_len) + >>> c.transform(timedim, spacedim, ureg, 2) + 6.0 + >>> def time_to_len_indexed(ureg, time, n=1): ... 'Time to length converter, n is the index of refraction of the material' ... return 3. * time / n - >>> c = Context(n=3) - >>> c.add_transformation(timedim, spacedim, f) - >>> c.transform(timedim, spacedim, 2) - 2 + >>> c = Context(defaults={'n':3}) + >>> c.add_transformation(timedim, spacedim, time_to_len_indexed) + >>> c.transform(timedim, spacedim, ureg, 2) + 2.0 >>> c.redefine("pound = 0.5 kg") """ diff --git a/pint/definitions.py b/pint/definitions.py index 338d1fc99..8b7e5817a 100644 --- a/pint/definitions.py +++ b/pint/definitions.py @@ -20,17 +20,17 @@ class PreprocessedDefinition( ): """Splits a definition into the constitutive parts. - A definition is given as a string with equalities in a single line. + A definition is given as a string with equalities in a single line:: ---------------> rhs - a = b = c = d = e - | | | -------> aliases (optional) - | | | - | | -----------> symbol (use "_" to - | | - | ---------------> value - | - -------------------> name + a = b = c = d = e + | | | -------> aliases (optional) + | | | + | | -----------> symbol (use "_" for no symbol) + | | + | ---------------> value + | + -------------------> name Attributes ---------- @@ -175,11 +175,12 @@ def __str__(self): class PrefixDefinition(Definition): - """Definition of a prefix. + """Definition of a prefix:: - - = [= ] [= ] [ = ] [...] + - = [= ] [= ] [ = ] [...] + + Example:: - Example: deca- = 1e+1 = da- = deka- """ @@ -205,11 +206,12 @@ def from_string(cls, definition, non_int_type=float): class UnitDefinition(Definition): - """Definition of a unit. + """Definition of a unit:: + + = [= ] [= ] [ = ] [...] - = [= ] [= ] [ = ] [...] + Example:: - Example: millennium = 1e3 * year = _ = millennia Parameters @@ -279,11 +281,12 @@ def from_string(cls, definition, non_int_type=float): class DimensionDefinition(Definition): - """Definition of a dimension. + """Definition of a dimension:: - [dimension name] = + [dimension name] = + + Example:: - Example: [density] = [mass] / [volume] """ @@ -323,11 +326,12 @@ def from_string(cls, definition, non_int_type=float): class AliasDefinition(Definition): - """Additional alias(es) for an already existing unit. + """Additional alias(es) for an already existing unit:: + + @alias = [ = ] [...] - @alias = [ = ] [...] + Example:: - Example: @alias meter = my_meter """ diff --git a/pint/quantity.py b/pint/quantity.py index c087b0cab..1f1816648 100644 --- a/pint/quantity.py +++ b/pint/quantity.py @@ -260,7 +260,10 @@ def __bytes__(self): return str(self).encode(locale.getpreferredencoding()) def __repr__(self): - return f"" + if isinstance(self._magnitude, float): + return f"" + else: + return f"" def __hash__(self): self_base = self.to_base_units() diff --git a/pint/registry.py b/pint/registry.py index bc946e45b..a05937671 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -1675,12 +1675,16 @@ def context(self, *names, **kwargs): Examples -------- - Context can be called by their name:: + Context can be called by their name: + >>> import pint + >>> ureg = pint.UnitRegistry() + >>> ureg.add_context(pint.Context('one')) + >>> ureg.add_context(pint.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 @@ -1690,13 +1694,13 @@ def context(self, *names, **kwargs): >>> 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 - 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 @@ -1736,9 +1740,9 @@ def with_context(self, name, **kwargs): Example ------- - >>> @ureg.with_context('sp') - ... def my_cool_fun(wavelenght): - ... print('This wavelength is equivalent to: %s', wavelength.to('terahertz')) + >>> @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/requirements_docs.txt b/requirements_docs.txt index 8bd0205ee..50e54ef8e 100644 --- a/requirements_docs.txt +++ b/requirements_docs.txt @@ -12,3 +12,4 @@ xarray sparse dask[complete] setuptools>=41.2 +Serialize