Obsah
1. Gophernotes: kombinace interaktivního prostředí Jupyteru s jazykem Go
2. Projekt Gonum Numerical Packages (Gonum)
4. Klávesové zkratky použitelné v interaktivní smyčce projektu Gomacro
5. Základní použití interaktivní smyčky REPL projektu Gomacro
6. Manipulace s maticemi (v REPL)
7. Zobrazení vybraného obsahu rozsáhlých matic
9. Maticový součin a podobné operace
10. Použití projektu Gophernotes společně s Jupyter notebookem
11. Spuštění Gophernotes v Dockeru
12. Kombinace projektů Gophernotes, Gonum a Gomacro
16. Načtení rastrových obrázků
17. Načtení vektorových obrázků ve formátu SVG
18. Obsah navazující části seriálu
19. Repositář s demonstračními příklady
1. Gophernotes: kombinace interaktivního prostředí Jupyteru s jazykem Go
„There is a tension, especially in scientific computing, between ease and simplicity“
V dnešním článku si popíšeme potenciálně velmi užitečný nástroj nazvaný Gophernotes, který uživatelům (a zdaleka se nemusí jednat pouze o vývojáře) používajícím programovací jazyk Go zpřístupňuje interaktivní prostředí založené na známém projektu Jupyter, který vznikl z neméně známého a používaného projektu IPython Notebook. Toto interaktivní prostředí, které se zobrazuje přímo ve webovém prohlížeči, obsahuje klasickou smyčku REPL (Read–Eval–Print–Loop), což mj. znamená, že se jednotlivé výrazy zapsané uživatelem mohou ihned vyhodnocovat s prakticky okamžitou zpětnou vazbou. Navíc však nástroj Gophernotes dokáže do okna prohlížeče vykreslovat základní grafy, a to jak s přímým využitím předaných dat (vektory či sekvence čísel), tak i při specifikaci funkce, jejíž průběh se má vykreslit (existují zde ovšem mnohá omezení, kterými se budu zabývat v navazujících kapitolách). Třešničkou na dortu je podpora pro práci se vzorci psanými v TeXu či LaTeXu.
Obrázek 1: Klasický IPython notebook – nástroj, který umožňoval interaktivní ovládání interpretru Pythonu z GUI, nabízel všechny možnosti konzolového IPythonu a navíc i podporoval práci s grafickými objekty (rastrové obrázky, grafy, diagramy atd.).
Celé grafické uživatelské rozhraní Gophernotes napodobuje diář (notebook), do kterého se zapisují jak poznámky, tak i programový kód a jeho výsledek, takže se tento systém může hodit i pro tvorbu (interaktivních) prezentací, použití sdílené pracovní plochy atd. Ostatně v tomto ohledu není přístup zvolený autory nijak nový ani přelomový, protože například i populární Matlab používá podobnou technologii (i když založenou na jiném programovacím jazyku).
DObrázek 2: Použití Pythonu v Jupyteru při výpočtu fraktálů. Složitější numerické výpočty jsou jednou z oblastí, v níž by bylo výhodnější použít jiný programovací jazyk, resp. přesněji jeho jádro propojené s Jupyterem.
Zdroj
Již v úvodním odstavci jsme si řekli, že Gophernotes je založen na projektu Jupyter. Ve skutečnosti Gophernotes do Jupyteru doplňuje modul (takzvaný kernel) zajišťující interakci s jazykem Go, podobně jako existují další podobné moduly určené pro programovací jazyky Python, Julia, Lua, jazyk Hy atd. V případě jazyka Go je ovšem situace poněkud složitější, protože Go je primárně překladačem. Aby bylo možné zkombinovat možnosti interpretru a klasického překladače, vznikl projekt pojmenovaný Gomacro, o jehož některých možnostech se zmíníme v navazujících kapitolách.
Obrázek 3: Nejenom pro numerické výpočty může být ideální kombinací jazyk Julia a projekt Jupyter notebook.
Zdroj
2. Projekt Gonum Numerical Packages (Gonum)
Samotný programovací jazyk Go obsahuje podporu pro práci s maticemi a řezy (ostatně se jedná o základní datové typy tohoto jazyka). Práce s těmito datovými strukturami je podporována i ve standardní knihovně jazyka. Ovšem například v porovnání se známou a velmi často používanou knihovnou NumPy ze světa Pythonu (nebo s možnostmi Matlabu či R) jsou možnosti standardní instalace Go v této oblasti mnohem menší. Ovšem některé operace, které známe z NumPy, byly implementovány v sadě knihoven, které jsou součástí projektu nazvaného jednoduše Gonum Numerical Packages. Tento projekt obsahuje zejména knihovnu pro práci s maticemi (naprosté základy si ukážeme níže a více se jim budeme věnovat příště), algoritmy lineární algebry, podporu pro tvorbu grafů, podporu práce s takzvanými „datovými rámci“ (ve světě Pythonu se používá pandas) atd.
Obrázek 4: Logo projektu Gonum Numerical Packages.
Samotnou sadu knihoven z projektu Gonum Numerical Packages nainstalujeme (pro aktivního uživatele) snadno, konkrétně příkazem „go get“:
$ go get -u gonum.org/v1/gonum/...
S některými vlastnostmi knihovnu mat z projektu Gonum se setkáme po instalaci projektu Gomacro.
3. Projekt Gomacro
Jak jsme si již řekli v úvodní kapitole, aby bylo možné programovací jazyk Go zařadit do nástrojů typu Jupyter, je nutné, aby byl k dispozici buď přímo klasický interpret, nebo alespoň překladač umožňující postupný překlad jednotlivých výrazů, funkcí a metod s jejich následným spouštěním a zpracováním výsledků. A právě tato funkcionalita je nabízena projektem nazvaným Gomacro, který dokáže pracovat jako interpret jazyka Go a nabízí programátorům i plnohodnotnou smyčku REPL.
Instalace tohoto projektu se opět provede příkazem „go get“:
$ go get -u github.com/cosmos72/gomacro
Dále je nutné se přesvědčit o tom, že je adresář $HOME/go/bin zařazen do proměnné prostředí PATH. V opačném případě by totiž nebylo možné příkaz gomacro volat odkudkoli (což platí i pro další nástroje naprogramované v jazyku Go a instalované příkazem „go get“).
Pokud je $HOME/go/bin vložen do proměnné prostředí PATH, bude možné Gomacro spustit:
$ gomacro // GOMACRO, an interactive Go interpreter with generics and macros // Copyright (C) 2018-2019 Massimiliano Ghilardi <https://github.com/cosmos72/gomacro> // License MPL v2.0+: Mozilla Public License version 2.0 or later <http://mozilla.org/MPL/2.0/> // This is free software with ABSOLUTELY NO WARRANTY. // // Type :help for help gomacro>
// warning: could not find package "github.com/cosmos72/gomacro" in $GOPATH = "/home/tester/go/", assuming package is located in "/home/tester/go/src/github.com/cosmos72/gomacro"
Aby bylo možné odlišit příkazy jazyka Go od nových příkazů zavedených Gomacrem, začínají příkazy Gomacra dvojtečkou:
gomacro> :help // type Go code to execute it. example: func add(x, y int) int { return x + y } // interpreter commands: :debug EXPR debug expression or statement interactively :env [NAME] show available functions, variables and constants in current package, or from imported package NAME :help show this help :inspect EXPR inspect expression interactively :options [OPTS] show or toggle interpreter options :package "PKGPATH" switch to package PKGPATH, importing it if possible :quit quit the interpreter :unload "PKGPATH" remove package PKGPATH from the list of known packages. later attempts to import it will trigger a recompile :write [FILE] write collected declarations and/or statements to standard output or to FILE use :opt Declarations and/or :opt Statements to start collecting them // abbreviations are allowed if unambiguous.
Dále je možné prozkoumat výrazy jazyka Go:
gomacro> :inspect 1*(2+3) 1*(2+3) = {int 5} // untyped.Lit 0. Kind = int // untyped.Kind 1. Val = 5 // constant.Value 2. basicTypes = [<nil> 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 0x11060b0 <nil> <nil> <nil> <nil> <nil> <nil> <nil> 0x11060b0 <nil> 0x11060b0] // *[]xreflect.Type // type ? for inspector help
Prozkoumat lze i volání funkcí, kdy se mj. zobrazí jejich výsledek:
gomacro> import "fmt" gomacro> :inspect fmt.Printf("%d\n", 42) // warning: expression returns 2 values, using only the first one: [int error] 42 fmt.Printf("%d\n", 42) = 3 // int // type ? for inspector help
Popř. lze vypsat metody aplikovatelné pro zvoleného příjemce (receiver):
inspect fmt.Printf("%d\n", 42)> methods methods of int: m0. func (int).Add(int, int) int m1. func (int).And(int, int) int m2. func (int).AndNot(int, int) int m3. func (int).Cmp(int) int m4. func (int).Equal(int) bool m5. func (int).Less(int) bool m6. func (int).Lsh(int, uint8) int m7. func (int).Mul(int, int) int m8. func (int).Neg(int) int m9. func (int).Not(int) int m10. func (int).Or(int, int) int m11. func (int).Quo(int, int) int m12. func (int).Rem(int, int) int m13. func (int).Rsh(int, uint8) int m14. func (int).Sub(int, int) int m15. func (int).Xor(int, int) int
Výpis tzv. prostředí, tj. dostupných funkcí a datových typů:
gomacro> :env // ----- builtin binds ----- Eval = {0x1213270 func(interface{}, interface{}) interface{}} // fast.Function EvalKeepUntyped = {0x1213320 func(interface{}, interface{}) interface{}} // fast.Function EvalType = {0x1213660 func(interface{}, interface{}) reflect.Type} // fast.Function Interp = {0x1213240 func(interface{}) interface{}} // fast.Function MacroExpand = {0x1214310 func(interface{}, interface{}) (go/ast.Node, bool)} // fast.Function MacroExpand1 = {0x1214400 func(interface{}, interface{}) (go/ast.Node, bool)} // fast.Function MacroExpandCodeWalk = {0x12144f0 func(interface{}, interface{}) (go/ast.Node, bool)} // fast.Function Parse = {0x1216310 func(string, interface{}) interface{}} // fast.Function append = 0x120efd0 // fast.Builtin cap = 0x120fb30 // fast.Builtin close = 0x1210290 // fast.Builtin complex = 0x1210880 // fast.Builtin copy = 0x1211f00 // fast.Builtin delete = 0x1212ae0 // fast.Builtin false = {bool false} // untyped.Lit imag = 0x1216e30 // fast.Builtin len = 0x1213960 // fast.Builtin make = 0x1214bd0 // fast.Builtin new = 0x1215bb0 // fast.Builtin nil = nil // panic = 0x1216020 // fast.Builtin print = 0x1216a60 // fast.Builtin println = 0x1216a60 // fast.Builtin real = 0x1216e30 // fast.Builtin recover = 0x12180e0 // fast.Builtin true = {bool true} // untyped.Lit // ----- builtin types ----- Pointer = unsafe.Pointer // unsafe.Pointer bool = bool // bool byte = uint8 // uint8 complex128 = complex128 // complex128 complex64 = complex64 // complex64 error = error // interface float32 = float32 // float32 float64 = float64 // float64 int = int // int int16 = int16 // int16 int32 = int32 // int32 int64 = int64 // int64 int8 = int8 // int8 rune = int32 // int32 string = string // string uint = uint // uint uint16 = uint16 // uint16 uint32 = uint32 // uint32 uint64 = uint64 // uint64 uint8 = uint8 // uint8 uintptr = uintptr // uintptr // ----- main binds ----- fmt = {fmt "fmt", 19 binds, 6 types} // *fast.Import
4. Klávesové zkratky použitelné v interaktivní smyčce projektu gomacro
Vzhledem k tomu, že je gomacro vybaveno i interaktivní smyčkou REPL, je důležité, aby bylo možné editovat příkazový řádek, mít k dispozici historii příkazového řádku (s možností vyhledávání) atd. Pro tento účel používá gomacro knihovnu https://github.com/peterh/liner naprogramovanou v jazyce Go, která je inspirována céčkovou knihovnou linenoise (ke které se ještě na stránkách Rootu vrátíme). V této kapitole jsou vypsány vybrané klávesové zkratky, které jsou ve výchozím nastavení použity v interaktivní smyčce projektu gomacro. Většina zkratek vychází z Emacsu a uživatelé je mohou znát například i z editoru Joe, z shellu (BASH atd.), pokud ovšem není nastaven režim emulující chování textového editoru Vi/Vim. Pro větší přehlednost jsou příkazy rozděleny do několika skupin.
Příkazy pro přesuny kurzoru
Základní příkazy pro přesun kurzoru používají kombinaci kláves Ctrl+znak, Alt+znak popř. alternativně Esc, znak v případě, že zkratky Alt+znak kolidují s emulátorem terminálu (například vyvolávají příkazy z menu). V případě, že je terminál správně nakonfigurován, měly by fungovat i kurzorové šipky, kombinace Ctrl+šipky a navíc i klávesy Home a End (se zřejmou funkcí):
Klávesa | Alternativa | Význam |
---|---|---|
Ctrl+B | šipka doleva | přesun kurzoru na předchozí znak |
Ctrl+F | šipka doprava | přesun kurzoru na následující znak |
Alt+B | Ctrl+šipka doleva | přesun kurzoru na předchozí slovo |
Alt+F | Ctrl+šipka doprava | přesun kurzoru na další slovo |
Esc, B | shodné s klávesovou zkratkou Alt+B | |
Esc, F | shodné s klávesovou zkratkou Alt+F | |
Ctrl+A | Home | přesun kurzoru na začátek řádku |
Ctrl+E | End | přesun kurzoru na konec řádku |
Mazání textu, práce s yank bufferem
Pro přesun části textu v rámci editovaného řádku (nebo na nějaký jiný řádek atd.) se používá takzvaný yank buffer (v Emacsu se používá označení kill ring), do něhož se smazaný text uloží. Pro vložení takto smazaného textu do jiné oblasti se používá operace nazvaná yank (odpovídá operaci paste). Některé dále uvedené příkazy dokážou s yank bufferem pracovat (obdoba cut/copy/paste):
Klávesa | Význam |
---|---|
Ctrl+H | smaže znak před kurzorem |
BackSpace | smaže znak před kurzorem |
Ctrl+K | smaže text od kurzoru do konce řádku |
Ctrl+U | smaže text od začátku řádku do pozice kurzoru |
Ctrl+W | smaže předchozí slovo |
Alt+D | smaže následující slovo |
Ctrl+Y | vloží text z yank bufferu na místo, na němž se nachází kurzor (yank neboli paste) |
Alt+Y | po operaci Ctrl+Y dokáže rotovat historií a obnovit tak (před)předchozí smazaný text |
Ctrl+D | smaže jeden znak (pokud je ovšem na řádku nějaký obsah, jinak typicky ukončí aplikaci) |
Práce s historií dříve zadaných příkazů
Velmi užitečné klávesové zkratky umožňují procházet historií dříve zadaných příkazů. Pro vyhledávání v historii slouží zkratka Ctrl+R:
Klávesa | Význam |
---|---|
Ctrl+P | průchod historií – předchozí text |
Ctrl+N | průchod historií – následující text |
Ctrl+R | zpětné (interaktivní) vyhledávání v historii |
Některé další dostupné příkazy
Mezi další užitečné zkratky patří režim completeru, v němž se gomacro snaží nalézt symbol z tabulky funkcí či metod:
Klávesa | Význam |
---|---|
Tab | implicitní klávesa pro zavolání completeru |
Shift+Tab | návrat na předchozí návrh doplnění jména funkce/metody |
Ctrl+T | prohození dvou znaků (před kurzorem a na pozici kurzoru) |
Ctrl+L | smazání obrazovky |
5. Základní použití interaktivní smyčky REPL projektu Gomacro
V této kapitole se seznámíme s některými možnostmi, které nám interaktivní smyčka projektu Gomacro nabízí. Pokud na vstup zadáme nějaký výraz (aritmetický, logický, výraz s řetězci atd.), je tento výraz přeložen a ihned vyhodnocen. Jeho výsledek se vypíše na výstup, stejně, jako by jazyk Go byl interpretován:
gomacro> 1+1 {int 2} // untyped.Lit
Můžeme provést i import knihovny (balíčku):
gomacro> import "fmt"
U funkce či výrazu vracejícího více hodnot se zobrazí všechny hodnoty. V případě funkce i se jmény a typy návratových hodnot (velmi praktické, protože ihned vidíme, že například funkce fmt.Println vrací ve druhé návratové hodnotě příznak chyby):
gomacro> fmt.Println("test") test 5 // int <nil> // error
Deklarovat můžeme i proměnné, a to libovolného typu, včetně řezů (slice):
gomacro> var a []int gomacro> a [] // []int gomacro> a=append(a, 10) gomacro> a [10] // []int
Zavolání metod objektů, zde konkrétně metody řezu:
gomacro> a.Cap() 1 // int gomacro> a.Len() 1 // int
Použít můžeme i programovou smyčku:
gomacro> for i := 1; i < 10; i++ { . . . . a=append(a, i) . . . . } gomacro> a [10 1 2 3 4 5 6 7 8 9] // []int gomacro> a.Cap() 16 // int gomacro> a.Len() 10 // int
Další příklad – funkce s několika návratovými hodnotami:
gomacro> func x(i int) (int, float64, byte) { . . . . return i, 1.0/float64(i), byte(i) . . . . } gomacro> x(10) 10 // int 0.1 // float64 10 // uint8
Funkce vracející chybu:
gomacro> f, err := os.Open("foobarbaz") gomacro> f // *os.File gomacro> err open foobarbaz: no such file or directory // error
Funkce, která naopak otevře existující soubor:
gomacro> f, err := os.Open(".bashrc") gomacro> f &{0xc00048d260} // *os.File gomacro> err <nil> // error
Malá připomínka, že k hodnotě nil je přiřazen i typ:
gomacro> var ii interface{} = nil gomacro> ii <nil> // interface{} gomacro> var p *int = nil gomacro> p <nil> // *int gomacro> var m map[string]string = nil gomacro> m map[] // map[string]string
6. Manipulace s maticemi (v REPL)
Nyní, když máme nainstalovánu jak interaktivní smyčku REPL (Gomacro) i projekt Gonum s několika numerickými knihovnami, si můžeme ukázat, jak se manipuluje s maticemi, které v oblasti numerických výpočtů mnohdy představují základní datový typ.
Používat budeme dva balíčky – standardní balíček „fmt“ a balíček „mat“ z Gonum:
gomacro> import "fmt" gomacro> import "gonum.org/v1/gonum/mat" // debug: looking for package "gonum.org/v1/gonum/mat" ... // debug: compiling "/home/ptisnovs/go/src/gomacro.imports/gonum.org/v1/gonum/mat/mat.go" ...
Pro reprezentaci matic se používá několik struktur. Základem je je dense matrix používaná pro matice běžné velikosti, které obsahují libovolné prvky (a kde typicky nepřevažují prvky nulové):
gomacro> zero := mat.NewDense(5, 6, nil) gomacro> zero &{{5 6 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 6} 5 6} // *gonum.org/v1/gonum/mat.Dense
Naplnění matice daty:
gomacro> m2 := mat.NewDense(3, 4, []float64{1,2,3,4,5,6,7,8,9,10,11,12})
7. Zobrazení vybraného obsahu rozsáhlých matic
Nyní se pokusme vytvořit relativně velkou matici o rozměrech 100×100 prvků:
gomacro> big := mat.NewDense(100, 100, nil)
Matici můžeme naplnit daty, a to pomocí metody Set (vyplníme jen prvky na hlavní úhlopříčce):
gomacro> for i := 0; i < 100; i++ { . . . . big.Set(i, i, 1) . . . . }
Přímý tisk hodnoty takové matice ovšem není přehledný:
gomacro> big &{{100 100 [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... ... ... 0 0 0 0 0 1] 100} 100 100} // *gonum.org/v1/gonum/mat.Dense
Ani přímý tisk přes standardní funkci fmt.Printf není ideální:
gomacro> fmt.Printf("%v\n", big) &{{100 100 [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... ... ...
Výhodnější je použití funkce mat.Formatted, které se ve druhém parametru předá oddělovač hodnot na řádku a ve třetím parametru pak informace o tom, kolik mezních sloupců a řádků se má vytisknout. Pokud nám postačuje tisk prvních a posledních tří řádků a sloupců, lze použít:
gomacro> fmt.Printf("excerpt big identity matrix: %v\n\n", . . . . mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3))) excerpt big identity matrix: Dims(100, 100) ⎡1 0 0 ... ... 0 0 0⎤ ⎢0 1 0 0 0 0⎥ ⎢0 0 1 0 0 0⎥ . . . ⎢0 0 0 1 0 0⎥ ⎢0 0 0 0 1 0⎥ ⎣0 0 0 ... ... 0 0 1⎦ 261 // int <nil> // error
V REPLu navíc nemusíme volat funkci fmt.Printf, protože se výsledná hodnota zobrazí automaticky:
gomacro> mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3)) Dims(100, 100) ⎡1 0 0 ... ... 0 0 0⎤ ⎢0 1 0 0 0 0⎥ ⎢0 0 1 0 0 0⎥ . . . ⎢0 0 0 1 0 0⎥ ⎢0 0 0 0 1 0⎥ ⎣0 0 0 ... ... 0 0 1⎦ // fmt.Formatter
Dtto, ale pro mezních pět řádků a sloupců:
gomacro> mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(5)) Dims(100, 100) ⎡1 0 0 0 0 ... ... 0 0 0 0 0⎤ ⎢0 1 0 0 0 0 0 0 0 0⎥ ⎢0 0 1 0 0 0 0 0 0 0⎥ ⎢0 0 0 1 0 0 0 0 0 0⎥ ⎢0 0 0 0 1 0 0 0 0 0⎥ . . . ⎢0 0 0 0 0 1 0 0 0 0⎥ ⎢0 0 0 0 0 0 1 0 0 0⎥ ⎢0 0 0 0 0 0 0 1 0 0⎥ ⎢0 0 0 0 0 0 0 0 1 0⎥ ⎣0 0 0 0 0 ... ... 0 0 0 0 1⎦ // fmt.Formatter
8. Transpozice a součet matic
Mezi další podporované základní maticové operace patří transpozice a součet matic.
Nejdříve vytvoříme proměnnou pro uložení výsledku (nealokuje se žádná další paměť):
gomacro> var c mat.Dense gomacro> c {mat:{0 0 [] 0} capRows:0 capCols:0} // gonum.org/v1/gonum/mat.Dense
Dále vytvoříme dvě matice se třemi řádky a čtyřmi prvky na řádku:
gomacro> m1 := mat.NewDense(3, 4, {}) gomacro> m1 &{{3 4 [0 0 0 0 0 0 0 0 0 0 0 0] 4} 3 4} // *gonum.org/v1/gonum/mat.Dense gomacro> m2 := mat.NewDense(3, 4, []float64{1,2,3,4,5,6,7,8,9,10,11,12}) gomacro> m2 &{{3 4 [1 2 3 4 5 6 7 8 9 10 11 12] 4} 3 4} // *gonum.org/v1/gonum/mat.Dense
Obě matice vytiskneme v čitelném formátu:
gomacro> mat.Formatted(m1) ⎡0 0 0 0⎤ ⎢0 0 0 0⎥ ⎣0 0 0 0⎦ // fmt.Formatter gomacro> mat.Formatted(m2) ⎡ 1 2 3 4⎤ ⎢ 5 6 7 8⎥ ⎣ 9 10 11 12⎦ // fmt.Formatter
Výpočet transponované matice s jejím následným vytištěním:
gomacro> m3 := m2.T() gomacro> mat.Formatted(m3) ⎡ 1 5 9⎤ ⎢ 2 6 10⎥ ⎢ 3 7 11⎥ ⎣ 4 8 12⎦ // fmt.Formatter
Součet matic je řešen metodou:
gomacro> c.Add(m3, m3) gomacro> mat.Formatted(&c) ⎡ 2 10 18⎤ ⎢ 4 12 20⎥ ⎢ 6 14 22⎥ ⎣ 8 16 24⎦ // fmt.Formatter
9. Maticový součin a podobné operace
Podporována je i operace maticového součinu, ale pochopitelně pouze za předpokladu, že počet sloupců první matice odpovídá počtu řádků matice druhé:
gomacro> var c mat.Dense gomacro> c.Mul(m3, m2) mat: dimension mismatch
Pokud matice m2 a m3 předáme ve správném pořadí, bude možné matice vynásobit a uložit výsledek do příjemce:
gomacro> c.Mul(m2, m3) gomacro> mat.Formatted(&c) ⎡ 30 70 110⎤ ⎢ 70 174 278⎥ ⎣110 278 446⎦ // fmt.Formatter
Provést lze i násobení dvou matic prvek po prvku (což ovšem neodpovídá maticovému násobení):
gomacro> var c mat.Dense gomacro> c.MulElem(m3, m3) gomacro> mat.Formatted(&c) ⎡ 1 25 81⎤ ⎢ 4 36 100⎥ ⎢ 9 49 121⎥ ⎣ 16 64 144⎦ // fmt.Formatter
10. Použití projektu Gophernotes společně s Jupyter notebookem
Nástroj Gophernotes je založen na klasické technologii klient-server, kde klientem je webový prohlížeč spuštěný u uživatele (či uživatelů) a serverem je Jupyter s přidaným modulem (kernelem) pro jazyk Go vybaveným výše popsaným projektem gomacro. Výraz, popř. blok výrazů představujících programový kód napsaný v programovacím jazyce Go, je po stlačení klávesové zkratky Shift+Enter přenesen na server, kde je zpracován a výsledek je poslán zpět do prohlížeče.
JavaScriptový kód na straně prohlížeče zajistí interpretaci získaných výsledků a jejich zařazení na správné místo do dynamické webové stránky (jedná se vlastně o dnes tak populární SPA – Single Page Application se všemi přednostmi a zápory, které toto řešení přináší). Výsledky poslané serverem na klienta mohou být ve skutečnosti různého typu; typicky se jedná o fragment HTML (tabulky atd.), obrázek typu SVG (graf, histogram), rastrový obrázek (graf získaný například ze systému R), vzorec vykreslený z TeXového či LaTeXového zdrojového kódu apod. Samotná architektura nástroje Jupyter je otevřená a poměrně snadno rozšiřitelná, což znamená, že je v případě potřeby možné přidat například další typy grafů apod.
Existují i podobně koncipované projekty. Na stránkách Rootu jsme se například seznámili s projektem Gorilla REPL, který je určen pro programovací jazyk Clojure:
Obrázek 5: Interaktivní prostředí nástroje Gorilla REPL spuštěné v běžném webovém prohlížeči (zde konkrétně ve Firefoxu).
Obrázek 6: Standardní grafy jsou v Gorilla REPL do stránky vkládány ve formátu SVG.
Obrázek 7: Ukázka použití jednoduchého sloupcového grafu.
11. Spuštění Gophernotes v Dockeru
Nejjednodušší způsob, jakým lze spustit Gophernotes i se všemi potřebnými závislostmi, spočívá v použití Dockeru, protože již existuje připravený obraz obsahující Gophernotes, Jupyter, gomacro i další knihovny pro numerické výpočty a zpracování dat. Následující příkaz zajistí stažení obrazů, spuštění Gophernotesu a namapování HTTP serveru (Jupyter) na port 8888:
$ docker run -it -p 8888:8888 gopherdata/gophernotes:latest-ds Unable to find image 'gopherdata/gophernotes:latest-ds' locally Trying to pull repository docker.io/gopherdata/gophernotes ... sha256:e2ef4a5b318604b8e5116fcf470e11fecbb2c18631cb73bdbed46ed026e862a6: Pulling from docker.io/gopherdata/gophernotes a44d943737e8: Pull complete 0bbfb29b138b: Pull complete ef49c0fa046c: Pull complete Digest: sha256:e2ef4a5b318604b8e5116fcf470e11fecbb2c18631cb73bdbed46ed026e862a6 Status: Downloaded newer image for docker.io/gopherdata/gophernotes:latest-ds [I 15:14:32.110 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret [I 15:14:32.998 NotebookApp] Serving notebooks from local directory: / [I 15:14:32.999 NotebookApp] The Jupyter Notebook is running at: [I 15:14:33.000 NotebookApp] http://(6c7428d3f7f9 or 127.0.0.1):8888/?token=f4d754332b4be755cfb351018840af76767e80829d7dfc61 [I 15:14:33.000 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). [C 15:14:33.006 NotebookApp] To access the notebook, open this file in a browser: file:///root/.local/share/jupyter/runtime/nbserver-1-open.html Or copy and paste one of these URLs: http://(6c7428d3f7f9 or 127.0.0.1):8888/?token=f4d754332b4be755cfb351018840af76767e80829d7dfc61
12. Kombinace projektů Gophernotes, Gonum a Gomacro
„There is a tension, especially in scientific computing, between ease and simplicity“
Do adresního řádku webového browseru napíšeme adresu: http://127.0.0.1:8888.
Obrázek 8: Prohlížeč se zeptá na token, který zkopírujeme ze zprávy vypsané po spuštění Dockeru s gophernotesem.
Obrázek 9: Grafické uživatelské rozhraní Jupyteru s Gophernotesem.
Obrázek 10: Zprávy zapisované na chybový výstup jsou podbarveny červeně, zprávy zapisované na výstup standardní nemají podbarvení žádné (implicitní barvou je bílé pozadí).
Obrázek 11: Formátování matic tak, jak jsme si to ukázali v předchozích kapitolách.
13. Použití Markdownu
Vzhledem k tomu, že je možné projekt Jupyter použít i pro tvorbu prezentací, asi nás nepřekvapí, že je podporována tvorba poznámek, které mohou být naformátovány. Podporován je především známý a široce používaný formátovací jazyk Markdown. Podívejme se na následující příklad, v němž je Markdown použit pro zobrazení textu neproporcionálním písmem, tučným písmem a kurzivou:
Obrázek 12: Použití funkce Display.markdown.
14. Matematická sazba
Podporována je i matematická sazba odvozená od možností TeXu a LaTeXu. Příkladem může být zápis vzorce s integrálem a zlomkem:
F(x) &= \int^a_b \frac{1}{3}x^3
Další dva příklady ukazují použití horních indexů (mocnin), zlomku a zápisu druhé odmocniny:
Display(display.Math(`x^2+y^2`)) Display(display.Math(`\frac{1}{\sqrt{x}}`))
Obrázek 13: Výsledek zobrazení vzorce \frac{1}{\sqrt{x}}
.
15. Víceřádkové vzorce
Použít lze i víceřádkovou sazbu vzorců. Časté bývá použití matic, na jejichž začátku a konci musíme použít „velké“ hranaté závorky (namísto pouhého zápisu [ a ]):
Display(display.Math(`\left[ \begin{matrix} 1 & 0\\ 0 & 1 \end{matrix} \right]`))
Obrázek 14: Matice vykreslená TeXovským formátovačem.
Podobný zápis je vyžadován i u složitějších vzorců se zlomky, integrály, sumami, limity atd.:
Display(display.Math(` \left[ \frac{ N } { \left( \frac{L}{p} \right) - (m+n) } \right] `))
Obrázek 14: Složený zlomek vykreslený TeXovským formátovačem.
16. Načtení rastrových obrázků
Velmi často se setkáme s nutností zobrazit přímo v diáři rastrový obrázek. Ten může vzniknout několika způsoby, typicky se však jedná (ve světě výpočtů, simulací, ML atd.) o nějaký graf (heatmap atd.), výsledek aplikace rastrových operací na vstupní data atd. Pro zobrazení rastrového obrázku lze použít funkce dostupné z balíčku display, který je automaticky načten při inicializaci diáře, takže nemusíme provádět jeho explicitní import. V následujícím příkladu je ukázáno, jak lze načíst obrázek z externího zdroje (stáhneme ho pomocí http.Get) a zobrazit ho funkcí display.PNG (obrázek je reprezentován řezem bajtů obsahujícím jeho podobu zakódovanou do PNG – včetně hlaviček, palety, metadat atd.). Podobné funkce pochopitelně existují i pro rastrové obrázky uložené ve formátu JPEG či GIF:
import ( "image" "net/http" "io/ioutil" ) resp, err := http.Get("https://github.com/gopherdata/gophernotes/raw/master/files/gophernotes-logo.png") bytes, err := ioutil.ReadAll(resp.Body) resp.Body.Close() display.PNG(bytes)
Obrázek 15: Rastrový obrázek s logem projektu Gophernotes načtený přímo do diáře.
17. Načtení vektorových obrázků ve formátu SVG
Zmiňme se o další užitečné vlastnosti projektu Gophernotes v kombinaci s Jypyterem. Jedná se o schopnost zobrazit přímo do vytvářeného diáře diagram, graf či nárys uložený do vektorového formátu SVG (Scalable Vector Graphics). Pro tento účel se používá funkce display.SVG, které se předá řez bajtů obsahující data s popisem SVG. Ta mohou vzniknout různým způsobem – lze je stáhnout, vytvořit programově atd. atd.:
resp, err := http.Get("http://jupyter.org/assets/nav_logo.svg") bytes, err := ioutil.ReadAll(resp.Body) resp.Body.Close() display.SVG(string(bytes))
Obrázek 16: Logo projektu Jupyter je uloženo do vektorového formátu SVG a je ho tak možné přímo stáhnout a zobrazit v diáři.
18. Obsah navazující části seriálu
Možností, která nám nabízí kombinace projektů Gomacro, Gonum a Gophernotes, je pochopitelně mnohem více, než bylo naznačeno v předchozích kapitolách. I z tohoto důvodu se s touto trojicí projektů setkáme i v navazujících částech seriálu o programovacím jazyce Go.
19. Repositář s demonstračními příklady
Zdrojové kódy všech dnes použitých demonstračních příkladů byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/go-root (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář (ten je ovšem – alespoň prozatím – velmi malý, dnes má přibližně pět až šest megabajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
20. Odkazy na Internetu
- Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/ - The Gonum Numerical Computing Package
https://www.gonum.org/post/introtogonum/ - Gomacro na GitHubu
https://github.com/cosmos72/gomacro - gophernotes – Use Go in Jupyter notebooks and nteract
https://github.com/gopherdata/gophernotes - gonum
https://github.com/gonum - go-gota/gota – DataFrames and data wrangling in Go (Golang)
https://porter.io/github.com/go-gota/gota - A repository for plotting and visualizing data
https://github.com/gonum/plot - Gonum Numerical Packages
https://www.gonum.org/ - Stránky projektu MinIO
https://min.io/ - MinIO Quickstart Guide
https://docs.min.io/docs/minio-quickstart-guide.html - MinIO Go Client API Reference
https://docs.min.io/docs/golang-client-api-reference - MinIO Python Client API Reference
https://docs.min.io/docs/python-client-api-reference.html - Performance at Scale: MinIO Pushes Past 1.4 terabits per second with 256 NVMe Drives
https://blog.min.io/performance-at-scale-minio-pushes-past-1–3-terabits-per-second-with-256-nvme-drives/ - Benchmarking MinIO vs. AWS S3 for Apache Spark
https://blog.min.io/benchmarking-apache-spark-vs-aws-s3/ - MinIO Client Quickstart Guide
https://docs.min.io/docs/minio-client-quickstart-guide.html - Analýza kvality zdrojových kódů Minia
https://goreportcard.com/report/github.com/minio/minio - This is MinIO
https://www.youtube.com/watch?v=vF0lQh0XOCs - Running MinIO Standalone
https://www.youtube.com/watch?v=dIQsPCHvHoM - „Amazon S3 Compatible Storage in Kubernetes“ – Rob Girard, Principal Tech Marketing Engineer, Minio
https://www.youtube.com/watch?v=wlpn8K0jJ4U - Ginkgo
http://onsi.github.io/ginkgo/ - Gomega
https://onsi.github.io/gomega/ - Ginkgo's Preferred Matcher Library na GitHubu
https://github.com/onsi/gomega/ - Provided Matchers
http://onsi.github.io/gomega/#provided-matchers - Dokumentace k balíčku goexpect
https://godoc.org/github.com/google/goexpect - Balíček goexpect
https://github.com/google/goexpect - Balíček go-expect
https://github.com/Netflix/go-expect - Balíček gexpect
https://github.com/ThomasRooney/gexpect - Expect (originál naprogramovaný v TCL)
https://core.tcl-lang.org/expect/index - Expect (Wikipedia)
https://en.wikipedia.org/wiki/Expect - Pexpect
https://pexpect.readthedocs.io/en/stable/ - Golang SSH Client: Multiple Commands, Crypto & Goexpect Examples
http://networkbit.ch/golang-ssh-client/ - goblin na GitHubu
https://github.com/franela/goblin - Mocha framework
https://mochajs.org/ - frisby na GitHubu
https://github.com/verdverm/frisby - package frisby
https://godoc.org/github.com/verdverm/frisby - Frisby alternatives and similar packages (generováno)
https://go.libhunt.com/frisby-alternatives - Cucumber for golang
https://github.com/DATA-DOG/godog - How to Use Godog for Behavior-driven Development in Go
https://semaphoreci.com/community/tutorials/how-to-use-godog-for-behavior-driven-development-in-go - Comparative Analysis Of GoLang Testing Frameworks
https://www.slideshare.net/DushyantBhalgami/comparative-analysis-of-golang-testing-frameworks - A Quick Guide to Testing in Golang
https://caitiem.com/2016/08/18/a-quick-guide-to-testing-in-golang/ - Tom's Obvious, Minimal Language.
https://github.com/toml-lang/toml - xml.org
http://www.xml.org/ - Soubory .properties
https://en.wikipedia.org/wiki/.properties - Soubory INI
https://en.wikipedia.org/wiki/INI_file - JSON to YAML
https://www.json2yaml.com/ - Data Format Converter
https://toolkit.site/format.html - Viper na GitHubu
https://github.com/spf13/viper - GoDotEnv na GitHubu
https://github.com/joho/godotenv - The fantastic ORM library for Golang
http://gorm.io/ - Dokumentace k balíčku gorilla/mux
https://godoc.org/github.com/gorilla/mux - Gorilla web toolkitk
http://www.gorillatoolkit.org/ - Metric types
https://prometheus.io/docs/concepts/metric_types/ - Histograms with Prometheus: A Tale of Woe
http://linuxczar.net/blog/2017/06/15/prometheus-histogram-2/ - Why are Prometheus histograms cumulative?
https://www.robustperception.io/why-are-prometheus-histograms-cumulative - Histograms and summaries
https://prometheus.io/docs/practices/histograms/ - Instrumenting Golang server in 5 min
https://medium.com/@gsisimogang/instrumenting-golang-server-in-5-min-c1c32489add3 - Semantic Import Versioning in Go
https://www.aaronzhuo.com/semantic-import-versioning-in-go/ - Sémantické verzování
https://semver.org/ - Getting started with Go modules
https://medium.com/@fonseka.live/getting-started-with-go-modules-b3dac652066d - Create projects independent of $GOPATH using Go Modules
https://medium.com/mindorks/create-projects-independent-of-gopath-using-go-modules-802260cdfb51o - Anatomy of Modules in Go
https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16 - Modules
https://github.com/golang/go/wiki/Modules - Go Modules Tutorial
https://tutorialedge.net/golang/go-modules-tutorial/ - Module support
https://golang.org/cmd/go/#hdr-Module_support - Go Lang: Memory Management and Garbage Collection
https://vikash1976.wordpress.com/2017/03/26/go-lang-memory-management-and-garbage-collection/ - Golang Internals, Part 4: Object Files and Function Metadata
https://blog.altoros.com/golang-part-4-object-files-and-function-metadata.html - What is REPL?
https://pythonprogramminglanguage.com/repl/ - What is a REPL?
https://codewith.mu/en/tutorials/1.0/repl - Programming at the REPL: Introduction
https://clojure.org/guides/repl/introduction - What is REPL? (Quora)
https://www.quora.com/What-is-REPL - Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/ - Read-eval-print loop (Wikipedia)
https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop - Vim as a Go (Golang) IDE using LSP and vim-go
https://octetz.com/posts/vim-as-go-ide - gopls
https://github.com/golang/go/wiki/gopls - IDE Integration Guide
https://github.com/stamblerre/gocode/blob/master/docs/IDE_integration.md - How to instrument Go code with custom expvar metrics
https://sysdig.com/blog/golang-expvar-custom-metrics/ - Golang expvar metricset (Metricbeat Reference)
https://www.elastic.co/guide/en/beats/metricbeat/7.x/metricbeat-metricset-golang-expvar.html - Package expvar
https://golang.org/pkg/expvar/#NewInt - Java Platform Debugger Architecture: Overview
https://docs.oracle.com/en/java/javase/11/docs/specs/jpda/jpda.html - The JVM Tool Interface (JVM TI): How VM Agents Work
https://www.oracle.com/technetwork/articles/javase/index-140680.html - JVM Tool Interface Version 11.0
https://docs.oracle.com/en/java/javase/11/docs/specs/jvmti.html - Creating a Debugging and Profiling Agent with JVMTI
http://www.oracle.com/technetwork/articles/javase/jvmti-136367.html - JVM TI (Wikipedia)
http://en.wikipedia.org/wiki/JVM_TI - IBM JVMTI extensions
http://publib.boulder.ibm.com/infocenter/realtime/v2r0/index.jsp?topic=%2Fcom.ibm.softrt.doc%2Fdiag%2Ftools%2Fjvmti_extensions.html - Go & cgo: integrating existing C code with Go
http://akrennmair.github.io/golang-cgo-slides/#1 - Using cgo to call C code from within Go code
https://wenzr.wordpress.com/2018/06/07/using-cgo-to-call-c-code-from-within-go-code/ - Package trace
https://golang.org/pkg/runtime/trace/ - Introducing HTTP Tracing
https://blog.golang.org/http-tracing - Command trace
https://golang.org/cmd/trace/ - A StreamLike, Immutable, Lazy Loading and smart Golang Library to deal with slices
https://github.com/wesovilabs/koazee - Funkce vyššího řádu v knihovně Underscore
https://www.root.cz/clanky/funkce-vyssiho-radu-v-knihovne-underscore/ - Delve: a debugger for the Go programming language.
https://github.com/go-delve/delve - Příkazy debuggeru Delve
https://github.com/go-delve/delve/tree/master/Documentation/cli - Debuggery a jejich nadstavby v Linuxu
http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu/ - Debuggery a jejich nadstavby v Linuxu (2. část)
http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-2-cast/ - Debuggery a jejich nadstavby v Linuxu (3): Nemiver
http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-3-nemiver/ - Debuggery a jejich nadstavby v Linuxu (4): KDbg
http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-4-kdbg/ - Debuggery a jejich nadstavby v Linuxu (5): ladění aplikací v editorech Emacs a Vim
http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-5-ladeni-aplikaci-v-editorech-emacs-a-vim/ - Debugging Go Code with GDB
https://golang.org/doc/gdb - Debugging Go (golang) programs with gdb
https://thornydev.blogspot.com/2014/01/debugging-go-golang-programs-with-gdb.html - GDB – Dokumentace
http://sourceware.org/gdb/current/onlinedocs/gdb/ - GDB – Supported Languages
http://sourceware.org/gdb/current/onlinedocs/gdb/Supported-Languages.html#Supported-Languages - GNU Debugger (Wikipedia)
https://en.wikipedia.org/wiki/GNU_Debugger - The LLDB Debugger
http://lldb.llvm.org/ - Debugger (Wikipedia)
https://en.wikipedia.org/wiki/Debugger - 13 Linux Debuggers for C++ Reviewed
http://www.drdobbs.com/testing/13-linux-debuggers-for-c-reviewed/240156817 - Go is on a Trajectory to Become the Next Enterprise Programming Language
https://hackernoon.com/go-is-on-a-trajectory-to-become-the-next-enterprise-programming-language-3b75d70544e - Go Proverbs: Simple, Poetic, Pithy
https://go-proverbs.github.io/ - Handling Sparse Files on Linux
https://www.systutorials.com/136652/handling-sparse-files-on-linux/ - Gzip (Wikipedia)
https://en.wikipedia.org/wiki/Gzip - Deflate
https://en.wikipedia.org/wiki/DEFLATE - 10 tools written in Go that every developer needs to know
https://gustavohenrique.net/en/2019/01/10-tools-written-in-go-that-every-dev-needs-to-know/ - Hexadecimální prohlížeče a editory s textovým uživatelským rozhraním
https://www.root.cz/clanky/hexadecimalni-prohlizece-a-editory-s-textovym-uzivatelskym-rozhranim/ - Hex dump
https://en.wikipedia.org/wiki/Hex_dump - Rozhraní io.ByteReader
https://golang.org/pkg/io/#ByteReader - Rozhraní io.RuneReader
https://golang.org/pkg/io/#RuneReader - Rozhraní io.ByteScanner
https://golang.org/pkg/io/#ByteScanner - Rozhraní io.RuneScanner
https://golang.org/pkg/io/#RuneScanner - Rozhraní io.Closer
https://golang.org/pkg/io/#Closer - Rozhraní io.Reader
https://golang.org/pkg/io/#Reader - Rozhraní io.Writer
https://golang.org/pkg/io/#Writer - Typ Strings.Reader
https://golang.org/pkg/strings/#Reader - VACUUM (SQL)
https://www.sqlite.org/lang_vacuum.html - VACUUM (Postgres)
https://www.postgresql.org/docs/8.4/sql-vacuum.html - go-cron
https://github.com/rk/go-cron - gocron
https://github.com/jasonlvhit/gocron - clockwork
https://github.com/whiteShtef/clockwork - clockwerk
https://github.com/onatm/clockwerk - JobRunner
https://github.com/bamzi/jobrunner - Rethinking Cron
https://adam.herokuapp.com/past/2010/4/13/rethinking_cron/ - In the Beginning was the Command Line
https://web.archive.org/web/20180218045352/http://www.cryptonomicon.com/beginning.html - repl.it (REPL pro různé jazyky)
https://repl.it/languages - GOCUI – Go Console User Interface (celé uživatelské prostředí, nejenom input box)
https://github.com/jroimartin/gocui - Read–eval–print loop
https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop - go-prompt
https://github.com/c-bata/go-prompt - readline
https://github.com/chzyer/readline - A pure golang implementation for GNU-Readline kind library
https://golangexample.com/a-pure-golang-implementation-for-gnu-readline-kind-library/ - go-readline
https://github.com/fiorix/go-readline - 4 Python libraries for building great command-line user interfaces
https://opensource.com/article/17/5/4-practical-python-libraries - prompt_toolkit 2.0.3 na PyPi
https://pypi.org/project/prompt_toolkit/ - python-prompt-toolkit na GitHubu
https://github.com/jonathanslenders/python-prompt-toolkit - The GNU Readline Library
https://tiswww.case.edu/php/chet/readline/rltop.html - GNU Readline (Wikipedia)
https://en.wikipedia.org/wiki/GNU_Readline - readline — GNU readline interface (Python 3.x)
https://docs.python.org/3/library/readline.html - readline — GNU readline interface (Python 2.x)
https://docs.python.org/2/library/readline.html - GNU Readline Library – command line editing
https://tiswww.cwru.edu/php/chet/readline/readline.html - gnureadline 6.3.8 na PyPi
https://pypi.org/project/gnureadline/ - Editline Library (libedit)
http://thrysoee.dk/editline/ - Comparing Python Command-Line Parsing Libraries – Argparse, Docopt, and Click
https://realpython.com/comparing-python-command-line-parsing-libraries-argparse-docopt-click/ - libedit or editline
http://www.cs.utah.edu/~bigler/code/libedit.html - WinEditLine
http://mingweditline.sourceforge.net/ - rlcompleter — Completion function for GNU readline
https://docs.python.org/3/library/rlcompleter.html - rlwrap na GitHubu
https://github.com/hanslub42/rlwrap - rlwrap(1) – Linux man page
https://linux.die.net/man/1/rlwrap - readline(3) – Linux man page
https://linux.die.net/man/3/readline - history(3) – Linux man page
https://linux.die.net/man/3/history - Dokumentace k balíčku oglematchers
https://godoc.org/github.com/jacobsa/oglematchers - Balíček oglematchers
https://github.com/jacobsa/oglematchers - Dokumentace k balíčku ogletest
https://godoc.org/github.com/jacobsa/ogletest - Balíček ogletest
https://github.com/jacobsa/ogletest - Dokumentace k balíčku assert
https://godoc.org/github.com/stretchr/testify/assert - Testify – Thou Shalt Write Tests
https://github.com/stretchr/testify/ - package testing
https://golang.org/pkg/testing/ - Golang basics – writing unit tests
https://blog.alexellis.io/golang-writing-unit-tests/ - An Introduction to Programming in Go / Testing
https://www.golang-book.com/books/intro/12 - An Introduction to Testing in Go
https://tutorialedge.net/golang/intro-testing-in-go/ - Advanced Go Testing Tutorial
https://tutorialedge.net/golang/advanced-go-testing-tutorial/ - GoConvey
http://goconvey.co/ - Testing Techniques
https://talks.golang.org/2014/testing.slide - 5 simple tips and tricks for writing unit tests in #golang
https://medium.com/@matryer/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742 - Afinní transformace
https://cs.wikibooks.org/wiki/Geometrie/Afinn%C3%AD_transformace_sou%C5%99adnic - package gg
https://godoc.org/github.com/fogleman/gg - Generate an animated GIF with Golang
http://tech.nitoyon.com/en/blog/2016/01/07/go-animated-gif-gen/ - Generate an image programmatically with Golang
http://tech.nitoyon.com/en/blog/2015/12/31/go-image-gen/ - The Go image package
https://blog.golang.org/go-image-package - Balíček draw2D: 2D rendering for different output (raster, pdf, svg)
https://github.com/llgcode/draw2d - Draw a rectangle in Golang?
https://stackoverflow.com/questions/28992396/draw-a-rectangle-in-golang - YAML
https://yaml.org/ - edn
https://github.com/edn-format/edn - Smile
https://github.com/FasterXML/smile-format-specification - Protocol-Buffers
https://developers.google.com/protocol-buffers/ - Marshalling (computer science)
https://en.wikipedia.org/wiki/Marshalling_(computer_science) - Unmarshalling
https://en.wikipedia.org/wiki/Unmarshalling - Introducing JSON
http://json.org/ - Package json
https://golang.org/pkg/encoding/json/ - The Go Blog: JSON and Go
https://blog.golang.org/json-and-go - Go by Example: JSON
https://gobyexample.com/json - Writing Web Applications
https://golang.org/doc/articles/wiki/ - Golang Web Apps
https://www.reinbach.com/blog/golang-webapps-1/ - Build web application with Golang
https://legacy.gitbook.com/book/astaxie/build-web-application-with-golang/details - Golang Templates – Golang Web Pages
https://www.youtube.com/watch?v=TkNIETmF-RU - Simple Golang HTTPS/TLS Examples
https://github.com/denji/golang-tls - Playing with images in HTTP response in golang
https://www.sanarias.com/blog/1214PlayingwithimagesinHTTPresponseingolang - MIME Types List
https://www.freeformatter.com/mime-types-list.html - Go Mutex Tutorial
https://tutorialedge.net/golang/go-mutex-tutorial/ - Creating A Simple Web Server With Golang
https://tutorialedge.net/golang/creating-simple-web-server-with-golang/ - Building a Web Server in Go
https://thenewstack.io/building-a-web-server-in-go/ - How big is the pipe buffer?
https://unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer - How to turn off buffering of stdout in C
https://stackoverflow.com/questions/7876660/how-to-turn-off-buffering-of-stdout-in-c - setbuf(3) – Linux man page
https://linux.die.net/man/3/setbuf - setvbuf(3) – Linux man page (stejný obsah jako předchozí stránka)
https://linux.die.net/man/3/setvbuf - Select waits on a group of channels
https://yourbasic.org/golang/select-explained/ - Rob Pike: Simplicity is Complicated (video)
http://www.golang.to/posts/dotgo-2015-rob-pike-simplicity-is-complicated-youtube-16893 - Algorithms to Go
https://yourbasic.org/ - Využití knihovny Pygments (nejenom) pro obarvení zdrojových kódů
https://www.root.cz/clanky/vyuziti-knihovny-pygments-nejenom-pro-obarveni-zdrojovych-kodu/ - Využití knihovny Pygments (nejenom) pro obarvení zdrojových kódů: vlastní filtry a lexery
https://www.root.cz/clanky/vyuziti-knihovny-pygments-nejenom-pro-obarveni-zdrojovych-kodu-vlastni-filtry-a-lexery/ - Go Defer Simplified with Practical Visuals
https://blog.learngoprogramming.com/golang-defer-simplified-77d3b2b817ff - 5 More Gotchas of Defer in Go — Part II
https://blog.learngoprogramming.com/5-gotchas-of-defer-in-go-golang-part-ii-cc550f6ad9aa - The Go Blog: Defer, Panic, and Recover
https://blog.golang.org/defer-panic-and-recover - The defer keyword in Swift 2: try/finally done right
https://www.hackingwithswift.com/new-syntax-swift-2-defer - Swift Defer Statement
https://andybargh.com/swift-defer-statement/ - Modulo operation (Wikipedia)
https://en.wikipedia.org/wiki/Modulo_operation - Node.js vs Golang: Battle of the Next-Gen Languages
https://www.hostingadvice.com/blog/nodejs-vs-golang/ - The Go Programming Language (home page)
https://golang.org/ - GoDoc
https://godoc.org/ - Go (programming language), Wikipedia
https://en.wikipedia.org/wiki/Go_(programming_language) - Go Books (kniha o jazyku Go)
https://github.com/dariubs/GoBooks - The Go Programming Language Specification
https://golang.org/ref/spec - Go: the Good, the Bad and the Ugly
https://bluxte.net/musings/2018/04/10/go-good-bad-ugly/ - Package builtin
https://golang.org/pkg/builtin/ - Package fmt
https://golang.org/pkg/fmt/ - The Little Go Book (další kniha)
https://github.com/dariubs/GoBooks - The Go Programming Language by Brian W. Kernighan, Alan A. A. Donovan
https://www.safaribooksonline.com/library/view/the-go-programming/9780134190570/ebook_split010.html - Learning Go
https://www.miek.nl/go/ - Go Bootcamp
http://www.golangbootcamp.com/ - Programming in Go: Creating Applications for the 21st Century (další kniha o jazyku Go)
http://www.informit.com/store/programming-in-go-creating-applications-for-the-21st-9780321774637 - Introducing Go (Build Reliable, Scalable Programs)
http://shop.oreilly.com/product/0636920046516.do - Learning Go Programming
https://www.packtpub.com/application-development/learning-go-programming - The Go Blog
https://blog.golang.org/ - Getting to Go: The Journey of Go's Garbage Collector
https://blog.golang.org/ismmkeynote - Go (programovací jazyk, Wikipedia)
https://cs.wikipedia.org/wiki/Go_(programovac%C3%AD_jazyk) - Rychle, rychleji až úplně nejrychleji s jazykem Go
https://www.root.cz/clanky/rychle-rychleji-az-uplne-nejrychleji-s-jazykem-go/ - Installing Go on the Raspberry Pi
https://dave.cheney.net/2012/09/25/installing-go-on-the-raspberry-pi - How the Go runtime implements maps efficiently (without generics)
https://dave.cheney.net/2018/05/29/how-the-go-runtime-implements-maps-efficiently-without-generics - Niečo málo o Go – Golang (slovensky)
http://golangsk.logdown.com/ - How Many Go Developers Are There?
https://research.swtch.com/gophercount - Most Popular Technologies (Stack Overflow Survery 2018)
https://insights.stackoverflow.com/survey/2018/#most-popular-technologies - Most Popular Technologies (Stack Overflow Survery 2017)
https://insights.stackoverflow.com/survey/2017#technology - JavaScript vs. Golang for IoT: Is Gopher Winning?
https://www.iotforall.com/javascript-vs-golang-iot/ - The Go Programming Language: Release History
https://golang.org/doc/devel/release.html - Go 1.11 Release Notes
https://golang.org/doc/go1.11 - Go 1.10 Release Notes
https://golang.org/doc/go1.10 - Go 1.9 Release Notes (tato verze je stále používána)
https://golang.org/doc/go1.9 - Go 1.8 Release Notes (i tato verze je stále používána)
https://golang.org/doc/go1.8 - Go on Fedora
https://developer.fedoraproject.org/tech/languages/go/go-installation.html - Writing Go programs
https://developer.fedoraproject.org/tech/languages/go/go-programs.html - The GOPATH environment variable
https://tip.golang.org/doc/code.html#GOPATH - Command gofmt
https://tip.golang.org/cmd/gofmt/ - The Go Blog: go fmt your code
https://blog.golang.org/go-fmt-your-code - C? Go? Cgo!
https://blog.golang.org/c-go-cgo - Spaces vs. Tabs: A 20-Year Debate Reignited by Google’s Golang
https://thenewstack.io/spaces-vs-tabs-a-20-year-debate-and-now-this-what-the-hell-is-wrong-with-go/ - 400,000 GitHub repositories, 1 billion files, 14 terabytes of code: Spaces or Tabs?
https://medium.com/@hoffa/400–000-github-repositories-1-billion-files-14-terabytes-of-code-spaces-or-tabs-7cfe0b5dd7fd - Gofmt No Longer Allows Spaces. Tabs Only
https://news.ycombinator.com/item?id=7914523 - Why does Go „go fmt“ uses tabs instead of whitespaces?
https://www.quora.com/Why-does-Go-go-fmt-uses-tabs-instead-of-whitespaces - Interactive: The Top Programming Languages 2018
https://spectrum.ieee.org/static/interactive-the-top-programming-languages-2018 - Go vs. Python
https://www.peterbe.com/plog/govspy - PackageManagementTools
https://github.com/golang/go/wiki/PackageManagementTools - A Tour of Go: Type inference
https://tour.golang.org/basics/14 - Go Slices: usage and internals
https://blog.golang.org/go-slices-usage-and-internals - Go by Example: Slices
https://gobyexample.com/slices - What is the point of slice type in Go?
https://stackoverflow.com/questions/2098874/what-is-the-point-of-slice-type-in-go - The curious case of Golang array and slices
https://medium.com/@hackintoshrao/the-curious-case-of-golang-array-and-slices-2565491d4335 - Introduction to Slices in Golang
https://www.callicoder.com/golang-slices/ - Golang: Understanding ‚null‘ and nil
https://newfivefour.com/golang-null-nil.html - What does nil mean in golang?
https://stackoverflow.com/questions/35983118/what-does-nil-mean-in-golang - nils In Go
https://go101.org/article/nil.html - Go slices are not dynamic arrays
https://appliedgo.net/slices/ - Go-is-no-good (nelze brát doslova)
https://github.com/ksimka/go-is-not-good - Rust vs. Go
https://news.ycombinator.com/item?id=13430108 - Seriál Programovací jazyk Rust
https://www.root.cz/serialy/programovaci-jazyk-rust/ - Modern garbage collection: A look at the Go GC strategy
https://blog.plan99.net/modern-garbage-collection-911ef4f8bd8e - Go GC: Prioritizing low latency and simplicity
https://blog.golang.org/go15gc - Is Golang a good language for embedded systems?
https://www.quora.com/Is-Golang-a-good-language-for-embedded-systems - Running GoLang on an STM32 MCU. A quick tutorial.
https://www.mickmake.com/post/running-golang-on-an-mcu-a-quick-tutorial - Go, Robot, Go! Golang Powered Robotics
https://gobot.io/ - Emgo: Bare metal Go (language for programming embedded systems)
https://github.com/ziutek/emgo - UTF-8 history
https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt - Less is exponentially more
https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html - Should I Rust, or Should I Go
https://codeburst.io/should-i-rust-or-should-i-go-59a298e00ea9 - Setting up and using gccgo
https://golang.org/doc/install/gccgo - Elastic Tabstops
http://nickgravgaard.com/elastic-tabstops/ - Strings, bytes, runes and characters in Go
https://blog.golang.org/strings - Datový typ
https://cs.wikipedia.org/wiki/Datov%C3%BD_typ - Seriál o programovacím jazyku Rust: Základní (primitivní) datové typy
https://www.root.cz/clanky/programovaci-jazyk-rust-nahrada-c-nebo-slepa-cesta/#k09 - Seriál o programovacím jazyku Rust: Vytvoření „řezu“ z pole
https://www.root.cz/clanky/prace-s-poli-v-programovacim-jazyku-rust/#k06 - Seriál o programovacím jazyku Rust: Řezy (slice) vektoru
https://www.root.cz/clanky/prace-s-vektory-v-programovacim-jazyku-rust/#k05 - Printf Format Strings
https://www.cprogramming.com/tutorial/printf-format-strings.html - Java: String.format
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#format-java.lang.String-java.lang.Object…- - Java: format string syntax
https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax - Selectors
https://golang.org/ref/spec#Selectors - Calling Go code from Python code
http://savorywatt.com/2015/09/18/calling-go-code-from-python-code/ - Go Data Structures: Interfaces
https://research.swtch.com/interfaces - How to use interfaces in Go
http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go - Interfaces in Go (part I)
https://medium.com/golangspec/interfaces-in-go-part-i-4ae53a97479c - Part 21: Goroutines
https://golangbot.com/goroutines/ - Part 22: Channels
https://golangbot.com/channels/ - [Go] Lightweight eventbus with async compatibility for Go
https://github.com/asaskevich/EventBus - What about Trait support in Golang?
https://www.reddit.com/r/golang/comments/8mfykl/what_about_trait_support_in_golang/ - Don't Get Bitten by Pointer vs Non-Pointer Method Receivers in Golang
https://nathanleclaire.com/blog/2014/08/09/dont-get-bitten-by-pointer-vs-non-pointer-method-receivers-in-golang/ - Control Flow
https://en.wikipedia.org/wiki/Control_flow - Structured programming
https://en.wikipedia.org/wiki/Structured_programming - Control Structures
https://www.golang-book.com/books/intro/5 - Control structures – Go if else statement
http://golangtutorials.blogspot.com/2011/06/control-structures-if-else-statement.html - Control structures – Go switch case statement
http://golangtutorials.blogspot.com/2011/06/control-structures-go-switch-case.html - Control structures – Go for loop, break, continue, range
http://golangtutorials.blogspot.com/2011/06/control-structures-go-for-loop-break.html - Goroutine IDs
https://blog.sgmansfield.com/2015/12/goroutine-ids/ - Different ways to pass channels as arguments in function in go (golang)
https://stackoverflow.com/questions/24868859/different-ways-to-pass-channels-as-arguments-in-function-in-go-golang - justforfunc #22: using the Go execution tracer
https://www.youtube.com/watch?v=ySy3sR1LFCQ - Single Function Exit Point
http://wiki.c2.com/?SingleFunctionExitPoint - Entry point
https://en.wikipedia.org/wiki/Entry_point - Why does Go have a GOTO statement?!
https://www.reddit.com/r/golang/comments/kag5q/why_does_go_have_a_goto_statement/ - Effective Go
https://golang.org/doc/effective_go.html - GoClipse: an Eclipse IDE for the Go programming language
http://goclipse.github.io/ - GoClipse Installation
https://github.com/GoClipse/goclipse/blob/latest/documentation/Installation.md#installation - The zero value of a slice is not nil
https://stackoverflow.com/questions/30806931/the-zero-value-of-a-slice-is-not-nil - Go-tcha: When nil != nil
https://dev.to/pauljlucas/go-tcha-when-nil–nil-hic - Nils in Go
https://www.doxsey.net/blog/nils-in-go