Metadata-Version: 2.1
Name: qnit
Version: 0.4.0
Summary: A Python library for object-oriented parameters, physical quantities and units with a strong support for typing.
Home-page: https://gitlab.com/c4dht/qnit
License: GNU AGPLv3
Author: Paul Kernstock
Author-email: paul.kernstock@posteo.de
Maintainer: Paul Kernstock
Maintainer-email: paul.kernstock@posteo.de
Requires-Python: >=3.9,<3.13
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Dist: numpy (>=1,<2)
Requires-Dist: pandas (>=2,<3)
Requires-Dist: pandas-stubs (>=2,<3)
Requires-Dist: pint[pandas] (>=0.22,<0.23)
Requires-Dist: scipy (>=1,<2)
Project-URL: Repository, https://gitlab.com/c4dht/qnit
Description-Content-Type: text/markdown

# qnit

[kjuː.nɪt]

A Python library for object-oriented parameters, physical quantities and units with a strong support for typing.

This library heavily builds upon [Pint](https://github.com/hgrecco/pint) and [Pint-Pandas](https://github.com/hgrecco/pint-pandas).

This project is currently under heavy development. Expect API changes.

## Feature Overview

* [x] `Quantity`s you can `set` with magnitude and units, convert to other units, get magnitudes or work with the underlying `pint` quantity.
* [x] `Parameter`s with optional quantity values which can be worked with accordingly.
* [x] Quantities and Parameters with 1-dimensional array values.
* [x] Easily extensible library of physical quantities, specifying:
  * Units type (e.g. Mass)
  * Internal Units (to be used for conversion at user interfaces, e.g. SI units, e.g. kilograms)
  * Default display units (to be used in user frontends, e.g. grams)
  * Available units (given as `UnitCollection`s for the above units type)
* [x] Support for `Quantity`s and `Parameter`s as `dataclass` fields.
* [x] Heavy support for typing:
  * Specify a quantity's units type and get type hints when you're about to do something wrong, converting an `Energy` quantity to `kg` units.
  * Specify a parameter's data type and be hinted when you're about to set an incompatible value

## Getting Started

### Install

Install qnit from the PyPI in your virtual environment:

```bash
$ python -m pip install qnit
```

### Usage

```python
from qnit import Quantity, quantity_types, unit_collections, unit_types, ureg

# Create a mass quantity and set its value
mass: Quantity[unit_types.MassUnit] = Quantity(
  quantity_type=quantity_types.Mass,
  description="A mass quantity.",
)
mass.set(magnitude=42, units=unit_collections.Mass.kg)

# Play with the underlying `pint` quantity.
mass.pint_quantity.to(unit_collections.Mass.g)
mass.pint_quantity.to('g')
# <Quantity(42000.0, 'gram')>

mass.pint_quantity.m_as(unit_collections.Mass.g)
mass.pint_quantity.m_as('g')
# 42000.0

mass.pint_quantity + 4 * ureg.kg
# <Quantity(46.0, 'kilogram')>

# Get magnitudes as different units
mass.magnitude(units=unit_collections.Mass.t)
# 0.042
mass.internal_magnitude
# 42.0
mass.display_magnitude
# 42.0
```

Use mypy or your favorite IDE to warn you about units related errors before runtime

```python hl_lines="0"
from qnit import Quantity, quantity_types, unit_collections, unit_types

mass: Quantity[unit_types.MassUnit] = Quantity(
  quantity_type=quantity_types.Mass,
  description="A mass quantity.",
  magnitude=42,
  units=unit_collections.Mass.kg,
)
mass.magnitude(unit_collections.Energy.kWh)
# Warning here: Expected type 'MassUnit', got 'EnergyUnit' instead 
```

### Development

To set up a development environment you need a virtual environment and [Poetry](https://python-poetry.org/docs/#installation), for example:

```shell
POETRY_VIRTUALENVS_IN_PROJECT=1 poetry install
```

#### Testing and Type Checks

Tests for `qnit` are written with `pytest`. You can run the test suite with

```shell
pytest tests
```

Both `qnit` itself as well as its tests are to be properly typed. To check this you can run

```shell
mypy src
mypy tests
```

You can also run the test suite in all supported Python environments together with the type checks using [tox](https://tox.wiki/en/4.11.4/installation.html):

```shell
tox run
```

For this to work, you should have all supported Python versions installed in your operating system, e.g. by using [pyenv](https://github.com/pyenv/pyenv).

