Numscrypt aneb Numpy běžící ve webovém prohlížeči

26. 10. 2023
Doba čtení: 29 minut

Sdílet

 Autor: Depositphotos
S projektem Transcrypt popsaným na začátku týdne je velmi úzce spojen projekt nazvaný Numscrypt (Nµmscrλpt). Jedná se o částečnou portaci známé knihovny Numpy do JavaScriptu, takže funkce z Numpy je možné využít v pythonních skriptech.

Obsah

1. Numscrypt aneb Numpy běžící ve webovém prohlížeči

2. Numpy vs. Numscrypt

3. Instalace knihovny Numscrypt

4. Příprava projektu pro otestování možností Numscryptu

5. Problematika importu „správného“ balíčku Numpy

6. Import různých balíčků pro CPython a pro Transcrypt

7. Výsledek transpřekladu do JavaScriptu

8. Tisk obsahu pole na konzoli webového prohlížeče

9. Tisk obsahu pole přímo na webovou stránku

10. Specifikace typu prvků pole

11. Konstrukce dvourozměrného pole

12. Konstruktor numpy.zeros a numpy.ones

13. Konstruktor jednotkové matice

14. Indexování prvků polí

15. Vytváření „řezů“ z polí

16. Sčítání, odčítání a násobení matic

17. Závěrečné zhodnocení

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

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

20. Odkazy na Internetu

1. Numscrypt aneb Numpy běžící ve webovém prohlížeči

S projektem Transcrypt popsaným na začátku týdne je velmi úzce spojen projekt nazvaný Numscrypt (psaný též Nµmscrλpt). Jedná se o částečnou portaci známé knihovny Numpy do JavaScriptu, takže funkce a přetížené operátory z Numpy je možné využít v Pythonních skriptech transpilovaných do JavaScriptu. Interně je Numscrypt založen na typovaných polích JavaScriptu, což na jednu stranu zajišťuje velmi rychlé operace, na stranu druhou je však dimenze polí omezena na 1 či 2 (vektory, matice) a navíc prvky polí mohou být pouze typu int32, float32, float64, complex32 a complex64. Taktéž je (prozatím) omezeno množství funkcí, které jsou v Numscryptu definovány. A navíc – práce s přetíženými operátory není příliš přímočará – viz též šestnáctou kapitolu. Dnešní článek tak bude hledat odpověď na otázku, zda se jedná o slepou cestu či nikoli.

Poznámka: Numscrypt lze sice považovat za (v mnoha ohledech omezenou) alternativu k nativní knihovně Numpy, ale jak uvidíme dále, budeme muset zajistit import korektního balíčku – ideálně totiž budeme chtít, aby se jeden Pythonovský skript mohl použít jak s běžným CPythonem (a tedy se standardní knihovnou Numpy), tak i po transpřekladu do JavaScriptu (a tedy s knihovnou Numscrypt).

2. Numpy vs. Numscrypt

Numpy a Numscrypt mají některé společné vlastnosti a některé (zásadní) rozdíly.

Funkce a objekty nabízené knihovnou Numpy se sice volají přímo z Pythonu, ve skutečnosti se však interní datové struktury dosti podstatným způsobem odlišují od datových struktur využívaných samotným Pythonem. V knihovně Numpy tvoří základ datová struktura nazvaná ndarray, která reprezentuje pole o prakticky libovolném počtu dimenzí (ostatně ono „nd“ ve jménu „ndarray“ značí N-dimensional). Tato pole se liší od běžných seznamů či n-tic v Pythonu, protože ndarray jsou homogenní datovou strukturou: všechny prvky totiž mají shodný typ a navíc všechny prvky leží za sebou, zatímco seznamy v Pythonu jsou měnitelné (prvky lze přidávat a odebírat) a obecně nehomogenní (každý prvek může mít odlišný datový typ). Za tuto velkou flexibilitu se samozřejmě platí, a to jak většími nároky na operační paměť (reference na objekty), tak i pomalejším zpracováním.

V Numscryptu jsou pole realizována formou JavaScriptových polí s jednou či dvěma dimenzemi. Jde tedy, jak již víme, o typovaná pole s omezenou množinou typů prvků pole. Opět se tedy jedná o homogenní datové struktury s neměnitelným tvarem (z tohoto pohledu jsou perzistentní). Kvůli zcela odlišné implementaci není možné jednoduše měnit tvar pole – operace reshape tedy prozatím není dostupná.

3. Příprava projektu pro otestování možností Numscryptu

Instalace Numscryptu probíhá, resp. přesněji řečeno může probíhat podobně jako instalace Transcryptu (ve skutečnosti je nutné nainstalovat oba zmíněné balíčky). Instalaci tedy můžeme provést například s využitím standardního nástroje pip, který již velmi dobře známe. Instalace pouze pro aktuálně přihlášeného uživatele vypadá takto:

$ pip3 install --user transcrypt numscrypt
 
Collecting transcrypt
  Downloading Transcrypt-3.9.1-py2.py3-none-any.whl (19.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 19.0/19.0 MB 3.0 MB/s eta 0:00:00
Collecting numscrypt
  Downloading Numscrypt-0.0.40.tar.gz (4.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.7/4.7 MB 5.0 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Requirement already satisfied: mypy in /usr/local/lib64/python3.11/site-packages (from transcrypt) (1.6.1)
Requirement already satisfied: typing-extensions>=4.1.0 in /usr/local/lib/python3.11/site-packages (from mypy->transcrypt) (4.8.0)
Requirement already satisfied: mypy-extensions>=1.0.0 in /usr/local/lib/python3.11/site-packages (from mypy->transcrypt) (1.0.0)
Installing collected packages: transcrypt, numscrypt
  DEPRECATION: numscrypt is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for numscrypt ... done
Successfully installed numscrypt-0.0.40 transcrypt-3.9.1

4. Příprava projektu pro otestování možností Numscryptu

Transcrypt i Numscrypt je možné nastavit i jako závislý balíček (přímá závislost, popř. vývojová závislost) při použití nástroje PDM, který byl na Rootu popsán minulý týden. Ukažme si pro úplnost, jak by mohl vypadat projekt, který je na Transcryptu a na knihovně Numscrypt postaven.

Nejprve si necháme vytvořit kostru nového projektu (prozatím bez závislostí):

$ pdm init

Poctivě odpovíme na položené otázky (většinou jen potvrzením klávesou Enter, další odpovědi jsou označeny tučně):

Creating a pyproject.toml for PDM...
Please enter the Python interpreter to use
0. /usr/bin/python (3.11)
1. /usr/bin/python3.11 (3.11)
2. /usr/bin/python3 (3.11)
Please select (0): 0
Would you like to create a virtualenv with /usr/bin/python? [y/n] (y): y
Virtualenv is created successfully at /home/ptisnovs/test2/.venv
Is the project a library that is installable?
If yes, we will need to ask a few more questions to include the project name and build backend [y/n] (n): n
License(SPDX name) (MIT):
Author name (): Pavel Tisnovsky
Author email (): tisnik@nowhere.us
Python requires('*' to allow any) (>=3.11):
Project is initialized successfully

Do právě vzniklého projektu ve druhém kroku přidáme závislost na Transcryptu (navíc s přepínačem -d, protože se jedná o závislost pro vývojáře):

$ pdm add -d transcrypt

V tomto kroku by se měly nainstalovat stejné balíčky, jako při instalaci přes pip (viz předchozí kapitolu):

Adding group dev to lockfile
Adding packages to dev dev-dependencies: transcrypt
🔒 Lock successful
Changes are written to pyproject.toml.
Synchronizing working set with resolved packages: 4 to add, 0 to update, 0 to remove
 
  ✔ Install mypy-extensions 1.0.0 successful
  ✔ Install typing-extensions 4.8.0 successful
  ✔ Install transcrypt 3.9.1 successful
  ✔ Install mypy 1.6.1 successful
 
🎉 All complete!

Navíc ve třetím kroku přidáme i knihovnu Numscrypt, a to naprosto stejným příkazem (balíček pro vývojáře):

$ pdm add -d numscrypt

Průběh instalace:

Adding packages to dev dev-dependencies: numscrypt
🔒 Lock successful
Changes are written to pyproject.toml.
Synchronizing working set with resolved packages: 1 to add, 0 to update, 0 to remove
 
  ✔ Install numscrypt 0.0.40 successful
 
🎉 All complete!

Výsledný projektový soubor, který se jmenuje project.toml, by měl vypadat následovně (obsahuje všechny přímé závislosti, ale ne již tranzitivní závislosti):

[project]
name = ""
version = ""
description = ""
authors = [
    {name = "Pavel Tisnovsky", email = "tisnik@nowhere.us"},
]
dependencies = []
requires-python = ">=3.11"
readme = "README.md"
license = {text = "MIT"}
 
[tool.pdm.dev-dependencies]
dev = [
    "transcrypt>=3.9.1",
    "numscrypt>=0.0.40",
]

Pro úplnost si taktéž ukažme lock file, který obsahuje jak přímé závislosti, tak i závislosti nepřímé:

# This file is @generated by PDM.
# It is not intended for manual editing.
 
[metadata]
groups = ["default", "dev"]
cross_platform = true
static_urls = false
lock_version = "4.3"
content_hash = "sha256:4d013d66c37e565481b0e84339bbabab4630036b0845805982beb532561f4ee5"
 
[[package]]
name = "mypy"
version = "1.6.1"
requires_python = ">=3.8"
summary = "Optional static typing for Python"
dependencies = [
    "mypy-extensions>=1.0.0",
    "typing-extensions>=4.1.0",
]
files = [
    {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"},
    {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"},
    {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"},
    {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"},
    {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"},
    {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"},
    {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"},
    {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"},
    {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"},
    {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"},
    {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"},
    {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"},
]
 
[[package]]
name = "mypy-extensions"
version = "1.0.0"
requires_python = ">=3.5"
summary = "Type system extensions for programs checked with the mypy type checker."
files = [
    {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
    {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
 
[[package]]
name = "numscrypt"
version = "0.0.40"
summary = "A tiny bit of NumPy for Transcrypt using JavaScript typed arrays"
dependencies = [
    "transcrypt",
]
files = [
    {file = "Numscrypt-0.0.40.tar.gz", hash = "sha256:427e5730707f246058993662b28410e0862ba79bb72126aeae5f5d423823f40d"},
]
 
[[package]]
name = "transcrypt"
version = "3.9.1"
summary = "Python to JavaScript transpiler, supporting multiple inheritance and generating lean, highly readable code"
dependencies = [
    "mypy",
]
files = [
    {file = "Transcrypt-3.9.1-py2.py3-none-any.whl", hash = "sha256:73f5b3587f561aff66fa82f5fb3407f8b5950e991ad335f5f6dd889990ab0e10"},
]
 
[[package]]
name = "typing-extensions"
version = "4.8.0"
requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+"
files = [
    {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
    {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
]

5. Problematika importu „správného“ balíčku Numpy

Pokusme se nyní (trans)přeložit následující skript, který je naprosto legální a v případě, že použijeme CPython a knihovnu Numpy, tak skutečně zkonstruuje jednorozměrné pole a následně ho vypíše na terminál:

# Knihovna Numpy a Numscrypt
#
# Konstrukce jednorozměrného pole konstruktorem numpy.array()
#
# vytvoření pole se čtyřmi prvky
 
# import hlavního balíčku knihovny Numpy
import numpy
 
# konstrukce pole
a = numpy.array([1, 2, 3, 4])
 
# tisk obsahu pole na standardní výstup
print(a)

Transpřeklad se spustí tímto příkazem (přepínač -n zakazuje optimalizace):

$ pdm run transcrypt -n 01_array.py

Jak je z následujícího výpisu patrné, nebude transpřeklad úspěšný, protože se nenalezne soubor numpy.py ani soubor numpy.js v žádném z adresářů, z nichž lze import provést:

Transcrypt (TM) Python to JavaScript Small Sane Subset Transpiler Version 3.9.0
Copyright (C) Geatec Engineering. License: Apache 2.0
 
 
Saving target code in: /home/ptisnovs/test2/__target__/org.transcrypt.__runtime__.js
 
Error while compiling (offending file last):
        File '01_array', line 6, namely:
 
        Import error, can't find any of:
                /home/ptisnovs/test2/numpy.py
                /home/ptisnovs/test2/numpy.js
                /home/ptisnovs/test2/.venv/lib/python3.11/site-packages/transcrypt/modules/numpy.py
                /home/ptisnovs/test2/.venv/lib/python3.11/site-packages/transcrypt/modules/numpy.js
                /home/ptisnovs/test2/.venv/bin/numpy.py
                /home/ptisnovs/test2/.venv/bin/numpy.js
                /usr/lib64/python3.11/numpy.py
                /usr/lib64/python3.11/numpy.js
                /usr/lib64/python3.11/lib-dynload/numpy.py
                /usr/lib64/python3.11/lib-dynload/numpy.js
                /home/ptisnovs/test2/.venv/lib64/python3.11/site-packages/numpy.py
                /home/ptisnovs/test2/.venv/lib64/python3.11/site-packages/numpy.js
                /home/ptisnovs/test2/.venv/lib/python3.11/site-packages/numpy.py
                /home/ptisnovs/test2/.venv/lib/python3.11/site-packages/numpy.js
 
 
Aborted
Poznámka: problém spočívá v tom, že ve skutečnosti nechceme použít „klasickou“ knihovnu Numpy, ale její JavaScriptovou alternativu, tedy knihovnu Numscrypt.

6. Import různých balíčků pro CPython a pro Transcrypt

Jak je však možné přímo v Pythonovském skriptu rozlišit, zda je skript spuštěn ve standardním CPythonu či zda byl transpřeložen (či je transpřekládán) do JavaScriptu? Protože právě na tom, jaká operace je prováděna, závisí, který balíček budeme chtít naimportovat – zda numpy nebo numscrypt.

Ideální a čitelné řešení v tomto případě (prozatím) neexistuje, ovšem můžeme použít tento trik – zkontrolujeme jméno nástroje, který skript zpracovává. Jedná se ovšem o dosti nestandardní konstrukci:

from org.transcrypt.stubs.browser import __envir__
 
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np

Import standardní knihovny Numpy bude „obalen“ do pseudofunkcí __pragma__. Jejich zápis sice skutečně odpovídá volání běžných funkcí, ale ve skutečnosti jsou vyhodnocovány již v době transpřekladu:

__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')
Poznámka: v každém případě, nezávisle na tom, zda skript spouštíme v CPythonu či zda je překládán do JavaScriptu, budeme mít k dispozici balíček dostupný pod jmenným aliasem np.

Výsledný skript by měl nyní vypadat následovně:

# Knihovna Numpy a Numscrypt
#
# Konstrukce jednorozměrného pole konstruktorem numpy.array()
#
# vytvoření pole se čtyřmi prvky
 
from org.transcrypt.stubs.browser import __envir__
 
# import hlavního balíčku knihovny Numpy
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np
 
# import pro CPython
__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')
 
# konstrukce pole
a = np.array([1, 2, 3, 4])
 
# tisk obsahu pole na standardní výstup
print(a)

7. Výsledek transpřekladu do JavaScriptu

Pro zajímavost se podívejme na výsledek překladu (transpřekladu) do JavaScriptu. Jedná se o přímočarou a dobře čitelnou transformaci kódu, která je zvláštní pouze „vytažením“ příkazu pro import balíčku z podmínky:

// Transcrypt'ed from Python, 2023-10-25 10:11:33
 
import {AssertionError, AttributeError, BaseException, DeprecationWarning, Exception, IndexError, IterableError, KeyError, NotImplementedError, RuntimeWarning, StopIteration, UserWarning, ValueError, Warning, __JsIterator__, __PyIterator__, __Terminal__, __add__, __and__, __call__, __class__, __envir__, __eq__, __floordiv__, __ge__, __get__, __getcm__, __getitem__, __getslice__, __getsm__, __gt__, __i__, __iadd__, __iand__, __idiv__, __ijsmod__, __ilshift__, __imatmul__, __imod__, __imul__, __in__, __init__, __ior__, __ipow__, __irshift__, __isub__, __ixor__, __jsUsePyNext__, __jsmod__, __k__, __kwargtrans__, __le__, __lshift__, __lt__, __matmul__, __mergefields__, __mergekwargtrans__, __mod__, __mul__, __ne__, __neg__, __nest__, __or__, __pow__, __pragma__, __pyUseJsNext__, __rshift__, __setitem__, __setproperty__, __setslice__, __sort__, __specialattrib__, __sub__, __super__, __t__, __terminal__, __truediv__, __withblock__, __xor__, abs, all, any, assert, bool, bytearray, bytes, callable, chr, copy, deepcopy, delattr, dict, dir, divmod, enumerate, filter, float, getattr, hasattr, input, int, isinstance, issubclass, len, list, map, max, min, object, ord, pow, print, property, py_TypeError, py_iter, py_metatype, py_next, py_reversed, py_typeof, range, repr, round, set, setattr, sorted, str, sum, tuple, zip} from './org.transcrypt.__runtime__.js';
 
import * as np from './numscrypt.js';
 
var __name__ = '__main__';
if (__envir__.executor_name == __envir__.transpiler_name) {
}
 
export var a = np.array ([1, 2, 3, 4]);
 
print (a);
 
//# sourceMappingURL=02_array.map

8. Tisk obsahu pole na konzoli webového prohlížeče

V Pythonním skriptu jsme pole vytiskli standardní funkcí print. Pokud přeložíme takový program do JavaScriptu, bude print (tentokrát její JavaScriptová varianta) provádět tisk na konzoli webového prohlížeče (ve Firefoxu lze zobrazit přes Ctrl+Shift+K):

# Knihovna Numpy a Numscrypt
#
# Konstrukce jednorozměrného pole konstruktorem numpy.array()
#
# vytvoření pole se čtyřmi prvky
 
# import hlavního balíčku knihovny Numpy
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np
 
# import pro CPython
__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')
 
 
# konstrukce pole
a = np.array([1, 2, 3, 4])
 
# tisk obsahu pole na standardní výstup
print(a)

Transpřeložený skript lze na HTML stránku načíst následujícím způsobem:

<html>
    <head>
        <title>Numscrypt demo</title>
    </head>
    <body>
        <h2>Numscrypt demo</h2>
        <script type="module">import * as numpy_demo from './__target__/03_array_web.js';</script>
    </body>
</html>
Poznámka: opět platí, že si musíte spustit lokální HTTP server, například příkazem (načtení lokální stránky povede k tomu, že se skripty zablokují, což je; jak jsem psal už minule, poněkud absurdní):
$ python3 -m http.server

Výsledek by měl vypadat následovně:

Obrázek 1: Konzole prohlížeče se zobrazeným polem.

9. Tisk obsahu pole přímo na webovou stránku

Samozřejmě nám nic nebráni v tom, abychom si pole (resp. přesněji řečeno jeho prvky) nechali vytisknout přímo na webovou stránku. Náš skript nepatrně upravíme tak, aby pole zapsal do zvoleného HTML elementu na stránce, což je triviální:

# Knihovna Numpy a Numscrypt
#
# Konstrukce jednorozměrného pole konstruktorem numpy.array()
#
# vytvoření pole se čtyřmi prvky
 
# import hlavního balíčku knihovny Numpy
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np
 
# import pro CPython
__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')
 
 
def construct_array():
    # konstrukce pole
    a = np.array([1, 2, 3, 4])
 
    # tisk obsahu pole na webovou stránku
    document.getElementById("output").innerHTML = str(a)
 
 
construct_array()

Následně nám postačí si webovou stránku upravit – přidat si do ní vhodný HTML element s ID nastaveným na output:

<html>
    <head>
        <title>Numscrypt demo</title>
    </head>
    <body>
        <h2>Numscrypt demo</h2>
        <pre id="output" style="font-size:300%; background-color:#ffffc0; padding:5px;">
        </pre>
        <script type="module">import * as numpy_demo from './__target__/04_array_web.js';</script>
    </body>
</html>

Výsledek by měl vypadat následovně:

Obrázek 2: HTML stránka se zobrazeným polem.

10. Specifikace typu prvků pole

Při vytváření polí typu ndarray v Numpy, ať již se jedná o vektory, matice či o pole s větším množstvím dimenzí, lze specifikovat datový typ všech prvků a dokonce i uspořádání prvků v paměti (buď podle zvyklostí jazyka Fortran nebo jazyka C). V knihovně Numscrypt jsme omezeni pouze na pět datových typů prvků:

  1. int32
  2. float32
  3. float64
  4. complex32
  5. complex64

To by mělo pro některé účely plně postačovat, na druhé straně nastanou problémy při zpracování zvukových a obrazových dat.

Podívejme se nyní na to, jak lze specifikovat datový typ prvků pole na float32:

# Knihovna Numpy a Numscrypt
#
# Konstrukce jednorozměrného pole konstruktorem numpy.array()
#
# explicitní specifikace typu všech prvků pole
# (interně se provádí přetypování)
 
# import hlavního balíčku knihovny Numpy
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np
 
# import pro CPython
__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')
 
 
def construct_array():
    # konstrukce pole
    a = np.array(range(10), dtype=np.float)
 
    # tisk obsahu pole na webovou stránku
    document.getElementById("output").innerHTML = str(a)
 
 
construct_array()

11. Konstrukce dvourozměrného pole

Základem konstrukce dvourozměrného pole (podporovaného v Numscryptu) je předání hodnot prvků formou seznamu seznamů, seznamu n-tic atd. Je to ukázáno na dalším příkladu. Tvar pole je odvozen na základě předaných dat:

# Knihovna Numpy
#
# Příklady použití funkce numpy.array
#
# vytvoření dvourozměrné matice
 
# import hlavního balíčku knihovny Numpy
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np
 
# import pro CPython
__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')
 
# konstrukce pole
a = np.array([[1, 2, 3], [4, 5, 6]])
 
# tisk obsahu pole na standardní výstup
print(a)
Poznámka: připomeňme si, že současná verze knihovny Numscrypt nepodporuje pole s více než dvěma dimenzemi.

12. Konstruktor numpy.zeros a numpy.ones

Kromě funkce numpy.array se poměrně často setkáme s nutností vytvořit vektor či matici s nulovými prvky. V tomto případě samozřejmě není nutné složitě vytvářet a předávat takové pole do funkce numpy.array, ale lze namísto toho využít funkci nazvanou numpy.zeros, což je rychlejší i méně paměťově náročnější. Té se předá n-tice (musí se skutečně jednat o n-tici, nikoli o seznam parametrů, proto nezapomeňte na závorky) specifikující dimenzi vektoru, matice či N-dimenzionálního pole. Stejné konstruktory nalezneme i v Numscryptu.

Konstrukce jednorozměrného pole neboli vektoru:

# konstrukce pole
a = np.zeros((10,))
 
# tisk obsahu pole na standardní výstup
print(a)

Konstrukce dvojrozměrného pole neboli matice:

# konstrukce pole
a = np.zeros((5, 5))
 
# tisk obsahu pole na standardní výstup
print(a)

Dalším velmi často používaným typem vektoru či matice je taková struktura, jejíž všechny prvky mají hodnotu 1. Takový vektor. popř. matice. je možné vytvořit funkcí numpy.ones.

Konstrukce jednorozměrného pole neboli vektoru:

# konstrukce pole
a = np.ones((10,))
 
# tisk obsahu pole na standardní výstup
print(a)

Konstrukce dvojrozměrného pole neboli matice:

# konstrukce pole
a = np.ones((3, 4))
 
# tisk obsahu pole na standardní výstup
print(a)
Poznámka: všechny dále uváděné příklady mají na začátku tyto řádky s importem. Kvůli omezení celkové délky článku již tyto řádky nebudeme neustále opakovat:
# import hlavního balíčku knihovny Numpy
if __envir__.executor_name == __envir__.transpiler_name:
    import numscrypt as np
 
# import pro CPython
__pragma__ ('skip')
import numpy as np
__pragma__ ('noskip')

13. Konstruktor jednotkové matice

Pro konstrukci jednotkové matice lze využít konstruktor np.identity, nikoli však np.eye, který sice existuje v Numpy, ale nikoli v Numscryptu. Jednotkovou matici o velikosti 10×10 prvků sestrojíme takto:

# konstrukce pole
a = np.identity(10)
 
# tisk obsahu pole na standardní výstup
print(a)

14. Indexování prvků polí

Jakým způsobem se pole s využitím knihovny Numpy i Numscrypt vytváří již víme. Ještě si však musíme říct, jak se prvky uložené v polích vybírají neboli indexují. V případě jednorozměrných polí je to ve skutečnosti velmi jednoduché – prvky jsou totiž číslovány od nuly a díky přetížení operátoru [] (operátor indexování) je možné prvky v případě potřeby indexovat i od konce pole. V tomto případě se musí použít záporné číslo, takže a[1] značí druhý prvek pole zatímco a[-1] první prvek od konce:

# jednorozměrná pole - vektory
a = np.array([1,2,3,4,5,6,7,8,9,10])
 
# tisk původního pole
print(a)
 
# indexování prvků od nuly
print(a[0])
 
# indexování prvků od nuly
print(a[5])
 
# indexovat lze i od konce pole
print(a[-1])
 
# indexovat lze i od konce pole
print(a[-5])

U dvourozměrných polí je situace poněkud komplikovanější, neboť v tomto případě je nutné použít dva či větší počet indexů (jeden index pro každou dimenzi). Vzhledem k tomu, že v různých programovacích jazycích a rozličných specializovaných nástrojích typu R či Matlab, se používají odlišné způsoby zápisu více indexů, podporuje knihovna Numpy (i Numscrypt) dva způsoby zápisu – buď se všechny indexy oddělí čárkou a vloží se do jediného bloku omezeného hranatými závorkami [], nebo se alternativně pro každou dimenzi použije zvláštní hranatá závorka (syntaxe odvozená od Céčka):

# dvourozměrná pole - matice
a = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
 
# tisk původního pole
print(a)
 
# přístup k prvkům: řádek/sloupec
print(a[0][2])
 
# přístup k prvkům: řádek/sloupec
print(a[2][0])

15. Vytváření „řezů“ z polí

V mnoha případech je nutné z polí získat hodnoty většího množství prvků tvořících souvislý blok. Může se například jednat o všechny prvky pole kromě prvku prvního a posledního (typické pro některé filtry), prvky z první poloviny pole atd. I v tomto případě knihovna Numpy (a taktéž Numscrypt) nabízí vývojářům velmi elegantní řešení, a to ve formě takzvaných řezů (slices). Namísto jediného indexu je totiž možné zadat dva indexy oddělené dvojtečkou, které potom reprezentují začátek a konec řezu:

# původní pole
a = np.array([1,2,3,4,5,6,7,8,9,10])
 
# tisk původního pole
print(a)
 
# slicing
b = a[3:7]
 
# tisk nového pole
print(b)
Poznámka: interně je pro realizaci této operace volána funkce __getslice__.

16. Sčítání, odčítání a násobení matic

V případě, že uživatel vytvoří matice o stejné velikosti, lze takové matice sčítat či odčítat. Pokud se k matici přičte či odečte skalární hodnota (matice+10, matice-42), jedná se o operaci prováděnou s každým prvkem matice zvlášť (sčítají se prvky se shodným indexem či indexy).

Zaměřme se nyní pouze na součet matic. V knihovně Numpy lze realizovat velmi snadno:

# dvourozměrná pole - matice
a = np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10],[11,12,13,14]])
 
b = np.identity(4)
 
# tisk původního pole
print(a)
 
# tisk původního pole
print(b)
 
# operace nad celou maticí
c = a + b
 
print(c)

Ovšem takto zapsaný skript není plně kompatibilní s Numscryptem! (předpokládám že proto, že na úrovni AST chybí příslušné metainformace). Z tohoto důvodu je nutné postupovat nepatrně odlišně – použít pseudofunkci „__pragma__“, s níž jsme se již setkali. Tentokráte jí předáme parametr „opov“ a „noopov“:

bitcoin_skoleni

# dvourozměrná pole - matice
a = np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10],[11,12,13,14]])
 
b = np.identity(4)
 
# tisk původního pole
print(a)
 
# tisk původního pole
print(b)
 
# operace nad celou maticí
__pragma__ ('opov')
c = a + b
__pragma__ ('noopov')
 
print(c)
Poznámka: převod skriptů tedy není zcela triviální a vyžaduje ruční zásahy.

17. Závěrečné zhodnocení

Projekt Numscrypt je postaven na zajímavé myšlence, která si zaslouží další vývoj, ovšem v současnosti se podle mého názoru v žádném případě nejedná o plnohodnotnou náhradu například za Pyscript, který podporuje celé Numpy (tento projekt je založen na odlišném principu, ale cíle jsou totožné – umožnit použití Pythonu a Numpy na straně webového klienta). Ostatně i verze Numscryptu naznačuje, že se prozatím nejedná o stabilní produkt, takže jeho reálné nasazení je v současnosti spíše cestou k mnoha problémům; navíc je nutné stávající skripty ručně upravovat.

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

# Příklad Stručný popis Adresa
1 01_array.py problematika importu „správného“ balíčku Numpy https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/01_array.py
2 02_array.py import různých balíčků pro CPython a pro Transcrypt https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/02_array.py
       
3 03_array_web.py tisk obsahu pole na konzoli webového prohlížeče https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/03_array_web.py
4 03_array.js výsledek transpilace kódu z Pythonu do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/03_array.js
5 03_array_web.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/03_array_web.html
       
5 04_array_web.py tisk obsahu pole přímo na webovou stránku https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/04_array_web.py
6 04_array.js výsledek transpilace kódu z Pythonu do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/04_array.js
7 04_array_web.html webová stránka s načtením modulu a prvkem pro tisk pole https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/04_array_web.html
       
7 05_array_dtype.py specifikace typu prvků pole https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/05_array_dtype.py
8 05_array_dtype.html webová stránka s načtením modulu a prvkem pro tisk pole https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/05_array_dtype.html
     
9 06_2D_array.py konstrukce a tisk dvourozměrného pole https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/06_2D_array.py
10 06_2D_array.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/06_2D_array.html
11 07_zeros_1D_array.py konstrukce jednorozměrného pole vyplněného nulami https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/07_zeros_1D_array.py
12 07_zeros_1D_array.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/07_zeros_1D_array.html
13 08_zeros_2D_array.py konstrukce dvourozměrného pole vyplněného nulami https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/08_zeros_2D_array.py
14 08_zeros_2D_array.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/08_zeros_2D_array.html
15 09_ones_1D_array.py konstrukce jednorozměrného pole vyplněného jedničkami https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/09_ones_1D_array.py
16 09_ones_1D_array.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/09_ones_1D_array.html
17 10_ones_2D_array.py konstrukce dvourozměrného pole vyplněného jedničkami https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/10_ones_2D_array.py
18 10_ones_2D_array.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/10_ones_2D_array.html
19 11_identity_2D_array.py konstrukce jednotkové matice https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/11_identity_2D_array.py
20 11_identity_2D_array.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/11_identity_2D_array.html
21 13_selectors_1D.py výběr prvků (selektor jednorozměrného pole) https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/13_selectors_1D.py
22 13_selectors_1D.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/13_selectors_1D.html
23 14_selectors_2D.py výběr prvků a vektorů (selektor dvourozměrného pole) https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/14_selectors_2D.py
24 14_selectors_2D.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/14_selectors_2D.html
25 15_slicing.py řezy (slicing) https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/15_slicing.py
26 15_slicing.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscryp­t/15_slicing.html
27 16_add.py součet matic (přetížený operátor), nekorektní příklad https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/16_add.py
28 16_add.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/16_add.html
29 17_add.py součet matic (přetížený operátor), korektní příklad https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/17_add.py
30 17_add.html webová stránka s načtením modulu https://github.com/tisnik/most-popular-python-libs/blob/master/numscrypt/17_add.html

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

V této kapitole jsou uvedeny odkazy na skripty, s nimiž jsme se seznámili při popisu nástroje Transcrypt v tomto článku:

# Příklad Stručný popis Adresa
1 factorial.py výpočet faktoriálu realizovaný v Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/transcryp­t/factorial.py
2 factorial.js výsledek transpřekladu příkladu factorial.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcryp­t/factorial.js
3 lists.py základní práce se seznamy v Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/lists.py
4 lists.js výsledek transpřekladu příkladu lists.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/lists.js
5 maps.py základní práce s mapami (slovníky) v Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/maps.py
6 maps.js výsledek transpřekladu příkladu maps.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/maps.js
7 adder.py jednoduchá funkce pro součet dvou hodnot https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/adder.py
8 adder.js výsledek transpřekladu příkladu adder.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/adder.js
9 counter_closure.py čítač realizovaný s využitím uzávěru v Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/transcryp­t/counter_closure.py
10 counter_closure.js výsledek transpřekladu příkladu counter_closure.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcryp­t/counter_closure.js
11 hello.py demonstrační příklad dodávaný přímo s Transcryptem https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/hello.py
12 hello.js výsledek transpřekladu příkladu hello.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/hello.js
       
13 canvas1.html HTML stránka s kreslicí plochou a načtením skriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcryp­t/canvas1.html
14 canvas1.py vykreslení textu na kreslicí plochu naprogramované v Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/canvas1.py
15 canvas1.js výsledek transpřekladu příkladu canvas1.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/canvas1.js
       
16 canvas2.html HTML stránka s kreslicí plochou a načtením skriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcryp­t/canvas2.html
17 canvas2.py vykreslení cesty složené ze křivek na kreslicí plochu naprogramované v Pythonu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/canvas2.py
18 canvas2.js výsledek transpřekladu příkladu canvas2.py do JavaScriptu https://github.com/tisnik/most-popular-python-libs/blob/master/transcrypt/canvas2.js

20. Odkazy na Internetu

  1. Numscrypt: A tiny bit of NumPy for Transcrypt, using JavaScript typed arrays
    https://www.transcrypt.or­g/numscrypt/numscrypt.html
  2. Dokumentace k projektu Numscrypt
    https://www.transcrypt.or­g/numscrypt/docs/html/index­.html
  3. Stránky projektu Transcrypt
    https://www.transcrypt.org/
  4. Balíček Transcrypt na PyPi
    https://pypi.org/project/Transcrypt/
  5. Transcrypt na GitHubu
    https://github.com/Transcryp­tOrg/Transcrypt
  6. Transcrypt: getting started
    https://www.transcrypt.or­g/docs/html/installation_u­se.html
  7. Google Closure Compiler
    https://github.com/google/closure-compiler
  8. Statické typové kontroly zdrojových kódů Pythonu prováděné nástrojem Mypy
    https://www.root.cz/clanky/staticke-typove-kontroly-zdrojovych-kodu-pythonu-provadene-nastrojem-mypy/
  9. Statické typové kontroly zdrojových kódů Pythonu prováděné nástrojem Mypy (2.část)
    https://www.root.cz/clanky/staticke-typove-kontroly-zdrojovych-kodu-pythonu-provadene-nastrojem-mypy-2-cast/
  10. Statické typové kontroly zdrojových kódů Pythonu prováděné nástrojem Mypy (3)
    https://www.root.cz/clanky/staticke-typove-kontroly-zdrojovych-kodu-pythonu-provadene-nastrojem-mypy-3/
  11. PyScript
    https://pyscript.net/
  12. PyScript na GitHubu
    https://github.com/pyscript/pyscript
  13. Getting started with PyScript
    https://github.com/pyscrip­t/pyscript/blob/main/docs/tu­torials/getting-started.md
  14. PyScript examples
    https://github.com/pyscrip­t/pyscript/tree/main/exam­ples
  15. What is PyScript
    https://docs.pyscript.net/la­test/concepts/what-is-pyscript.html
  16. Pyodide
    https://pyodide.org/en/stable/
  17. PyScript: JavaScript and Python Interoperability
    https://www.jhanley.com/blog/pyscript-javascript-and-python-interoperability/
  18. Pyscript: JavaScript Event Callbacks
    https://www.jhanley.com/blog/pyscript-javascript-callbacks/
  19. Compiling to WebAssembly: It’s Happening!
    https://hacks.mozilla.org/2015/12/com­piling-to-webassembly-its-happening/
  20. WebAssembly
    https://webassembly.org/
  21. Blogy o WASM a Emscripten
    https://www.jamesfmackenzi­e.com/sitemap/#emscripten
  22. wat2wasm demo
    https://webassembly.github­.io/wabt/demo/wat2wasm/
  23. WABT: The WebAssembly Binary Toolkit
    https://github.com/WebAssembly/wabt
  24. Programming using Web Assembly
    https://medium.com/@alexc73/pro­gramming-using-web-assembly-c4c73a4e09a9
  25. Experiments with image manipulation in WASM using Go
    https://agniva.me/wasm/2018/06/18/shim­mer-wasm.html
  26. Fable
    https://fable.io/
  27. Využití WebAssembly z programovacího jazyka Go
    https://www.root.cz/clanky/vyuziti-webassembly-z-programovaciho-jazyka-go/
  28. WebAssembly prošlo standardizací ve W3C, byla vydána verze 1.0
    https://www.root.cz/zpravic­ky/webassembly-proslo-standardizaci-ve-w3c-byla-vydana-verze-1–0/
  29. WebAssembly na Wiki Golangu
    https://github.com/golang/go/wi­ki/WebAssembly
  30. The future of WebAssembly – A look at upcoming features and proposals
    https://blog.scottlogic.com/2018/07/20/wasm-future.html
  31. Writing WebAssembly By Hand
    https://blog.scottlogic.com/2018/04/26/we­bassembly-by-hand.html
  32. WebAssembly Specification
    https://webassembly.github­.io/spec/core/index.html
  33. Index of Instructions
    https://webassembly.github­.io/spec/core/appendix/in­dex-instructions.html
  34. The WebAssembly Binary Toolkit
    https://github.com/WebAssembly/wabt
  35. Will WebAssembly replace JavaScript? Or Will WASM Make JavaScript More Valuable in Future?
    https://dev.to/vaibhavshah/will-webassembly-replace-javascript-or-will-wasm-make-javascript-more-valuable-in-future-5c6e
  36. Roadmap (pro WebAssemly)
    https://webassembly.org/roadmap/
  37. S-expression
    https://en.wikipedia.org/wiki/S-expression
  38. Understanding WebAssembly text format
    https://developer.mozilla.org/en-US/docs/WebAssembly/Under­standing_the_text_format
  39. Learning Golang through WebAssembly – Part 1, Introduction and setup
    https://www.aaron-powell.com/posts/2019–02–04-golang-wasm-1-introduction/
  40. Learning Golang through WebAssembly – Part 2, Writing your first piece of Go
    https://www.aaron-powell.com/posts/2019–02–05-golang-wasm-2-writing-go/
  41. Learning Golang through WebAssembly – Part 3, Interacting with JavaScript from Go
    https://www.aaron-powell.com/posts/2019–02–06-golang-wasm-3-interacting-with-js-from-go/
  42. Golang webassembly (wasm) testing with examples
    https://jelinden.fi/blog/golang-webassembly-wasm-testing-with-examples/qB7Tb2KmR
  43. Use Cases (of WebAssembly)
    https://webassembly.org/docs/use-cases/
  44. JupyterLite na PyPi
    https://pypi.org/project/jupyterlite/
  45. JupyterLite na GitHubu
    https://github.com/jupyter­lite/jupyterlite
  46. Dokumentace k projektu JupyterLite
    https://github.com/jupyter­lite/jupyterlite
  47. A quick guide about Python implementations
    https://blog.rmotr.com/a-quick-guide-about-python-implementations-aa224109f321
  48. How Brython works
    https://github.com/brython-dev/brython/wiki/How%20Brython%20works
  49. Brython – A Python 3 implementation for client-side web programming
    http://www.brython.info/
  50. Brython videos and talks
    https://github.com/brython-dev/brython/wiki/Brython-videos-and-talks
  51. What is Brython?
    https://medium.com/frontendweb/what-is-brython-6edb424b07f6
  52. Python in browser (tabulka s porovnáními)
    http://stromberg.dnsalias­.org/~strombrg/pybrowser/pyt­hon-browser.html
  53. JavaScript is Assembly Language for the Web: Sematic Markup is Dead! Clean vs. Machine-coded HTML
    http://www.hanselman.com/blog/Ja­vaScriptIsAssemblyLanguage­ForTheWebSematicMarkupIsDe­adCleanVsMachinecodedHTML­.aspx
  54. pyscript VS brython
    https://www.libhunt.com/compare-pyscript-vs-brython
  55. PyScript – Run Python in the Browser! THE END of JavaScript???
    https://www.youtube.com/wat­ch?v=du8vQC44PC4
  56. PyScript is Python in Your Browser
    https://www.youtube.com/wat­ch?v=MJvCeKwr4z4
  57. JupyterLite na PyPi
    https://pypi.org/project/jupyterlite/
  58. JupyterLite na GitHubu
    https://github.com/jupyter­lite/jupyterlite
  59. Dokumentace k projektu JupyterLite
    https://github.com/jupyter­lite/jupyterlite
  60. Matplotlib Home Page
    http://matplotlib.org/
  61. Matplotlib (Wikipedia)
    https://en.wikipedia.org/wi­ki/Matplotlib
  62. Popis barvových map modulu matplotlib.cm
    https://gist.github.com/en­dolith/2719900#id7
  63. Ukázky (palety) barvových map modulu matplotlib.cm
    http://matplotlib.org/exam­ples/color/colormaps_refe­rence.html
  64. Galerie grafů vytvořených v Matplotlibu
    https://matplotlib.org/3.2.1/gallery/
  65. Replacing Javascript with Python
    https://stackoverflow.com/qu­estions/69510962/replacing-javascript-with-python
  66. Can Python Replace Javascript in the Future?
    https://dev.to/katholder/can-python-replace-javascript-in-the-future-4bbn
  67. asm.js
    http://asmjs.org/
  68. asm.js: Working Draft
    http://asmjs.org/spec/latest/
  69. Manual asm.js Demonstration
    https://www.youtube.com/wat­ch?v=qkiqMuf5M84
  70. asm.js – frequently asked questions
    http://asmjs.org/faq.html
  71. When asm.js is faster than normal JS code, why should I write new code in JS?
    https://stackoverflow.com/qu­estions/16527195/when-asm-js-is-faster-than-normal-js-code-why-should-i-write-new-code-in-js
  72. Faster Canvas Pixel Manipulation with Typed Arrays
    https://hacks.mozilla.org/2011/12/fas­ter-canvas-pixel-manipulation-with-typed-arrays/
  73. Anatomy of source maps
    https://www.bugsnag.com/blog/source-maps/
  74. Source Map Revision 3 Proposal
    https://sourcemaps.info/spec.html
  75. Integrovaná vývojová prostředí ve Fedoře: vykreslování grafů s využitím knihoven Numpy a matplotlib
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-vykreslovani-grafu-s-vyuzitim-knihoven-numpy-a-matplotlib/
  76. Integrovaná vývojová prostředí ve Fedoře: praktické použití IPython Notebooku a knihovny Numpy (2.část)
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-prakticke-pouziti-ipython-notebooku-a-knihovny-numpy-2-cast/
  77. Integrovaná vývojová prostředí ve Fedoře: praktické použití IPython Notebooku a knihovny Numpy
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-prakticke-pouziti-ipython-notebooku-a-knihovny-numpy/

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.