Hlavní navigace

Popis vybraných balíčků nabízených projektem Gonum

V článku o nástroji Gophernotes jsme se mj. zmínili i o balíčcích určených pro numerické výpočty vytvořených v rámci projektu Gonum. Dnes si některé z těchto balíčků popíšeme s využitím množství demonstračních příkladů.
Pavel Tišnovský 31. 12. 2019
Doba čtení: 41 minut

Sdílet

11. Trojúhelníkové matice

12. Balíček stat

13. Výpočet průměrů, rozptylů a směrodatných odchylek

14. Výpočet entropie

15. Korelace

16. Kovariance

17. Lineární regrese

18. Obsah následující části seriálu

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

20. Odkazy na Internetu

1. Popis vybraných balíčků nabízených projektem Gonum

Na článek Gophernotes: kombinace interaktivního prostředí Jupyteru s jazykem Go, který je součástí seriálu o programovacím jazyku Go, dnes navážeme. Popíšeme si totiž možnosti vybraných balíčků nabízených projektem Gonum. Opět použijeme interaktivní smyčku jazyka Go (REPL) implementovanou projektem Gomacro, protože právě zcela interaktivní prostředí (realizované buď v terminálu, nebo v projektech typu Jupyter Notebook) je pro testování možností nových či neznámých knihoven takřka ideálním nástrojem.

Popis instalace balíčků Gonum a Gomacro byl uveden minule, takže si dnes již můžeme smyčku REPL Gomacra přímo spustit. V případě, že je adresář $HOME/go/bin vložen do proměnné prostředí PATH, bude možné Gomacro spustit příkazem gomacro:

$ 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>
Poznámka: opět je nutné již před popisem jednotlivých funkcí a metod připomenout, že knihovny pro numerické a symbolické výpočty podporované v rámci projektu Gonum nejsou ze syntaktického hlediska tak dobře integrovány, jako je tomu například ve specializovaných jazycích R a Julia či v Pythonu doplněném o balíčky NumPy a SciPy. Je tomu tak z toho prostého důvodu, že jazyk Go (ve verzi 1.x) nepodporuje přetěžování operátorů, takže například není možné implementovat maticové operace „přirozenou“ cestou (zrovna příklad NumPy ukazuje, že přetěžování operátorů, pokud je použito v rozumné míře, může být v praxi velmi užitečné). Tato vlastnost programovacího jazyka Go je nejvíce viditelná právě u maticových a vektorových operacích, kde i vytvoření řezu je nutné implementovat samostatnou funkcí.

2. Pomocný balíček gonum.org/v1/gonum/floats

Prvním balíčkem, s nímž se v dnešním článku setkáme, je pomocný balíček (knihovna) s plným jménem gonum.org/v1/gonum/floats, k jehož funkcím budeme přistupovat pouze s využitím poslední části názvu – floats. Tento balíček slouží k operacím prováděným nad řezy (slice) a poli (array) hodnot typu float64. Jedná se tedy o velmi užitečné rozšíření základní knihovny programovacího jazyka Go, díky jehož existenci lze ušetřit psaní mnoha programových smyček (nalezení maximálního či minimálního prvku, výpočet sumy všech prvků atd.). Možnosti tohoto balíčku otestujeme přímo v interaktivní smyčce (REPL) implementované v rámci projektu Gomacro, už jen z toho důvodu, že v výstupů je patrná jak hodnota výsledku (výsledků), tak i její typ.

Nejprve je pochopitelně nutné balíček importovat:

gomacro> import "gonum.org/v1/gonum/floats"

Následně vytvoříme dvojici řezů, z nichž každý ukazuje na pole o šesti prvcích (mnoho dále popsaných operací vyžaduje, aby oba řezy měly shodný počet prvků):

gomacro> x := []float64{1,2,3,4,5,6}
 
gomacro> y := []float64{1,5,3,5,5,0}

Funkce Min a Max vyhledají prvek s poli s minimální, resp. maximální hodnotou (vrací se přímo hodnota takového prvku):

gomacro> floats.Min(x)
1       // float64
 
gomacro> floats.Max(x)
6       // float64

Podobným způsobem lze najít indexy prvků s minimální, resp. maximální hodnotou:

gomacro> floats.MinIdx(x)
0       // int
 
gomacro> floats.MaxIdx(x)
5       // int
 
gomacro> floats.MinIdx(y)
5       // int
 
gomacro> floats.MaxIdx(y)
1       // int
Poznámka: povšimněte si, že pokud existuje několik prvků s totožnou hodnotou, vrátí se index prvního z nich.

Funkce Sum vrátí součet prvků v poli, funkce Prod naopak výsledek součinu všech prvků:

gomacro> floats.Sum(x)
21      // float64
 
gomacro> floats.Prod(x)
720     // float64

Porovnání všech prvků ve dvou řezech zajišťuje funkce Equal:

gomacro> floats.Equal(x,x)
true    // bool

Porovnání všech prvků, ovšem na podobnost (do určitého rozsahu), nikoli na totožnost:

x := []float64{1, 2, 3, 4, 5, 6}
y := []float64{1, 2, 3, 4, 5, 6}
z := []float64{1.0, 2.2, 2.8, 4.2, 4.8, 6.0}
 
fmt.Printf("x:   %v\n", x)
fmt.Printf("y:   %v\n", y)
fmt.Printf("z:   %v\n", z)
 
fmt.Printf("x~=y (±0,10)?: %t\n", floats.EqualApprox(x, y, 0.1))
fmt.Printf("x~=z (±0,05)?: %t\n", floats.EqualApprox(x, z, 0.05))
fmt.Printf("x~=z (±0,09)?: %t\n", floats.EqualApprox(x, z, 0.09))
fmt.Printf("x~=z (±0,10)?: %t\n", floats.EqualApprox(x, z, 0.10))
fmt.Printf("x~=z (±0,11)?: %t\n", floats.EqualApprox(x, z, 0.11))

S výsledky:

x:   [1 2 3 4 5 6]
y:   [1 2 3 4 5 6]
z:   [1 2.2 2.8 4.2 4.8 6]
 
x~=y (±0,10)?: true
x~=z (±0,05)?: false
x~=z (±0,09)?: false
x~=z (±0,10)?: true
x~=z (±0,11)?: true
Poznámka: existují i další možnosti porovnání, například porovnání hodnot ze dvou řezů, přičemž dvě hodnoty NaN (Not a Number) jsou považovány za shodné (v obecném případě to ovšem neplatí, protože porovnání dvou NaN na ekvivalenci vrací podle normy hodnotu false a nikoli true).

3. Další funkce z balíčku gonum.org/v1/gonum/floats

Popišme si ještě některé další vybrané funkce, které nalezneme v balíčku gonum.org/v1/gonum/floats. Často používanou funkcí je funkce provádějící skalární součin prvků ze dvou řezů o shodné délce:

gomacro> floats.Dot(x, x)
91      // float64
gomacro> floats.Dot(x, y)
65      // float64

Následující dvě funkce nazvané Reverse a Scale změní obsah původního řezu. Nejedná se tedy o funkce v matematickém významu (což je zvláštní, protože toto chování neodpovídá pravidlům, které knihovna Gonum v jiných balíčcích dodržuje).

Otočení všech prvků v řezu:

gomacro> floats.Reverse(x)
 
gomacro> x
[6 5 4 3 2 1]   // []float64

Změna měřítka prvků (vynásobení každého prvku konstantou):

gomacro> floats.Scale(10, x)
 
gomacro> x
[60 50 40 30 20 10]     // []float64

Užitečná je i funkce nazvaná Within, která vrací index i takového prvku z řezu s, pro který platí s[i] <= v < s[i+1]. Funkci lze použít pouze pro řezy, v nichž jsou prvky seřazeny vzestupně a současně řez obsahuje alespoň dva prvky (tyto podmínky jsou testovány a pokud nejsou splněny, vyvolá se panic):

gomacro> x := []float64{1,2,3,4,5,6}
 
gomacro> floats.Within(x, 3)
2       // int
 
gomacro> floats.Within(x, 3.5)
2       // int
 
gomacro> floats.Within(x, 10)
-1      // int

Vypočítat můžeme i takzvanou kumulativní sumu, což je nový řez, jehož první prvek je zkopírován z původního řezu, druhý prvek obsahuje hodnotu prvního sečtenou z hodnotou druhého prvku atd.:

gomacro> floats.CumSum(x, y)
[1 6 9 14 19 19]        // []float64
 
gomacro> floats.CumSum(x, x)
[1 7 16 30 49 68]       // []float64

Zajímavá je funkce nazvaná Argsort. Tato funkce setřídí řez předaný v prvním parametru, navíc ovšem do dalšího řezu (ten musí být vytvořen) vloží původní indexy prvků. Tento druhý řez tedy musí být typu []int a nikoli []float64:

gomacro> y
[1 5 3 5 5 0]   // []float64
 
gomacro> indexes := [6]int{}
 
gomacro> floats.Argsort(y, indexes)

Řez y by měl být po provedení operace Argsort setříděn a navíc by řez indexes měl obsahovat původní indexy v nesetříděném řezu:

gomacro> y
[0 1 3 5 5 5]   // []float64
 
gomacro> indexes
[5 0 2 1 3 4]   // [6]int
Poznámka: zajímavé v tomto kontextu je, že balíček Gonum prozatím nenabízí plnohodnotné „indexování“ s využitím obsahu jiného řezu, tedy operaci, kterou najdeme jak v jazyku Julia, tak i v knihovně NumPy pro programovací jazyk Python.

4. Jednorozměrné vektory

Nyní se vrátíme k popisu balíčku gonum.org/v1/gonum/mat, s jehož základním použitím jsme se již seznámili minule. Ovšem v předchozím článku jsme se zabývali převážně popisem práce s běžnými čtvercovými a obdélníkovými maticemi, i když možnosti tohoto balíčku jsou ve skutečnosti větší. Pracovat lze i s vektory, které jsou (minimálně z pohledu balíčku mat) sloupcové. Výchozím typem vektorů je datová struktura vecdense představující vektor s měnitelnými (mutable) prvky. Interně se jedná o pole prvků, a proto je zde použito slovo „dense“

Nový sloupcový vektor se vytvoří konstruktorem nazvaným NewVecDense, a to následujícím způsobem:

gomacro> v := mat.NewVecDense(10, nil)
 
gomacro> mat.Formatted(v)
⎡0⎤
⎢0⎥
⎢0⎥
⎢0⎥
⎢0⎥
⎢0⎥
⎢0⎥
⎢0⎥
⎢0⎥
⎣0⎦     // fmt.Formatter

V případě, že budeme chtít vektor inicializovat prvky se známou hodnotou, použijeme sice stejný konstruktor, ale namísto druhé hodnoty nil lze předat řez s hodnotami typu float64. Volání konstruktoru tedy bude vypadat následovně:

gomacro> v := mat.NewVecDense(10, []float64{1,2,3,4,5,6,7,8,9,10})
 
gomacro> mat.Formatted(v)
⎡ 1⎤
⎢ 2⎥
⎢ 3⎥
⎢ 4⎥
⎢ 5⎥
⎢ 6⎥
⎢ 7⎥
⎢ 8⎥
⎢ 9⎥
⎣10⎦    // fmt.Formatter

U vektorů lze zjistit jejich velikost (délka zde vlastně odpovídá výšce) a taktéž kapacitu:

gomacro> v.Len()
10      // int
 
gomacro> v.Cap()
10      // int

Metoda Dims vrací dimenzi vektoru – n řádků a jeden sloupec:

gomacro> v.Dims()
10      // int
1       // int

Pochopitelně je možné vytvořit i řádkový vektor o to maticovou operací transpozice zapisovanou metodou se jménem T:

gomacro> v.T()
{Matrix:0xc001792870}   // gonum.org/v1/gonum/mat.Matrix
 
gomacro> mat.Formatted(v.T())
[ 1   2   3   4   5   6   7   8   9  10]        // fmt.Formatter
Poznámka: výsledkem je v tomto případě matice s jedním řádkem.

5. Získání řezu (slice) z vektoru

Často je zapotřebí z vektoru získat pouze určitou část. V případě polí a řezů (jakožto základních datových typů programovacího jazyka Go) je pro tento účel použit operátor řezu (slice), ovšem u vektorů typu vecdense je namísto toho nutné použít metodu nazvanou SliceVec. Použití této metody je snadné, i když nutno podotknout, že ne tak čitelné, jako použití skutečného operátoru pro provedení řezu.

Nejprve vytvoříme nový vektor s deseti prvky:

gomacro> v := mat.NewVecDense(10, []float64{1,2,3,4,5,6,7,8,9,10})

Následně vytvoříme řez tvořený prvky s indexy 4 a 5:

gomacro> mat.Formatted(v.SliceVec(4, 6))
⎡5⎤
⎣6⎦     // fmt.Formatter
Poznámka: povšimněte si, že první prvek řezu je určen „včetně“, zatímco druhý prvek „kromě“ (uzavřený vs. otevřený interval).

Podobně lze vytvořit řez obsahující všechny původní prvky:

gomacro> mat.Formatted(v.SliceVec(0, 9))
⎡1⎤
⎢2⎥
⎢3⎥
⎢4⎥
⎢5⎥
⎢6⎥
⎢7⎥
⎢8⎥
⎣9⎦     // fmt.Formatter

Indexy prvků musí být kladná čísla – jinými slovy to znamená, že není povolena počítat indexy od konce vektoru tak, jak to známe z některých jiných knihoven:

gomacro> mat.Formatted(v.SliceVec(0, -1))
mat: index out of range

Řez vektoru je skutečným řezem ve smyslu, že se jedná o „pohled“ na původní vektor. V dalším příkladu vytvoříme řez nazvaný w, jehož obsah je nepřímo změněn modifikací obsahu původního vektoru v:

gomacro> v := mat.NewVecDense(10, []float64{1,2,3,4,5,6,7,8,9,10})
 
gomacro> w := v.SliceVec(0, 9)
 
gomacro> mat.Formatted(w)
⎡1⎤
⎢2⎥
⎢3⎥
⎢4⎥
⎢5⎥
⎢6⎥
⎢7⎥
⎢8⎥
⎣9⎦     // fmt.Formatter
 
gomacro> v.SetVec(5, 100)
 
gomacro> mat.Formatted(w)
⎡  1⎤
⎢  2⎥
⎢  3⎥
⎢  4⎥
⎢  5⎥
⎢100⎥
⎢  7⎥
⎢  8⎥
⎣  9⎦   // fmt.Formatter

6. Čtení a modifikace prvků vektoru

Způsob nastavení nové hodnoty prvku vektoru jsme již viděli v předchozí kapitole. Pro tento účel se používá metoda nazvaná SetVec; opět tedy platí, že nelze použít přetížený operátor:

gomacro> v := mat.NewVecDense(10, []float64{1,2,3,4,5,6,7,8,9,10})
 
gomacro> for i := 0; i < v.Len(); i++ {
. . . .      v.SetVec(i, 1.0 / float64(i))
. . . .  }

Změněný vektor bude mít opět deset prvků:

gomacro> mat.Formatted(v)
⎡               +Inf⎤
⎢                  1⎥
⎢                0.5⎥
⎢ 0.3333333333333333⎥
⎢               0.25⎥
⎢                0.2⎥
⎢0.16666666666666666⎥
⎢0.14285714285714285⎥
⎢              0.125⎥
⎣ 0.1111111111111111⎦   // fmt.Formatter

Existují dvě metody určené pro přečtení hodnoty prvku z vektoru. První metoda se jmenuje At a používá se i pro čtení prvků z dvourozměrných matic (u sloupcových vektorů je druhý index vždy nulový):

gomacro> for i := 0; i < v.Len(); i++ {
. . . .    fmt.Printf("%10.6f\n", v.At(i, 0))
. . . .  }

      +Inf
  1.000000
  0.500000
  0.333333
  0.250000
  0.200000
  0.166667
  0.142857
  0.125000
  0.111111

Druhá metoda se jmenuje AtVec a předává se jí jen jediný index:

gomacro> for i := 0; i < w.Len(); i++ {
. . . .      fmt.Printf("%10.6f\n", w.AtVec(i))
. . . .  }
 
 10.000000
  0.000000
 20.000000
  0.000000
 30.000000

7. Operace nad vektory

V této kapitole si popíšeme některé další operace, které lze provádět s vektory. Nejdříve vytvoříme dvojici vektorů, které budou použity v dalších příkazech:

gomacro> v1 := mat.NewVecDense(5, nil)
 
gomacro> v2 := mat.NewVecDense(5, []float64{1,0,2,0,3})
 
gomacro> mat.Formatted(v1)
⎡0⎤
⎢0⎥
⎢0⎥
⎢0⎥
⎣0⎦     // fmt.Formatter
 
gomacro> mat.Formatted(v2)
⎡1⎤
⎢0⎥
⎢2⎥
⎢0⎥
⎣3⎦     // fmt.Formatter

Třetí vektor bude použit jako cíl pro některé operace:

gomacro> v := mat.NewVecDense(5, nil)

Operace součtu dvou vektorů realizovaná metodou – modifikuje se v ní příjemce (receiver):

gomacro> v.AddVec(v1, v2)
 
gomacro> mat.Formatted(v)
⎡1⎤
⎢0⎥
⎢2⎥
⎢0⎥
⎣3⎦     // fmt.Formatter
 
gomacro> v.AddVec(v2, v2)
 
gomacro> mat.Formatted(v)
⎡2⎤
⎢0⎥
⎢4⎥
⎢0⎥
⎣6⎦     // fmt.Formatter

Operace rozdílu vektorů, opět s modifikací příjemce:

gomacro> v.SubVec(v1, v2)
 
gomacro> mat.Formatted(v)
⎡-1⎤
⎢ 0⎥
⎢-2⎥
⎢ 0⎥
⎣-3⎦    // fmt.Formatter

Změna měřítka, tj. vynásobení všech prvků vektoru nějakou konstantou:

gomacro> v.ScaleVec(10.0, v2)
 
gomacro> mat.Formatted(v)
⎡10⎤
⎢ 0⎥
⎢20⎥
⎢ 0⎥
⎣30⎦    // fmt.Formatter

Vynásobení dvou vektorů stylem prvek po prvku (nejedná se o vektorový součin):

gomacro> v.MulElemVec(v2, v2)
 
gomacro> mat.Formatted(v)
⎡1⎤
⎢0⎥
⎢4⎥
⎢0⎥
⎣9⎦     // fmt.Formatter

Podporována je i operace vynásobení matice a vektoru, samozřejmě za předpokladu, že počet sloupců matice bude odpovídat počtu řádků sloupcového vektoru:

gomacro> m := mat.NewDense(3, 3, []float64{1,0,0,0,1,0,0,0,1})
 
gomacro> v3 := mat.NewVecDense(3, []float64{2,3,4})
 
gomacro> v := mat.NewVecDense(3, nil)
 
gomacro> v.MulVec(m, v3)
 
gomacro> mat.Formatted(v)
⎡2⎤
⎢3⎥
⎣4⎦     // fmt.Formatter

Vynásobení vektoru maticí reprezentující otočení okolo z-ové osy o 90°:

gomacro> m := mat.NewDense(3, 3, []float64{0,-1,0,1,0,0,0,0,1})
 
gomacro> v.MulVec(m, v3)
 
gomacro> mat.Formatted(v)
⎡-3⎤
⎢ 2⎥
⎣ 4⎦    // fmt.Formatter

Skalární součin dvou vektorů o stejné velikosti:

gomacro> mat.Dot(v1, v2)
0       // float64
 
gomacro> mat.Dot(v2, v2)
14      // float64

Získání prvku s největší a nejmenší hodnotou:

gomacro> mat.Max(v)
4       // float64
 
gomacro> mat.Min(v)
-3      // float64

Součet všech prvků vektoru:

gomacro> mat.Sum(v)
3       // float64

8. Obecné dvourozměrné matice

I obecné dvourozměrné matice byly popsány v předchozí části seriálu o programovacím jazyce Go, takže si jen ve stručnosti shrňme některé základní operace. Matici vytváříme konstruktorem NewDense:

gomacro> d := mat.NewDense(6, 5, nil)
 
gomacro> mat.Formatted(d)
⎡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⎦ // fmt.Formatter

Konstrukce matice s inicializací jejich prvků:

gomacro> d := mat.NewDense(4, 3, []float64{1,2,3,4,5,6,7,8,9,10,11,12})
 
gomacro> mat.Formatted(d)
⎡ 1   2   3⎤
⎢ 4   5   6⎥
⎢ 7   8   9⎥
⎣10  11  12⎦    // fmt.Formatter

Druhá matice, tentokrát se třemi řádky a čtyřmi sloupci:

gomacro> d := mat.NewDense(3, 4, []float64{1,2,3,4,5,6,7,8,9,10,11,12})
 
gomacro> mat.Formatted(d)
⎡ 1   2   3   4⎤
⎢ 5   6   7   8⎥
⎣ 9  10  11  12⎦        // fmt.Formatter

Čtvercová matice 3×3 prvky:

gomacro> m := mat.NewDense(3, 3, []float64{1,2,3,4,5,6,7,8,9})
 
gomacro> mat.Formatted(m)
⎡1  2  3⎤
⎢4  5  6⎥
⎣7  8  9⎦       // fmt.Formatter

Přečtení i-tého sloupce matice. Výsledkem je v tomto případě běžný řez programovacího jazyka Go:

gomacro> mat.Col(nil, 0, m)
[1 4 7] // []float64
 
gomacro> mat.Col(nil, 1, m)
[2 5 8] // []float64
 
gomacro> mat.Col(nil, 2, m)
[3 6 9] // []float64
 
gomacro> mat.Col(nil, 3, m)
mat: column index out of range

Přečtení j-tého řádku matice. Výsledkem je v tomto případě opět běžný řez programovacího jazyka Go:

gomacro> mat.Row(nil, 0, m)
[1 2 3] // []float64
 
gomacro> mat.Row(nil, 1, m)
[4 5 6] // []float64
 
gomacro> mat.Row(nil, 2, m)
[7 8 9] // []float64
 
gomacro> mat.Row(nil, 3, m)
mat: column index out of range

Výpočet determinantu matice 3×3 prvky:

gomacro> mat.Det(m)
6.66133814775094e-16    // float64

Opět můžeme použít funkce pro získání prvku s nejmenší hodnotou, největší hodnotou a pro součet (sumu) všech prvků v matici:

gomacro> mat.Min(m)
1       // float64
 
gomacro> mat.Max(m)
9       // float64
 
gomacro> mat.Sum(m)
45      // float64

Poslední zajímavou metodou je metoda, která vrací diagonální matici (všechny prvky kromě prvků na hlavní diagonále jsou nulové):

gomacro> mat.Formatted(m.DiagView())
⎡1  0  0⎤
⎢0  5  0⎥
⎣0  0  9⎦       // fmt.Formatter

9. Symetrické matice

V knihovně mat existuje i konstruktor pro symetrické matice. Chování tohoto konstruktoru je ovšem poněkud zvláštní – předat je mu totiž nutné všechny prvky odpovídající velikosti matice. Například pro matici 3×3 prvky (symetrická matice je vždy čtvercová) je nutné konstruktoru předat devět hodnot prvků, i když se z těchto hodnot použije jen šest prvků (horní trojúhelníková matice):

gomacro> s := mat.NewSymDense(3, []float64{1,2,3,4,5,6,7,8,9})
 
gomacro> mat.Formatted(s)
⎡1  2  3⎤
⎢2  5  6⎥
⎣3  6  9⎦       // fmt.Formatter

Tyto matice mají zachovávají většinu základních vlastností běžných matic, tj. můžeme například získat informace o jejich kapacitě, velikosti (v jednotlivých dimenzích) atd.:

gomacro> s.Caps()
3       // int
3       // int
 
gomacro> s.Dims()
3       // int
3       // int

Vytvořit je možné i transformovanou matici, což je ovšem jen kopie matice původní:

gomacro> mat.Formatted(s.T())
⎡1  2  3⎤
⎢2  5  6⎥
⎣3  6  9⎦       // fmt.Formatter

Prvky symetrické matice se nastavují metodou SetSym (jiná metoda ani není k dispozici). Tato metoda pochopitelně zachovává „symetričnost“ matice, tj. změní se buď jeden prvek na hlavní diagonále nebo dvojice prvků:

gomacro> s.SetSym(1, 0, -100)
 
gomacro> mat.Formatted(s)
⎡   1  -100     3⎤
⎢-100     5     6⎥
⎣   3     6     9⎦      // fmt.Formatter

10. Diagonální matice

Další variantou matic jsou diagonální matice. Ty lze vytvořit konstruktorem NewDiagDense:

gomacro> d := mat.NewDiagDense(10, nil)
 
gomacro> mat.Formatted(d)
⎡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  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  0  0  0  0⎥
⎢0  0  0  0  0  0  0  0  0  0⎥
⎣0  0  0  0  0  0  0  0  0  0⎦  // fmt.Formatter

Konstruktoru je možné předat hodnoty všech prvků na hlavní diagonále:

gomacro> d := mat.NewDiagDense(10, []float64{1,2,3,4,5,6,7,8,9,10})
 
gomacro> mat.Formatted(d)
⎡ 1   0   0   0   0   0   0   0   0   0⎤
⎢ 0   2   0   0   0   0   0   0   0   0⎥
⎢ 0   0   3   0   0   0   0   0   0   0⎥
⎢ 0   0   0   4   0   0   0   0   0   0⎥
⎢ 0   0   0   0   5   0   0   0   0   0⎥
⎢ 0   0   0   0   0   6   0   0   0   0⎥
⎢ 0   0   0   0   0   0   7   0   0   0⎥
⎢ 0   0   0   0   0   0   0   8   0   0⎥
⎢ 0   0   0   0   0   0   0   0   9   0⎥
⎣ 0   0   0   0   0   0   0   0   0  10⎦        // fmt.Formatter

A opět jsou k dispozici metody pro získání základních informací o existující matici:

gomacro> d.Diag()
10      // int
 
gomacro> d.Dims()
10      // int
10      // int

Pro nastavení hodnoty prvku diagonální matice se používá metoda SetDiag:

gomacro> d := mat.NewDiagDense(10, []float64{1,2,3,4,5,6,7,8,9,10})
 
gomacro> d.SetDiag(1, 100)
 
gomacro> mat.Formatted(d)
⎡  1    0    0    0    0    0    0    0    0    0⎤
⎢  0  100    0    0    0    0    0    0    0    0⎥
⎢  0    0    3    0    0    0    0    0    0    0⎥
⎢  0    0    0    4    0    0    0    0    0    0⎥
⎢  0    0    0    0    5    0    0    0    0    0⎥
⎢  0    0    0    0    0    6    0    0    0    0⎥
⎢  0    0    0    0    0    0    7    0    0    0⎥
⎢  0    0    0    0    0    0    0    8    0    0⎥
⎢  0    0    0    0    0    0    0    0    9    0⎥
⎣  0    0    0    0    0    0    0    0    0   10⎦      // fmt.Formatter

11. Trojúhelníkové matice

V knihovně mat jsou vývojářům k dispozici i funkce a metody určené pro práci s trojúhelníkovými maticemi. Opět si nejprve řekněme, jakým způsobem se tyto matice vytváří. Použít můžeme konstruktor NewTriDense, kterému se předává jak velikost trojúhelníkové matice (je pochopitelně čtvercová), tak i to, zda se jedná o horní či dolní trojúhelníkovou matici. A opět platí, že je nutné zapsat všechny prvky trojúhelníkové matice, i když se ve skutečnosti využijí pouze hodnoty prvků na hlavní diagonále a horním, resp. dolním trojúhelníku.

Horní trojúhelníková matice se vytváří takto:

gomacro> t1 := mat.NewTriDense(3, mat.Upper, []float64{1,2,3,4,5,6,7,8,9})
 
gomacro> mat.Formatted(t1)
⎡1  2  3⎤
⎢0  5  6⎥
⎣0  0  9⎦       // fmt.Formatter

Dolní trojúhelníková matice inicializovaná shodnými hodnotami se konstruuje následovně:

gomacro> t2 := mat.NewTriDense(3, mat.Lower, []float64{1,2,3,4,5,6,7,8,9})
 
gomacro> mat.Formatted(t2)
⎡1  0  0⎤
⎢4  5  0⎥
⎣7  8  9⎦       // fmt.Formatter

Získat můžeme pohled obsahující pouze prvky na hlavní diagonále:

gomacro> mat.Formatted(t1.DiagView())
⎡1  0  0⎤
⎢0  5  0⎥
⎣0  0  9⎦       // fmt.Formatter
 
gomacro> mat.Formatted(t2.DiagView())
⎡1  0  0⎤
⎢0  5  0⎥
⎣0  0  9⎦       // fmt.Formatter

Trojúhelníkové matice lze transponovat, čímž se z horní matice stane dolní a naopak:

gomacro> mat.Formatted(t1.T())
⎡1  0  0⎤
⎢2  5  0⎥
⎣3  6  9⎦       // fmt.Formatter
 
gomacro> mat.Formatted(t2.T())
⎡1  4  7⎤
⎢0  5  8⎥
⎣0  0  9⎦       // fmt.Formatter

Pro nastavení hodnot prvků trojúhelníkové matice slouží metoda NewTriDense, která zajistí, aby se neměnily prvky v té části trojúhelníkové matice, které musí být nulové:

gomacro> t1 := mat.NewTriDense(3, mat.Upper, []float64{1,2,3,4,5,6,7,8,9})
 
gomacro> t1.SetTri(2, 0, 100)
mat: triangular set out of bounds
 
gomacro> t1.SetTri(0, 2, 100)
 
gomacro> mat.Formatted(t1)
⎡  1    2  100⎤
⎢  0    5    6⎥
⎣  0    0    9⎦ // fmt.Formatter

12. Balíček stat

Třetím balíčkem, s jehož možnostmi se dnes ve stručnosti seznámíme, je balíček nazvaný stat. Najdeme v něm různé funkce a metody, které se týkají především statistických výpočtů, ovšem například i lineární regrese (proložení naměřených či vypočtených bodů úsečkou) apod. Většina základních funkcí pracuje s hodnotami uloženými v řezu hodnot typu float64, většinou doplněných o další řez obsahující váhy hodnot (výchozí váhou je 1.0). Podrobnější informace o možnostech tohoto balíčku budou uvedeny příště.

13. Výpočet průměrů, rozptylů a směrodatných odchylek

Základní funkcí, která má všeobecné využití, je výpočet aritmetického průměru (AM=Arithmetic Mean). Tato funkce se v knihovně stat jmenuje Mean. Této funkci se předává řez s hodnotami a popř. i další řez s vahami. Pokud je druhým parametrem hodnota nil, budou váhy všech prvků rovny 1.0:

gomacro> stat.Mean([]float64{1,2,3,4,5}, nil)
3       // float64
 
gomacro> stat.Mean([]float64{1,2,3,4,5}, []float64{1,1,1,1,1})
3       // float64
 
gomacro> stat.Mean([]float64{1,2,3,4,5}, []float64{1,1,1,1,10})
4.285714285714286       // float64

K dispozici je i funkce pro výpočet geometrického průměru (GM=Geometric Mean) se stejnými vlastnostmi, jako je tomu u výše zmíněné funkce Mean:

gomacro> stat.GeometricMean([]float64{1,2,3,4,5}, nil)
2.605171084697352       // float64
 
gomacro> stat.GeometricMean([]float64{1,2,3,4,5}, []float64{1,1,1,1,1})
2.605171084697352       // float64
 
gomacro> stat.GeometricMean([]float64{1,2,3,4,5}, []float64{1,1,1,1,10})
3.9614192356754674      // float64

Vypočítat lze i harmonický průměr (HM=Harmonic Mean), a to s využitím funkce HarmonicMean:

gomacro> stat.HarmonicMean([]float64{1,2,3,4,5}, nil)
2.1897810218978098      // float64
 
gomacro> stat.HarmonicMean([]float64{1,2,3,4,5}, []float64{1,1,1,1,1})
2.1897810218978098      // float64
 
gomacro> stat.HarmonicMean([]float64{1,2,3,4,5}, []float64{1,1,1,1,10})
3.4285714285714293      // float64

V dalších příkladech budeme používat pole o sto prvcích naplněné náhodnými hodnotami:

gomacro> import "math/rand"
 
gomacro> ys := [100]float64{}
 
gomacro> for i := 0; i < len(ys); i++ {
. . . .      ys[i] = 50.0 - float64(i) + 2.0*rand.Float64() - 1.0
. . . .  }

Výpočet aritmetického průměru:

gomacro> stat.Mean(ys[:], nil)
0.48154185382982606     // float64

Výpočet směrodatné odchylky a standardní chyby (SE):

gomacro> stat.StdDev(ys[:], nil)
28.95847713231853       // float64
 
gomacro> stat.StdErr(stat.StdDev(ys[:], nil), 100)
2.895847713231853       // float64

Aritmetický průměr i směrodatnou odchylku lze vypočítat jedinou funkcí MeanStdDev, která vrací dvojici hodnot:

gomacro> stat.MeanStdDev(ys[:], nil)
0.48154185382982606     // float64
28.95847713231853       // float64

14. Výpočet entropie

Vypočítat lze i entropii pro hodnoty, které se v sekvenci vyskytují s různou pravděpodobností. Touto funkcí a jejím konkrétním významem se budeme podrobněji zabývat příště, takže jen krátce:

gomacro> stat.Entropy([]float64{0.25, 0.25, 0.25, 0.25})
1.3862943611198906      // float64
 
gomacro> stat.Entropy([]float64{0.20, 0.20, 0.20, 0.40})
1.3321790402101223      // float64
 
gomacro> stat.Entropy([]float64{0.10, 0.10, 0.10, 0.70})
0.9404479886553264      // float64
 
gomacro> stat.Entropy([]float64{0.00, 0.00, 0.00, 1.00})
0       // float64
Poznámka: v posledním příkladu se hodnoty vyskytovaly se 100% pravděpodobností, takže entropie takové zprávy je nulová.

15. Korelace

V knihovně stat nalezneme i funkce pro výpočet korelace. Nejdříve si však připravíme dvojici řezů, které pro výpočet korelace využijeme:

gomacro> x := []float64{1,2,3,4,5,6}
 
gomacro> y := []float64{1,5,3,5,5,0}

Korelace řezu se sebou samým:

gomacro> stat.Correlation(x, x, nil)
1       // float64
 
gomacro> stat.Correlation(y, y, nil)
1       // float64

Korelace mezi dvěma řezy:

gomacro> stat.Correlation(x, y, nil)
-0.07195396418966687    // float64

Korelace mezi různými řezy, jejichž korespondující prvky se vždy liší pouze o jedničku:

gomacro> z := []float64{2,3,4,5,6,7}
 
gomacro> stat.Correlation(x, z, nil)
1       // float64

V dalším příkladu vypočítáme korelaci mezi vzestupnou a sestupnou řadou šesti hodnot (zde se jedná o antikorelaci):

gomacro> w := []float64{6,5,4,3,2,1}
 
gomacro> stat.Correlation(x, w, nil)
-1      // float64

16. Kovariance

Pro výpočet kovariance (https://cs.wikipedia.org/wi­ki/Kovariance) slouží funkce Covariance, která může sloužit pro zjištění, zda jsou dvě veličiny či naměřené hodnoty na sobě lineárně závislé či nikoli:

gomacro> stat.Covariance(x, x, nil)
3.5     // float64
 
gomacro> stat.Covariance(x, y, nil)
-0.3    // float64
 
gomacro> stat.Covariance(x, z, nil)
3.5     // float64
 
gomacro> stat.Covariance(x, w, nil)
-3.5    // float64

17. Lineární regrese

Poslední funkcí, se kterou se dnes setkáme, je funkce určená pro výpočet lineární regrese (tedy proložení úsečky naměřenými hodnotami). Nejdříve si připravíme dvojici řezů obsahujících x-ové a y-ové hodnoty:

gomacro> xs := []float64{1,2,3,4,5}
gomacro> ys := []float64{2,3,4,5,6}

Dále vypočteme posun a směrnici úsečky, kterou proložíme mezi naměřenými body (tato úsečka bude procházet všemi body):

gomacro> stat.LinearRegression(xs, ys, nil, false)
1       // float64
1       // float64

Posledním parametrem si můžeme vynutit, aby úsečka procházela počátkem souřadného systému (což ovšem pro tyto konkrétní hodnoty moc nedává význam):

gomacro> stat.LinearRegression(xs, ys, nil, true)
0       // float64
1.2727272727272727      // float64

Zkusme nyní použít odlišné hodnoty, které představují body na úsečce, která neprochází počátkem souřadného systému:

gomacro> xs := []float64{1,2,3,4,5}
 
gomacro> ys := []float64{-2,0,2,4,6}
 
gomacro> stat.LinearRegression(xs, ys, nil, false)
-4      // float64
2       // float64

Nyní je posun roven –4 a směrnice 2.

Praktičtěji zaměřený příklad pro body, které se nepatrně odchylují od ideálního průběhu funkce:

gomacro> import "math/rand"
gomacro> xs := [100]float64{}
gomacro> ys := [100]float64{}
gomacro> for i := 0; i < len(xs); i++ {
. . . .      xs[i] = float64(i)
. . . .  }

Výpočet y-ových souřadnic bodů:

gomacro> for i := 0; i < len(ys); i++ {
. . . .      ys[i] = 50.0 - float64(i) + 2.0*rand.Float64() - 1.0
. . . .  }

Výpočet lineární regrese (posunu a směrnice):

gomacro> stat.LinearRegression(xs[:], ys[:], nil, false)
49.88218549333264       // float64
-0.9979928007980367     // float64

Obrázek 1: Průběh funkce (s náhodnými výchylkami), kterou lze proložit úsečkou s posunem cca 50 a směrnicí cca –1.0.

Můžeme si vynutit, aby úsečka procházela počátkem souřadného systému (což opět pro tyto konkrétní hodnoty nemá význam):

MIF obecny

gomacro> stat.LinearRegression(xs[:], ys[:], nil, true)
0       // float64
-0.24600005466739383    // float64

18. Obsah následující části seriálu

V navazující části seriálu o programovacím jazyku Go si ukážeme možnosti nabízené dalšími balíčky z knihovny Gonum. Bude se jednat zejména o balíčky s funkcemi pro numerickou derivaci a integraci, práci s náhodnými hodnotami (resp. jejich sekvencemi), práci s grafovými strukturami aj.

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:

# Příklad Stručný popis Cesta
1 floats01.go nalezení minimální a maximální hodnoty, výpočet sumy a produktu https://github.com/tisnik/go-root/blob/master/article49/flo­ats01.go
2 floats02.go nalezení indexu prvku s minimální, resp. maximální hodnotou https://github.com/tisnik/go-root/blob/master/article49/flo­ats02.go
3 floats03.go otočení prvků a změna měřítka https://github.com/tisnik/go-root/blob/master/article49/flo­ats03.go
4 floats04.go přičtení, odečtení, vynásobení a vydělení řezu od jiného řezu https://github.com/tisnik/go-root/blob/master/article49/flo­ats04.go
5 floats05.go součet hodnot ze dvou řezů https://github.com/tisnik/go-root/blob/master/article49/flo­ats05.go
6 floats06.go rozdíl hodnot ze dvou řezů https://github.com/tisnik/go-root/blob/master/article49/flo­ats06.go
7 floats07.go součin hodnot ze dvou řezů https://github.com/tisnik/go-root/blob/master/article49/flo­ats07.go
8 floats08.go podíl hodnot ze dvou řezů https://github.com/tisnik/go-root/blob/master/article49/flo­ats08.go
9 floats09.go porovnání hodnot ze dvou řezů na shodnost https://github.com/tisnik/go-root/blob/master/article49/flo­ats09.go
10 floats10.go porovnání hodnot ze dvou řezů na podobnost https://github.com/tisnik/go-root/blob/master/article49/flo­ats10.go
       
11 mat11.go konstrukce jednorozměrného vektoru https://github.com/tisnik/go-root/blob/master/article49/mat11.go
12 mat12.go konstrukce jednorozměrného vektoru s inicializací prvků https://github.com/tisnik/go-root/blob/master/article49/mat12.go
13 mat13.go vytvoření řádkového vektoru transpozicí vektoru sloupcového https://github.com/tisnik/go-root/blob/master/article49/mat13.go
14 mat14.go součet dvou vektorů https://github.com/tisnik/go-root/blob/master/article49/mat14.go
15 mat15.go rozdíl dvou vektorů https://github.com/tisnik/go-root/blob/master/article49/mat15.go
16 mat16.go vynásobení prvků vektorů konstantou https://github.com/tisnik/go-root/blob/master/article49/mat16.go
17 mat17.go vynásobení prvků dvou vektorů https://github.com/tisnik/go-root/blob/master/article49/mat17.go
18 mat18.go vynásobení vektoru a matice https://github.com/tisnik/go-root/blob/master/article49/mat18.go
19 mat19.go vynásobení vektoru a matice https://github.com/tisnik/go-root/blob/master/article49/mat19.go
20 mat20.go další operace s vektory https://github.com/tisnik/go-root/blob/master/article49/mat20.go
21 mat21.go konstrukce symetrické matice https://github.com/tisnik/go-root/blob/master/article49/mat21.go
22 mat22.go základní vlastnosti symetrické matice https://github.com/tisnik/go-root/blob/master/article49/mat22.go
23 mat23.go základní vlastnosti symetrické matice https://github.com/tisnik/go-root/blob/master/article49/mat23.go
24 mat24.go metody běžné obdélníkové matice https://github.com/tisnik/go-root/blob/master/article49/mat24.go
25 mat25.go získání diagonály matice https://github.com/tisnik/go-root/blob/master/article49/mat25.go
26 mat26.go získání i-tého sloupce či j-tého řádku matice https://github.com/tisnik/go-root/blob/master/article49/mat26.go
27 mat27.go konstrukce diagonální matice https://github.com/tisnik/go-root/blob/master/article49/mat27.go
28 mat28.go základní vlastnosti diagonální matice https://github.com/tisnik/go-root/blob/master/article49/mat28.go
29 mat29.go základní vlastnosti diagonální matice https://github.com/tisnik/go-root/blob/master/article49/mat29.go
30 mat30.go konstrukce trojúhelníkové matice https://github.com/tisnik/go-root/blob/master/article49/mat30.go
31 mat31.go základní vlastnosti trojúhelníkové matice https://github.com/tisnik/go-root/blob/master/article49/mat31.go
32 mat32.go základní vlastnosti trojúhelníkové matice https://github.com/tisnik/go-root/blob/master/article49/mat32.go
       
33 stat01.go výpočet průměrů https://github.com/tisnik/go-root/blob/master/article49/stat01.go
34 stat02.go výpočet geometrického průměru https://github.com/tisnik/go-root/blob/master/article49/stat02.go
35 stat03.go výpočet harmonického průměru https://github.com/tisnik/go-root/blob/master/article49/stat03.go
36 stat04.go výpočet směrodatné odchylky a standardní chyby https://github.com/tisnik/go-root/blob/master/article49/stat04.go
37 stat05.go výpočet průměru a standardní chyby jedinou funkcí https://github.com/tisnik/go-root/blob/master/article49/stat05.go

20. Odkazy na Internetu

  1. Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
    https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/
  2. The Gonum Numerical Computing Package
    https://www.gonum.org/pos­t/introtogonum/
  3. Gomacro na GitHubu
    https://github.com/cosmos72/gomacro
  4. gophernotes – Use Go in Jupyter notebooks and nteract
    https://github.com/gopher­data/gophernotes
  5. gonum
    https://github.com/gonum
  6. go-gota/gota – DataFrames and data wrangling in Go (Golang)
    https://porter.io/github.com/go-gota/gota
  7. A repository for plotting and visualizing data
    https://github.com/gonum/plot
  8. Gonum Numerical Packages
    https://www.gonum.org/
  9. Stránky projektu MinIO
    https://min.io/
  10. MinIO Quickstart Guide
    https://docs.min.io/docs/minio-quickstart-guide.html
  11. MinIO Go Client API Reference
    https://docs.min.io/docs/golang-client-api-reference
  12. MinIO Python Client API Reference
    https://docs.min.io/docs/python-client-api-reference.html
  13. 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/
  14. Benchmarking MinIO vs. AWS S3 for Apache Spark
    https://blog.min.io/benchmarking-apache-spark-vs-aws-s3/
  15. MinIO Client Quickstart Guide
    https://docs.min.io/docs/minio-client-quickstart-guide.html
  16. Analýza kvality zdrojových kódů Minia
    https://goreportcard.com/re­port/github.com/minio/minio
  17. This is MinIO
    https://www.youtube.com/wat­ch?v=vF0lQh0XOCs
  18. Running MinIO Standalone
    https://www.youtube.com/wat­ch?v=dIQsPCHvHoM
  19. „Amazon S3 Compatible Storage in Kubernetes“ – Rob Girard, Principal Tech Marketing Engineer, Minio
    https://www.youtube.com/wat­ch?v=wlpn8K0jJ4U
  20. Ginkgo
    http://onsi.github.io/ginkgo/
  21. Gomega
    https://onsi.github.io/gomega/
  22. Ginkgo's Preferred Matcher Library na GitHubu
    https://github.com/onsi/gomega/
  23. Provided Matchers
    http://onsi.github.io/gomega/#provided-matchers
  24. Dokumentace k balíčku goexpect
    https://godoc.org/github.com/go­ogle/goexpect
  25. Balíček goexpect
    https://github.com/google/goexpect
  26. Balíček go-expect
    https://github.com/Netflix/go-expect
  27. Balíček gexpect
    https://github.com/Thomas­Rooney/gexpect
  28. Expect (originál naprogramovaný v TCL)
    https://core.tcl-lang.org/expect/index
  29. Expect (Wikipedia)
    https://en.wikipedia.org/wiki/Expect
  30. Pexpect
    https://pexpect.readthedoc­s.io/en/stable/
  31. Golang SSH Client: Multiple Commands, Crypto & Goexpect Examples
    http://networkbit.ch/golang-ssh-client/
  32. goblin na GitHubu
    https://github.com/franela/goblin
  33. Mocha framework
    https://mochajs.org/
  34. frisby na GitHubu
    https://github.com/verdverm/frisby
  35. package frisby
    https://godoc.org/github.com/ver­dverm/frisby
  36. Frisby alternatives and similar packages (generováno)
    https://go.libhunt.com/frisby-alternatives
  37. Cucumber for golang
    https://github.com/DATA-DOG/godog
  38. How to Use Godog for Behavior-driven Development in Go
    https://semaphoreci.com/com­munity/tutorials/how-to-use-godog-for-behavior-driven-development-in-go
  39. Comparative Analysis Of GoLang Testing Frameworks
    https://www.slideshare.net/Dushy­antBhalgami/comparative-analysis-of-golang-testing-frameworks
  40. A Quick Guide to Testing in Golang
    https://caitiem.com/2016/08/18/a-quick-guide-to-testing-in-golang/
  41. Tom's Obvious, Minimal Language.
    https://github.com/toml-lang/toml
  42. xml.org
    http://www.xml.org/
  43. Soubory .properties
    https://en.wikipedia.org/wi­ki/.properties
  44. Soubory INI
    https://en.wikipedia.org/wi­ki/INI_file
  45. JSON to YAML
    https://www.json2yaml.com/
  46. Data Format Converter
    https://toolkit.site/format.html
  47. Viper na GitHubu
    https://github.com/spf13/viper
  48. GoDotEnv na GitHubu
    https://github.com/joho/godotenv
  49. The fantastic ORM library for Golang
    http://gorm.io/
  50. Dokumentace k balíčku gorilla/mux
    https://godoc.org/github.com/go­rilla/mux
  51. Gorilla web toolkitk
    http://www.gorillatoolkit.org/
  52. Metric types
    https://prometheus.io/doc­s/concepts/metric_types/
  53. Histograms with Prometheus: A Tale of Woe
    http://linuxczar.net/blog/2017/06/15/pro­metheus-histogram-2/
  54. Why are Prometheus histograms cumulative?
    https://www.robustperception.io/why-are-prometheus-histograms-cumulative
  55. Histograms and summaries
    https://prometheus.io/doc­s/practices/histograms/
  56. Instrumenting Golang server in 5 min
    https://medium.com/@gsisi­mogang/instrumenting-golang-server-in-5-min-c1c32489add3
  57. Semantic Import Versioning in Go
    https://www.aaronzhuo.com/semantic-import-versioning-in-go/
  58. Sémantické verzování
    https://semver.org/
  59. Getting started with Go modules
    https://medium.com/@fonse­ka.live/getting-started-with-go-modules-b3dac652066d
  60. Create projects independent of $GOPATH using Go Modules
    https://medium.com/mindorks/create-projects-independent-of-gopath-using-go-modules-802260cdfb51o
  61. Anatomy of Modules in Go
    https://medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16
  62. Modules
    https://github.com/golang/go/wi­ki/Modules
  63. Go Modules Tutorial
    https://tutorialedge.net/golang/go-modules-tutorial/
  64. Module support
    https://golang.org/cmd/go/#hdr-Module_support
  65. Go Lang: Memory Management and Garbage Collection
    https://vikash1976.wordpres­s.com/2017/03/26/go-lang-memory-management-and-garbage-collection/
  66. Golang Internals, Part 4: Object Files and Function Metadata
    https://blog.altoros.com/golang-part-4-object-files-and-function-metadata.html
  67. What is REPL?
    https://pythonprogramminglan­guage.com/repl/
  68. What is a REPL?
    https://codewith.mu/en/tu­torials/1.0/repl
  69. Programming at the REPL: Introduction
    https://clojure.org/guides/re­pl/introduction
  70. What is REPL? (Quora)
    https://www.quora.com/What-is-REPL
  71. Gorilla REPL: interaktivní prostředí pro programovací jazyk Clojure
    https://www.root.cz/clanky/gorilla-repl-interaktivni-prostredi-pro-programovaci-jazyk-clojure/
  72. Read-eval-print loop (Wikipedia)
    https://en.wikipedia.org/wi­ki/Read%E2%80%93eval%E2%80%93prin­t_loop
  73. Vim as a Go (Golang) IDE using LSP and vim-go
    https://octetz.com/posts/vim-as-go-ide
  74. gopls
    https://github.com/golang/go/wi­ki/gopls
  75. IDE Integration Guide
    https://github.com/stamble­rre/gocode/blob/master/doc­s/IDE_integration.md
  76. How to instrument Go code with custom expvar metrics
    https://sysdig.com/blog/golang-expvar-custom-metrics/
  77. Golang expvar metricset (Metricbeat Reference)
    https://www.elastic.co/gu­ide/en/beats/metricbeat/7­.x/metricbeat-metricset-golang-expvar.html
  78. Package expvar
    https://golang.org/pkg/expvar/#NewInt
  79. Java Platform Debugger Architecture: Overview
    https://docs.oracle.com/en/ja­va/javase/11/docs/specs/jpda/jpda­.html
  80. The JVM Tool Interface (JVM TI): How VM Agents Work
    https://www.oracle.com/technet­work/articles/javase/index-140680.html
  81. JVM Tool Interface Version 11.0
    https://docs.oracle.com/en/ja­va/javase/11/docs/specs/jvmti­.html
  82. Creating a Debugging and Profiling Agent with JVMTI
    http://www.oracle.com/technet­work/articles/javase/jvmti-136367.html
  83. JVM TI (Wikipedia)
    http://en.wikipedia.org/wiki/JVM_TI
  84. IBM JVMTI extensions
    http://publib.boulder.ibm­.com/infocenter/realtime/v2r0/in­dex.jsp?topic=%2Fcom.ibm.sof­trt.doc%2Fdiag%2Ftools%2Fjvmti_ex­tensions.html
  85. Go & cgo: integrating existing C code with Go
    http://akrennmair.github.io/golang-cgo-slides/#1
  86. Using cgo to call C code from within Go code
    https://wenzr.wordpress.com/2018/06/07/u­sing-cgo-to-call-c-code-from-within-go-code/
  87. Package trace
    https://golang.org/pkg/runtime/trace/
  88. Introducing HTTP Tracing
    https://blog.golang.org/http-tracing
  89. Command trace
    https://golang.org/cmd/trace/
  90. A StreamLike, Immutable, Lazy Loading and smart Golang Library to deal with slices
    https://github.com/wesovilabs/koazee
  91. Funkce vyššího řádu v knihovně Underscore
    https://www.root.cz/clanky/funkce-vyssiho-radu-v-knihovne-underscore/
  92. Delve: a debugger for the Go programming language.
    https://github.com/go-delve/delve
  93. Příkazy debuggeru Delve
    https://github.com/go-delve/delve/tree/master/Do­cumentation/cli
  94. Debuggery a jejich nadstavby v Linuxu
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu/
  95. Debuggery a jejich nadstavby v Linuxu (2. část)
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-2-cast/
  96. Debuggery a jejich nadstavby v Linuxu (3): Nemiver
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-3-nemiver/
  97. Debuggery a jejich nadstavby v Linuxu (4): KDbg
    http://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-4-kdbg/
  98. 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/
  99. Debugging Go Code with GDB
    https://golang.org/doc/gdb
  100. Debugging Go (golang) programs with gdb
    https://thornydev.blogspot­.com/2014/01/debugging-go-golang-programs-with-gdb.html
  101. GDB – Dokumentace
    http://sourceware.org/gdb/cu­rrent/onlinedocs/gdb/
  102. GDB – Supported Languages
    http://sourceware.org/gdb/cu­rrent/onlinedocs/gdb/Suppor­ted-Languages.html#Supported-Languages
  103. GNU Debugger (Wikipedia)
    https://en.wikipedia.org/wi­ki/GNU_Debugger
  104. The LLDB Debugger
    http://lldb.llvm.org/
  105. Debugger (Wikipedia)
    https://en.wikipedia.org/wi­ki/Debugger
  106. 13 Linux Debuggers for C++ Reviewed
    http://www.drdobbs.com/testing/13-linux-debuggers-for-c-reviewed/240156817
  107. 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
  108. Go Proverbs: Simple, Poetic, Pithy
    https://go-proverbs.github.io/
  109. Handling Sparse Files on Linux
    https://www.systutorials.com/136652/han­dling-sparse-files-on-linux/
  110. Gzip (Wikipedia)
    https://en.wikipedia.org/wiki/Gzip
  111. Deflate
    https://en.wikipedia.org/wiki/DEFLATE
  112. 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/
  113. Hexadecimální prohlížeče a editory s textovým uživatelským rozhraním
    https://www.root.cz/clanky/he­xadecimalni-prohlizece-a-editory-s-textovym-uzivatelskym-rozhranim/
  114. Hex dump
    https://en.wikipedia.org/wi­ki/Hex_dump
  115. Rozhraní io.ByteReader
    https://golang.org/pkg/io/#ByteReader
  116. Rozhraní io.RuneReader
    https://golang.org/pkg/io/#RuneReader
  117. Rozhraní io.ByteScanner
    https://golang.org/pkg/io/#By­teScanner
  118. Rozhraní io.RuneScanner
    https://golang.org/pkg/io/#Ru­neScanner
  119. Rozhraní io.Closer
    https://golang.org/pkg/io/#Closer
  120. Rozhraní io.Reader
    https://golang.org/pkg/io/#Reader
  121. Rozhraní io.Writer
    https://golang.org/pkg/io/#Writer
  122. Typ Strings.Reader
    https://golang.org/pkg/strin­gs/#Reader
  123. VACUUM (SQL)
    https://www.sqlite.org/lan­g_vacuum.html
  124. VACUUM (Postgres)
    https://www.postgresql.or­g/docs/8.4/sql-vacuum.html
  125. go-cron
    https://github.com/rk/go-cron
  126. gocron
    https://github.com/jasonlvhit/gocron
  127. clockwork
    https://github.com/whiteShtef/cloc­kwork
  128. clockwerk
    https://github.com/onatm/clockwerk
  129. JobRunner
    https://github.com/bamzi/jobrunner
  130. Rethinking Cron
    https://adam.herokuapp.com/pas­t/2010/4/13/rethinking_cron/
  131. In the Beginning was the Command Line
    https://web.archive.org/web/20180218045352/htt­p://www.cryptonomicon.com/be­ginning.html
  132. repl.it (REPL pro různé jazyky)
    https://repl.it/languages
  133. GOCUI – Go Console User Interface (celé uživatelské prostředí, nejenom input box)
    https://github.com/jroimartin/gocui
  134. Read–eval–print loop
    https://en.wikipedia.org/wi­ki/Read%E2%80%93eval%E2%80%93prin­t_loop
  135. go-prompt
    https://github.com/c-bata/go-prompt
  136. readline
    https://github.com/chzyer/readline
  137. A pure golang implementation for GNU-Readline kind library
    https://golangexample.com/a-pure-golang-implementation-for-gnu-readline-kind-library/
  138. go-readline
    https://github.com/fiorix/go-readline
  139. 4 Python libraries for building great command-line user interfaces
    https://opensource.com/article/17/5/4-practical-python-libraries
  140. prompt_toolkit 2.0.3 na PyPi
    https://pypi.org/project/prom­pt_toolkit/
  141. python-prompt-toolkit na GitHubu
    https://github.com/jonathan­slenders/python-prompt-toolkit
  142. The GNU Readline Library
    https://tiswww.case.edu/php/chet/re­adline/rltop.html
  143. GNU Readline (Wikipedia)
    https://en.wikipedia.org/wi­ki/GNU_Readline
  144. readline — GNU readline interface (Python 3.x)
    https://docs.python.org/3/li­brary/readline.html
  145. readline — GNU readline interface (Python 2.x)
    https://docs.python.org/2/li­brary/readline.html
  146. GNU Readline Library – command line editing
    https://tiswww.cwru.edu/php/chet/re­adline/readline.html
  147. gnureadline 6.3.8 na PyPi
    https://pypi.org/project/gnureadline/
  148. Editline Library (libedit)
    http://thrysoee.dk/editline/
  149. Comparing Python Command-Line Parsing Libraries – Argparse, Docopt, and Click
    https://realpython.com/comparing-python-command-line-parsing-libraries-argparse-docopt-click/
  150. libedit or editline
    http://www.cs.utah.edu/~bi­gler/code/libedit.html
  151. WinEditLine
    http://mingweditline.sourceforge.net/
  152. rlcompleter — Completion function for GNU readline
    https://docs.python.org/3/li­brary/rlcompleter.html
  153. rlwrap na GitHubu
    https://github.com/hanslub42/rlwrap
  154. rlwrap(1) – Linux man page
    https://linux.die.net/man/1/rlwrap
  155. readline(3) – Linux man page
    https://linux.die.net/man/3/readline
  156. history(3) – Linux man page
    https://linux.die.net/man/3/history
  157. Dokumentace k balíčku oglematchers
    https://godoc.org/github.com/ja­cobsa/oglematchers
  158. Balíček oglematchers
    https://github.com/jacobsa/o­glematchers
  159. Dokumentace k balíčku ogletest
    https://godoc.org/github.com/ja­cobsa/ogletest
  160. Balíček ogletest
    https://github.com/jacobsa/ogletest
  161. Dokumentace k balíčku assert
    https://godoc.org/github.com/stret­chr/testify/assert
  162. Testify – Thou Shalt Write Tests
    https://github.com/stretchr/testify/
  163. package testing
    https://golang.org/pkg/testing/
  164. Golang basics – writing unit tests
    https://blog.alexellis.io/golang-writing-unit-tests/
  165. An Introduction to Programming in Go / Testing
    https://www.golang-book.com/books/intro/12
  166. An Introduction to Testing in Go
    https://tutorialedge.net/golang/intro-testing-in-go/
  167. Advanced Go Testing Tutorial
    https://tutorialedge.net/go­lang/advanced-go-testing-tutorial/
  168. GoConvey
    http://goconvey.co/
  169. Testing Techniques
    https://talks.golang.org/2014/tes­ting.slide
  170. 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
  171. Afinní transformace
    https://cs.wikibooks.org/wi­ki/Geometrie/Afinn%C3%AD_tran­sformace_sou%C5%99adnic
  172. package gg
    https://godoc.org/github.com/fo­gleman/gg
  173. Generate an animated GIF with Golang
    http://tech.nitoyon.com/en/blog/2016/01/07/­go-animated-gif-gen/
  174. Generate an image programmatically with Golang
    http://tech.nitoyon.com/en/blog/2015/12/31/­go-image-gen/
  175. The Go image package
    https://blog.golang.org/go-image-package
  176. Balíček draw2D: 2D rendering for different output (raster, pdf, svg)
    https://github.com/llgcode/draw2d
  177. Draw a rectangle in Golang?
    https://stackoverflow.com/qu­estions/28992396/draw-a-rectangle-in-golang
  178. YAML
    https://yaml.org/
  179. edn
    https://github.com/edn-format/edn
  180. Smile
    https://github.com/FasterXML/smile-format-specification
  181. Protocol-Buffers
    https://developers.google.com/protocol-buffers/
  182. Marshalling (computer science)
    https://en.wikipedia.org/wi­ki/Marshalling_(computer_sci­ence)
  183. Unmarshalling
    https://en.wikipedia.org/wi­ki/Unmarshalling
  184. Introducing JSON
    http://json.org/
  185. Package json
    https://golang.org/pkg/encoding/json/
  186. The Go Blog: JSON and Go
    https://blog.golang.org/json-and-go
  187. Go by Example: JSON
    https://gobyexample.com/json
  188. Writing Web Applications
    https://golang.org/doc/articles/wiki/
  189. Golang Web Apps
    https://www.reinbach.com/blog/golang-webapps-1/
  190. Build web application with Golang
    https://legacy.gitbook.com/bo­ok/astaxie/build-web-application-with-golang/details
  191. Golang Templates – Golang Web Pages
    https://www.youtube.com/wat­ch?v=TkNIETmF-RU
  192. Simple Golang HTTPS/TLS Examples
    https://github.com/denji/golang-tls
  193. Playing with images in HTTP response in golang
    https://www.sanarias.com/blog/1214Pla­yingwithimagesinHTTPrespon­seingolang
  194. MIME Types List
    https://www.freeformatter.com/mime-types-list.html
  195. Go Mutex Tutorial
    https://tutorialedge.net/golang/go-mutex-tutorial/
  196. Creating A Simple Web Server With Golang
    https://tutorialedge.net/go­lang/creating-simple-web-server-with-golang/
  197. Building a Web Server in Go
    https://thenewstack.io/building-a-web-server-in-go/
  198. How big is the pipe buffer?
    https://unix.stackexchange­.com/questions/11946/how-big-is-the-pipe-buffer
  199. How to turn off buffering of stdout in C
    https://stackoverflow.com/qu­estions/7876660/how-to-turn-off-buffering-of-stdout-in-c
  200. setbuf(3) – Linux man page
    https://linux.die.net/man/3/setbuf
  201. setvbuf(3) – Linux man page (stejný obsah jako předchozí stránka)
    https://linux.die.net/man/3/setvbuf
  202. Select waits on a group of channels
    https://yourbasic.org/golang/select-explained/
  203. Rob Pike: Simplicity is Complicated (video)
    http://www.golang.to/posts/dotgo-2015-rob-pike-simplicity-is-complicated-youtube-16893
  204. Algorithms to Go
    https://yourbasic.org/
  205. Využití knihovny Pygments (nejenom) pro obarvení zdrojových kódů
    https://www.root.cz/clanky/vyuziti-knihovny-pygments-nejenom-pro-obarveni-zdrojovych-kodu/
  206. 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/
  207. Go Defer Simplified with Practical Visuals
    https://blog.learngoprogram­ming.com/golang-defer-simplified-77d3b2b817ff
  208. 5 More Gotchas of Defer in Go — Part II
    https://blog.learngoprogramming.com/5-gotchas-of-defer-in-go-golang-part-ii-cc550f6ad9aa
  209. The Go Blog: Defer, Panic, and Recover
    https://blog.golang.org/defer-panic-and-recover
  210. The defer keyword in Swift 2: try/finally done right
    https://www.hackingwithswift.com/new-syntax-swift-2-defer
  211. Swift Defer Statement
    https://andybargh.com/swift-defer-statement/
  212. Modulo operation (Wikipedia)
    https://en.wikipedia.org/wi­ki/Modulo_operation
  213. Node.js vs Golang: Battle of the Next-Gen Languages
    https://www.hostingadvice­.com/blog/nodejs-vs-golang/
  214. The Go Programming Language (home page)
    https://golang.org/
  215. GoDoc
    https://godoc.org/
  216. Go (programming language), Wikipedia
    https://en.wikipedia.org/wi­ki/Go_(programming_langua­ge)
  217. Go Books (kniha o jazyku Go)
    https://github.com/dariubs/GoBooks
  218. The Go Programming Language Specification
    https://golang.org/ref/spec
  219. Go: the Good, the Bad and the Ugly
    https://bluxte.net/musings/2018/04/10/go-good-bad-ugly/
  220. Package builtin
    https://golang.org/pkg/builtin/
  221. Package fmt
    https://golang.org/pkg/fmt/
  222. The Little Go Book (další kniha)
    https://github.com/dariubs/GoBooks
  223. The Go Programming Language by Brian W. Kernighan, Alan A. A. Donovan
    https://www.safaribookson­line.com/library/view/the-go-programming/9780134190570/e­book_split010.html
  224. Learning Go
    https://www.miek.nl/go/
  225. Go Bootcamp
    http://www.golangbootcamp.com/
  226. Programming in Go: Creating Applications for the 21st Century (další kniha o jazyku Go)
    http://www.informit.com/sto­re/programming-in-go-creating-applications-for-the-21st-9780321774637
  227. Introducing Go (Build Reliable, Scalable Programs)
    http://shop.oreilly.com/pro­duct/0636920046516.do
  228. Learning Go Programming
    https://www.packtpub.com/application-development/learning-go-programming
  229. The Go Blog
    https://blog.golang.org/
  230. Getting to Go: The Journey of Go's Garbage Collector
    https://blog.golang.org/ismmkeynote
  231. Go (programovací jazyk, Wikipedia)
    https://cs.wikipedia.org/wi­ki/Go_(programovac%C3%AD_ja­zyk)
  232. Rychle, rychleji až úplně nejrychleji s jazykem Go
    https://www.root.cz/clanky/rychle-rychleji-az-uplne-nejrychleji-s-jazykem-go/
  233. Installing Go on the Raspberry Pi
    https://dave.cheney.net/2012/09/25/in­stalling-go-on-the-raspberry-pi
  234. 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
  235. Niečo málo o Go – Golang (slovensky)
    http://golangsk.logdown.com/
  236. How Many Go Developers Are There?
    https://research.swtch.com/gop­hercount
  237. Most Popular Technologies (Stack Overflow Survery 2018)
    https://insights.stackover­flow.com/survey/2018/#most-popular-technologies
  238. Most Popular Technologies (Stack Overflow Survery 2017)
    https://insights.stackover­flow.com/survey/2017#techno­logy
  239. JavaScript vs. Golang for IoT: Is Gopher Winning?
    https://www.iotforall.com/javascript-vs-golang-iot/
  240. The Go Programming Language: Release History
    https://golang.org/doc/de­vel/release.html
  241. Go 1.11 Release Notes
    https://golang.org/doc/go1.11
  242. Go 1.10 Release Notes
    https://golang.org/doc/go1.10
  243. Go 1.9 Release Notes (tato verze je stále používána)
    https://golang.org/doc/go1.9
  244. Go 1.8 Release Notes (i tato verze je stále používána)
    https://golang.org/doc/go1.8
  245. Go on Fedora
    https://developer.fedorapro­ject.org/tech/languages/go/go-installation.html
  246. Writing Go programs
    https://developer.fedorapro­ject.org/tech/languages/go/go-programs.html
  247. The GOPATH environment variable
    https://tip.golang.org/doc/co­de.html#GOPATH
  248. Command gofmt
    https://tip.golang.org/cmd/gofmt/
  249. The Go Blog: go fmt your code
    https://blog.golang.org/go-fmt-your-code
  250. C? Go? Cgo!
    https://blog.golang.org/c-go-cgo
  251. 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/
  252. 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
  253. Gofmt No Longer Allows Spaces. Tabs Only
    https://news.ycombinator.com/i­tem?id=7914523
  254. Why does Go „go fmt“ uses tabs instead of whitespaces?
    https://www.quora.com/Why-does-Go-go-fmt-uses-tabs-instead-of-whitespaces
  255. Interactive: The Top Programming Languages 2018
    https://spectrum.ieee.org/sta­tic/interactive-the-top-programming-languages-2018
  256. Go vs. Python
    https://www.peterbe.com/plog/govspy
  257. PackageManagementTools
    https://github.com/golang/go/wi­ki/PackageManagementTools
  258. A Tour of Go: Type inference
    https://tour.golang.org/basics/14
  259. Go Slices: usage and internals
    https://blog.golang.org/go-slices-usage-and-internals
  260. Go by Example: Slices
    https://gobyexample.com/slices
  261. What is the point of slice type in Go?
    https://stackoverflow.com/qu­estions/2098874/what-is-the-point-of-slice-type-in-go
  262. The curious case of Golang array and slices
    https://medium.com/@hackintoshrao/the-curious-case-of-golang-array-and-slices-2565491d4335
  263. Introduction to Slices in Golang
    https://www.callicoder.com/golang-slices/
  264. Golang: Understanding ‚null‘ and nil
    https://newfivefour.com/golang-null-nil.html
  265. What does nil mean in golang?
    https://stackoverflow.com/qu­estions/35983118/what-does-nil-mean-in-golang
  266. nils In Go
    https://go101.org/article/nil.html
  267. Go slices are not dynamic arrays
    https://appliedgo.net/slices/
  268. Go-is-no-good (nelze brát doslova)
    https://github.com/ksimka/go-is-not-good
  269. Rust vs. Go
    https://news.ycombinator.com/i­tem?id=13430108
  270. Seriál Programovací jazyk Rust
    https://www.root.cz/seria­ly/programovaci-jazyk-rust/
  271. Modern garbage collection: A look at the Go GC strategy
    https://blog.plan99.net/modern-garbage-collection-911ef4f8bd8e
  272. Go GC: Prioritizing low latency and simplicity
    https://blog.golang.org/go15gc
  273. Is Golang a good language for embedded systems?
    https://www.quora.com/Is-Golang-a-good-language-for-embedded-systems
  274. Running GoLang on an STM32 MCU. A quick tutorial.
    https://www.mickmake.com/post/running-golang-on-an-mcu-a-quick-tutorial
  275. Go, Robot, Go! Golang Powered Robotics
    https://gobot.io/
  276. Emgo: Bare metal Go (language for programming embedded systems)
    https://github.com/ziutek/emgo
  277. UTF-8 history
    https://www.cl.cam.ac.uk/~mgk25/uc­s/utf-8-history.txt
  278. Less is exponentially more
    https://commandcenter.blog­spot.com/2012/06/less-is-exponentially-more.html
  279. Should I Rust, or Should I Go
    https://codeburst.io/should-i-rust-or-should-i-go-59a298e00ea9
  280. Setting up and using gccgo
    https://golang.org/doc/install/gccgo
  281. Elastic Tabstops
    http://nickgravgaard.com/elastic-tabstops/
  282. Strings, bytes, runes and characters in Go
    https://blog.golang.org/strings
  283. Datový typ
    https://cs.wikipedia.org/wi­ki/Datov%C3%BD_typ
  284. Seriál o programovacím jazyku Rust: Základní (primitivní) datové typy
    https://www.root.cz/clanky/pro­gramovaci-jazyk-rust-nahrada-c-nebo-slepa-cesta/#k09
  285. 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
  286. Seriál o programovacím jazyku Rust: Řezy (slice) vektoru
    https://www.root.cz/clanky/prace-s-vektory-v-programovacim-jazyku-rust/#k05
  287. Printf Format Strings
    https://www.cprogramming.com/tu­torial/printf-format-strings.html
  288. Java: String.format
    https://docs.oracle.com/ja­vase/8/docs/api/java/lang/Strin­g.html#format-java.lang.String-java.lang.Object…-
  289. Java: format string syntax
    https://docs.oracle.com/ja­vase/8/docs/api/java/util/For­matter.html#syntax
  290. Selectors
    https://golang.org/ref/spec#Selectors
  291. Calling Go code from Python code
    http://savorywatt.com/2015/09/18/ca­lling-go-code-from-python-code/
  292. Go Data Structures: Interfaces
    https://research.swtch.com/interfaces
  293. How to use interfaces in Go
    http://jordanorelli.com/pos­t/32665860244/how-to-use-interfaces-in-go
  294. Interfaces in Go (part I)
    https://medium.com/golangspec/in­terfaces-in-go-part-i-4ae53a97479c
  295. Part 21: Goroutines
    https://golangbot.com/goroutines/
  296. Part 22: Channels
    https://golangbot.com/channels/
  297. [Go] Lightweight eventbus with async compatibility for Go
    https://github.com/asaske­vich/EventBus
  298. What about Trait support in Golang?
    https://www.reddit.com/r/go­lang/comments/8mfykl/what_a­bout_trait_support_in_golan­g/
  299. 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/
  300. Control Flow
    https://en.wikipedia.org/wi­ki/Control_flow
  301. Structured programming
    https://en.wikipedia.org/wi­ki/Structured_programming
  302. Control Structures
    https://www.golang-book.com/books/intro/5
  303. Control structures – Go if else statement
    http://golangtutorials.blog­spot.com/2011/06/control-structures-if-else-statement.html
  304. Control structures – Go switch case statement
    http://golangtutorials.blog­spot.com/2011/06/control-structures-go-switch-case.html
  305. Control structures – Go for loop, break, continue, range
    http://golangtutorials.blog­spot.com/2011/06/control-structures-go-for-loop-break.html
  306. Goroutine IDs
    https://blog.sgmansfield.com/2015/12/go­routine-ids/
  307. Different ways to pass channels as arguments in function in go (golang)
    https://stackoverflow.com/qu­estions/24868859/different-ways-to-pass-channels-as-arguments-in-function-in-go-golang
  308. justforfunc #22: using the Go execution tracer
    https://www.youtube.com/wat­ch?v=ySy3sR1LFCQ
  309. Single Function Exit Point
    http://wiki.c2.com/?Single­FunctionExitPoint
  310. Entry point
    https://en.wikipedia.org/wi­ki/Entry_point
  311. Why does Go have a GOTO statement?!
    https://www.reddit.com/r/go­lang/comments/kag5q/why_do­es_go_have_a_goto_statemen­t/
  312. Effective Go
    https://golang.org/doc/ef­fective_go.html
  313. GoClipse: an Eclipse IDE for the Go programming language
    http://goclipse.github.io/
  314. GoClipse Installation
    https://github.com/GoClip­se/goclipse/blob/latest/do­cumentation/Installation.md#in­stallation
  315. The zero value of a slice is not nil
    https://stackoverflow.com/qu­estions/30806931/the-zero-value-of-a-slice-is-not-nil
  316. Go-tcha: When nil != nil
    https://dev.to/pauljlucas/go-tcha-when-nil–nil-hic
  317. Nils in Go
    https://www.doxsey.net/blog/nils-in-go