Obsah
1. Manipulace s veličinami a jednotkami v knihovně Astropy
4. Manipulace s veličinami a jednotkami: od knihovny Pint ke knihovně Astropy
5. Specifikace jednotky u definované či vypočtené hodnoty
6. Atributy s hodnotou, jednotkou a datovým typem
7. Aritmetické operace s dvojicí hodnot se stejnou veličinou
8. Výpočet, jehož výsledkem je odlišná veličina
10. Zjištění, na které jednotky lze výsledek převést
11. Alternativy k odvozeným jednotkám
13. Kontroly prováděné při převodu jednotek
14. Hodnoty s jednotkami a typové informace
16. Explicitní zápis typových informací
17. Jednotky hodnot uložených v n-dimenzionálních polích
18. Příloha: základní (pod)balíčky dostupné po instalaci Astropy
19. Repositář s demonstračními příklady
1. Manipulace s veličinami a jednotkami v knihovně Astropy
Na předchozí dva články Manipulace s jednotkami a veličinami: aby se nesčítaly hrušky s jablky a Kooperace mezi knihovnami Pint a SymPy při manipulaci s veličinami a jednotkami dnes navážeme. Ukážeme si totiž, jak je tato problematika řešena v rozsáhlé knihovně Astropy. Uvidíme, že základní myšlenka je sice prakticky totožná, ale možnosti poskytované knihovnou Astropy jsou kupodivu mnohem větší a taktéž jsou zaměřeny více prakticky.
2. Knihovna Astropy
Na projekt Astropy se sice můžeme dívat jako na jednu rozsáhlou knihovnu vytvořenou pro programovací jazyk Python, ve skutečnosti se však jedná o několik relativně samostatně využitelných balíčků, k nimž mohou být přidány další doplňující balíčky. Ovšem primární určení všech těchto balíčků je zřejmé – využívají se zejména v astronomii. Tento obor je tedy další oblastí, v níž se začal ve větší míře prosazovat programovací jazyk Python (ostatně už v roce 2012 byl tento jazyk preferován 42% dotázaných z oboru astronomie). Jak je v IT zvykem, díky této popularitě Pythonu začaly nekoordinovaně vznikat různé Pythonní balíčky řešící rozličné problémy z tohoto oboru. Projekt Astropy vznikl v roce 2011 a jeho hlavním cílem bylo sjednocení existující funkcionality do uceleného a dobře dokumentovaného balíčku, což se do značné míry podařilo (a je to jen dobře, protože se jedná o snadno nainstalovatelnou a použitelnou knihovnu).

Obrázek 1: Logo projektu Astropy.
3. Instalace knihovny Astropy
Instalaci knihovny Astropy lze realizovat různými způsoby. V komunitě se pro tento účel většinou používá Anaconda (opět odbočka: autorem Anacondy i NumPy je stejný vývojář Travis Oliphant), my ovšem pro účely dnešního článku zůstaneme u klasického pip. Na rozdíl od knihovny Pint, která neměla žádné závislosti, je tomu v případě Astropy jinak, což je ostatně patrné i ze zpráv vypisovaných v průběhu instalace:
$ pip3 install astropy
Instalace balíčků, na kterých Astropy přímo či tranzitivně závisí:
Defaulting to user installation because normal site-packages is not writeable
Collecting astropy
Downloading astropy-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (10.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.3/10.3 MB 7.1 MB/s eta 0:00:00
Requirement already satisfied: numpy<2,>=1.22 in ./.local/lib/python3.11/site-packages (from astropy) (1.26.2)
Collecting pyerfa>=2.0.1.1
Downloading pyerfa-2.0.1.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (738 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 738.7/738.7 kB 4.0 MB/s eta 0:00:00
Collecting astropy-iers-data>=0.2024.2.26.0.28.55
Downloading astropy_iers_data-0.2024.4.15.2.45.49-py3-none-any.whl (1.9 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.9/1.9 MB 7.9 MB/s eta 0:00:00
Requirement already satisfied: PyYAML>=3.13 in /usr/lib64/python3.11/site-packages (from astropy) (6.0)
Requirement already satisfied: packaging>=19.0 in ./.local/lib/python3.11/site-packages (from astropy) (23.2)
Installing collected packages: pyerfa, astropy-iers-data, astropy
Successfully installed astropy-6.0.1 astropy-iers-data-0.2024.4.15.2.45.49 pyerfa-2.0.1.4
Po proběhnutí instalace zkontrolujeme závislosti:
$ pip show astropy
Po zadání výše uvedeného příkazu by se měly vypsat podrobnější informace o balíčku, a to včetně jeho závislostí. Ty jsou uvedeny na řádku Requires:
Name: astropy Version: 6.0.1 Summary: Astronomy and astrophysics core library Home-page: Author: Author-email: The Astropy Developers <astropy.team@gmail.com> License: BSD-3-Clause Location: /home/ptisnovs/.local/lib/python3.11/site-packages Requires: astropy-iers-data, numpy, packaging, pyerfa, PyYAML Required-by:
4. Manipulace s veličinami a jednotkami: od knihovny Pint ke knihovně Astropy
V navazujících kapitolách použijeme podobně koncipované demonstrační příklady, jaké jsme si ukázali při popisu knihovny Pint, takže bude snadné si porovnat shodné vlastnosti i rozdíly mezi oběma knihovnami (alespoň co se týče využívání veličin a jednotek). Nejprve si tedy ukážeme způsob specifikace jednotek, poté si řekneme, jak se jednotky mění při provádění výpočtů, provedeme převody mezi jednotkami atd.
5. Specifikace jednotky u definované či vypočtené hodnoty
V dnešním prvním demonstračním příkladu je ukázáno, jakým způsobem se zapíše hodnota 10 sekund, což je, jak již víme (ze základní školy), numerická hodnota doplněná o jednotku. Podobně jako tomu bylo v případě knihoven Pint a SymPy, i zde se spojení bezrozměrné hodnoty s jednotkou provádí přes (přetíženou) operaci součinu:
from astropy import units as u t1 = 10 * u.second print(t1)
Výsledkem výše zmíněného součinu je objekt obsahující hodnotu i jednotku, což je ostatně patrné i z výpisu obsahu (hodnoty) objektu funkcí print:
10.0 s
6. Atributy s hodnotou, jednotkou a datovým typem
Objekt s (fyzikální) hodnotou obsahuje trojici důležitých atributů, které se jmenují value, unit a dtype. První atribut obsahuje numerickou hodnotu, druhý atribut jednotku a třetí datový typ:
from astropy import units as u t1 = 10 * u.second print(t1.value) print(t1.unit) print(t1.dtype)
Z výsledků je patrné, že datový typ odpovídá konvencím knihovny NumPy, což by ovšem nemělo být příliš překvapivé, protože tato knihovna tvoří základ celého balíčku Astropy:
10.0 s float64
7. Aritmetické operace s dvojicí hodnot se stejnou veličinou
V dalším demonstračním příkladu si ukážeme operaci, kterou jsme si již popisovali u knihovny Pint. Jedná se o operace s dvojicí časových údajů (tedy se stejnými veličinami, i když se jednotky mohou odlišovat). Na základě toho, jaká konkrétní aritmetická operace je provedena, bude výsledkem údaj s časovou jednotkou, s kvadrátem časové jednotky, s převrácenou časovou jednotkou nebo dokonce bezrozměrné číslo:
from astropy import units as u t1 = 10 * u.second t2 = 1 * u.minute t3 = 1 * u.second print(t1) print(t2) print(t1*t1) print(1/t1) print(t1+t2) print(t1-t2) print(t2/t1) print(t1/t3)
A takto vypadají výsledky. Povšimněte si, jak se zapisuje s-1, s2 atd.:
10.0 s 1.0 min 100.0 s2 0.1 1 / s 70.0 s -50.0 s 0.1 min / s 10.0
Předchozí příklad si ještě rozšiřme tak, aby se explicitně vypsaly jednotky výsledků a nikoli hodnoty společně s jednotkami:
from astropy import units as u t1 = 10 * u.second t2 = 1 * u.minute t3 = 1 * u.second print(t1.unit) print(t2.unit) print((t1*t1).unit) print((1/t1).unit) print((t1+t2).unit) print((t1-t2).unit) print((t2/t1).unit) print((t1/t3).unit)
Na první pohled to sice nemusí být patrné, ale poslední příkaz print vypsal pouze prázdný řádek, protože bezrozměrná hodnota nemá přiřazenou žádnou jednotku:
s min s2 1 / s s s min / s
8. Výpočet, jehož výsledkem je odlišná veličina
Pokusme se nyní provést nějaký triviální výpočet, například výpočet rychlosti z ujeté vzdálenosti a času. Jedná se o výpočet, u kterého nás bude zajímat, jaká jednotka (veličina) bude přiřazena k vypočtenému výsledku:
from astropy import units as u s = 100 * u.meter t = 20 * u.second print(s/t)
Výsledkem je v tomto případě podle očekávání rychlost pět metrů za sekundu:
5.0 m / s
Pro další rozšiřování si tento demonstrační příklad nepatrně upravíme tak, aby vypsal i veličinu, jejíž hodnotu vypisujeme:
from astropy import units as u
s = 100 * u.meter
t = 20 * u.second
v = s / t
print("v =", v)
Nyní je již výsledek konkrétnější a při výpisu většího množství výsledků i přehlednější:
v = 5.0 m / s
9. Výpočet zrychlení a síly
Nepatrnou úpravou vypočítáme kromě rychlosti i zrychlení, přičemž nás opět budou v první řadě zajímat jednotky výsledku, nikoli to, zda výpočet má přesný fyzikální význam (měli bychom totiž počítat buď derivaci, nebo změnu rychlosti za jednotku času, nikoli pouze dělit rychlost časem):
from astropy import units as u
s = 100 * u.meter
t = 20 * u.second
v = s / t
a = v / t
print("v =", v)
print("a =", a)
Z výsledků je patrné, že jsou korektní, a to jak z hlediska vypočtených hodnot, tak i jejich jednotek:
v = 5.0 m / s a = 0.25 m / s2
Opět se nyní na chvíli vraťme ke knihovně Pint, kde jsme si na základě zrychlení a hmotnosti tělesa vypočítali sílu, která způsobila ono zrychlení. Opět se jedná o běžné výpočty, pouze s hodnotami, k nimž byly doplněny jednotky:
from astropy import units as u
s = 100 * u.meter
t = 20 * u.second
m = 100 * u.kilogram
v = s / t
a = v / t
f = m * a
print("v =", v)
print("a =", a)
print("f =", f)
Z výsledků plyne, že jednotky jsou opět korektní (a čistě náhodou používáme základní jednotky, to ovšem ve skutečnosti není nutné):
v = 5.0 m / s a = 0.25 m / s2 f = 25.0 kg m / s2
10. Zjištění, na které jednotky lze výsledek převést
Velmi zajímavou a potenciálně užitečnou vlastností knihovny astropy.units je možnost zjištění, na jaké další jednotky je možné převést vybranou jednotku (ne ovšem hodnotu). Například si to můžeme ukázat u časové jednotky sekunda:
from astropy import units as u
t = u.second
for c in t.compose():
print(c)
Možné převody sekundy na další časové jednotky vypadá takto:
s 3.16881e-08 a 3.16881e-08 yr 8.2672e-07 fortnight 1.65344e-06 wk 1.15741e-05 d 1.16058e-05 sday 0.000277778 h 0.0166667 min
from astropy import units as u
t = u.fortnight
for c in t.compose():
print(c)
S výsledky:
fortnight 0.0383299 a 0.0383299 yr 2 wk 14 d 14.0383 sday 336 h 20160 min 1.2096e+06 s
11. Alternativy k odvozeným jednotkám
Zajímavější je situace u odvozených jednotek. Například se podívejme, jaké jsou alternativy k jednotce s-1:
from astropy import units as u
t = u.second ** -1
for c in t.compose():
print(c)
Výsledky:
Bq Hz 2.7027e-11 Ci
Pokračujme v pokusech dále; stále v oblasti časových jednotek a jednotek odvozených:
from astropy import units as u
t = u.second ** -2
for c in t.compose():
print(c)
Výsledky:
Bq / s Hz / s 1 / s2 2.7027e-11 Ci / s 100 Gal / m 2.75423e+22 AB / kg 1e+26 Jy / kg 3600 / min2 1.296e+07 / h2 7.42425e+09 / sday2 7.46496e+09 / d2 3.65783e+11 / wk2 1.46313e+12 / fortnight2 9.95882e+14 / a2 9.95882e+14 / yr2 100 % / s2
Podobným způsobem lze zjistit, že kg m / s odpovídá jednomu Netwonu:
from astropy import units as u
t = u.kilogram * u.meter / u.second ** 2
for c in t.compose():
print(c)
Výsledky:
N 100000 dyn
12. Převody mezi jednotkami
Nyní již tedy můžeme velmi snadno zjistit, na kterou jednotku lze nějakou hodnotu převést. Samotný převod se provádí s využitím metody nazvané jednoduše to. Této metodě je nutné předat jednotku, na kterou se má převod provést. V praxi je převod triviální, jak je to ostatně patrné z následujícího demonstračního příkladu:
from astropy import units as u f = 100 / u.second print(f) print(f.to(u.Hz))
Tento skript nejdříve vypíše hodnotu s původní jednotkou a poté výsledek převodu na kýženou jednotku:
100.0 1 / s 100.0 Hz
13. Kontroly prováděné při převodu jednotek
Samozřejmě se ovšem provádí kontroly, zda je zadaný převod jednotek korektní. Pokud se například pokusíme převést údaj o délce na Hertze (tj. na frekvenci), dojde po spuštění skriptu k vyhození výjimky:
from astropy import units as u l = 100 * u.nm print(l) print(l.to(u.Hz))
A tímto způsobem knihovna astropy.units zareaguje na nekorektní převody jednotek (důležitý je poslední řádek, na němž je přesně napsáno, o jaký problém se jedná):
100.0 nm
Traceback (most recent call last):
File "/home/ptisnovs/src/most-popular-python-libs/astropy/14_to.py", line 6, in <module>
print(l.to(u.Hz))
^^^^^^^^^^
File "/home/ptisnovs/.local/lib/python3.11/site-packages/astropy/units/quantity.py", line 943, in to
value = self._to_value(unit, equivalencies)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ptisnovs/.local/lib/python3.11/site-packages/astropy/units/quantity.py", line 896, in _to_value
return self.unit.to(
^^^^^^^^^^^^^
File "/home/ptisnovs/.local/lib/python3.11/site-packages/astropy/units/core.py", line 1196, in to
return self._get_converter(Unit(other), equivalencies)(value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ptisnovs/.local/lib/python3.11/site-packages/astropy/units/core.py", line 1125, in _get_converter
raise exc
File "/home/ptisnovs/.local/lib/python3.11/site-packages/astropy/units/core.py", line 1108, in _get_converter
return self._apply_equivalencies(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ptisnovs/.local/lib/python3.11/site-packages/astropy/units/core.py", line 1086, in _apply_equivalencies
raise UnitConversionError(f"{unit_str} and {other_str} are not convertible")
astropy.units.core.UnitConversionError: 'nm' (length) and 'Hz' (frequency) are not convertible
Ve skutečnosti však mezi délkou a frekvencí existuje přímý vztah, a to konkrétně v souvislosti s vlnovou délkou. Zde se ovšem musí brát do úvahy (fázová) rychlost. Pro převod mezi vlnovou délkou a frekvencí elektromagnetického vlnění (fázová rychlost odpovídá rychlosti světla) můžeme použít nepovinný parametr equivalencies předaný metodě to:
from astropy import units as u l = 100 * u.meter print(l) print(l.to(u.Hz, equivalencies=u.spectral()))
A takto vypadají vypočtené výsledky (druhá hodnota vám asi bude povědomá – numericky odpovídá rychlosti světla):
100.0 m 2997924.58 Hz
14. Hodnoty s jednotkami a typové informace
Při práci s hodnotami, k nimž jsou přiřazeny i jednotky, je mnohdy vhodné explicitně zadávat i typové informace. Podívejme se nejprve na příklad, ve kterém typové informace chybí. V příkladu je definována funkce pro výpočet rychlosti:
from astropy import units as u
def velocity(s, t):
return s/t
s = 100 * u.meter
t = 20 * u.second
v = velocity(s, t)
print(v)
Vzhledem k tomu, že je tato funkce volána s korektními parametry, bude i výsledek výpočtu odpovídat očekávání:
5.0 m / s
Ovšem nic uživatelům nezabraňuje ve volání funkce velocity s otočením parametrů:
from astropy import units as u
def velocity(s, t):
return s/t
s = 100 * u.meter
t = 20 * u.second
v = velocity(t, s)
print(v)
Výsledek v takovém případě pochopitelně nebude korektní, což je ostatně jasně patrné z výsledku zobrazeného po spuštění skriptu:
0.2 s / m
15. Deklarace datového typu
Knihovna Astropy ovšem umožňuje použít třídu nazvanou Quantity pro specifikaci datového typu. Podobně jako u dalších typových informací (typové nápovědy – type hints) se specifikace typu může zpřesnit zápisem jednotky do hranatých závorek. V následujícím příkladu jsou definovány tři proměnné, které obsahují přímo typy, konkrétně typy „délková jednotka metr“, „časová jednotka sekunda“ a „rychlost v metrech za sekundu“:
from astropy import units as u length = u.Quantity[u.meter] time = u.Quantity[u.second] velocity = u.Quantity[u.meter/u.second] print(length) print(time) print(velocity)
Po spuštění skriptu je z výpisu ihned zřejmé, že hodnotami jsou skutečně přímo typy představující fyzikální jednotky:
typing.Annotated[astropy.units.quantity.Quantity, Unit("m")]
typing.Annotated[astropy.units.quantity.Quantity, Unit("s")]
typing.Annotated[astropy.units.quantity.Quantity, Unit("m / s")]
Poměrně snadno můžeme nadeklarovat proměnnou s hodnotou a jednotkou přímo s využitím konstruktoru Quantity, což ovšem znamená, že se zápis odlišuje od zápisu v předchozím skriptu:
from astropy import units as u length = u.Quantity(1, u.meter) time = u.Quantity(2, u.second) velocity = u.Quantity(1/5, u.meter/u.second) print(length) print(time) print(velocity)
Výsledky:
1.0 m 2.0 s 0.2 m / s
16. Explicitní zápis typových informací
Nyní již máme k dispozici všechny potřebné znalosti nutné pro specifikaci informací o typech přímo v deklaraci funkce (parametry + návratové hodnoty). Tyto informace mohou využít integrovaná vývojová prostředí, popř. nástroje typu Pyright či Mypy pro kontrolu, zda je funkce volána s korektními argumenty:
from astropy import units as u
def velocity(s: u.Quantity[u.meter], t: u.Quantity[u.second]) -> u.Quantity[u.meter/u.second]:
return s/t
s = 100 * u.meter
t = 20 * u.second
v = velocity(s, t)
print(v)
Chování skriptu v runtime se ovšem nezmění, protože interpretr programovacího jazyka Python informace o typech ignoruje:
5.0 m / s
17. Jednotky hodnot uložených v n-dimenzionálních polích
Vzhledem k tomu, že knihovna Astropy do značné míry závisí na známé a často využívané knihovně NumPy, nabízí se otázka, jak vlastně uložit hodnoty s jednotkami do n-rozměrných polí. Ve skutečnosti je to v praxi velmi snadné, protože pole s hodnotami bez jednotek můžeme vynásobit jednotkou (tedy vlastně skalárem). V takovém případě se realizuje takzvaný broadcast, tj. skalár se nejprve rozšíří na pole o stejném tvaru, jaký má druhý operand a teprve poté se provede zapsaná operace prvek po prvku.
To si samozřejmě můžeme snadno ukázat. Nejprve pole a s bezrozměrnými hodnotami převedeme na nové pole obsahující časové údaje. A poté podílem (prvek po prvku) s polem s délkami vypočteme rychlosti. Přitom pole s délkami obsahuje pouze jeden prvek, takže i zde se provede broadcast:
import numpy as np
from astropy import units as u
a = np.array(range(10)) + 1
print("a = ", a)
t = a * u.second
print("t = ", t)
l = np.array(1.0) * u.meter
print("l = ", l)
v = l / t
print("v = ", v)
Výsledkem by mělo být pole s deseti rychlostmi (poslední dva řádky výpisu):
a = [ 1 2 3 4 5 6 7 8 9 10] t = [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] s l = 1.0 m v = [1. 0.5 0.33333333 0.25 0.2 0.16666667 0.14285714 0.125 0.11111111 0.1 ] m / s
A samozřejmě i zde platí, že některé operace mohou vést k výslednému poli obsahujícímu bezrozměrné hodnoty:
import numpy as np
from astropy import units as u
a = np.array(range(10)) + 1
print("a = ", a)
t = a * u.second
print("t = ", t)
d = t / t
print("d = ", d)
18. Příloha: základní (pod)balíčky dostupné po instalaci Astropy
Seznam všech standardních i doplňujících balíčků pro Astropy je dostupný na adrese https://www.astropy.org/affiliated/index.html. V dnešním článku se ovšem budeme zabývat jediným balíčkem s názvem astropy.units. Ovšem po instalaci Astopy je snadné zjistit, které (pod)balíčky vlastně obsahuje:
| table |
| stats |
| config |
| coordinates |
| wcs |
| visualization |
| nddata |
| samp |
| uncertainty |
| constants |
| io |
| cosmology |
| units |
| convolution |
| extern |
| modeling |
| time |
| utils |
| timeseries |
| tests |
19. Repositář s demonstračními příklady
Zdrojové kódy všech prozatím popsaných demonstračních příkladů určených pro programovací jazyk Python 3 byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/most-popular-python-libs.
Knihovna Pint
Knihovna SymPy kombinovaná s knihovnou Pint
Knihovna Astropy
20. Odkazy na Internetu
- Unit-aware arithmetic in Xarray, via pint
https://xarray.dev/blog/introducing-pint-xarray - Xarray: sémantické rozšíření n-rozměrných polí z knihovny NumPy
https://www.root.cz/clanky/xarray-semanticke-rozsireni-n-rozmernych-poli-z-knihovny-numpy/ - Xarray: sémantické rozšíření n-rozměrných polí z knihovny NumPy (dokončení)
https://www.root.cz/clanky/xarray-semanticke-rozsireni-n-rozmernych-poli-z-knihovny-numpy-dokonceni/ - Stránky projektu Astropy
https://www.astropy.org/ - Astropy na Wikipedii
https://en.wikipedia.org/wiki/Astropy - Astropy na GitHubu
https://github.com/astropy/astropy - Astropy: Getting started
https://docs.astropy.org/en/stable/index_getting_started.html - Units and Quantities
https://uomresearchit.github.io/programming_with_python/06-units_and_quantities/index.html - Mars Climate Orbiter
https://en.wikipedia.org/wiki/Mars_Climate_Orbiter - Derivative Calculator
https://www.derivative-calculator.net/ - Fyzikální veličina (Wikipedia)
https://cs.wikipedia.org/wiki/Fyzik%C3%A1ln%C3%AD_veli%C4%8Dina - Fyzikální jednotka (Wikipedia)
https://cs.wikipedia.org/wiki/Fyzik%C3%A1ln%C3%AD_jednotka - Soustava SI (Wikipedia)
https://cs.wikipedia.org/wiki/Soustava_SI - Dokumentace ke knihovně Pint
https://pint.readthedocs.io/en/stable/index.html - Knihovna astropy na PyPi
https://pypi.org/project/astropy/ - Knihovna Pint na PyPi
https://pypi.org/project/Pint/ - Repositář knihovny Pint
https://github.com/hgrecco/pint - Knihovna units na PyPi (nevyvíjený projekt)
https://pypi.org/project/units/ - Knihovna quantity na PyPi
https://pypi.org/project/quantity/ - Repositář s knihovnou quantity
https://github.com/mamrhein/quantity - SymPy
https://www.sympy.org/en/index.html - SymPy na PyPi
https://pypi.org/project/sympy/ - mpmath
https://mpmath.org/ - mpmath na PyPi
https://pypi.org/project/mpmath/ - Symbolic Maths in Python
https://alexandrugris.github.io/maths/2017/04/30/symbolic-maths-python.html - SymPy shell
https://live.sympy.org/ - Symbolic programming
https://en.wikipedia.org/wiki/Symbolic_programming - Symbolic language (programming)
https://en.wikipedia.org/wiki/Symbolic_language_(programming) - Computer algebra
https://en.wikipedia.org/wiki/Computer_algebra - Knihovna xarray-units na PyPi
https://pypi.org/project/xarray-units/ - Kawa: překvapivě silný a výkonný dialekt Scheme pro JVM
https://www.root.cz/clanky/kawa-prekvapive-silny-a-vykonny-dialekt-scheme-pro-jvm/ - Jazyk Kawa v ekosystému virtuálního stroje Javy
https://www.root.cz/clanky/jazyk-kawa-v-ekosystemu-virtualniho-stroje-javy/ - Zpracování vektorů, matic a N-rozměrných polí v programovacím jazyku Kawa
https://www.root.cz/clanky/zpracovani-vektoru-matic-a-n-rozmernych-poli-v-programovacim-jazyku-kawa/ - Kawa: Compiling Scheme to Java
https://www.mit.edu/afs.new/sipb/project/kawa/doc/kawa-tour.html - Kawa in Languages shootout
http://per.bothner.com/blog/2010/Kawa-in-shootout/ - Kawa 2.0 Supports Scheme R7RS
https://developers.slashdot.org/story/14/12/13/2259225/kawa-20-supports-scheme-r7rs/ - Kawa — fast scripting on the Java platform
https://lwn.net/Articles/623349/