Hlavní navigace

Manipulace s jednotkami a veličinami: aby se nesčítaly hrušky s jablky

16. 4. 2024
Doba čtení: 30 minut

Sdílet

 Autor: Root.cz s využitím DALL-E
Při vývoji algoritmů s fyzikálními i jinými výpočty se používají hodnoty s různými jednotkami, které odpovídají různým veličinám. Programovací jazyky s jednotkami přímo nepracují, takže je nutné využít podpůrné knihovny.

Obsah

1. Práce s jednotkami a veličinami: aby se nesčítaly hrušky s jablky

2. Instalace knihovny Pint

3. Základní práce s jednotkami

4. Operace s hodnotami s veličinami

5. Výpočty s různými veličinami

6. Nekorektní kombinace veličin

7. Konverze jednotek

8. Plocha a rychlost

9. Zrychlení a síla

10. Explicitní zobrazení jednotek a veličin

11. Prefixy (předpony) jednotek

12. Binární prefixy, převody bajtů na bity

13. Práce s úhly

14. Redukce jednotek

15. Převod na základní jednotky

16. Formátování hodnot s jednotkami

17. Příloha 1: výpis všech jednotek nabízených knihovnou Pint

18. Příloha 2: podpora pro práci s jednotkami v jazyku Kawa

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Práce s jednotkami a veličinami: aby se nesčítaly hrušky s jablky

V mnoha aplikacích a informačních systémech se provádí jednodušší i složitější výpočty. A právě při vývoji algoritmů, které výpočty provádí, se používají hodnoty s různými jednotkami (metr, sekunda, Kč, …), které odpovídají různým veličinám (délka, čas, měna atd.). Nabízí se tedy otázka, jakým způsobem dokáže programovací jazyk zajistit, aby se „nesčítaly hrušky s jablky“, tj. aby se při výpočtech používaly proměnné a konstanty se správnou veličinou. Příkladem může být výpočet rychlosti ze dvou hodnot představujících odlišné veličiny: vzdálenosti a času.

Tento problém se mnohdy na úrovni programovacího jazyka vůbec neřeší, protože informace o použité jednotce nebývá součástí informace o datovém typu (hodnoty či proměnné – podle toho, zda je jazyk typovaný staticky či dynamicky). Jinými slovy pouze například víme, že proměnná obsahuje hodnotu typu float, ale již nevíme, zda tato hodnota představuje vzdálenost v metrech, čas v sekundách, čas v rocích, teplotu apod. Samozřejmě je možné v objektově orientovaných jazycích namísto běžných hodnot používat pouze objekty různých typů, to však většinou vyžaduje explicitně naprogramovat všechny možné kombinace operací (tedy že můžeme sčítat délky, že výsledkem podílu délky a času bude rychlost atd.).

Alternativní způsob, jak pracovat s hodnotami, ke kterým jsou nějakým způsobem přiřazeny jednotky, spočívá ve využití knihoven, které tuto funkcionalitu již poskytují. Předností těchto knihoven bývá to, že již obsahují mnoho předdefinovaných jednotek, pravidla pro operace s hodnotami s různými jednotkami (viz již výše zmíněný podíl vzdálenosti a času atd.) a taktéž většinou možnost převodu mezi jednotkami (z milimetrů na palce, ze sekund na hodiny, mezi různými variantami specifikace úhlů či teploty…). Pro programovací jazyk Python takových knihoven existuje větší množství. V dnešním článku si popíšeme základní vlastnosti knihovny nazvané Pint (což je mimochodem taktéž označení jednotky „pinta“ pro veličinu „objem“), ovšem v navazujících textech se seznámíme i s některými dalšími podobně koncipovanými knihovnami.

2. Instalace knihovny Pint

Instalace knihovny Pint je velmi snadná, protože tato knihovna je dostupná přes PyPi a navíc nevyžaduje žádné další závislosti. Instalaci tedy provedeme standardním nástrojem pip pro právě přihlášeného uživatele:

$ pip3 install --user pint

Ze zpráv vypisovaných v průběhu instalace knihovny Pint je patrné, že se skutečně neinstalují žádné další tranzitivní závislosti:

Collecting pint
  Downloading Pint-0.23-py3-none-any.whl (305 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 305.0/305.0 kB 2.1 MB/s eta 0:00:00
Requirement already satisfied: typing-extensions in /usr/local/lib/python3.11/site-packages (from pint) (4.8.0)
Installing collected packages: pint
Successfully installed pint-0.23

Otestování, že je možné knihovnu naimportovat:

$ python3
 
>>> import pint
>>> help(pint)
 
Help on package pint:
 
NAME
    pint
 
DESCRIPTION
    pint
    ~~~~
 
    Pint is Python module/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.
 
    :copyright: 2016 by Pint Authors, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.

3. Základní práce s jednotkami

Podívejme se nyní na zcela základní možnosti, která nám knihovna Pint poskytuje. V prvním příkladu nadeklarujeme novou proměnnou nazvanou t1, která obsahuje hodnotu „10 sekund“. Nejde tedy o pouhé bezrozměrné číslo 10, ale k číslu je přiřazena i jednotka:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t1 = 10 * ureg.second
 
print(t1)

Výsledek je zobrazen ve formě hodnoty + jednotky:

10 second

Zobrazit si můžeme i příslušnou veličinu a to přečtením atributu dimensionality:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t1 = 10 * ureg.second
 
print(t1.dimensionality)

Opět se podívejme na výsledek:

[time]

4. Operace s hodnotami s veličinami

Samozřejmě je umožněno, aby se s hodnotami, ke kterým jsou přiřazeny veličiny, prováděly obvyklé operace. Vyzkoušejme si například operace prováděné s dvojicí časových údajů:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t1 = 10 * ureg.second
t2 = 1 * ureg.minute
 
print(t1)
print(t2)
print(t1*t1)
print(1/t1)
print(t1+t2)
print(t1-t2)
print(t2/t1)

Výsledky:

10 second
1 minute
100 second ** 2
0.1 / second
70 second
-50 second
0.1 minute / second
Poznámka: poslední výsledek je ve skutečnosti bezrozměrnou hodnotou. K této problematice se ještě vrátíme.

A opět je možné si u všech výsledků zobrazit příslušnou veličinu:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t1 = 10 * ureg.second
t2 = 1 * ureg.minute
 
x = t1*t1
y = 1/t1
z = t1 + t2
w = t1/t2
 
print(x.dimensionality)
print(y.dimensionality)
print(z.dimensionality)
print(w.dimensionality)

Nyní je již korektně uvedeno, že poslední hodnota je bezrozměrná:

[time] ** 2
1 / [time]
[time]
dimensionless

5. Výpočty s různými veličinami

Prozatím jsme výpočty prováděli pouze s dvojicí časových údajů nebo bezrozměrné hodnoty a časového údaje. Pochopitelně však můžeme ve výpočtu použít i rozdílné veličiny. Asi nejjednodušším případem je výpočet rychlosti na základě zadané vzdálenosti a času:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
s = 100 * ureg.meter
t = 20 * ureg.second
 
print(s/t)

Vypočtený výsledek bude mít korektní hodnotu i jednotku:

5.0 meter / second

A opět si můžeme nechat odvodit i veličinu výsledku:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
s = 100 * ureg.meter
t = 20 * ureg.second
 
v = s / t
print(v.dimensionality)

Výsledek by měl v tomto případě vypadat následovně:

[length] / [time]

6. Nekorektní kombinace veličin

Mnohé kombinace veličin nejsou korektní – jednalo by se totiž o ono pověstné sčítání hrušek s jablky. Zkusme například sečíst 10 sekund s jedním metrem:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
a = 10 * ureg.second
b = 1 * ureg.meter
 
c = a + b
 
print(a.dimensionality)
print(b.dimensionality)
print(c.dimensionality)

Tento skript skončí chybou, protože při sčítání je vyhozena výjimka typu DimensionalityError:

  File "07_wrong_op.py", line 8, in <module>
    c = a + b
  File "/home/ptisnovs/.local/lib/python3.11/site-packages/pint/facets/plain/quantity.py", line 1188, in __add__
    return self._add_sub(other, operator.add)
  File "/home/ptisnovs/.local/lib/python3.11/site-packages/pint/facets/plain/quantity.py", line 108, in wrapped
    return f(self, *args, **kwargs)
  File "/home/ptisnovs/.local/lib/python3.11/site-packages/pint/facets/plain/quantity.py", line 1090, in _add_sub
    raise DimensionalityError(
pint.errors.DimensionalityError: Cannot convert from 'second' ([time]) to 'meter' ([length])

7. Konverze jednotek

Knihovna Pint podporuje i konverze jednotek. Tato operace se pochopitelně provádí pro jednotky stejné veličiny a realizuje se metodou nazvanou to, které se předá kýžená jednotka. Je to vlastně velmi jednoduché:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t1 = 1800 * ureg.second
t2 = t1.to(ureg.minute)
t3 = t1.to(ureg.hour)
 
print(t1, t1.dimensionality)
print(t2, t2.dimensionality)
print(t3, t3.dimensionality)

Výsledkem bude stejná hodnota, ovšem pokaždé reprezentovaná odlišnými jednotkami:

1800 second [time]
30.0 minute [time]
0.5 hour [time]

Nejvíce jednotek nalezneme u veličiny délka (a možná objem), takže si to vyzkoušejme:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
s1 = 1000 * ureg.meter
s2 = s1.to(ureg.millimetre)
s3 = s1.to(ureg.nautical_mile)
s4 = s1.to(ureg.inch)
s5 = s1.to(ureg.ly)
 
print(s1, s1.dimensionality)
print(s2, s2.dimensionality)
print(s3, s3.dimensionality)
print(s4, s4.dimensionality)
print(s5, s5.dimensionality)

Výsledky:

1000000.0 millimeter [length]
0.5399568034557236 nautical_mile [length]
39370.07874015748 inch [length]
1.0570008340246153e-13 light_year [length]

8. Plocha a rychlost

V praxi se poměrně často setkáme s plošnou mírou, popř. s objemem. Hodnoty tohoto typu lze získat snadno, například vynásobením dvou délek (plocha) či tří délek (objem) atd. A knihovna Pint obsahuje podporu pro většinu plošných a objemových jednotek, včetně (u plochy) arů a hektarů či u objemu například oné pinty, která dala knihovně jméno. Tyto jednotky lze použít i pro převody tak, jak je to ukázáno v dalším demonstračním příkladu:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
s1 = 100 * ureg.meter
a1 = s1*s1
a2 = a1.to(ureg.are)
a3 = a1.to(ureg.hectare)
 
print(s1, s1.dimensionality)
print(a1, a1.dimensionality)
print(a2, a2.dimensionality)
print(a3, a3.dimensionality)

Po spuštění se nejdříve vypíše hodnota reprezentující délku a poté tři hodnoty reprezentující plochu, pokaždé ovšem popsanou odlišnou jednotkou:

100 meter [length]
10000 meter ** 2 [length] ** 2
100.0 are [length] ** 2
1.0 hectare [length] ** 2

Podobně lze pracovat s rychlostí. Tu je možné získat například podílem délky (přesněji řečeno vzdálenosti) a času. A opět jsou k dispozici různé jednotky rychlosti, včetně jejího vyjádření v uzlech (knot):

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
s = 1 * ureg.mile
t = 1 * ureg.hour
v = s/t
v2 = v.to(ureg.kilometer_per_hour)
v3 = v.to(ureg.meter_per_second)
v4 = v.to(ureg.knot)
 
print(v)
print(v2)
print(v3)
print(v4)

Výsledky – stejná rychlost, pokaždé ovšem vypsaná s využitím odlišné jednotky:

1.0 mile / hour
1.609344 kilometer_per_hour
0.44704000000000005 meter_per_second
0.868976241900648 knot

9. Zrychlení a síla

Podobně se můžeme setkat se zrychlením, které je typicky vyjádřeno v jednotce metry za sekundu2:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t = 1 * ureg.second
s = 100 * ureg.meter
v = s/t
a = v/t
 
print(t)
print(v)
print(a)

Takto vypadají výsledky zobrazené po spuštění skriptu:

1 second
100.0 meter / second
100.0 meter / second ** 2

Při znalosti zrychlení (nějaké hmoty) a hmotnosti lze vypočítat sílu (z čehož si můžeme snadno odvodit i použitou jednotku). Výpočet může vypadat následovně:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
m = 1.5 * ureg.kilogram
t = 1 * ureg.second
s = 100 * ureg.meter
v = s/t
a = v/t
f = m*a
 
print(m)
print(t)
print(v)
print(a)
print(f)

Opět se podívejme na výsledky, které se vypíšou po spuštění tohoto demonstračního příkladu:

1.5 kilogram
1 second
100.0 meter / second
100.0 meter / second ** 2
150.0 kilogram * meter / second ** 2

Ovšem můžeme též zapsat sílu s využitím jednotky N (Newton) a vypočítat energii:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
f1 = 10 * ureg.newton
f2 = 20 * ureg.newton
f3 = f1 + f2
l = 100 * ureg.meter
e = f3 * l
 
print(f1)
print(f2)
print(f3)
print(e)

S výsledky:

10 newton
20 newton
30 newton
3000 meter * newton

10. Explicitní zobrazení jednotek a veličin

U každé hodnoty lze přečíst jak její veličinu, tak i jednotku. K tomuto účelu slouží atributy nazvané units a dimensionality (ten již známe). Otestujme si tedy, jaké veličiny a jednotky získáme pro všechny hodnoty použité při výpočtu síly, která působí na těleso určité hmotnosti a tím ho urychluje:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
m = 1.5 * ureg.kilogram
t = 1 * ureg.second
s = 100 * ureg.meter
v = s/t
a = v/t
f = m*a
 
print(m.units, "\n", m.dimensionality, "\n")
print(t.units, "\n", t.dimensionality, "\n")
print(v.units, "\n", v.dimensionality, "\n")
print(a.units, "\n", a.dimensionality, "\n")
print(f.units, "\n", f.dimensionality, "\n")

Po spuštění tohoto skriptu získáme následující pětici jednotek a veličin:

kilogram
 [mass]
 
second
 [time]
 
meter / second
 [length] / [time]
 
meter / second ** 2
 [length] / [time] ** 2
 
kilogram * meter / second ** 2
 [length] * [mass] / [time] ** 2
Poznámka: operátor ** má větší prioritu než podíl, takže meter/second**2 značí meter/second,2.

11. Prefixy (předpony) jednotek

U všech jednotek lze zapisovat i prefixy, resp. předpony, ať již se jedná o prefixy definované v SI (kilo-, mega-, mili-, mikro-) tak i například prefixy deci- či deca-. Podívejme se nejdříve na použití prefixů společně s jednotkou gram:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
m1 = 1.5 * ureg.gram
m2 = 1.5 * ureg.kilogram
m3 = 1.5 * ureg.milligram
m4 = 1.5 * ureg.decigram
m5 = 1.5 * ureg.decagram
m6 = 1.5 * ureg.microgram
 
print(m1)
print(m2)
print(m3)
print(m4)
print(m5)
print(m6)
 
print()
 
print(m1.to(ureg.gram))
print(m2.to(ureg.gram))
print(m3.to(ureg.gram))
print(m4.to(ureg.gram))
print(m5.to(ureg.gram))
print(m6.to(ureg.gram))

Tento skript nejprve vypíše všechny váhy s původními jednotkami s prefixy a posléze stejnou hodnotu, ovšem převedenou na gramy:

1.5 gram
1.5 kilogram
1.5 milligram
1.5 decigram
1.5 decagram
1.5 microgram
 
1.5 gram
1500.0 gram
0.0015 gram
0.15000000000000002 gram
15.0 gram
1.5e-06 gram

Podobně je možné použít předpony „směrem dolů“, což si pro změnu ukážeme na časové jednotce sekunda (poznámka: přiznám se, že prefixy za femto- pro mě byly novinkou):

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
t1 = 1 * ureg.second
t2 = 1 * ureg.millisecond
t3 = 1 * ureg.microsecond
t4 = 1 * ureg.nanosecond
t5 = 1 * ureg.picosecond
t6 = 1 * ureg.femtosecond
t7 = 1 * ureg.attosecond
t8 = 1 * ureg.zeptosecond
t9 = 1 * ureg.yoctosecond
t10 = 1 * ureg.rontosecond
t11 = 1 * ureg.quectosecond
 
print(t1)
print(t2)
print(t3)
print(t4)
print(t5)
print(t6)
print(t7)
print(t8)
print(t9)
print(t10)
print(t11)
 
print()
 
print(t1.to(ureg.second))
print(t2.to(ureg.second))
print(t3.to(ureg.second))
print(t4.to(ureg.second))
print(t5.to(ureg.second))
print(t6.to(ureg.second))
print(t7.to(ureg.second))
print(t8.to(ureg.second))
print(t9.to(ureg.second))
print(t10.to(ureg.second))
print(t11.to(ureg.second))

Tento skript opět nejdříve vypíše původní hodnoty a posléze tyto hodnoty převede na sekundy:

1 second
1 millisecond
1 microsecond
1 nanosecond
1 picosecond
1 femtosecond
1 attosecond
1 zeptosecond
1 yoctosecond
1 rontosecond
1 quectosecond
 
1 second
0.001 second
1e-06 second
1e-09 second
1e-12 second
1e-15 second
1e-18 second
1e-21 second
1e-24 second
1e-27 second
1e-30 second

Následují SI předpony „směrem nahoru“ (opět se přiznám, že předpony uvedené po prefixu exa- pro mě byly novinkou):

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
p1 = 1 * ureg.watt
p2 = 1 * ureg.kilowatt
p3 = 1 * ureg.megawatt
p4 = 1 * ureg.gigawatt
p5 = 1 * ureg.terawatt
p6 = 1 * ureg.petawatt
p7 = 1 * ureg.exawatt
p8 = 1 * ureg.zettawatt
p9 = 1 * ureg.yottawatt
p10 = 1 * ureg.ronnawatt
p11 = 1 * ureg.quettawatt
 
print(p1)
print(p2)
print(p3)
print(p4)
print(p5)
print(p6)
print(p7)
print(p8)
print(p9)
print(p10)
print(p11)
 
print()
 
print(p1.to(ureg.watt))
print(p2.to(ureg.watt))
print(p3.to(ureg.watt))
print(p4.to(ureg.watt))
print(p5.to(ureg.watt))
print(p6.to(ureg.watt))
print(p7.to(ureg.watt))
print(p8.to(ureg.watt))
print(p9.to(ureg.watt))
print(p10.to(ureg.watt))
print(p11.to(ureg.watt))

Výsledky:

1 watt
1 kilowatt
1 megawatt
1 gigawatt
1 terawatt
1 petawatt
1 exawatt
1 zettawatt
1 yottawatt
1 ronnawatt
1 quettawatt
 
1 watt
1000.0 watt
1000000.0 watt
1000000000.0 watt
1000000000000.0 watt
1000000000000000.0 watt
1e+18 watt
1e+21 watt
1e+24 watt
1e+27 watt
1.0000000000000002e+30 watt

12. Binární prefixy, převody bajtů na bity

Kromě desítkových předpon popsaných v předchozí kapitole nalezneme v knihovně Pint i binární předpony. Minimálně první tři až čtyři z těchto předpon asi není zapotřebí čtenářům Roota dopodrobna představovat, takže si hned ukažme jejich použití:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
c1 = 1 * ureg.byte
c2 = 1 * ureg.kibibyte
c3 = 1 * ureg.mebibyte
c4 = 1 * ureg.gibibyte
c5 = 1 * ureg.tebibyte
c6 = 1 * ureg.pebibyte
c7 = 1 * ureg.exbibyte
c8 = 1 * ureg.zebibyte
c9 = 1 * ureg.yobibyte
 
print(c1)
print(c2)
print(c3)
print(c4)
print(c5)
print(c6)
print(c7)
print(c8)
print(c9)
 
print()
 
print(c1.to(ureg.byte))
print(c2.to(ureg.byte))
print(c3.to(ureg.byte))
print(c4.to(ureg.byte))
print(c5.to(ureg.byte))
print(c6.to(ureg.byte))
print(c7.to(ureg.byte))
print(c8.to(ureg.byte))
print(c9.to(ureg.byte))

Ze zobrazených výsledků je patrné, že každá další předpona znamená zvýšení hodnoty 1024× a nikoli 1000×:

1 byte
1 kibibyte
1 mebibyte
1 gibibyte
1 tebibyte
1 pebibyte
1 exbibyte
1 zebibyte
1 yobibyte
 
1 byte
1024.0 byte
1048576.0 byte
1073741824.0 byte
1099511627776.0 byte
1125899906842624.0 byte
1.152921504606847e+18 byte
1.1805916207174113e+21 byte
1.2089258196146292e+24 byte

S binárními předponami jsou spojeny jak jednotky bajt, tak i a bit, takže si ještě pro úplnost ukažme převody míry informace reprezentované v bajtech na bity:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
c1 = 1 * ureg.byte
c2 = 1 * ureg.kibibyte
c3 = 1 * ureg.mebibyte
c4 = 1 * ureg.gibibyte
c5 = 1 * ureg.tebibyte
c6 = 1 * ureg.pebibyte
c7 = 1 * ureg.exbibyte
c8 = 1 * ureg.zebibyte
c9 = 1 * ureg.yobibyte
 
print(c1)
print(c2)
print(c3)
print(c4)
print(c5)
print(c6)
print(c7)
print(c8)
print(c9)
 
print()
 
print(c1.to(ureg.bit))
print(c2.to(ureg.bit))
print(c3.to(ureg.bit))
print(c4.to(ureg.bit))
print(c5.to(ureg.bit))
print(c6.to(ureg.bit))
print(c7.to(ureg.bit))
print(c8.to(ureg.bit))
print(c9.to(ureg.bit))

A takto vypadají výsledky (oproti předchozímu skriptu jsou vynásobeny osmi):

1 byte
1 kibibyte
1 mebibyte
1 gibibyte
1 tebibyte
1 pebibyte
1 exbibyte
1 zebibyte
1 yobibyte
 
8 bit
8192 bit
8388608 bit
8589934592 bit
8796093022208 bit
9007199254740992 bit
9223372036854775808 bit
9444732965739290427392 bit
9671406556917033397649408 bit

13. Práce s úhly

Ještě si pro úplnost vyzkoušíme práci s úhly, protože i v této oblasti existuje vetší množství více či méně užitečných jednotek. Poměrně zajímavou jednotkou je „turn(s)“, přičemž jeden turn (jedno otočení) odpovídá 360°. A opět je pochopitelně možné všechny úhlové jednotky převádět například na stupně, radiány atd. tak, jak je ukázáno na dalším příkladu:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
a = 0.5 * ureg.turns
 
print(a)
print(a.to(ureg.degrees))
print(a.to(ureg.radians))
print(a.to(ureg.arcminute))

Výsledky pro vstupní úhel odpovídající polovině otáčky:

0.5 turn
180.0 degree
3.141592653589793 radian
10799.999999999998 arcminute

14. Redukce jednotek

Knihovna Pint podporuje i takzvanou redukci (zjednodušení) jednotek. Při některých výpočtech totiž například výsledek může mít jednotku odpovídající m3/hektar, což je vlastně podíl objemové a plošné veličiny. Tento podíl lze zkrátit na délkovou veličinu. A tuto redukci, resp. zjednodušení, do jisté míry zajišťuje metoda nazvaná to_reduced_units, i když z výsledků dalšího příkladu je patrné, že mnohem čitelnější výsledek získáme explicitním převodem na zvolenou délkovou jednotku (například na milimetry):

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
l = 1.5 * ureg.meter
s = l * l
v = s * l
d = v / (10 * ureg.hectare)
 
print(l)
print(s)
print(v)
print(d)
print(d.to_reduced_units())
print(d.to(ureg.millimeter))

Tento skript po svém spuštění nejdříve vypíše délku, dále vypočtenou plochu, vypočtený objem a poté hodnotu d odpovídající výšce (hloubce?) vody, která naprší na jednotku plochy:

1.5 meter
2.25 meter ** 2
3.375 meter ** 3
0.3375 meter ** 3 / hectare
3.375e-07 hectare ** 0.5
0.03375 millimeter

15. Převod na základní jednotky

Předposlední vlastností knihovny Pint, se kterou se dnes seznámíme, je podpora převodu hodnoty s jakoukoli jednotkou na základní jednotku dané veličiny. Pokusme se například nepatrně upravit skript z předchozí kapitoly takovým způsobem, aby se výsledná výška (hloubka) hladiny vody převedla na základní délkovou (SI) jednotku, tedy na metry:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
l = 1.5 * ureg.meter
s = l * l
v = s * l
d = v / (10 * ureg.hectare)
 
print(l)
print(s)
print(v)
print(d)
print(d.to_base_units())

Na posledním řádku výpisu je patrné, že se tento převod skutečně provedl:

1.5 meter
2.25 meter ** 2
3.375 meter ** 3
0.3375 meter ** 3 / hectare
3.375000000000001e-05 meter

Podobně například můžeme převést rychlost vypočtenou v jednotce „světelný rok/rok“ (světelný rok je pochopitelně vzdálenost, ne čas) na hodnotu reprezentovanou v metrech za sekundu, což je pro tuto veličinu základní jednotka:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
s = 4.0 * ureg.ly
t = 10000 * ureg.year
v = s / t
 
print(s)
print(t)
print(v)
print(v.to_base_units())

Výsledek 0,0004 světelného roku za rok je převeden na metry za sekundu:

4.0 light_year
10000 year
0.0004 light_year / year
119916.9832 meter / second

A konečně se podívejme na převod hodnoty reprezentující energii na její základní jednotku:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
f1 = 10 * ureg.newton
f2 = 20 * ureg.newton
f3 = f1 + f2
l = 100 * ureg.meter
e = f3 * l
 
print(f1)
print(f2)
print(f3)
print(e.to(ureg.joule))
print(e.to_base_units())

Takto vypadá výsledek:

10 newton
20 newton
30 newton
3000.0 joule
3000.0 kilogram * meter ** 2 / second ** 2

16. Formátování hodnot s jednotkami

Dostáváme se k poslední operaci, kterou si v dnešním článku popíšeme. Ukažme si, jak knihovna Pint podporuje naformátovaný výstup. Použijeme přitom hodnotu představující vypočtený tlak, přičemž veličinou je v tomto případě kg/m/s2. Formátovaný výstup bude proveden do HTML formátu a taktéž do formátu (La)TeXu:

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
m = 1.5 * ureg.kilogram
t = 1 * ureg.second
s = 100 * ureg.meter
v = s/t
a = v/t
f = m*a
 
area = 10 * ureg.meter * ureg.meter
 
pressure = f / area
 
print(f)
print(f"{f:H}")
print(f"{f:L}")
 
print(pressure)
print(f"{pressure:H}")
print(f"{pressure:L}")

Skript nejprve vypíše vypočtenou sílu (v plain textu, v HTML i v TeXu):

150.0 kilogram * meter / second ** 2
150.0 kilogram meter/second<sup>2</sup>
150.0\ \frac{\mathrm{kilogram} \cdot \mathrm{meter}}{\mathrm{second}^{2}}

Následně je vypsán vypočtený tlak:

15.0 kilogram / meter / second ** 2
15.0 kilogram/(meter second<sup>2</sup>)
15.0\ \frac{\mathrm{kilogram}}{\left(\mathrm{meter} \cdot \mathrm{second}^{2}\right)}

17. Příloha 1: výpis všech jednotek nabízených knihovnou Pint

Knihovna Pint má nadefinováno velké množství jednotek, které si můžeme snadno vypsat. Výpis všech jednotek do formy HTML tabulky zajišťuje následující krátký skript (který by možná bylo lepší přepsat s využitím filter a partition do více funkcionální podoby):

from pint import UnitRegistry
 
ureg = UnitRegistry()
 
print("<tr>", end="")
 
c = 0
for item in dir(ureg):
    if item[0] != "_":
        print(f"<td>{item}</td>", end="")
        c += 1
        if c == 6:
            print("</tr>\n<tr>", end="")
            c=0

Povšimněte si, že některé jednotky mohou být zapsány poměrně čitelně pomocí Unicode znaků:

% A A90 A_US A_it Ah
At B BDFT BF BTU Ba
Bd Bi Bq Btu Btu_iso Btu_it
Btu_th C C90 Ci Cl Context
D DPI Da ECC EC_therm E_h
Eh F FBM F90 Fr G
G0 Gal Gb Group Gy H
H2O H90 Hg Hg_0C Hg_32F Hg_60F
Hz J K KPH K_J K_J90
K_alpha_Cu_d220 K_alpha_Mo_d220 K_alpha_W_d220 L Ly M
MPH Measurement Mx N N_A Ne
NeC Nm Np Oe P PPCM
PPI PSH Pa Phi0 Quantity R
RKM R_K R_K90 R_inf R_∞ Rd
Ry S SPL St Sv System
T Ta Td Tj Tt U
UK_bbl UK_bushel UK_cup UK_cwt UK_fluid_ounce UK_force_ton
UK_gallon UK_gill UK_horsepower UK_hundredweight UK_pint UK_pk
UK_quart UK_ton UK_ton_force US_cwt US_dry_barrel US_dry_gallon
US_dry_pint US_dry_quart US_fluid_dram US_fluid_ounce US_force_ton US_hundredweight
US_international_ampere US_international_ohm US_international_volt US_liquid_cup US_liquid_dram US_liquid_fifth
US_liquid_gallon US_liquid_gill US_liquid_ounce US_liquid_quart US_pint US_shot
US_therm US_ton US_ton_force Unit UnitsContainer V
VA V90 V_US V_it W W90
Wb Wh Xu_Cu Xu_Mo Z0 a
a0 a0 a_u_action a_u_current a_u_electric_field a_u_energy
a_u_force a_u_intensity a_u_length a_u_mass a_u_temp a_u_time
abA abC abF abH abS abV
abampere abcoulomb aberdeen abfarad abhenry abmho
abohm absiemens abvolt abΩ acre acre_feet
acre_foot add_context alpha amp ampere ampere_hour
ampere_turn amu angstrom angstrom_star angular_degree angular_minute
angular_second ap_dr ap_lb ap_oz apothecary_dram apothecary_ounce
apothecary_pound arc_minute arc_second arcdeg arcdegree arcmin
arcminute arcsec arcsecond are astronomical_unit at
atm atm_l atmosphere atmosphere_liter atomic_mass_constant atomic_unit_of_action
atomic_unit_of_current atomic_unit_of_electric_field atomic_unit_of_energy atomic_unit_of_force atomic_unit_of_intensity atomic_unit_of_length
atomic_unit_of_mass atomic_unit_of_temperature atomic_unit_of_time au auto_reduce_dimensions autoconvert_offset_to_baseunit
avdp_dram avdp_ounce avdp_pound avogadro_constant avogadro_number avoirdupois_dram
avoirdupois_ounce avoirdupois_pound b bag bar barad
barie barn barrel barrie baryd barye
baud bbl becquerel beer_barrel beer_bbl big_point
biot biot_turn bit bits_per_pixel blob board_feet
board_foot bohr bohr_magneton bohr_radius boiler_horsepower boltzmann_constant
bp bpp bps british_thermal_unit bu buckingham
bushel byte c c0 c1 c2
cables_length cache_folder cal cal15 cal_it cal_th
calorie candela candle carat case_sensitive cc
cd celsius centimeter centimeter_H2O centimeter_Hg centimeter_Hg_0C
centipoise centuries century chain characteristic_impedance_of_vacuum check
cicero circle circular_mil classical_electron_radius clausius cmH2O
cmHg cm1 cm_H2O cm_Hg cmil common_year
conductance_quantum context conventional_ampere90 conventional_coulomb90 conventional_farad90 conventional_henry90
conventional_josephson_constant conventional_mercury conventional_ohm90 conventional_volt90 conventional_von_klitzing_constant conventional_water
conventional_watt90 convert cooling_tower_ton coulomb coulomb_constant count
counts_per_second cp cps css_pixel ct cu_ft
cu_in cu_yd cubic_centimeter cubic_feet cubic_foot cubic_inch
cubic_yard cup curie cwt cycle d
dB dBm dBu d220 dalton darcy
day debye decade decibel decibelmicrowatt decibelmilliwatt
decimeter decitex default_as_delta default_format default_system define
deg degC degF degK degR degRe
degree degreeC degreeF degreeK degreeR degreeRe
degree_Celsius degree_Fahrenheit degree_Kelvin degree_Rankine degree_Reaumur degree_Réaumur
delta_celsius delta_degC delta_degF delta_degRe delta_degreeC delta_degreeF
delta_degreeRe delta_degree_Celsius delta_degree_Fahrenheit delta_degree_Reaumur delta_degree_Réaumur delta_fahrenheit
delta_reaumur delta_réaumur den denier dgal didot
dirac_constant disable_contexts dot dots_per_inch dpi dqt
dr drachm dram dry_barrel dry_gallon dry_pint
dry_quart dtex dwt dyn dyne e
eV electric_constant electrical_horsepower electron_g_factor electron_mass electron_volt
elementary_charge enable_contexts entropy_unit enzyme_unit enzymeunit eon
eps0 eps0 epsilon0 erg esu eu
eulers_number fahrenheit farad faraday faraday_constant fathom
feet feet_H2O femtometer fermi fifteen_degree_calorie fifth
fine_structure_constant first_radiation_constant fldr floz fluid_dram fluid_ounce
fluidram fm fmt_locale foot foot_H2O foot_per_second
foot_pound footpound force_gram force_kilogram force_long_ton force_metric_ton
force_ndarray force_ndarray_like force_ounce force_pound force_short_ton force_t
force_ton fortnight fps franklin ft ftH2O
ft_lb fur furlong g g0 g0
g_e gn gal galileo gallon gamma
gamma_mass gauss get_base_units get_compatible_units get_dimensionality get_group
get_name get_root_units get_symbol get_system gf gi
gilbert gill gon gr grad grade
grain gram gram_force gravitational_constant gravity gray
gregorian_year h ha hand hartree hartree_energy
hbar hectare henry hertz hogshead horsepower
hour hp hr hundredweight hydraulic_horsepower impedance_of_free_space
imperial_barrel imperial_bbl imperial_bu imperial_bushel imperial_cp imperial_cup
imperial_fldr imperial_floz imperial_fluid_drachm imperial_fluid_dram imperial_fluid_ounce imperial_fluid_scruple
imperial_gal imperial_gallon imperial_gi imperial_gill imperial_minim imperial_peck
imperial_pint imperial_pk imperial_pt imperial_qt imperial_quart in
inHg in_Hg inch inch_H2O_39F inch_H2O_60F inch_Hg
inch_Hg_32F inch_Hg_60F inches international_british_thermal_unit international_calorie international_feet
international_foot international_inch international_inches international_knot international_mile international_steam_table_calorie
international_yard is_compatible_with jig josephson_constant joule julian_year
jute k k_B k_C karat kat
katal kayser kelvin kgf kilogram kilogram_force
kilometer kilometer_per_hour kilometer_per_second kip kip_per_square_inch knot
knot_international kph kps ksi kt l
lambda lambert langley lattice_spacing_of_Si lb lbf
lbt league leap_year li light_year lightyear
link liquid_cup liquid_gallon liquid_gill liquid_pint liquid_quart
liter litre lm ln10 load_definitions long_hundredweight
long_ton long_ton_force lumen lunar_month lux lx
ly m m_e mn m_p m_u
magnetic_constant magnetic_flux_quantum mas maxwell mean_international_ampere mean_international_ohm
mean_international_volt mercury mercury_60F meter meter_per_second metre
metric_horsepower metric_ton metric_ton_force mho mi microgram
microliter micrometer micromole micron mil mil_length
mile mile_per_hour millennia millennium milliarcsecond milligram
millimeter millimeter_Hg millimeter_Hg_0C min minim minute
mmHg mm_Hg mol molar molar_gas_constant mole
molec molecule month mph mpl_formatter mps
mu0 mu0 mu_B muN nautical_mile neper
neutron_mass newton newtonian_constant_of_gravitation nit nmi non_int_type
nuclear_magneton number_english number_meter oct octave octet
oersted ohm ohm90 ohm_US ohm_it oil_barrel
oil_bbl ounce ounce_force oz ozf ozt
parse_expression parse_pattern parse_unit_name parse_units parsec particle
pascal pc pdl peak_sun_hour peck pel
pennyweight percent perch pi pi_theorem pica
picture_element pint pixel pixels_per_centimeter pixels_per_inch pk
planck_constant planck_current planck_length planck_mass planck_temperature planck_time
point poise pole pond pound pound_force
pound_force_per_square_inch poundal pp ppi ppm preprocessors
printers_dpi printers_pica printers_point proton_mass psi pt
px qt quad quadrillion_Btu quart quarter
r_e rad radian rads rankine rd
reaumur reciprocal_centimeter refrigeration_ton rem remove_context revolution
revolutions_per_minute revolutions_per_second reyn rhe rod roentgen
rpm rps rutherford rydberg rydberg_constant réaumur
röntgen s scaled_point scruple sec second
second_radiation_constant section separate_format_defaults set_fmt_locale setup_matplotlib sft
shake short_hundredweight short_ton short_ton_force shot sidereal_day
sidereal_month sidereal_year siemens sievert sigma sigma_e
slinch slm slpm slug slugette smi
sound_pressure_level speed_of_light sq_deg sq_ft sq_in sq_mi
sq_perch sq_pole sq_rod sq_yd sqdeg square_degree
square_feet square_foot square_inch square_inches square_league square_mile
square_rod square_survey_mile square_yard sr standard_atmosphere standard_gravity
standard_liter_per_minute statA statC statF statH statT
statV statWb statampere statcoulomb statfarad stathenry
statmho statohm stattesla statvolt statweber statΩ
stefan_boltzmann_constant steradian stere stilb stokes stone
super_feet super_foot superficial_feet superficial_foot survey_foot survey_link
survey_mile sv svedberg sverdrup synodic_month sys
t tTNT t_force tablespoon tansec tbsp
teaspoon technical_atmosphere tesla tex tex_cicero tex_didot
tex_pica tex_point tf th therm thermochemical_british_thermal_unit
thermochemical_calorie thm thomson_cross_section thou tlb toe
ton ton_TNT ton_force ton_of_refrigeration tonne tonne_of_oil_equivalent
torr townsend toz tropical_month tropical_year troy_ounce
troy_pound tsp turn u unified_atomic_mass_unit unit_pole
us_statute_mile vacuum_permeability vacuum_permittivity volt volt_ampere von_klitzing_constant
water water_39F water_4C water_60F watt watt_hour
watthour weber week wien_frequency_displacemen­t_law_constant wien_u wien_wavelength_displacemen­t_law_constant
wien_x with_context wraps x_unit_Cu x_unit_Mo yard
yd year yr zeta °C °F
°K °R °Re µ µ_0 µ_B
µ_N Å Å_star ångström ørsted ħ
Δcelsius ΔdegC ΔdegF ΔdegRe ΔdegreeC ΔdegreeF
ΔdegreeRe Δdegree_Réaumur Δfahrenheit Δreaumur Δréaumur Δ°C
Δ°F Δ°Re Φ_0 Ω Ω_90 Ω_US
Ω_it α γ ε_0 ζ λ
μ π σ σ_e Å
Poznámka: v případě potřeby je možné si zaregistrovat nové jednotky, popř. si všechny jednotky nechat lokalizovat.

18. Příloha 2: podpora pro práci s jednotkami v jazyku Kawa

Python není prvním programovacím jazykem, do něhož byla přidána podpora pro práci s veličinami a jednotkami. Velmi pěkně je integrace jednotek řešena v jazyku Kawa, což je jedna z variant Scheme, která běží nad JVM a s níž jsme se již na stránkách Roota poměrně do podrobností seznámili (viz odkazy uvedené ve dvacáté kapitole). Mezi vymoženosti jazyka Kawa patří možnost přiřadit libovolné číselné hodnotě i její jednotku. Jednotka je k číselné hodnotě přiřazena v čase běhu aplikace a zúčastní se i operací prováděných s danou hodnotou (součet, součin, rozdíl, podíl). Můžeme tak například používat konstanty s přiřazenými jednotkami:

1A
0.5V
32cm
120s
Poznámka: zápis je tedy přirozenější, než v případě Pint.

Nebo též z běžné hodnoty:

(make-quantity 10 "cm")
10cm
 
(make-quantity 10 unit:cm)
10cm
Poznámka: dané jednotky ovšem musí být nejdříve definovány – viz další text.

Pochopitelně lze vytvořit i proměnné a inicializovat je hodnotou i s uvedením jednotky. To se provádí následujícím způsobem:

(define MAX_CURRENT 1A)
(define AVERAGE_DISTANCE 32cm)
(define TIMEOUT 120s)

Je však možné použít libovolnou jednotku? Resp. přesněji řečeno, kontroluje se, zda je uvedená jednotka známá a nedopustíme se například omylem přepisu, jako v následujícím příkladu?

(define AVERAGE_DISTANCE 32cn)

Jednotky (jejich identifikátory) se skutečně kontrolují. Přímo v základních knihovnách programovacího jazyka Kawa jsou některé jednotky definovány, další je možné definovat podle toho, jaký konkrétní problém vyvíjená aplikace řeší. Definice nové jednotky může vypadat následovně:

(define-base-unit meter "distance")
(define-unit stadion 176meter)

Vytvořili jsme jednotku „metr“ a „stadion“, který měří přibližně 176 metrů.

S novou jednotkou můžeme provést například součin s bezrozměrnou konstantou, což jednotku (ani veličinu) nijak nezmění:

(* 2stadion 3)
6.0stadion

To však není vše – jazyk Kawa totiž do určité míry dokáže odvodit i jednotku výsledku nějaké operace. U součtu a rozdílu je to jednoduché, ovšem podobně se odvozuje i jednotka při násobení a dělení:

Cloud 24 - tip 1

(* 10cm 2)
20.0cm
 
(* 10cm 10)
100.0cm
 
(* 10cm 10cm)
100.0cm^2
 

Dělení hodnot s různými jednotkami:

(/ 10s 5cm)
2.0s*cm^-1
 
(/ 5cm 10s)
0.5cm*s^-1
Poznámka: toto je skutečně velmi užitečná vlastnost, která nám pomůže odhalit mnohé chyby v algoritmu. Na konci výpočtu se totiž můžeme přesvědčit i o jednotce výsledku a zjistit tak, že se neprovádí „podivné“ operace, které například ani nemají obdobu v reálném světě. Ostatně můžeme si uvést příklad či příklady dalších výpočtů:
(define-base-unit A "electric current")
3A
3.0A
 
(define-base-unit V "voltage")
5V
5.0V
 
(* 3A 5V)
15.0A*V
 
(define power (* 3A 5V))
(define resistance (/ 5V 3A))
power
15.0A*V
 
resistance
1.6666666666666667V*A^-1
 
(define wrong-power (* 3A 5cm))
wrong-power
15.0A*cm
 

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:

# Demonstrační příklad Stručný popis příkladu Cesta
1 01_time.py základní použití časových jednotek https://github.com/tisnik/most-popular-python-libs/blob/master/pint/01_time.py
2 02_dimensionality.py získání veličiny https://github.com/tisnik/most-popular-python-libs/blob/master/pint/02_di­mensionality.py
3 03_time.py operace s časovými jednotkami https://github.com/tisnik/most-popular-python-libs/blob/master/pint/03_time.py
4 04_time_dimensionality.py získání veličiny https://github.com/tisnik/most-popular-python-libs/blob/master/pint/04_ti­me_dimensionality.py
       
5 05_velocity.py rychlostní jednotky https://github.com/tisnik/most-popular-python-libs/blob/master/pint/05_velocity.py
6 06_velocity_dimensionality.py získání veličiny (nebo jejího přiblížení) https://github.com/tisnik/most-popular-python-libs/blob/master/pint/06_ve­locity_dimensionality.py
7 07_wrong_op.py detekce nekorektních operací https://github.com/tisnik/most-popular-python-libs/blob/master/pint/07_wrong_op.py
8 08_conversion.py konverze jednotek, první příklad https://github.com/tisnik/most-popular-python-libs/blob/master/pint/08_conversion.py
9 09_conversion.py konverze jednotek, druhý příklad https://github.com/tisnik/most-popular-python-libs/blob/master/pint/09_conversion.py
10 10_area.py výpočet plochy https://github.com/tisnik/most-popular-python-libs/blob/master/pint/10_area.py
11 11_velocity.py výpočet rychlosti https://github.com/tisnik/most-popular-python-libs/blob/master/pint/11_velocity.py
12 12_acceleration.py výpočet zrychlení https://github.com/tisnik/most-popular-python-libs/blob/master/pint/12_ac­celeration.py
13 13_force.py výpočet síly https://github.com/tisnik/most-popular-python-libs/blob/master/pint/13_force.py
14 14_units_and_dimensionality.py veličiny a jednotky https://github.com/tisnik/most-popular-python-libs/blob/master/pint/14_u­nits_and_dimensionality.py
15 15_prefixes.py použití prefixů u jednotek, první příklad https://github.com/tisnik/most-popular-python-libs/blob/master/pint/15_prefixes.py
16 16_prefixes.py použití prefixů u jednotek, druhý příklad https://github.com/tisnik/most-popular-python-libs/blob/master/pint/16_prefixes.py
17 17_prefixes.py použití prefixů u jednotek, třetí příklad https://github.com/tisnik/most-popular-python-libs/blob/master/pint/17_prefixes.py
18 18_binary_prefixes.py binární prefixy https://github.com/tisnik/most-popular-python-libs/blob/master/pint/18_bi­nary_prefixes.py
19 19_byte_to_bites.py binární prefixy a převod bajtů na bity https://github.com/tisnik/most-popular-python-libs/blob/master/pint/19_by­te_to_bites.py
20 20_angle.py úhlové jednotky https://github.com/tisnik/most-popular-python-libs/blob/master/pint/20_angle.py
       
21 21_list_units.py výpis všech dostupných jednotek https://github.com/tisnik/most-popular-python-libs/blob/master/pint/21_list_units.py
       
22 22_reduced_units.py redukce dimensionality https://github.com/tisnik/most-popular-python-libs/blob/master/pint/22_re­duced_units.py
23 23_to_base_units.py redukce na základní jednotky https://github.com/tisnik/most-popular-python-libs/blob/master/pint/23_to_ba­se_units.py
24 24_to_base_units.py redukce na základní jednotky https://github.com/tisnik/most-popular-python-libs/blob/master/pint/24_to_ba­se_units.py
25 25_formatting.py formátovaný výstup https://github.com/tisnik/most-popular-python-libs/blob/master/pint/25_formatting.py

20. Odkazy na Internetu

  1. Units and Quantities
    https://uomresearchit.git­hub.io/programming_with_pyt­hon/06-units_and_quantities/index.html
  2. Fyzikální veličina (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Fyzik%C3%A1ln%C3%AD_ve­li%C4%8Dina
  3. Fyzikální jednotka (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Fyzik%C3%A1ln%C3%AD_jed­notka
  4. Soustava SI (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Soustava_SI
  5. Dokumentace ke knihovně Pint
    https://pint.readthedocs.i­o/en/stable/index.html
  6. Knihovna astropy na PyPi
    https://pypi.org/project/astropy/
  7. Knihovna Pint na PyPi
    https://pypi.org/project/Pint/
  8. Repositář knihovny Pint
    https://github.com/hgrecco/pint
  9. Knihovna units na PyPi (nevyvíjený projekt)
    https://pypi.org/project/units/
  10. Knihovna quantity na PyPi
    https://pypi.org/project/quantity/
  11. Repositář s knihovnou quantity
    https://github.com/mamrhein/quantity
  12. Knihovna xarray-units na PyPi
    https://pypi.org/project/xarray-units/
  13. 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/
  14. Jazyk Kawa v ekosystému virtuálního stroje Javy
    https://www.root.cz/clanky/jazyk-kawa-v-ekosystemu-virtualniho-stroje-javy/
  15. 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/
  16. Kawa: Compiling Scheme to Java
    https://www.mit.edu/afs.new/sip­b/project/kawa/doc/kawa-tour.html
  17. Kawa in Languages shootout
    http://per.bothner.com/blog/2010/Kawa-in-shootout/
  18. Kawa 2.0 Supports Scheme R7RS
    https://developers.slashdot­.org/story/14/12/13/2259225/ka­wa-20-supports-scheme-r7rs/
  19. Kawa — fast scripting on the Java platform
    https://lwn.net/Articles/623349/

Byl pro vás článek přínosný?