diff --git a/courses/snake/info.yml b/courses/snake/info.yml
new file mode 100644
index 0000000000..4133cb22ea
--- /dev/null
+++ b/courses/snake/info.yml
@@ -0,0 +1,78 @@
+title: Hadí workshop
+description: Hravá ochutnávka programování
+long_description: |
+
+ Chceš se naučit programovat, ale nevíš kde začít?
+ Máme tu workshop právě pro tebe!
+
+ Pod vedením instruktora vytvoříš variantu klasické videohry Had,
+ kterou můžeš znát třeba ze starších mobilů Nokia.
+ Na vlastní kůži si vyzkoušíš jak se píše kód,
+ jaké jsou základní programovací koncepty, a jaké to je,
+ když počítač přestane trucovat a začne poslouchat tvoje příkazy.
+
+ (Přijde-li ti projekt málo praktický, nezoufej! Spíš než o hru jde
+ o základní programovací principy, které dál využiješ např. při tvorbě
+ webových aplikací, analýze dat, strojovém učení,
+ programování robotů nebo návrhu systémových nástrojů.)
+
+ Workshop je pro úplné začátečníky.
+ Není potřeba vědět nic o programování, stačí mít počítač a umět ho používat
+ (např. otevřít/uložit soubor, nainstalovat program).
+
+ Workshop je v češtině a zdarma.
+
+ Zalíbí-li se ti tahle ochutnávka, je možnost pokračovat jedním
+ z podzimních začátečnických kurzů PyLadies, které začnou nedlouho
+ po workshopu.
+
+ ---
+
+ Materiály níže jsou zatím poznámky pro lektora, často psané pro
+ pokročilejší studenty; na workshopu budou podány v jednodušší podobě.
+
+vars:
+ coach-present: true
+
+plan:
+- title: Příprava
+ slug: preparation
+ materials:
+ - lesson: fast-track/cmdline
+ - lesson: beginners/install
+ - lesson: beginners/venv-setup
+ - lesson: beginners/install-editor
+- title: Workshop
+ slug: intro
+ materials:
+ - title: Úvod
+ url: null
+ - lesson: fast-track/repl
+ - lesson: fast-track/str
+ - lesson: fast-track/conversion
+ - lesson: fast-track/variables
+ - lesson: fast-track/list
+ - lesson: fast-track/random
+ - lesson: fast-track/dict
+ - lesson: fast-track/bool
+ - lesson: fast-track/script
+ - lesson: fast-track/if
+ - lesson: fast-track/def
+ - lesson: fast-track/for
+ - lesson: fast-track/tuple
+ - title: "Doplnění: list slicing, del, n-tice, zip()"
+ url: null
+- title: Had
+ slug: workshop
+ materials:
+ - title: Instalalce Pygletu
+ url: null
+ - lesson: fast-track/pyglet
+ - lesson: snake/drawing
+ - lesson: snake/logic
+ - title: Zabalení spustitelného souboru (bonus)
+ url: null
+- title: Rozšíření
+ slug: extensions
+ materials:
+ - lesson: snake/toroid
diff --git a/lessons/beginners/cmdline/index.md b/lessons/beginners/cmdline/index.md
index 462dc1354e..669735fbdd 100644
--- a/lessons/beginners/cmdline/index.md
+++ b/lessons/beginners/cmdline/index.md
@@ -159,7 +159,7 @@ Pokud máš adresář `Desktop` nebo `Plocha`, přejdi tam. Pak nezapomeň ově
Jsi-li na Linuxu nebo macOS, dej si pozor na velikost písmen: na těchto
systémech jsou `Desktop` a `desktop` dvě různá jména.
-Jsi-li na Windows, `cd` už jsi používala – tento příkaz se chová různě
+Jsi-li na Windows, `cd` už jsi používal{{a}} – tento příkaz se chová různě
podle toho, jestli něco napíšeš za něj nebo ne.
{% call sidebyside() %}
diff --git a/lessons/beginners/install/linux.md b/lessons/beginners/install/linux.md
index 0a3b60455b..f8746a03e9 100644
--- a/lessons/beginners/install/linux.md
+++ b/lessons/beginners/install/linux.md
@@ -8,7 +8,7 @@ Nezalekni se – většinu sekcí pravděpodobně přeskočíš. :)
## Instalace Pythonu 3
Na Linuxu většinou Python 3 už bývá. Abys to zkontroloval{{a}}, spusť
-v [příkazové řádce]({{ lesson_url('beginners/cmdline') }}) příkaz:
+v příkazové řádce příkaz:
```console
$ python3 --version
diff --git a/lessons/beginners/install/macos.md b/lessons/beginners/install/macos.md
index 524075214c..3aa4703e71 100644
--- a/lessons/beginners/install/macos.md
+++ b/lessons/beginners/install/macos.md
@@ -4,7 +4,7 @@ Nainstaluj si nástroj [Homebrew](http://brew.sh), který řeší a zjednodušuj
instalaci aplikací a knihoven, které budeme potřebovat pro programování.
Jak na to?
-Spusť v [příkazové řádce]({{ lesson_url('beginners/cmdline') }}) příkaz:
+Spusť v příkazové řádce příkaz:
```console
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
diff --git a/lessons/beginners/install/windows.md b/lessons/beginners/install/windows.md
index 6d2940ad36..e0210ce66c 100644
--- a/lessons/beginners/install/windows.md
+++ b/lessons/beginners/install/windows.md
@@ -1,6 +1,6 @@
# Instalace Pythonu pro Windows
-Běž na [stahovací stránku Pythonu](https://www.python.org/downloads/)
+Běž na [stahovací stránku Pythonu](https://www.python.org/downloads/release/python-370/)
a stáhni si instalátor nejnovější stabilní verze Pythonu.
Ověř si že je to verze **3.6.0 nebo novější** –
verze 3.6.0 má jistá vylepšení, která budeme v tomto kurzu používat.
diff --git a/lessons/beginners/venv-setup/index.md b/lessons/beginners/venv-setup/index.md
index 015e6f653b..d20ed36b70 100644
--- a/lessons/beginners/venv-setup/index.md
+++ b/lessons/beginners/venv-setup/index.md
@@ -100,9 +100,9 @@ C:\Users\Helena\{{rootname}}
05/08/2014 07:28 PM
01
{% endcall %}
-{% if var('coach-present') -%}
+{# XXX: if var('coach-present') -%}
Výsledek pro kontrolu ukaž koučovi.
-{%- endif %}
+{%- endif #}
## Virtuální prostředí
@@ -171,9 +171,9 @@ V grafickém prohlížeči souborů to vypadá např. takto:
alt="(adresáře '01' a 'venv' vedle sebe)",
) }}
-{% if var('coach-present') -%}
+{# XXX: if var('coach-present') -%}
Výsledek pro kontrolu ukaž koučovi.
-{%- endif %}
+{%- endif #}
### Aktivace virtuálního prostředí
diff --git a/lessons/fast-track/bool/index.md b/lessons/fast-track/bool/index.md
new file mode 100644
index 0000000000..7e77d1dd2e
--- /dev/null
+++ b/lessons/fast-track/bool/index.md
@@ -0,0 +1,148 @@
+# Porovnávání věcí
+
+Programátoři často porovnávají různé hodnoty. Pojďme se podívat, jak na to.
+
+``` pycon
+>>> 5 > 2
+True
+>>> 5 > 8
+False
+>>> 5 < 8
+True
+```
+
+Když se Pythonu zeptáš, jestli je jedno číslo větší než druhé, odpoví ti
+`True` (pravda) nebo `False` (nepravda).
+
+Funguje to i se složitějšími výrazy:
+
+``` pycon
+>>> 5 > 2 * 2
+True
+```
+
+„Větší než“ a „menší než“ jsou značky známé z matematiky.
+Chceš-li se ale zeptat, jestli jsou dvě čísla stejná, je potřba použít
+trochu jiný zápis:
+
+``` pycon
+>>> 1 == 1
+True
+```
+
+Jedno rovnítko `=` používáme pro *přiřazení* hodnoty do proměnné.
+Když chceš zkontrolovat, jestli se věci navzájem *rovnají*, vždy, **vždy**
+musíš dát dvě rovnítka `==`.
+
+Další možnosti porovnávání jsou nerovnost (≠), větší nebo rovno (≤)
+a meší nebo rovno (≥).
+Většina lidí tyhle symboly nemá na klávesnici, a tak Python používá `!=`, `<=`
+a `>=`.
+
+``` pycon
+>>> 5 != 2
+True
+>>> 3 <= 2
+False
+>>> 6 >= 12 / 2
+True
+```
+
+Už jsi někdy slyšel{{a}} výraz „srovnávat jablka a hrušky“? Zkusme v Pythonu ekvivalent:
+
+``` pycon
+>>> 1 > 'krajta'
+Traceback (most recent call last):
+ File "", line 1, in
+TypeError: '>' not supported between instances of 'int' and 'str'
+```
+
+Stejně jako nelze srovnávat „jablka a hrušky“,
+Python není schopen porovnávat řetězce (`str`) a čísla (`int`).
+Místo toho zobrazí `TypeError` a říká nám, že tyto dva typy nelze porovnat.
+
+Co se stane, když v minulé ukázce zaměníš `>` za `==`?
+
+{% filter solution %}
+```pycon
+>>> 1 == 'krajta'
+False
+```
+
+Jablka a hrušky nemůžeš porovnávat, ale můžeš si potvrdit že jsou to dvě různé
+věci.
+{% endfilter %}
+
+
+## Logika
+
+Chceš zkusit ještě něco? Zadej tohle:
+
+``` pycon
+>>> 6 > 2 and 2 < 3
+True
+>>> 3 > 2 and 2 < 1
+False
+>>> 3 > 2 or 2 < 1
+True
+```
+
+V Pythonu můžeš zkombinovat několik porovnání do jednoho!
+
+* Pokud použiješ operátor `and`, obě strany musí být pravdivé, aby byl celý výraz pravdivý.
+* Pokud použiješ operátor `or`, stačí aby jen jedna strana z porovnání byla pravdivá.
+
+
+## Přítomnost
+
+Nebylo by pěkné zjistit, jestli tvoje číslo vyhrálo v loterii?
+Máš-li seznam, operátorem `in` se můžeš zeptat, jestli je v něm daný prvek:
+
+``` pycon
+>>> loterie = [3, 42, 12, 19, 30, 59]
+>>> 18 in loterie
+False
+>>> 42 in loterie
+True
+```
+
+Není to úplně porovnání, ale dostaneš stejný druh výsledku jako s `<` či `==`.
+
+
+## Pravdivostní hodnoty
+
+Právě ses dozvěděl{{a}} o novém typu objektu v Pythonu.
+Už známe typy řetězc, číslo, seznam nebo slovník; přidali jsme k nim
+*pravdivostní hodnotu*, nebo častěji anglicky *boolean*.
+
+Pravdivostní hodnoty jsou jenom dvě: `True` (pravda) nebo `False` (nepravda).
+
+Aby Python pochopil, že se jedná o tento typ,
+je potřeba dávat pozor na velikost písmen.
+`true`, `TRUE`, `tRUE` nebude fungovat – jedině `True` je správně.
+
+Jako každou hodnotu, i *boolean* můžeš uložit do proměnné:
+
+``` pycon
+>>> a = True
+>>> a
+True
+```
+
+Stejně tak můžeš uložit i výsledek porovnání:
+
+``` pycon
+>>> a = 2 > 5
+>>> a
+False
+```
+
+
+## Shrnutí
+
+V této sekci ses dozvěděl{{a}}:
+
+* V Pythonu můžeš **porovnávat** pomocí operátorů `>`, `>=`, `==` `<=`, `<`, `!=` a `in`
+* Operátory `and` a `or` umí **zkombinovat** dvě porovnání.
+* **Boolean** (pravdivostní hodnota) je typ, který může mít jednu ze dvou
+ hodnot: `True` (pravda) nebo `False` (nepravda).
diff --git a/lessons/fast-track/bool/info.yml b/lessons/fast-track/bool/info.yml
new file mode 100644
index 0000000000..f6696deb81
--- /dev/null
+++ b/lessons/fast-track/bool/info.yml
@@ -0,0 +1,12 @@
+title: Porovnávání a logika
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/cmdline/index.md b/lessons/fast-track/cmdline/index.md
new file mode 100644
index 0000000000..4e9b54cb30
--- /dev/null
+++ b/lessons/fast-track/cmdline/index.md
@@ -0,0 +1,312 @@
+{%- macro sidebyside(titles=['Unix', 'Windows']) -%}
+
+{%- endmacro -%}
+
+{%- if var('pyladies') -%}
+{% set purpose = 'PyLadies' %}
+{% set dirname = 'pyladies' %}
+{%- else -%}
+{% set purpose = 'Python' %}
+{% set dirname = 'naucse-python' %}
+{%- endif -%}
+
+
+# Příkazová řádka
+
+Většina uživatelů ovládá počítač v *grafickém rozhraní* – myší nebo prstem
+kliká na ikonky, vybírá příkazy z menu a kouká na animace.
+Programátoři ale často ovládají počítač *textově*, v příkazové řádce:
+napíšou příkaz nebo otázku a přečtou si případnou odpověď.
+Někteří to nemají moc rádi (příkazy je potřeba si pamatovat), někteří si
+to užívají (textové příkazy lze jednoduše opakovat a automatizovat),
+ale fakt je, že bez základní znalosti příkazové řádky se programátor neobejde.
+
+Seznamme se tedy se způsobem, který programátoři používají na zadávání příkazů.
+
+Příkazová řádka (respektive program, kterému se říká i *konzole* či *terminál*;
+anglicky *command line*, *console*, *terminal*)
+se na různých systémech otevírá různě:
+
+* Windows (české): Start → napsat na klávesnici „cmd“ → Příkazový řádek
+* Windows (anglické): Start → napsat na klávesnici „cmd“ → Command Prompt
+* macOS (anglický): Applications → Utilities → Terminal
+* Linux (GNOME): Menu Aktivity (levý horní roh) → hledat Terminál
+* Linux (KDE): Hlavní Menu → hledat Konsole
+
+Nevíš-li si rady, zkus
+{% if var('coach-present') -%}
+se zeptat kouče.
+{%- else -%}
+buď googlit, nebo se zeptat e-mailem.
+{%- endif %}
+
+Po otevření konzole tě uvítá okýnko s řádkem textu,
+kterým počítač vybízí k zadání příkazu.
+Podle systému bude tento řádek končit buď znakem `$` nebo `>`,
+před nímž můžou být ještě další informace:
+
+{% call sidebyside(titles=['Unix (Linux, macOS)', 'Windows']) %}
+$
+---
+>
+{% endcall %}
+
+Podle systému se potom liší i samotné příkazy, které budeš zadávat.
+
+> [note] Velikost písma
+> Je-li ve Windows moc malé písmo, klikni na ikonku okna a vyber Možnosti.
+> V záložce Písmo si pak můžeš vybrat větší font.
+>
+>
+> {{ figure(
+ img=static('windows-cmd-properties.png'),
+ alt='Screenshot menu příkazové řádky',
+) }}
+>
+> Na ostatních systémech hledej v nastavení, nebo zkus
+> Ctrl++ a
+> Ctrl+- (příp. se Shift).
+
+
+
+## První příkaz
+
+Začneme jednoduchým příkazem.
+Napiš `whoami` (z angl. *who am I?* – kdo jsem?)
+a stiskni Enter.
+Objeví se přihlašovací jméno. Třeba u Heleny to vypadalo takhle:
+
+{% call sidebyside() %}
+$ whoami
+helena
+---
+> whoami
+pocitac\Helena
+{% endcall %}
+
+
+
+> [note]
+> Znak `$` nebo `>` je v ukázce jen proto, aby bylo jasné, že zadáváme
+> příkaz do příkazové řádky.
+> Vypíše ho počítač, většinou ještě s něčím před ním,
+> takže ho nepiš sama! Zadej jen `whoami` a Enter.
+>
+> Stejně tak počítač sám vypíše přihlašovací jméno.
+
+
+## Aktuální adresář
+
+Příkazová řádka pracuje vždy v nějakém *adresáři* (neboli *složce*,
+angl. *directory*, *folder*).
+
+Je to podobné, jako když si na počítači otevřeš prohlížeč souborů.
+Na každém počítači takový program vypadá trochu jinak, ale většinou máš
+nahoře jméno aktuálního adresáře a v hlavním okýnku seznam souborů,
+které v tom adresáři jsou:
+
+{{ figure(
+ img=static('dirs.png'),
+ alt='Screenshot prohlížeče souborů',
+) }}
+
+Podobně příkazová řádka je vždy „v“ nějakém *aktuálním adresáři*.
+Který to je, to bývá napsáno před znakem `$` nebo `>` (občas ve zkrácené podobě).
+Vždycky se ale dá vypsat příkazem, který se podle systému
+jmenuje `pwd` nebo `cd` (z angl. *print working directory* – vypiš pracovní
+adresář, resp. *current directory* – aktuální adresář).
+
+{% call sidebyside() %}
+$ pwd
+/home/helena/
+---
+> cd
+C:\Users\helena
+{% endcall %}
+
+U tebe se bude aktuální adresář nejspíš jmenovat trochu jinak.
+
+Tento adresář – ten, ve kterém příkazová řádka „začíná“ – je tvůj
+*domovský adresář*.
+Typicky obsahuje všechny tvoje soubory a nastavení.
+
+
+## Co v tom adresáři je?
+
+V prohlížeči souborů se ukazují soubory v aktuálním adresáři neustále.
+V příkazové řádce si o ně ale musíš „říct“ příkazem `ls` nebo `dir`
+(z angl. *list* – vyjmenovat, resp. *directory* – adresář).
+Ten vypíše, co aktuální adresář obsahuje: všechny soubory,
+včetně podadresářů, které se v aktuálním adresáři nacházejí.
+Na některých systémech ukáže jen jména, jinde i další informace.
+Například:
+
+{% call sidebyside() %}
+$ ls
+Applications
+Desktop
+Downloads
+Music
+…
+---
+> dir
+ Directory of C:\Users\helena
+05/08/2014 07:28 PM Applications
+05/08/2014 07:28 PM Desktop
+05/08/2014 07:28 PM Downloads
+05/08/2014 07:28 PM Music
+…
+{% endcall %}
+
+Na tvém počítači nejspíš budou jiné soubory, ale aspoň `Desktop` a `Music`
+(nebo `Plocha` a `Hudba`) na většině počítačů jsou.
+
+
+## Kopírování textu
+
+Z příkazové řádky se dá kopírovat text.
+Háček je ale v tom, že to nejde přes Ctrl+C – tahle
+zkratka tu znamená něco jiného.
+
+Zkus si zkopírovat jméno aktuálního adresáře.
+
+* Na **Linuxu** všech systémech text vyber myší, pak klikni pravým tlačítkem
+ myši a z menu vyber kopírování.
+ Případně funguje zkratka Ctrl+Insert.
+
+* Na **macOS** to je nejjednodušší: text vyber a zkopíruj pomocí
+ ⌘+C
+
+* Na **Windows** napřed klikni na ikonku okýnka, rozbal *Edit* a vyber
+ *Vybrat* (*Select*). Pak text vyber myší a zkopíruj klávesou
+ Enter.
+
+ (Na některých verzích Windows jde vybírat přímo myší, nemusíš přes menu.)
+
+Zkus zkopírované jméno adresáře vložit do grafického prohlížeče souborů.
+Měl{{a}} bys pak vidět obsah i tam.
+
+V dalších sekcích budeme potřebovat adresáře `Desktop` a `Music` (nebo `Plocha`
+a `Hudba`).
+Jestli je ve svém domovském adresáři nemáš, v grafickém prohlížeči si je
+vytvoř a v příkazové řádce zkontroluj, že je máš.
+
+{% call sidebyside() %}
+$ ls
+…
+Desktop
+Music
+…
+---
+> dir
+ Directory of C:\Users\helena
+…
+05/08/2014 07:28 PM Desktop
+05/08/2014 07:28 PM Music
+…
+{% endcall %}
+
+
+## Změna aktuálního adresáře
+
+Aktuální adresář se dá změnit pomocí příkazu `cd`
+(z angl. *change directory* – změnit adresář).
+Za `cd` se píše jméno adresáře, kam chceš přejít.
+
+> [note] Déjà vu?
+> Jsi-li na Windows, příkaz `cd` už jsi používal{{a}}.
+> Chová se ale různě podle toho, jestli něco napíšeš za něj nebo ne!
+
+Přejdi do adresáře `Desktop` (nebo `Plocha`).
+Pak si nový aktuální adresář vypiš, aby sis ověřil{{a}},
+že jsi na správném místě.
+
+{% call sidebyside() %}
+$ cd Desktop
+$ pwd
+/home/helena/Desktop
+---
+> cd Desktop
+> cd
+C:\Users\helena\Desktop
+{% endcall %}
+
+> [note] Velikost písmen
+> Jsi-li na Linuxu nebo macOS, dej si pozor na velikost písmen: na těchto
+> systémech jsou `Desktop` a `desktop` dvě různá jména.
+
+> [note] Windows a disky
+> Pokud přecházíš do adresáře na jiném disku,
+> například `D:` místo `C:`, je potřeba kromě `cd`
+> zadat jméno disku s dvojtečkou jako zvláštní příkaz (např. `D:`).
+
+
+## Cesta zpět
+
+Zkusíme teď místo do `Desktop` (nebo `Plocha`) přejít do `Music`
+(nebo `Hudba)`.
+
+Když zadáš `cd Music`, pravděpodobně uvidíš *chybu*: v aktuálním
+adresáři (`Desktop`) žádné `Music` není.
+
+Aby ses do něj dostal{{a}}, musíš nejdřív zpátky, do „nadřazeného“ adresáře.
+To dělá příkaz `cd ..` – `cd`, mezera, a dvě tečky.
+Zkus ho zadat a pak se podívat, jak se aktuální adresář změnil:
+
+{% call sidebyside() %}
+$ cd ..
+$ pwd
+/home/helena
+---
+> cd ..
+> cd
+C:\Users\helena
+{% endcall %}
+
+Z domovského adresáře už můžeš zadat `cd Music` (nebo `cd Hudba`) bez chyby.
+
+
+## Další příkazy
+
+Textových příkazů existuje daleko víc než `whoami` a `cd`.
+Z příkazové řádky můžeš vytvářet adresáře, měnit soubory, nebo si třeba přečíst
+e-mail.
+
+I „grafické“ programy, které máš na počítači nainstalované, jdou
+z příkazové řádky spustit – a to většinou jen zadáním jména.
+Zkus, jestli na tvém počítači bude fungovat `firefox`, `notepad`, `safari`
+nebo `gedit`.
+
+Při učení Pythonu si ale vystačíme s málem: s `cd`/`pwd` a několika příkazy,
+které zanedlouho nainstalujeme – například `python`.
+
+
+## Konec
+
+Nakonec vyzkoušej ještě jeden příkaz.
+Ten, který příkazovou řádku zavírá: `exit`.
+
+Příkaz `exit` funguje stejně na všech systémech.
+Proto už nebudu používat ukázku rozdělenou pro Unix a Windows.
+
+```console
+$ exit
+```
+
+Ve zbytku těchto materiálů budeme pro kód, který je potřeba zadat do
+příkazové řádky, používat unixovské `$`.
+S touto konvencí se setkáš i ve většině návodů na internetu.
+Používáš-li Windows, je dobré si na `$` zvyknout, i když ve své
+řádce máš místo něj `>`.
+
diff --git a/lessons/fast-track/cmdline/info.yml b/lessons/fast-track/cmdline/info.yml
new file mode 100644
index 0000000000..e384bff995
--- /dev/null
+++ b/lessons/fast-track/cmdline/info.yml
@@ -0,0 +1,8 @@
+title: Úvod do příkazové řádky
+style: md
+attribution:
+- Pro PyLadies CZ napsal Petr Viktorin, 2014-2018.
+- |
+ Založeno na tutoriálu [Django Girls].
+ [Django Girls]: https://tutorial.djangogirls.org/en/intro_to_command_line/
+license: cc-by-sa-40
diff --git a/lessons/fast-track/cmdline/static/dirs.png b/lessons/fast-track/cmdline/static/dirs.png
new file mode 100644
index 0000000000..5126a1ec95
Binary files /dev/null and b/lessons/fast-track/cmdline/static/dirs.png differ
diff --git a/lessons/fast-track/cmdline/static/windows-cmd-properties.png b/lessons/fast-track/cmdline/static/windows-cmd-properties.png
new file mode 100644
index 0000000000..ebb2040b0a
Binary files /dev/null and b/lessons/fast-track/cmdline/static/windows-cmd-properties.png differ
diff --git a/lessons/fast-track/conversion/index.md b/lessons/fast-track/conversion/index.md
new file mode 100644
index 0000000000..f2201965ff
--- /dev/null
+++ b/lessons/fast-track/conversion/index.md
@@ -0,0 +1,53 @@
+# Převádění typů
+
+Pojď zkusit něco nového: zjistit délku čísla stejným způsobem,
+jakým jsme zjišťovali délku našeho jména.
+Zadej `len(304023)` a stiskni Enter:
+
+``` pycon
+>>> len(304023)
+Traceback (most recent call last):
+ File "", line 1, in
+TypeError: object of type 'int' has no len()
+```
+
+{# XXX: tohle nebude první chyba... #}
+Zobrazila se ti naše první chyba!
+Ta říká, že objekty typu `int` (zkratka anglického *integer*, celé číslo)
+nemají délku.
+Tak co můžeme udělat teď?
+Možná můžeme zkusit napsat naše číslo jako řetězec?
+Řetězce mají délky, že?
+
+```pycon
+>>> len("304023")
+6
+```
+
+Existuje i funkce, která *převede* číslo na řetězec. Jmenuje se `str`:
+
+```pycon
+>>> str(304023)
+"304023"
+>>> len(str(304023))
+6
+```
+
+Podobně funkce `int` převádí věci na celá čísla:
+
+```pycon
+>>> int("304023")
+```
+
+Můžeš převést čísla na text, ale nemůžeš jen tak převést text na čísla.
+Co by se stalo, kdyby ses pokusil{{a}} na číslo převést řetězec, ve kterém
+nejsou číslice?
+
+{% filter solution() %}
+``` pycon
+>>> int('hello')
+Traceback (most recent call last):
+ File "", line 1, in
+ValueError: invalid literal for int() with base 10: 'ahoj'
+```
+{% endfilter %}
diff --git a/lessons/fast-track/conversion/info.yml b/lessons/fast-track/conversion/info.yml
new file mode 100644
index 0000000000..32b55093de
--- /dev/null
+++ b/lessons/fast-track/conversion/info.yml
@@ -0,0 +1,12 @@
+title: Převádění typů
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/def/index.md b/lessons/fast-track/def/index.md
new file mode 100644
index 0000000000..331a105436
--- /dev/null
+++ b/lessons/fast-track/def/index.md
@@ -0,0 +1,211 @@
+# Vlastní funkce
+
+Pamatuješ na funkce `len()` a `print()`?
+Jsou jako kouzelná zaříkadla z knihy vázané v kůži: když víš jak se jmenují
+a umíš je správně {# XXX: vyslovit #}napsat, něco pro tebe udělají.
+
+Teď postoupíme na další úroveň: vymyslíme si vlastní zaříkadla!
+Jak? Budeme kombinovat příkazy, které už známe.
+
+Třeba funkce, která tě pozdraví, by měla:
+
+* Vypsat „ahoj!“
+* Vypsat „jak se máš?“
+
+Definice funkce v Pythonu začíná klíčovým slovem `def`,
+dále je uveden název a následují závorky (zatím prázdné).
+Pak je jako po `if` dvojtečka – a odsazené příkazy,
+které má funkce provést.
+
+```python
+def pozdrav():
+ print('Ahoj!')
+ print('Jak se máš?')
+```
+
+Naše první funkce je připravena!
+
+Když ale tenhle program spustíš, nic neudělá.
+To proto, že tohle je jen *definice* funkce.
+Python teď ví jak pozdravit – ale neřeklo se, že to má udělat!
+
+Na konec programu přidej volání.
+To už není součást funkce, ale pokračování samotného programu.
+Proto nesmí být odsazené:
+
+```python
+def pozdrav():
+ print('Ahoj!')
+ print('Jak se máš?')
+
+pozdrav()
+```
+
+Co se stane, když funkci zavoláš několikrát po sobě?
+
+```python
+def pozdrav():
+ print('Ahoj!')
+ print('Jak se máš?')
+
+pozdrav()
+pozdrav()
+pozdrav()
+```
+
+Co se stane, když volání dáš *nad* definici funkce, místo na konec programu?
+
+```python
+pozdrav()
+
+def pozdrav():
+ print('Ahoj!')
+ print('Jak se máš?')
+```
+
+{% filter solution %}
+``` pycon
+Traceback (most recent call last):
+ File "", line 1, in
+NameError: name 'pozdrav' is not defined
+```
+
+Python si stěžuje na `NameError` – nezná nic jménem `pozdrav`.
+
+Python totiž program čte odzhora dolů.
+Až příkazem `def` se „naučí" jak zdravit.
+Předtím, než se k příkazu `def` dostane, funkce neexistuje.
+{% endfilter %}
+
+## Parametry
+
+Tvoje funkce se dá volat jen jako `pozdrav()`.
+Funkce ale jako `len('slovo')` a `print(1 + 2)` umí navíc pracovat s hodnotou.
+
+Poďme napisať funkciu, ktorá ťa pozdraví menom.
+(Uľahčíme si to použitím jazyka, ktorý nepoužíva piaty pád.)
+{# XXX: Je to správně slovensky? #}
+
+```python
+def pozdrav(meno):
+ print('Vitam ťa,', meno)
+
+pozdrav('Ola')
+pozdrav('Soňa')
+pozdrav('Hubert')
+pozdrav('Anička')
+```
+
+Jak to funguje?
+V definici funkce uvedeš závorkách *parametr* – jméno proměnné se kterou bude
+funkce pracovat.
+Hodnotu pro tenhle parametr pak zadáš při volání funkce.
+
+Zvládneš napsat program, který se zeptá na jméno a pak tě pozdraví?
+
+{% filter solution %}
+```python
+def pozdrav(meno):
+ print('Vitam ťa,', meno)
+
+pozdrav(input('Jak se jmenuješ? '))
+```
+{% endfilter %}
+
+Co se stane, když funkci zavoláš bez hodnoty pro parametr?
+
+{% filter solution %}
+``` pycon
+Traceback (most recent call last):
+ File "", line 9, in
+TypeError: pozdrav() missing 1 required positional argument: 'meno'
+```
+
+Python si stěžuje na `TypeError` – funkce `pozdrav` nedostala povinný
+argument `meno`.
+{% endfilter %}
+
+Funkce může obsahovat jakýkoli kód.
+Třeba podmíněný příkaz, `if`.
+Příkazy po `if` je pak potřeba odsatit o *další* čtyři mezery:
+
+```python
+def pozdrav(meno):
+ print('Vitam ťa,', meno)
+ if meno == 'Ola':
+ print('Ty umíš programovať!')
+
+pozdrav('Hubert')
+pozdrav('Ola')
+pozdrav('Soňa')
+```
+
+
+## Vracení
+
+Další věc, kterou funkce jako `len` umí, je *vrátit* výsledek:
+
+``` python
+delka = len('Ola')
+print(delka) # napíše: 3
+```
+
+Jak na to?
+Ve funkci můžeš použít příkaz `return`, který funkci okamžitě ukončí
+a vrátí danou hodnotu:
+
+```python
+def dvojnasobek(x):
+ return x * 2
+
+print(dvojnasobek(42))
+```
+
+Zkus se zamyslet, jak napsat funkci, která pátý pád nějakého jména. Třeba:
+
+* `paty_pad('Ola')` → 'Olo'
+* `paty_pad('Soňa')` → 'Soňo'
+* `paty_pad('Hubert')` → 'Huberte'
+
+Tohle je velice složitý úkol, tak si ho trochu zjednodušíme.
+Funkce by měla dělat tohle:
+
+* Pokud jméno je „Hubert“:
+ * vrátí `Huberte`
+* Pokud jméno končí na `a`:
+ * vrátí jméno s `o` místo posledního písmenka
+* Jinak:
+ * Vrátí původní jméno. (Uživatel si toho snad nevšimne.)
+
+``` python
+def paty_pad(jmeno):
+ if jmeno == 'Hubert':
+ return 'Huberte'
+ elif jmeno[-1] == 'a':
+ return jmeno[:-1] + 'o'
+ else:
+ return jmeno
+```
+
+Dokážeš změnit funkci `pozdrav`, aby zdravila v češtině?
+
+{% filter solution %}
+``` python
+def pozdrav(jmeno):
+ print('Vítam tě,', paty_pad(jmeno))
+
+pozdrav('Hubert')
+pozdrav('Ola')
+pozdrav('Soňa')
+```
+{% endfilter %}
+
+
+## Shrnutí
+
+Co bylo nového tentokrát?
+
+* **Funkce** umožňuje pojmenovat nějkolik příkazů, a pak je zavolat najednou.
+* **Parametry** funkce, hodnoty se kterými funkce pracuje,
+ se zadávají v závorkách.
+* `return` ukončí funkci a vrátí hodnotu
diff --git a/lessons/fast-track/def/info.yml b/lessons/fast-track/def/info.yml
new file mode 100644
index 0000000000..c8a5b5efa0
--- /dev/null
+++ b/lessons/fast-track/def/info.yml
@@ -0,0 +1,12 @@
+title: Vlastní funkce
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/dict/index.md b/lessons/fast-track/dict/index.md
new file mode 100644
index 0000000000..4d75c1b746
--- /dev/null
+++ b/lessons/fast-track/dict/index.md
@@ -0,0 +1,143 @@
+# Slovníky
+
+Jiný typ hodnot, které v sobě mohou obsahovat další hodnoty, je *slovník*.
+Pro příklad si představ překladový slovník, třeba tenhle česko-anglický:
+
+* **Jablko**: Apple
+* **Knoflík**: Button
+* **Myš**: Mouse
+
+Slovník v Pythonu obsahuje záznamy, a každý záznam přiřazuje
+nějakému *klíči* nějakou *hodnotu*.
+V našem příkladu je klíči *Jablko* přiřazena hodnota *Apple*,
+klíči *Knoflík* náleží hodnota *Button*
+a klíč *Myš* ukazuje na *Mouse*.
+
+V Pythonu by se takový slovník napsal následovně:
+
+``` pycon
+>>> slovnik = {'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse'}
+```
+
+Naše klíče a hodnoty jsou slova – krátké texty, tedy řetězce,
+které je potřeba dát do uvozovek.
+Každý klíč je od své hodnoty oddělený dvojtečkou,
+jednotlivé dvojice se od sebe oddělují čárkou,
+a celý slovník je uzavřený ve složených závorkách.
+
+Když budeš chtít v takovém slovníku něco najít, potřebuješ vědět co hledat.
+Potřebuješ *klíč*.
+Pomocí hranatých závorek můžeš zjistit hodnotu, která danému klíči odpovídá:
+
+
+``` pycon
+>>> slovnik['Jablko']
+'Apple'
+```
+
+Je to podobné jako u seznamů, jen v hranatých závorkách není index
+(pořadí prvku) nebo rozmezí s dvojtečkou, ale právě klíč.
+
+> [note]
+> Naopak to nejde – slovník neumožňuje podle hodnoty přímo zjistit klíč.
+> Na překlad z angličtiny do češtiny bys potřeboval{{a}} druhý slovník.
+
+## Měnění slovníků
+
+Co se stane, když klíč ve slovníku není?
+
+``` pycon
+>>> slovnik['Pes']
+Traceback (most recent call last):
+ File "", line 1, in
+KeyError: 'Pes'
+```
+
+Python si postěžuje na `KeyError` – chybu klíče.
+
+Podobně jako seznamy se ale slovníky dají měnit.
+Nový záznam vytvoříš takhle:
+
+``` pycon
+>>> slovnik['Pes'] = 'Dog'
+>>> slovnik
+{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse', 'Pes': 'Dog'}
+```
+
+> [note]
+> Na rozdíl od překladového slovníku nemusí být Pythonní slovník seřazený
+> podle abecedy.
+> Není to potřeba, počítač umí rychle vyhledávat i bez seřazení.
+
+Kdybys potřebovala{{a}} změnit už existující záznam, použij stejný příkaz.
+K jednomu klíči může patřit jen jedna hodnota.
+
+``` pycon
+>>> slovnik['Pes'] = 'Extension cord'
+>>> slovnik
+{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse', 'Pes': 'Extension cord'}
+```
+
+{# XXX: Zmínit se o nehomogenních slovnících? #}
+
+Chceš-li ze zlovníku nějaký záznam smazat, dělá se to podobně jako
+u seznamů příkazem `del`:
+
+``` pycon
+>>> del slovnik['Pes']
+>>> slovnik
+{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse'}
+```
+
+A když budeš chtít zjistit, kolik je ve slovníku záznamů,
+zeptáš se podobně jako na počet znaků řetězce nebo prvků seznamu.
+Použiješ funkci `len()`.
+
+``` pycon
+>>> len(slovnik)
+3
+```
+
+{# XXX
+
+* Kontakty
+* Když číslo není číslo
+* Více čísel
+
+## K zamyšlení
+
+Ke každému klíči může patřit jen jedna hodnota.
+Jak bys zařídil{{a}}, aby hodnot víc?
+
+Zkus do Pythonní proměnné uložit tyto kontakty:
+
+* Katka:
+ * 4925219
+* Jirka:
+ * 7477058
+ * 3251156
+* Verča:
+ * 1019103
+
+{% filter solution %}
+Více hodnot se dá uložit do seznamu.
+Hodnoty budou seznamy čísel:
+
+```pycon
+>>> kontakty = {'Katka': ['4925219'], 'Jirka': ['7477058', '3251156'], 'Verča': ['1019103']}
+```
+{% endfilter %}
+
+Verča se přestěhovala do zahraničí a má nové číslo: `+897 3788509`.
+
+#}
+
+## Shrnutí
+
+Skvělé! Co víš o slovnících:
+
+* **Záznam** se skládá z **klíče** a **hodnoty**.
+* Ve slovníku se hledá pomocí **klíče**.
+* Záznamy se dají přepsat, přidat, nebo pomocí `del` smazat.
+
+Jsi připraven{{a}} na další část?
diff --git a/lessons/fast-track/dict/info.yml b/lessons/fast-track/dict/info.yml
new file mode 100644
index 0000000000..c58c5373cd
--- /dev/null
+++ b/lessons/fast-track/dict/info.yml
@@ -0,0 +1,12 @@
+title: Slovníky
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/for/index.md b/lessons/fast-track/for/index.md
new file mode 100644
index 0000000000..960c69e0db
--- /dev/null
+++ b/lessons/fast-track/for/index.md
@@ -0,0 +1,108 @@
+# Cykly
+
+Programátoři se neradi opakují.
+Programování je o automatizaci: nebudeme zdravit každého člověka zvlášť,
+vezměme seznam padesáti lidí a pozdravíme je všechny najednou!
+
+(No, někteří programátoři asi nejsou moc sociálně nadaní.
+Ale jinde se ta automatizace fakt hodí!)
+
+Ještě si vzpomínáš na seznamy?
+Udělej si seznam jmen:
+
+```python
+jmena = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Ty']
+```
+
+Udělejme program, který:
+
+* Pro každé jméno ze seznamu jmen:
+ * pozdraví daným jménem
+
+V Pythonu se takový *cyklus* – opakování „pro každý prvek seznamu“ – píše
+pomocí příkazu `for`:
+
+``` python
+for jmeno in jmena:
+ pozdrav(jmeno)
+```
+
+Celý program bude tedy vypadat takto:
+
+```python
+def pozdrav(jmeno):
+ print('Vítam tě,', jmeno)
+
+jmena = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Ty']
+for jmeno in jmena:
+ pozdrav(jmeno)
+```
+
+A když ho spustíme:
+
+``` console
+$ python3 python_intro.py
+Vitam ťa, Rachel
+Vitam ťa, Monica
+Vitam ťa, Phoebe
+Vitam ťa, Ola
+Vitam ťa, Ty
+```
+
+Jak vidíš, vše, co jsi vložila dovnitř příkazu `for` s odsazením,
+se zopakuje pro každý prvek seznamu `jmena`.
+
+{# XXX: exercise? #}
+
+## Opakuj n-krát
+
+Cyklus `for` můžeš použít i s jinými hodnotami než se seznamy.
+
+Často se používá s funkcí `range()`.
+Když chceš něco 200-krát zopakovat, napiš:
+
+```python
+for i in range(200):
+ print("Nebudu nikdy házet igelit do táboráku!")
+```
+
+Jak to funguje?
+`for i in range(X)` se dá přeložit jako „pro každé číslo
+od nuly do X“.
+Funkce `range` onu posloupnost čísel od nuly do X vytvoří.
+Do proměnné `i` Python postupně uloží každé číslo, podle toho po kolikáté
+cyklem prochází.
+
+```python
+for i in range(5):
+ print(i)
+```
+```
+0
+1
+2
+3
+4
+```
+
+Všimni si, že samotné `5` není zahrnuto ve výsledku:
+`range(5)` počítá od 0 do 4.
+Když počítáš od nuly a chceš pět čísel, skončíš u čtyřky.
+
+
+## Shrnutí
+
+A je to.
+*Jsi naprosto skvěl{{gnd('ý', 'á')}}!*
+Tohle byla složitá lekce, takže bys na sebe měl{{a}} být hrd{{gnd('ý', 'á')}}.
+My jsme na tebe velmi hrdí za to, že ses dostal{{a}} tak daleko!
+
+Naučil{{a}} ses:
+
+* **Cyklus** je způsob, jak opakovat nějaký postup několikrát po sobě
+* `range` pomáhá když potřebuješ určitý konkrétní počet opakování.
+
+Můžeš si jít krátce odpočinout – protáhnout se, projít se,
+zavřít oči – než se pustíme do další kapitoly. :)
+
+🧁
diff --git a/lessons/fast-track/for/info.yml b/lessons/fast-track/for/info.yml
new file mode 100644
index 0000000000..ca95e6f8f7
--- /dev/null
+++ b/lessons/fast-track/for/info.yml
@@ -0,0 +1,12 @@
+title: Cykly
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/if/index.md b/lessons/fast-track/if/index.md
new file mode 100644
index 0000000000..74768f6171
--- /dev/null
+++ b/lessons/fast-track/if/index.md
@@ -0,0 +1,134 @@
+# Podmínky
+
+Spoustu věcí v kódu chceme provádět, jen pokud jsou splněny určité podmínky.
+Proto má Python *podmíněné příkazy*.
+
+Zkusíme napsat program, který ověřuje tajné heslo.
+Tenhle program napíše `True`, když zadáš slovo `čokoláda`:
+
+```python
+heslo = input('Zadej heslo: ')
+print(heslo == 'čokoláda')
+```
+
+## Když – tak
+
+Vypsání `True` ale není moc zajímavé.
+Lepší program by dělal tohle:
+
+* Zeptá se na tajné heslo
+* Když je heslo správné:
+ * Pustí uživatele dovnitř
+
+Anglicky se „když“ řekne *if*. A to je i jméno Pythonního příkazu.
+Používá se takhle:
+
+```python
+heslo = input('Zadej heslo: ')
+if heslo == 'čokoláda':
+ print('Správně! Račte vstoupit.')
+```
+
+Podmíněný příkaz začíná `if`, pokračuje podmínkou (třeba porovnáním)
+a končí dvojtečkou.
+
+Po řádkem s `if` je příkaz *odsazený* – na začátku řádku jsou 4 mezery.
+
+Podle toho Python pozná, že tuhle část programu má provést,
+jen když je podmínka pravdivá.
+
+Ulož a spusť:
+
+``` console
+(venv) $ python python_intro.py
+Zadej heslo: čokoláda
+Správně! Můžeš vstoupit.
+```
+
+``` console
+(venv) $ python python_intro.py
+Zadej heslo: sezam
+```
+
+## Jinak
+
+V předchozím příkladu byl kód proveden pouze v případě, že podmínka byla splněna.
+Ještě lepší program by ale byl tenhle:
+
+* Zeptá se na tajné heslo
+* Když je heslo správné:
+ * Pustí uživatele dovnitř
+* Jinak (tedy pokud heslo nebylo správné):
+ * Spustí alarm
+
+K tomu má Python příkaz `else` – „jinak“:
+
+```python
+heslo = input('Zadej heslo: ')
+if heslo == 'čokoláda':
+ print('Správně! Račte vstoupit.')
+else:
+ print('POZOR! POZOR!')
+ print('NEOPRÁVNĚNÝ VSTUP!')
+```
+
+Funuje to?
+
+## Více možností
+
+Občas se stane, že se program musí rozhodnout mezi více možnostmi.
+K tomu slouží příkaz `elif`, zkratka znglického *else if* – „jinak, pokud“.
+
+Napišme program, který okomentuje hlasitost hudby:
+
+* Zeptá se na hlasitost, a odpověď uloží jako číslo.
+* Když je hlasitost do 20:
+ * vypíše „Je to dost potichu.“
+* Jinak, když je hlasitost do 40:
+ * vypíše „Jako hudba na pozadí dobré.“
+* Jinak, když je hlasitost do 60:
+ * vypíše „Skvělé, slyším všechny detaily.“
+* Jinak, když je hlasitost do 80:
+ * vypíše „Dobré na párty.“
+* Jinak, když je hlasitost do 100:
+ * vypíše „Trochu moc nahlas!“
+* Jinak:
+ * vypíše „Krvácí mi uši!“
+
+V Pythonu:
+
+```python
+hlasitost = int(input('Jaká je nastavená hlasitost rádia? '))
+if hlasitost < 20:
+ print("Je to dost potichu.")
+elif hlasitost < 40:
+ print("Jako hudba na pozadí dobré.")
+elif hlasitost < 60:
+ print("Skvělé, slyším všechny detaily.")
+elif hlasitost < 80:
+ print("Dobré na party.")
+elif hlasitost < 100:
+ print("Trochu moc nahlas!")
+else:
+ print("Krvácí mi uši!")
+```
+
+``` console
+(venv) $ python python_intro.py
+Jaká je nastavená hlasitost rádia? 28
+Jako hudba v pozadí dobré.
+```
+
+Všimni si, že se vybere vždycky jedna alternativa.
+Když zadáš `28`, Python se dostane k `hlasitost < 40`, vypíše
+příslušnou hlášku a další možnosti přeskočí.
+
+
+## Shrnutí
+
+Co jsi viděl{{a}} v této lekci?
+
+* Příkazy **if** (pokud), **elif** (jinak, pokud) a **else** (jinak)
+ podmiňují jiné příkazy.
+* **Odsazení** se používá pro podmíněné příkazy, které následují po
+ `if` apod..
diff --git a/lessons/fast-track/if/info.yml b/lessons/fast-track/if/info.yml
new file mode 100644
index 0000000000..3aac54ef9f
--- /dev/null
+++ b/lessons/fast-track/if/info.yml
@@ -0,0 +1,12 @@
+title: Podmínky
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/list/index.md b/lessons/fast-track/list/index.md
new file mode 100644
index 0000000000..e2ff2a37a8
--- /dev/null
+++ b/lessons/fast-track/list/index.md
@@ -0,0 +1,355 @@
+# Seznamy
+
+Vedle řetězců a celých čísel má Python další druhy hodnot.
+
+Teď se podíváme na jeden, který se nazývá *seznam* (anglicky *list*).
+To je hodnota, která v sobě obsahuje jiné hodnoty.
+
+{# Anglické termíny všude! #}
+
+Seznamy se zadávají tak, že dáš několik hodnot, oddělených čárkami,
+do hranatých závorek.
+Zkus si vytvořit třeba seznam čísel z loterie:
+
+``` pycon
+>>> [3, 42, 12, 19, 30, 59]
+[3, 42, 12, 19, 30, 59]
+```
+
+Abys s takovým seznamem mohl{{a}} pracovat,
+ulož si ho do proměnné:
+
+``` pycon
+>>> loterie = [3, 42, 12, 19, 30, 59]
+```
+
+Dobrá, máme seznam! Co s ním můžeme dělat?
+Podíváme se, kolik čísel v seznamu je.
+Dá se na to použít funkce, kterou už znáš.
+Tipneš si, která to je?
+
+{% filter solution %}
+``` pycon
+>>> len(loterie)
+6
+```
+
+Funkce `len()` umí zjistit nejen délku řetězce, ale i délku seznamu – tedy
+počet jeho prvků.
+{% endfilter %}
+
+Teď si zkus seznam seřadit. Na to existuje metoda `sort`:
+
+``` pycon
+>>> loterie.sort()
+```
+
+Tato metoda nic nevrátí, ale „potichu“ změní pořadí čísel v seznamu.
+Znovu si ho vypiš, ať vidíš co se stalo:
+
+``` pycon
+>>> loterie
+[3, 12, 19, 30, 42, 59]
+```
+
+Čísla v seznamu jsou nyní seřazena od nejnižší k nejvyšší hodnotě.
+
+Podobně funguje metoda `reverse`, která obrátí pořadí prvků.
+Vyzkoušej si ji!
+
+``` pycon
+>>> loterie.reverse()
+>>> loterie
+[59, 42, 30, 19, 12, 3]
+```
+
+## Přidávání do seznamu
+
+Podobně jako u řetězců se seznamy dají spojovat pomocí `+`:
+
+``` pycon
+>>> loterie + [5, 6, 7, 8]
+[59, 42, 30, 19, 12, 3, 5, 6, 7, 8]
+```
+
+Tím se vytvoří nový seznam, ten původní zůstává nezměněný:
+
+``` pycon
+>>> loterie
+[59, 42, 30, 19, 12, 3]
+```
+
+Pokud chceš něco přidat do původního seznamu, můžeš to provést pomocí metody
+`append`.
+Ale pozor! Tahle metoda potřebuje vědět co má do seznamu přidat.
+Nová hodnota se zadává do závorek:
+
+``` pycon
+>>> loterie.append(199)
+```
+
+Metoda opět nic nevrací, takže je potřeba seznam pro kontrolu vypsat:
+
+``` pycon
+>>> loterie
+[59, 42, 30, 19, 12, 3, 199]
+```
+
+## Vybírání prvků
+
+Když se budeš chtít na jednu věc ze seznamu podívat podrobněji,
+přijde vhod možnost vybrat si konkrétní prvek.
+Na to se v Pythonu používají hranaté závorky.
+
+{# XXX: MCQ #}
+
+Chceš-li vybrat prvek, zadej jméno seznamu a hned za ním hranaté závorky
+s pořadovým číslem prvku, který chceš:
+
+``` pycon
+>>> loterie[1]
+```
+
+Dostaneš první prvek?
+
+{% filter solution %}
+``` pycon
+>>> loterie
+[59, 42, 30, 19, 12, 3, 199]
+>>> loterie[1]
+42
+```
+
+Ne, dostaneš druhý prvek.
+
+Programátoři počítají od nuly.
+Chceš li tedy první prvek, popros Python o prvek číslo nula:
+
+``` pycon
+>>> loterie[0]
+42
+```
+
+Je to zpočátku divné, ale dá se na to zvyknout.
+{% endfilter %}
+
+Číslu prvku se také říká *index* a procesu vybírání prvků *indexování*.
+
+Zkus si indexování s dalšími indexy: 3, 100, 7, -1, -2, -6 nebo -100.
+Pokus se předpovědět výsledek před zadáním příkazu.
+Jak ti to půjde?
+
+{% filter solution %}
+``` pycon
+>>> loterie
+[59, 42, 30, 19, 12, 3, 199]
+
+>>> loterie[3]
+19
+```
+Index 3 označuje čtvrtý prvek.
+
+``` pycon
+>>> loterie[7]
+Traceback (most recent call last):
+ File "", line 1, in
+IndexError: list index out of range
+
+```
+Prvek s indexem 100 v seznamu není – nastane chyba.
+
+``` pycon
+>>> loterie[1000]
+Traceback (most recent call last):
+ File "", line 1, in
+IndexError: list index out of range
+```
+Prvek s indexem 7 v seznamu taky není.
+
+``` pycon
+>>> loterie[-1]
+199
+```
+Index -1 označuje *poslední* prvek.
+
+``` pycon
+>>> loterie[-2]
+3
+```
+Index -2 označuje předposlední prvek.
+
+``` pycon
+>>> loterie[-6]
+42
+```
+Index -6 označuje šestý prvek od konce.
+
+``` pycon
+>>> loterie[-100]
+Traceback (most recent call last):
+ File "", line 1, in
+IndexError: list index out of range
+```
+Stý prvek od konce v seznamu není. Nastane chyba.
+{% endfilter %}
+
+
+## Odstraňování
+
+Chceš-li ze seznamu něco odstranit, můžeš opět použít indexy.
+Tentokrát s příkazem `del`.
+Následujícím kódem odstraň počáteční číslo seznamu, tedy prvek číslo 0:
+
+``` pycon
+>>> del loterie[0]
+```
+
+Pak si seznam opět vypiš. Kousek chybí!
+
+``` pycon
+>>> loterie
+[42, 30, 19, 12, 3, 199]
+```
+
+Zkusíš odstranit poslední prvek?
+
+{% filter solution %}
+``` pycon
+>>> del loterie[-1]
+>>> loterie
+[42, 30, 19, 12, 3]
+```
+{% endfilter %}
+
+Občase se stane, že nechceš smazat prvek podle pozice, ale podle toho,
+co v seznamu je.
+K tomu slouží hodnota `remove`, která najde a odstraní danou hodnotu:
+
+```pycon
+>>> loterie
+[42, 3]
+>>> loterie.remove(3)
+>>> loterie
+[42]
+```
+
+
+## Řezání
+
+Ze seznamu se dá kromě jednoho prvku vybrat i prvků několik – část seznamu,
+takzvaný *podseznam*.
+
+Pojďme si opět udělat delší seznam čísel:
+
+``` pycon
+>>> cisla = ["První", "Druhý", "Třetí", "Čtvrtý"]
+```
+
+Budeš-li chtít vybrat prvky od druhého dál, dej do hranatých závorek číslo
+tohohle prvku, a za něj dvojtečku.
+
+``` pycon
+>>> cisla[1]
+'Druhý'
+>>> cisla[1:]
+['Druhý', 'Třetí"', 'Čtvrtý']
+```
+
+Vybráním podseznamu se seznam nemění, tak můžeš vybírat dál:
+
+```pycon
+>>> cisla
+['První', 'Druhý', 'Třetí', 'Čtvrtý']
+>>> cisla[1:]
+['Druhý', 'Třetí"', 'Čtvrtý']
+>>> cisla[2:]
+['Třetí', 'Čtvrtý']
+>>> cisla[3:]
+['Čtvrtý']
+>>> cisla[4:]
+[]
+```
+
+Budeš-li chtít vybrat prvky od začátku *do* některého prvku, dej dvojtečku
+*před* číslo prvku, který už ve výsledku nechceš
+
+
+``` pycon
+>>> cisla[2]
+'Třetí'
+>>> cisla[:2]
+['První', 'Druhý']
+```
+
+Úkol: máš-li nějaký seznam, jak z něj vybereš všechny prvky kromě posledního?
+
+{% filter solution %}
+Poslední číslo má index -1, vyberu tedy prvky do -1:
+
+``` pycon
+>>> cisla[:-1]
+['První', 'Druhý', 'Třetí']
+```
+
+{% endfilter %}
+
+Začátek a konec se dá kombinovat – číslo můžeš dát před i za dvojtečku:
+
+```pycon
+>>> cisla
+['První', 'Druhý', 'Třetí', 'Čtvrtý']
+>>> cisla[1:-1]
+['Druhý', 'Třetí']
+```
+
+Řezání funguje i pro příkaz `del`.
+Zkus vymazat prostřední dvě čísla:
+
+``` pycon
+>>> cisla
+['První', 'Druhý', 'Třetí', 'Čtvrtý']
+>>> del cisla[1:-1]
+>>> cisla
+['První', 'Čtvrtý']
+```
+
+
+## Řezání řetězců
+
+Hranaté závorky fungují i u řetězců, kde vybírají písmenka:
+
+``` pycon
+>>> jidlo = 'čokoláda'
+>>> jidlo[3]
+'o'
+>>> jidlo[1:4]
+'oko'
+```
+
+Představ si, že máš v proměnné `jmeno` ženské jméno jako `'Ola'`,
+`'Krystýna'` nebo `'Růžena'`.
+Jak z něj vytvoříš druhý pád (např. bez `'Růženy'`)?
+
+{% filter solution %}
+Vezmi jméno až po poslední písmeno a přidáš `'y'`. Například:
+``` python
+>>> jmeno = 'Růžena'
+>>> jmeno[:-1] + 'y'
+'Růženy'
+```
+{% endfilter %}
+
+
+## Shrnutí
+
+Uf! O seznamech toho bylo k naučení celkem hodně. Shrňme si, co už umíš:
+
+* **Seznam** je seřazená sekvence hodnot.
+* Pomocí **metod** se seznam dá řadit (`sort`) a obrátit (`reverse`),
+ nebo se do něj dá přidat (`append`) či odebrat (`remove`) prvek.
+* Prvky se dají **vybrat** nebo **odstranit** (`del`) podle indexu.
+* Číslování začíná **od nuly**, záporná čísla berou prvky od konce.
+* **Podseznam** je určitá část seznamu.
+* U **řetězců** funguje vybírání prvků a podřetězců podobně
+
+Jsi připraven{{a}} na další část?
diff --git a/lessons/fast-track/list/info.yml b/lessons/fast-track/list/info.yml
new file mode 100644
index 0000000000..b540485bdd
--- /dev/null
+++ b/lessons/fast-track/list/info.yml
@@ -0,0 +1,12 @@
+title: Seznamy
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/pyglet/index.md b/lessons/fast-track/pyglet/index.md
new file mode 100644
index 0000000000..f410bbdd47
--- /dev/null
+++ b/lessons/fast-track/pyglet/index.md
@@ -0,0 +1,297 @@
+# Grafika
+
+Teď si ukážeme, jak napsat grafickou aplikaci.
+
+Python obsahuje nástroje na kreslení obrázků,
+ale pro tvorbu her nejsou příliš vhodné.
+Použijeme proto *knihovnu* (nadstavbu) jménem Pyglet, která je přímo stavěná
+na interaktivní grafiku.
+
+Musíme si ji ale nejdřív zvlášť nainstalovat.
+Nejjistější je do příkazové řádky se zapnutým virtuálním prostředím
+zadat následující dva příkazy.
+(Existují i jednodušší způsoby, které ovšem vyžadují „správně“
+nastavený systém.)
+
+* Aktualizace nástroje `pip`, který umí instalovat knihovny pro Python:
+ ``` console
+ (venv)$ python -m pip install --upgrade pip
+ ```
+ (V překladu: **Python**e, spusť **m**odul **pip** a řekni mu,
+ ať na**instal**uje a kdyžtak aktualizuje (*upgrade*) knihovnu **pip**.)
+* Samotné nainstalování Pygletu:
+ ``` console
+ (venv)$ python -m pip install pyglet
+ ```
+ (V překladu: **Python**e, spusť **m**odul **pip** a řekni mu,
+ ať na**instal**uje knihovnu **pyglet**.)
+
+U mě vypadá instalace nějak takto:
+
+```console
+(venv)$ python -m pip install --upgrade pip
+Requirement already satisfied: pip in ./venv/lib/python3.6/site-packages (18.0)
+(venv)$ python -m pip install pyglet
+Collecting pyglet
+ Downloading pyglet-1.2.4-py3-none-any.whl (964kB)
+Installing collected packages: pyglet
+Successfully installed pyglet-1.2.4
+```
+
+Důležité je `Successfully installed`, resp. `Requirement already satisfied`
+na konci.
+To znamená že je knihovna připravená k použití!
+
+
+## Kostra programu
+
+Teď zkus v editoru vytvořit nový soubor, uložit ho jako `grafika.py`
+a napsat do něj následující program:
+
+```python
+import pyglet
+window = pyglet.window.Window()
+pyglet.app.run()
+print('Hotovo!')
+```
+
+Spusť ho. Mělo by se objevit černé okýnko.
+
+> [note] Okýnko není černé?
+> Na některých počítačích (často s macOS a některými druhy Linuxu) se stává,
+> že okýnko není černé, ale je v něm nějaký „nepořádek“.
+> To nevadí.
+> Než do okýnka začneme kreslit, nepořádek uklidíme.
+
+> [note] AttributeError?
+> Jestli dostaneš chybu
+> `AttributeError: module 'pyglet' has no attribute 'window'`, zkontroluj si,
+> zě jsi soubor pojmenoval{{a}} `grafika.py` a ne `pyglet.py`.
+> Soubor v editoru ulož jako `grafika.py`, případný soubor `pyglet.py` smaž,
+> a zkus to znovu.
+
+Hotovo? Pojďme si vysvětlit, co se v tomhle programu děje.
+
+Příkaz `import pyglet` ti zpřístupní grafickou knihovnu, tak jako třeba
+`import random` ti zpřístupní funkce okolo náhodných čísel.
+
+Zavolání `pyglet.window.Window()` vytvoří nové *okýnko* na obrazovce.
+Vrátí objekt, kterým pak tohle okýnko můžeš ovládat; ten si uložíme
+do proměnné `window`.
+
+Zavolání `pyglet.app.run()` pak spustí aplikaci.
+Co to znamená?
+
+Jednoduché programy, které jsi zatím psal{{a}}, jsou popisy procesu – podobně
+jako třeba recepty k vaření.
+Sled kroků, které Python postupně vykoná od prvního po poslední.
+Občas se něco opakuje a některé kroky se dají „zabalit“ do funkce,
+ale vždycky jsme zatím popisovali jeden postup od začátku po konec.
+
+Programy pro složitější aplikace spíš než jako recept vypadají jako příručka
+automechanika.
+Popisují, co se má stát v jaké situaci.
+Třeba program pro textový editor by mohl vypadat takhle:
+
+* Když uživatel zmáčkne písmenko na klávesnici, přidej ho do dokumentu.
+*
Když uživatel zmáčkne ⌫ Backspace, poslední písmenko umaž.
+* Když uživatel zmáčkne tlačítko Uložit, zapiš soubor na disk.
+
+I takový program se dá napsat i jako „recept“ – ale ten recept je pro všechny
+aplikace stejný:
+
+* Pořád dokola:
+ * Počkej, než se něco zajímavého stane
+ * Zareaguj na nastalou situaci
+
+A to je přesně to, co dělá `pyglet.app.run()`.
+Zpracovává *události*, situace na které je potřeba zareagovat.
+V tvém programu reaguje zavírací tlačítko okýnka a na klávesu Esc
+tím, že okno zavře a ukončí se.
+
+Tvůj úkol teď bude popsat, jaké další události jsou zajímavé
+a jak na ně reagovat.
+
+
+## Obsluha událostí
+
+Nejjednodušší událost, kterou můžeme obsloužit, je psaní textu na klávesnici.
+
+Zkus do programu těsně nad řádek `pyglet.app.run()` dát následující kód:
+
+``` python
+@window.event
+def on_text(text):
+ print(text)
+```
+
+Co to je?
+Je to definice funkce, ale na začátku má *dekorátor* – tu řádku začínající
+zavináčem.
+
+Dekorátor `window.event` je způsob, jak Pygletu říct, že má tuto funkci
+spustit, když se něco zajímavého stane.
+
+Co zajímavého?
+To Pyglet zjistí podle jména funkce: `on_text` reaguje na text.
+Vždycky, když uživatel zmáčkne klávesu, Pyglet zavolá tvoji funkci!
+
+A co udělá tvoje funkce? Zavolá `print`. To už znáš.
+Zadaný text se vypíše na konzoli, ze které program spouštíš.
+To, že je otevřené okýnko, neznamená že `print` začne automaticky psát do něj!
+
+
+## Kreslení
+
+Jak psát do okýnka?
+To je trochu složitější než do konzole.
+Text tu může mít různé barvy, velikosti, druhy písma,
+může být všelijak posunutý nebo natočený…
+
+Všechny tyhle *atributy* písma můžeme (i se samotným textem) uložit do objektu
+`Label` („popisek“).
+Zkus to – dej následující kód pod řádek s `window = `:
+
+```python
+label = pyglet.text.Label("Ahoj!", x=10, y=20)
+```
+
+V proměnné `label` teď budeš mít máš popisek s textem `"Ahoj"`, který patří
+na pozici (10, 20) – 10 bodů od pravého okraje okna, 20 od spodního.
+
+To je ale jen informace.
+Podobně jako pro vypsání textu do konzole je potřeba zavolat `print`,
+pro nakreslení textu je potřeba reagovat na událost
+*vykreslení okna* – `on_draw`.
+
+Dej pod funkci `on_text` tento kód:
+
+```python
+@window.event
+def on_draw():
+ window.clear()
+ label.draw()
+```
+
+Tuhle funkci Pyglet zavolá vždycky, když je potřeba nakreslit obsah okýnka.
+U animací (filmů nebo her) to často bývá třeba 60× za sekundu
+(„[60 FPS](https://cs.wikipedia.org/wiki/Sn%C3%ADmkov%C3%A1_frekvence)“).
+
+Funkce dělá dvě věci:
+* Smaže celé okýnko (nabarví ho na černo)
+* Vykreslí text
+
+V okně teď bude vidět pozdrav!
+
+
+Zkus ještě změnit `on_text` tak, aby se zadaný text místo na konzoli
+ukázal v okýnku.
+To se dělá přiřazením do *atributu* `label.text`:
+
+```python
+@window.event
+def on_text(text):
+ print('Starý text:', label.text)
+ label.text = text
+ print('Nový text:', label.text)
+```
+
+Zvládneš v této funkci nový text přidat ke starému,
+aby program fungoval jako jednoduchý textový editor?
+
+{% filter solution %}
+```python
+@window.event
+def on_text(text):
+ label.text = label.text + text
+```
+{% endfilter %}
+
+
+## Další událostí
+
+Na jaké další události se dá reagovat?
+Všechny jsou popsané v [dokumentaci Pygletu](https://pyglet.readthedocs.io/en/latest/modules/window.html#pyglet.window.Window.on_activate).
+Tady uvádím pár zajímavých.
+
+### Stisk klávesy
+
+Klávesy, které nezadávají text (šipky, Backspace nebo
+Enter, atp.) se dají rozpoznat v události `on_key_press`.
+
+Funkce `on_key_press` má dva argumenty: první je kód klávesy,
+který můžeš porovnat s konstantou z [pyglet.window.key](https://pyglet.readthedocs.io/en/latest/modules/window_key.html#key-constants).
+Druhý určuje stisknuté modifikátory jako Shift nebo Ctrl.
+
+``` python
+@window.event
+def on_key_press(key_code, modifier):
+ if key_code == pyglet.window.key.BACKSPACE:
+ label.text = label.text[:-1]
+
+ if key_code == pyglet.window.key.ENTER:
+ print('Zadaná zpráva:', label.text)
+ window.close()
+```
+
+Na macOS budeš možná muset zaměňit `BACKSPACE` za `DELETE`. {# XXX: je to tak? #}
+(Nebo si doma nastuduj [způsob](https://pyglet.readthedocs.io/en/latest/programming_guide/keyboard.html#motion-events), jak to dělat automaticky a správně.)
+
+
+### Kliknutí myši
+
+Při obsluze události `on_mouse_press` dostaneš informace o pozici
+kliknutí (x-ovou a x-ovou souřadnici)
+a navíc informaci o stisknutém tlačítku myši a modifikátoru.
+
+Takhle se třeba popisek přesune na místo kliknutí:
+
+```python
+@window.event
+def on_mouse_press(x, y, button, modifier):
+ label.x = x
+ label.y = y
+```
+
+
+## Celý program
+
+Pro případ, že by ses ztratil{{a}} nebo nevěděla,
+kam který kousek kódu patří, uvádím výsledný ukázkový program.
+
+```python
+import pyglet
+window = pyglet.window.Window()
+label = pyglet.text.Label("Ahoj!", x=10, y=20)
+
+
+@window.event
+def on_draw():
+ window.clear()
+ label.draw()
+
+
+@window.event
+def on_text(text):
+ label.text = label.text + text
+
+
+@window.event
+def on_key_press(key_code, modifier):
+ if key_code == pyglet.window.key.BACKSPACE:
+ label.text = label.text[:-1]
+
+ if key_code == pyglet.window.key.ENTER:
+ print('Zadaná zpráva:', label.text)
+ window.close()
+
+
+@window.event
+def on_mouse_press(x, y, button, modifier):
+ label.x = x
+ label.y = y
+
+
+pyglet.app.run()
+```
+
diff --git a/lessons/fast-track/pyglet/info.yml b/lessons/fast-track/pyglet/info.yml
new file mode 100644
index 0000000000..75daef2403
--- /dev/null
+++ b/lessons/fast-track/pyglet/info.yml
@@ -0,0 +1,5 @@
+title: Úvod do Pygletu
+style: md
+attribution:
+- Pro PyLadies Brno napsal Petr Viktorin, 2015-2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/random/index.md b/lessons/fast-track/random/index.md
new file mode 100644
index 0000000000..3cd715ab59
--- /dev/null
+++ b/lessons/fast-track/random/index.md
@@ -0,0 +1,55 @@
+# Náhoda
+
+Občas je potřeba vybrat náhodnou hodnotu.
+Na to není v Pythonu funkce k dispozici přímo, ale dá se zpřístupnit
+pomocí příkazu `import`"
+
+```pycon
+>>> from random import randrange
+>>> randrange(6)
+3
+```
+
+Neboli:
+
+* Z modulu `random` (který obsahuje funkce kolem náhodných hodnot)
+ zpřístupni funkci `randrange` (která umí vybírat náhodná čísla).
+* Vyber náhodné číslo ze šesti možností.
+
+Volání funkce `randrange` několikrát opakuj.
+Jaká čísla můžeš dostat?
+
+{% filter solution %}
+Čísla od 0 do 5 – šestku ne.
+Programátoři totiž počítají od nuly, a když počítáš od nuly a chceš šest čísel, dostaneš se jen k pětce.
+{% endfilter %}
+
+Modulů jako `random`, ze kterých se dají *naimportovat* užitečná rozšiření,
+je spousta – na práci s textem, kreslení obrázků, práci se soubory nebo dny
+v kalendáři, kompresi dat, posílání e-mailů, stahování z internetu…
+Stačí jen vědět (nebo umět najít), jak se ten správný modul a funkce jmenuje.
+A kdyby nestačilo to, co má Python zabudované v sobě, další rozšiřující moduly
+se dají doinstalovat.
+
+## Náhodný výběr
+
+Když už jsme u náhody, zkusme si ještě vylosovat náhodné číslo v loterii.
+Na výběr ze seznamu má modul `random` funkci `choice`:
+
+```pycon
+>>> from random import choice
+>>> loterie = [3, 42, 12, 19, 30, 59]
+>>> choice(loterie)
+12
+```
+
+Podobně se dá vybrat náhodná karta z ruky, náhodný účastník kurzu,
+náhodná barva – cokoli, co umíš dát do seznamu.
+
+
+## Shrnutí
+
+* Příkaz **import** ti dá k dispozici funkčnost, která není k dispozici přímo
+ v Pythonu.
+* Modul **random** obsahuje funkce **randrange** (náhodné číslo) a **choice**
+ (náhodný prvek seznamu).
diff --git a/lessons/fast-track/random/info.yml b/lessons/fast-track/random/info.yml
new file mode 100644
index 0000000000..80fe54e5e2
--- /dev/null
+++ b/lessons/fast-track/random/info.yml
@@ -0,0 +1,5 @@
+title: Náhoda
+style: md
+attribution:
+- Pro PyLadies Brno napsal Petr Viktorin, 2019.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/repl/index.md b/lessons/fast-track/repl/index.md
new file mode 100644
index 0000000000..9d821f200e
--- /dev/null
+++ b/lessons/fast-track/repl/index.md
@@ -0,0 +1,92 @@
+# Interaktivní režim Pythonu
+
+Chceš-li si začít hrát s Pythonem, otevři *příkazový řádek* a aktivuj virtuální prostředí. Zkontroluj si, že na začátku příkazové řádky ti svítí `(venv)`.
+
+Je-li tomu tak, nezbývá než – konečně – pustit Python. K tomu použij příkaz `python`:
+
+``` console
+$ python
+Python 3.6.6 (...)
+Type "help", "copyright", "credits" or "license" for more information.
+>>>
+```
+
+Příkaz vypíše několik informací. Z prvního řádku se můžeš ujistit, že používáš Python 3. (Vidíš-li číslo jako `2.7.11`, něco je špatně – popros o radu kouče.)
+
+Třemi „zobáčky“ ``>>>` pak Python poprosí o instrukce. Je to jako v příkazové řádce, ale místo příkazů jako `cd` a `mkdir` sem budeš psát příkazy Pythonu.
+
+Jako první instrukci použijeme Pythonu jako kalkulačku.
+Za tři zobáčky napiš třeba `2 + 3` a zmáčkni Enter.
+
+``` pycon
+>>> 2 + 3
+5
+```
+
+Zobrazila se ti správná odpověď?
+Pokud ano, gratuluji! První příkaz v Pythonu máš za sebou.
+
+Zkusíš i odečítání?
+
+A jak je to s násobením?
+{# XXX: Jak zapsat násobení? `4 x 5` `4 . 5` `4 × 5` `4 * 5` -#}
+Na kalkulačce bys zadala `4 × 5`, což se na klávesnici píše špatně.
+Python proto používá symbol `*`.
+
+``` pycon
+>>> 4 * 5
+20
+```
+
+Symboly jako `+` a `*` se odborně nazývají *operátory*.
+
+Operátor pro dělení je `/`.
+
+Při dělení může vzniknout necelé číslo, třeba dva a půl.
+Python používá desetinnou *tečku*, ukáže se tedy `2.5`:
+
+``` python
+>>> 5 / 2
+2.5
+```
+
+Z důvodů, do kterých teď nebudeme zabíhat, se při dělení desetinná tečka
+objeví i když vyjde číslo celé:
+``` pycon
+>>> 4 / 2
+2.0
+```
+
+Občas se hodí použít dělení se zbytkem.
+Výsledek tak zůstane jako celé číslo.
+Na to má Python operátory `//` (podíl) a `%` (zbytek):
+
+``` pycon
+>>> 5 // 2
+2
+>>> 5 % 2
+1
+```
+
+
+{# XXX:
+Kolik je
+?
+#}
+
+> [style-note]
+> Mezery mezi čísly a znamínkem nejsou nutné: `4*5` i `4 * 5` dělá
+> to samé co `4 * 5`.
+> Je ale zvykem psát kolem operátoru jednu mezeru z každé strany – tak jako
+> v těchto materiálech.
+> Kód je pak čitelnější.
+
+
+### Shrnutí
+
+Co ses zatím naučil{{a}}?
+
+* **Interaktivní režim Pythonu** umožňuje zadávat příkazy (kód) pro
+ Python a zobrazuje výsledky/odpovědi.
+* **Čísla** se používají na matematiku a práci s textem.
+* **Operátor** jako `+` a `*` kombinuje hodnoty a vytvoří výsledek.
diff --git a/lessons/fast-track/repl/info.yml b/lessons/fast-track/repl/info.yml
new file mode 100644
index 0000000000..31c415c76a
--- /dev/null
+++ b/lessons/fast-track/repl/info.yml
@@ -0,0 +1,12 @@
+title: Interaktivní režim Pythonu
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/script/index.md b/lessons/fast-track/script/index.md
new file mode 100644
index 0000000000..15d97c865d
--- /dev/null
+++ b/lessons/fast-track/script/index.md
@@ -0,0 +1,152 @@
+# Ulož to!
+
+Zatím jsi psal{{a}} všechny programy v konzoli v interaktivním režimu Pythonu,
+který nás omezuje na jeden řádek kódu.
+Když Python opustíš (nebo vypneš počítač),
+všechno co jsi zatím naprogramoval{{a}} se ztratí.
+
+Větší programy jsou trvanlivější: ukládají se do souborů a dají se kdykoli
+spustit znovu.
+
+Vyzkoušejme si to. Budeme potřebovat:
+
+* Ukončit interaktivní režim Pythonu
+* Otevřít editor kódu
+* Uložit kód do nového souboru
+* Spustit kód ze souboru!
+
+Zkus vypnout Python. Existuje na to funkce `exit()`:
+
+``` pycon
+>>> exit()
+```
+
+Tak se dostaneš zpět do příkazové řádky. Pamatuješ na ni?
+Už neuvidíš `>>>`, ale řádek končící `$` nebo `>`.
+Budou tu fungovat příkazy jako `cd` a `mkdir`,
+ale ne příkazy Pythonu, jako `1 + 1`.
+
+
+Doufám, že máš nainstalovaný [textový editor](../../beginners/install-editor/).
+Ten teď otevři, udělej si nový soubor a napiš do něj tento příkaz:
+
+```python
+print('Hello, PyLadies!')
+```
+
+Nový soubor ulož pod nějakým popisným názvem: `python_intro.py`.
+Ulož si jej do adresáře, kam si budeš dávat soubory k tomuto workshopu.
+Jméno musí končit na `.py`: tahle přípona říká editoru nebo i
+operačnímu systému, že jde o program v Pythonu a Python ho může spustit.
+
+> [note] Obarvování
+> Po uložení by se text měl obarvit.
+> V interaktivním režimu Pythonu mělo vše stejnou barvu,
+> ale nyní bys měla vidět, že jméno funkce `print` je jinou barvou než
+> řetězec v závorkách.
+> Barvy nevolíš {{gnd('sám', 'sama')}}, vybírá je editor na základě toho,
+> jak potom Python kódu porozumí.
+>
+> Nazývá se to "zvýrazňování syntaxe" a je to užitečná funkce.
+> Chce to trochu praxe, ale barvy můžou napovědět
+> že ti chybí uvozovka za řetězcem
+> nebo máš překlep v klíčovém slově jako `del`.
+> To je jeden z důvodů, proč používáme editory kódu :)
+
+Pokud máš soubor uložen, je čas jej spustit!
+Pomocí dovedností, které jsi se naučil{{a}} v sekci
+o příkazové řádce, *změň adresář* na ten, kam jsi soubor uložil{{a}}.
+
+{% if var('coach-present') %}
+Pokud nevíš jak dál, požádej o pomoc kouče.
+{% endif %}
+
+Nyní pomocí Pythonu spusť kód v souboru: zadej příkaz `python`, mezeru
+a jméno souboru ke spuštění.
+(Je to podobné jako příkaz `cd` pro konkrétní adresář –
+cd jmeno_adresare.)
+
+``` console
+(venv) $ python python_intro.py
+Hello, PyLadies!
+```
+
+Funguje? Vidíš text?
+Jesli ano, právě jsi spustil{{a}} svůj první opravdový program v Pythonu!
+Cítíš se úžasně?
+
+
+## Vstup a výstup
+
+Funkce `print()`, kterou jsi použil{{a}}, umí něco *vypsat* na obrazovku.
+V konzoli se hodnoty výrazů vypisovaly automaticky, abys je mohl{{a}}
+průběžně kontrolovat, ale programy v souborech bývají složitější a výpisy
+z každého kroku by byly nepřehledné.
+Proto na vypsání potřebuješ `print()`.
+Zkus si to:
+
+``` python
+jmeno = 'Ola'
+
+'Já jsem ' + jmeno # Tohle Python nevypíše
+
+print(jmeno * 8) # Tohle jo!
+```
+
+Do závorek funkce `print()` můžeš dát i víc hodnot oddělených čárkami.
+
+``` python
+jmeno = 'Amálka'
+vek = 5
+print('Já jsem', jmeno, 'a je mi', vek)
+
+print('Za rok mi bude', vek + 1)
+```
+
+Další užitečná funkce je `input()`, která se umí zeptat na otázku.
+Odpověď pak vrátí jako řetězec, který si můžeš uložit do proměnné:
+
+``` python
+jmeno = input('Jak se jmenuješ? ')
+
+print(jmeno, 'umí programovat!')
+```
+
+A co když budeš chtít spíš číslo než text?
+Pamatuješ si na funkci, která umí převést řetězec na číslo?
+
+``` python
+letopocet = int(input('Jaký je letos rok? '))
+
+print('Loni byl rok', letopocet - 1)
+```
+
+
+## Komentáře
+
+Všiml{{a}} sis u předchozího programu poznámek za „mřížkou“ (`#`)?
+
+``` python
+jmeno = 'Ola'
+
+'Já jsem ' + jmeno # Tohle Python nevypíše
+
+print(jmeno * 8) # Tohle jo!
+```
+
+To jsou takzvané *komentáře*.
+Jsou určené jen pro lidi: Python je úplně ignoruje.
+
+Teď, když své programy ukládáš na disk a můžeš se k nim vracet,
+je důležité aby byly *čitelné*: aby z nich nejen počítače, ale i lidi
+poznali, co mají dělat.
+Vždycky když napíšeš nějaký složitější kus kódu k němu zkus přidat komentář
+s vysvětlivkou.
+Až se k programu za pár dní nebo měsíců vrátíš, poděkuješ si!
+
+
+## Shrnutí
+
+* Příkaz **python** pustí uložený soubor jako program v Pythonu.
+* Funkce **print** vypisuje hodnoty.
+* **Komentáře** můžou zpřehlednit složitější kód. Python je ignoruje.
diff --git a/lessons/fast-track/script/info.yml b/lessons/fast-track/script/info.yml
new file mode 100644
index 0000000000..94b7f371ab
--- /dev/null
+++ b/lessons/fast-track/script/info.yml
@@ -0,0 +1,12 @@
+title: Ulož to!
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/str/index.md b/lessons/fast-track/str/index.md
new file mode 100644
index 0000000000..4e09b8915b
--- /dev/null
+++ b/lessons/fast-track/str/index.md
@@ -0,0 +1,198 @@
+# Řetězce
+
+Čísla jsou pro počítače dost užitečná (ostatně slovo *počítač* to naznačuje),
+ale Python umí pracovat i s jinými druhy informací.
+Třeba s textem.
+
+Zkus si to: zadej své jméno do uvozovek, jak vidíš níže:
+
+``` pycon
+>>> 'Ola'
+'Ola'
+```
+
+Nyní jsi vytvořil{{a}} svůj první *řetězec*!
+Řetězec (angl. *string*) je programátorský termín pro *text* – posloupnost
+znaků (písmenek),
+které mohou být zpracovány počítačem.
+
+Když řetězec zadáváš, musíš ho vždy uzavřít do uvozovek (apostrofů).
+Jinak by Python nepoznal, co je text se kterým má pracovat a co jsou instrukce
+které má provést.
+To je pro počítač docela důležité – lidem podobné věci dojdou z kontextu,
+ale počítač je hloupé zařízení.
+
+{{ figure(
+ img=static('quote-comic.svg'),
+ alt='(Ilustrační komiks. Člověk říká robotovi: "Řekni Pavlovi, ať mi zavolá!". Robot odpoví: "PAVLOVI AŤ MI ZAVOLÁ!")',
+) }}
+
+Řetězce se dají spojovat – „sečítat“ – pomocí `+`. Zkus toto:
+
+``` pycon
+>>> 'Já jsem ' + 'Ola'
+'Já jsem Ola'
+```
+
+Pozor na mezeru! Když zadáš `'Já jsem'+'Ola'`, spojí se ti dvě slova dohromady.
+Počítač považuje i mezeru za *znak*; chová se k ní stejně jako k jakémukoli
+písmenku.
+Když nedáš mezeru do uvozovek, nebude součástí řetězce.
+
+Zkus si dát do uvozovek i mezeru samotnou:
+
+``` pycon
+>>> 'Já jsem' + ' ' + 'Ola'
+'Já jsem Ola'
+```
+
+Kromě „sečítání“ můžeš řetězce i opakovat – násobit číslem:
+
+``` pycon
+>>> 'Ola' * 3
+'OlaOlaOla'
+```
+
+## Uvozování
+
+A co když budeš chtít dát dovnitř do svého řetězce apostrof?
+Můžeš kolem řetězce použít dvojité uvozovky:
+
+``` pycon
+>>> "To bych řek', že jsou pořádně praštěný!"
+"To bych řek', že jsou pořádně praštěný!"
+```
+
+Pythonu je jedno, se kterým druhem uvozovek řetězec zadáš.
+Podstatná jsou jen písmenka uvnitř.
+Když Python řetězec vypisuje, může si vybrat jiný druh uvozovek
+než jsi použil{{a}} ty:
+
+``` pycon
+>>> "Ola"
+'Ola'
+```
+
+## Funkce a metody
+
+Už umíš řetězce „sčítat“ (`'Ahoj ' + 'Olo!'`)
+a „násobit“ (`'la' * 3`).
+Na všechny ostatní věci, které se s textem dají dělat,
+ale na klávesnici není dost symbolů.
+Proto jsou některé operace pojmenované slovně – třeba takzvané *funkce*.
+
+Chceš-li znát počet písmen ve svém jméně, zavolej funkci `len`.
+Napiš `len` (bez uvozovek), pak kulaté závorky, a do těch závorek
+své jméno jako řetězec (v uvozovkách):
+
+``` pycon
+>>> len('Ola')
+3
+```
+
+Existuje funkce `type`, která zjistí jestli je něco číslo nebo řetězec.
+Jak bych ji zavolal?
+
+{% filter solution %}
+``` pycon
+>>> type(123)
+
+>>> type('123')
+
+```
+{% endfilter %}
+
+Kromě funkcí existují *metody*, které se zapisují trochu jinak.
+
+Chceš-li vidět své jméno velkými písmeny, zavolej metodu `upper`.
+Napiš řetězec, pak tečku, jméno metody `upper` (bez uvozovek) a prázdné
+závorky:
+
+``` pycon
+>>> 'Ola'.upper()
+'OLA'
+```
+
+Řetězce mají i metodu `lower`. Zkus ji zavolat na své jméno.
+
+{% filter solution %}
+``` pycon
+>>> 'Ola'.lower()
+'ola'
+```
+{% endfilter %}
+
+Co je metoda (které voláš s tečkou, jako `'Ola'.upper()`) a co je funkce
+(kde vložíš informaci do závorek jako `len('Ola')`),
+to se budeš muset vždycky zapamatovat nebo vyhledat.
+
+
+{# XXX: Move elsewhere? #}
+## Skládání výrazů
+
+Volání funkce nebo metody můžeš použít jako jinou hodnotu.
+
+Nech Python spočítat matematický výraz `(1 + 3) / 2`:
+
+```pycon
+>>> (1 + 3) / 2
+2.0
+```
+
+Python napřed sečte `1 + 3` a vyjde mu 4.
+Čtverku doplní místo `1 + 3` do původního příkladu, a dostane `4 / 2`.
+To vydělí a dostane `2.0`.
+
+Neboli: `(1 + 3) / 2` = `4 / 2` = `2.0`
+
+Zkus se zamyslet, jak Python zpracuje tyto výrazy:
+
+```pycon
+>>> len('Ola') + 1
+4
+```
+
+```pycon
+>>> 'Já jsem ' + 'Ola'.upper()
+'Já jsem OLA'
+```
+
+```pycon
+>>> len('Ola'.upper())
+3
+```
+
+```pycon
+>>> len('Ola' * 3)
+9
+```
+
+{% filter solution() %}
+`'Já jsem ' + 'Ola'.upper()` → `'Já jsem ' + 'OLA'` → `'Já jsem OLA'`
+
+`len('Ola') + 1` → `3 + 1` → `4`
+
+`len('Ola'.upper())` → `len('OLA')` → `3`
+
+`len('Ola' * 3)` → `len('OlaOlaOla')` → `9`
+{% endfilter %}
+
+
+Podobné skládání je v programování velice časté.
+Většinu základních stavebních bloků se začátečník naučí za pár
+týdnů – a pak po celou svou progrmátorskou kariéru objevuje nové způsoby,
+jak je poskládat do složitějších a složitějších konstrukcí.
+
+### Shrnutí
+
+OK, dost bylo řetězců. Co ses zatím naučil{{a}}:
+
+* **Řetězce** se používají na práci s textem.
+* **Operátory** `+` a `*` se používají na spojování a opakování řetězců.
+* **Funkce** a **metody** jako `len()` a `upper()` provádí na řetězcích
+ nějaké akce.
+* **Výrazy** se dají skládat dohromady.
+
+Čísla, řetězce a operátory a funkce jsou základy většiny programovacích jazyků.
+
+Připraven{{a}} na něco dalšího? Vsadíme se, že ano!
diff --git a/lessons/fast-track/str/info.yml b/lessons/fast-track/str/info.yml
new file mode 100644
index 0000000000..2356c8de7b
--- /dev/null
+++ b/lessons/fast-track/str/info.yml
@@ -0,0 +1,12 @@
+title: Řetězce
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/str/static/quote-comic.svg b/lessons/fast-track/str/static/quote-comic.svg
new file mode 100644
index 0000000000..cd80509d62
--- /dev/null
+++ b/lessons/fast-track/str/static/quote-comic.svg
@@ -0,0 +1,466 @@
+
+
+
+
diff --git a/lessons/fast-track/tuple/index.md b/lessons/fast-track/tuple/index.md
new file mode 100644
index 0000000000..2c763c5490
--- /dev/null
+++ b/lessons/fast-track/tuple/index.md
@@ -0,0 +1,91 @@
+# N-tice
+
+Už víš, že pomocí `return` lze z funkce vracet hodnotu:
+
+``` python
+def dvojnasobek(x):
+ return x * 2
+```
+
+Jak ale napsat funkci, která vrátí dvě hodnoty?
+Chci třeba napsat funkci, která spočítá podíl a zbytek po dělení.
+
+Dvě hodnoty se dají vrátit jako seznam:
+
+``` python
+def podil_a_zbytek(a, b):
+ podil = a // b
+ zbytek = a % b
+
+ return [podil, zbytek]
+
+print(podil_a_zbytek(5, 2))
+```
+
+Lepší je ale vrátit *dvojici* čísel – dvě čísla oddělená čárkou:
+
+``` python
+def podil_a_zbytek(a, b):
+ podil = a // b
+ zbytek = a % b
+
+ return podil, zbytek
+
+print(podil_a_zbytek(5, 2))
+```
+
+Tomuhle se říká dvojice – a podobně se tvoří trojice, čtveřice, pětice,
+šestice, prostě n-tice (angl. *tuple*) hodnot.
+Funguje podobně jako seznam, ale nedá se měnit – např. se do ní nedají
+přidávat další prvky pomocí `append`.
+Když mám trojici, vždycky zůstane jako trojice.
+
+Když máš n-tici, můžeš ji přiřazením *rozbalit* (angl. *unpack*)
+do několika proměnných:
+
+``` python
+podil, zbytek = podil_a_zbytek(5, 2)
+
+print(podil)
+print(zbytek)
+```
+
+N-tice mají spoustu využití, například:
+
+* Bod v prostoru má 3 souřadnice – trojice čísel!
+* Hrací karta má barvu a hodotu – dvojice čísla a řetězce, např. `(2, 'piky')`
+
+Občas je potřeba dát n-tice do seznamu, např. abys uložil{{a}}
+informace o celém balíčku hracích karet.
+V podobných případech je potřeba každou n-tici uzavřít do závorek,
+aby bylo jasné kde začíná a kde končí.
+Tady je seznam dvojic:
+
+```python
+ruka = [(2, 'piky'), (10, 'kříže'), (8, 'káry')]
+```
+
+Když takový seznam máš, můžeš ho projít v cyklu `for` s pomocí rozbalování:
+
+``` python
+for hodnota, barva in ruka:
+ print('Hraju', hodnota, 'a jsou to', barva)
+```
+
+## Zip
+
+N-tice, respektive sekvenci n-tic, vrací funkce `zip`,
+která umožňuje projít zároveň několik seznamů,
+jejichž prvky si navzájem odpovídají:
+
+``` python
+veci = ['tráva', 'slunce', 'mrkev', 'řeka']
+barvy = ['zelená', 'žluté', 'oranžová', 'modrá']
+mista = ['na zemi', 'nahoře', 'na talíři', 'za zídkou']
+
+for vec, barva, misto in zip(veci, barvy, mista):
+ print(barva, vec, 'je', misto)
+```
+
+V tomhle cyklu dostaneš napřed trojici prvních prvků ze všech tří seznamů,
+pak trojici všech druhých prvků, pak třetích, a tak dále.
diff --git a/lessons/fast-track/tuple/info.yml b/lessons/fast-track/tuple/info.yml
new file mode 100644
index 0000000000..f3110652a1
--- /dev/null
+++ b/lessons/fast-track/tuple/info.yml
@@ -0,0 +1,5 @@
+title: N-tice a rozbalování
+style: md
+attribution:
+- Pro PyLadies CZ napsal Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/fast-track/variables/index.md b/lessons/fast-track/variables/index.md
new file mode 100644
index 0000000000..91fa6bb626
--- /dev/null
+++ b/lessons/fast-track/variables/index.md
@@ -0,0 +1,128 @@
+# Proměnné
+
+Důležitým konceptem v programování jsou *proměnné*.
+Proměnná není nic jiného než *pojmenování* něčeho,
+co budeme chtít použít později.
+Programátoři proměnné používají k ukládání dat,
+aby byl jejich kód čitelnější a nemuseli si pamatovat konkrétní hodnoty.
+
+Řekněme, že chceš vytvořit novou proměnnou s názvem `jmeno`.
+To se zapíše takto:
+
+``` pycon
+>>> jmeno = 'Ola'
+```
+
+Proměnná `jmeno` teď bude mít hodnotu `'Ola'`.
+
+Jak sis mohl{{a}} všimnout, tenhle příkaz nic nevrátil – Python nevypsal
+žádný výsledek.
+Jak tedy víme, že proměnná skutečně existuje?
+
+Zadej samotné jméno proměnné (tedy `jmeno`, bez uvozovek) a stiskni
+Enter:
+
+``` pycon
+>>> jmeno
+'Ola'
+```
+
+Zkus si nastavit i jinou proměnnou – třeba svoji oblíbenou barvu:
+
+``` pycon
+>>> barva = 'modrá'
+>>> barva
+'modrá'
+```
+
+Kdykoli můžeš do proměnné přiřadit znovu, a změnit tak co se pod
+daným jménem skrývá:
+
+``` pycon
+>>> jmeno
+'Ola'
+>>> jmeno = "Soňa"
+>>> jmeno
+'Soňa'
+```
+
+Můžeš ji také použít ve funkcích:
+
+``` pycon
+>>> len(jmeno)
+4
+```
+
+Super, ne?
+Proměnná může obsahovat cokoliv, například také čísla!
+Zkus tohle:
+
+``` pycon
+>>> sirka = 4
+>>> delka = 6
+>>> sirka * delka
+24
+```
+
+Ale co když použiješ nesprávné jméno? Dokážeš odhadnout, co se stane?
+
+{% filter solution %}
+``` pycon
+>>> mesto = "Tokyo"
+>>> mmesto
+Traceback (most recent call last):
+ File "", line 1, in
+NameError: name 'mmesto' is not defined
+```
+{% endfilter %}
+
+Chyba!
+
+Python má různé typy chyb. Tato se nazývá `NameError`.
+Python ti vrátí tuto chybu, pokud se pokusíš použít proměnnou,
+která dosud nebyla nastavena.
+Pokud někdy dojde k této chybě, zkontroluj svůj kód, abys zjistil{{a}},
+jestli jsi někde neudělal{{a}} překlep.
+
+## Jména proměnných
+Profesionální programátoři pojmenovávají proměnné anglicky,
+aby jim rozuměli co nejvíc kolegů po celém světě.
+Ze začátku ale doporučujeme češtinu – je tak jasnější, která jména
+si můžeš zvolit {{gnd('sám', 'sama')}} (např. `barva`) a která jsou
+z Pythonu (např. `upper`).
+Nevýhoda je, že si časem budeš muset odvyknout.
+
+
+Každopádně je dobré nepoužívat diakritiku a vyhnout se velkým pímenům:
+místo `Jméno` použij jen `jmeno`.
+
+
+Která z těchto jmen ti Python dovolí použít jako proměnnou?
+
+* `tlacitko5`
+* `5tlacitko`
+* `tlačítko`
+* `oblibena barva`
+* `oblibena-barva`
+* `oblibenaBarva`
+
+{% filter solution %}
+
+* `tlacitko5` ano.
+* `5tlacitko` ne: jména musí začínat písmenkem.
+* `tlačítko` ano, ale je diakritice (`č`, `í`) je lepší se vyhnout.
+* `oblibena barva` ne: to není jedno jméno, ale dvě!
+* `oblibena-barva` taky ne: to Python bere jako odečtení dvou proměnných
+ (`oblibena` mínus `barva`).
+* `oblibenaBarva` ano, ale velkým písmenům je lepší se vyhnout.
+
+Kdybys potřeboval{{a}} ve jménu více slov, použij podtržítko: např.
+`oblibena_barva`.
+{% endfilter %}
+
+## Shrnutí
+
+* **Proměnné** jsou jména pro hodnoty.
+* Přiřazením (`=`) můžeš proměnnou nastavit na jakoukoli hodnotu.
+* Proměnné pojmenováváme **malými písmenky** bez diakritiky.
+* Na oddělení slov v rámci jména můžeme použít **podtržítko**.
diff --git a/lessons/fast-track/variables/info.yml b/lessons/fast-track/variables/info.yml
new file mode 100644
index 0000000000..1177b57aed
--- /dev/null
+++ b/lessons/fast-track/variables/info.yml
@@ -0,0 +1,12 @@
+title: Proměnné
+style: md
+attribution:
+- Založeno na materiálech [DjangoGirls](https://djangogirls.org/).
+- Část této kapitoly je založena na kurzu [Geek Girls Carrots](https://github.com/ggcarrots/django-carrots).
+- |
+ Původní DjangoGirls tutoriál přeložila do češtiny skupina dobrovolníků.
+ Poděkování patří hlavně: Davidovi (dakf), Kristýně Kumpánové,
+ Veronice Gabrielové, Tomáši Ehrlichovi, Aničce Jaegerové,
+ Matějovi Stuchlíkovi, Filipovi Sivákovi a Juraji M. Bezručkovi.
+- Pro PyLadies CZ upravil Petr Viktorin, 2018.
+license: cc-by-sa-40
diff --git a/lessons/snake/drawing/index.md b/lessons/snake/drawing/index.md
index 31350daa95..18d8fc648e 100644
--- a/lessons/snake/drawing/index.md
+++ b/lessons/snake/drawing/index.md
@@ -1,7 +1,7 @@
# Nakresli mi hada
-Většina videoher má vlastní svět – spoustu čísel, textů, seznamů a jiných
-datových objektů, které popisují všechno, co ve hře je – celý *stav* hry.
+Většina videoher má celý herní svět uložený jako spoustu čísel, textů, seznamů
+a jiných datových objektů, které popisují všechno, co ve hře je.
Tenhle stav se časem mění, ať už automaticky nebo podle akcí hráče.
A docela často – většinou zhruba šedesátkrát za vteřinu – se stav hry převede
na obrázek, který se hráčovi ukáže.
@@ -14,7 +14,7 @@ musí o hře „pamatovat“, aby mohl aktuální stav zobrazit?
Bude potřebovat například aktuální polohu všech částí hada: kde má začátek?
Kroutí se doprava nebo doleva? Jak je dlouhý?
-Naopak barvu hada se stavu ukložit nepotřebuješ – každý had v téhle hře bude
+Naopak barvu hada ve stavu uložit nepotřebuješ – každý had v téhle hře bude
stejný.
Napadne tě, jak polohu hada zapsat pomocí čísel, seznamů a dalších základních
@@ -35,7 +35,7 @@ Každý bod v rovině (třeba na obrazovce!)
je možné popsat dvěmi čísly: x-ovou a y-ovou souřadnicí.
Ta x-ová říká, jak moc vlevo je bod od nějakého počátku,
ta y-ová udává jak moc je nahoře.
-My za onen „počátek“ zvolíme roh okýnka, ve kterém se bude plazit náš had.
+My za onen „počátek“ zvolíme roh okýnka, ve kterém se bude náš had plazit.
Na rozdíl od školní geometrie se had bude plazit po čtverečkové mřížce.
Je to jako na šachovnici – když jde pěšec na D5, D značí, jak moc je to
@@ -98,11 +98,7 @@ se souřadnicemi (10, 20).
## Sázení čtverečku
Na to, abychom hada vykreslili, použijeme okýnko z Pygletu.
-Tady je základní kostra programu Pyglet, které už bys měl{{a}} rozumět.
-
-Udělej si nový, prázdný adresář na hadí hru, a kostru si
-zkopíruj do souboru `ui.py`.
-Budeme ji dál rozvíjet.
+Tady je základní kostra Pygletí aplikace, které už bys měl{{a}} rozumět:
```python
import pyglet
@@ -116,6 +112,10 @@ def on_draw():
pyglet.app.run()
```
+V editoru si otevři nový soubor, ulož ho jako `had.py` a kostru programu
+do něj zkopíruj.
+Budeme ji dál rozvíjet.
+
Stáhni si soubor [green.png]({{ static('green.png') }}) – zelený čtvereček –
a dej ho do adresáře, kam píšeš kód.
@@ -133,7 +133,7 @@ Potom zkus dovnitř do funkce `on_draw` přidat vykreslení obrázku na souřadn
green_image.blit(40, 50, width=10, height=10)
```
-Program spusť (`cd` do nového adresáře; `python ui.py`). Funguje?
+Program spusť (`cd` do nového adresáře; `python had.py`). Funguje?
(Je docela důležité, aby fungoval – nevidíš-li zelený čtvereček,
nečti dál a program radši oprav.)
@@ -142,8 +142,8 @@ Budeme radši používat čtverečky větší, řekněme 64 pixelů.
To číslo je „střelené od boku“.
V programu ho použijeme několikrát, a možná ho později budeš chtít upravit.
-Uložíme si ho proto do *konstanty* – proměnné, kterou nebudeme měnit.
-Konstanty se tradičně pojmenovávají velkými písmeny, a píšou se hned za řádek
+Uložíme si ho proto do *konstanty* (proměnné, kterou nebudeme měnit).
+Konstanty se tradičně pojmenovávají velkými písmeny a píšou se hned za řádek
`import` (i když to není technicky nutné).
Přidej tedy za `import` řádek:
@@ -201,8 +201,7 @@ for x, y in snake:
...
```
-Funguje to? Vidíš v tom – aspoň zhruba – hada
-(i když je poskládaný ze čtverečků)?
+Funguje to? Vidíš v tom – aspoň zhruba – hada poskládaného ze čtverečků?
{{ figure(
img=static('coords-blocks.svg'),
@@ -210,8 +209,8 @@ Funguje to? Vidíš v tom – aspoň zhruba – hada
) }}
Jestli ne, nezoufej, zkontroluj si to znovu, poptej se na radu.
-Řešení využij až jako krajní možnost, jak pokračovat dál – nebo na kontrolu
-správného řešení.
+Ukázkové řešení využij až jako krajní možnost, jak pokračovat dál.
+Nebo pro kontrolu.
{% filter solution %}
```python
@@ -230,7 +229,7 @@ def on_draw():
window.clear()
for x, y in snake:
green_image.blit(x * TILE_SIZE, y * TILE_SIZE,
- width=TILE_SIZE, height=TILE_SIZE)
+ width=TILE_SIZE, height=TILE_SIZE)
pyglet.app.run()
```
@@ -239,12 +238,11 @@ pyglet.app.run()
## Krmení
-
Aby bylo ve hře co dělat, budeme potřebovat pro hada krmení.
-Stáhni si do adresáře s projektem obrázek `apple.png` (ať už jednoduchý
-čtvereček nebo detailnější obrázek), a zkus vykreslit jídlo třeba
-na následující souřadnice:
+Stáhni si do adresáře s projektem obrázek
+[apple.png]({{ static('apple.png') }}) a zkus vykreslit
+jablíčka na následující souřadnice:
```python
food = [(2, 0), (5, 1), (1, 4)]
@@ -269,21 +267,21 @@ def on_draw():
window.clear()
for x, y in snake:
green_image.blit(x * TILE_SIZE, y * TILE_SIZE,
- width=TILE_SIZE, height=TILE_SIZE)
+ width=TILE_SIZE, height=TILE_SIZE)
for x, y in food:
red_image.blit(x * TILE_SIZE, y * TILE_SIZE,
- width=TILE_SIZE, height=TILE_SIZE)
+ width=TILE_SIZE, height=TILE_SIZE)
pyglet.app.run()
```
{% endfilter %}
-Používáš-li detailnější obrázek, možná si všimneš, že má trošičku „zubaté“ hrany.
-To je dáno způsobem, jakým v Pygletu obrázek vykreslujeme.
-Úplné vysvětlení by zabralo příliš času, proto ukážu jen řešení.
-Až se naučíš grafiku víc do hloubky, pochopíš co se tu děje :)
-
-Do funkce `on_draw`, hned za `clear`, dej následující dva řádky:
+Možná si všimneš, že obrázek má ve hře trošičku „zubaté“ hrany.
+To je dáno způsobem, jakým v Pygletu vykreslujeme.
+Úplné vysvětlení by se do tohoto návodu nevešlo, potřebuje trochu hlubší
+znalosti počítačové grafiky.
+Proto uvedu jen řešení.
+Do funkce `on_draw`, hned za `clear`, dej následující tři řádky:
```python
# Lepší vykreslování (pro nás zatím kouzelné zaříkadlo)
@@ -319,11 +317,11 @@ Obrázek se jmenuje odkud-kam.png.
> [note]
> Co jsou taková ta divná „hadí vajíčka”?
-> To je pro přímad, že by had byl jen jedno políčko dlouhý – a tedy měl hlavu
+>
+> To je pro případ, že by had byl jen jedno políčko dlouhý – a tedy měl hlavu
> i ocas na stejném políčku.
-> V naší hře se do takového stavu nedostaneme (had bude začínat s délkou 2),
-> ale může se stát, že se do něj dostaneš omylem při vývoji hry.
-> Když jsou obrázky k dispozici, lépe pak zjišťuješ, co je špatně.
+> V dodělané hře se do takového stavu nedostaneme (had bude začínat s délkou 2),
+> ale než hru dokončíme, budou tyhle obrázky užitečné.
Pojďme si teď tyhle obrázky *načíst*.
Šlo by to dělat postupně, třeba takhle:
@@ -338,76 +336,47 @@ bottom_top = pyglet.image.load('snake-tiles/bottom-top.png')
Ale obrázků je spousta, tímhle způsobem by to bylo zdlouhavé a nejspíš bys
na některý zapomněl{{a}}.
-Proto Pythonu řekneme, aby nám dal všechny soubory s koncovkou `.png` v daném
-adresáři.
-Na to se dá použít třída `Path` z modulu [`pathlib`](https://docs.python.org/3/library/pathlib.html).
-Zkus si napsat (do nového souboru, třeba `experiment.py`) tento kód
-a spustit ho.
-Dokážeš vysvětlit, co dělá?
-
-```python
-from pathlib import Path
-
-TILES_DIRECTORY = Path('snake-tiles')
+Proto si obrázky načteme automaticky, v cyklu, a dáme je do slovníku.
-for path in TILES_DIRECTORY.glob('*.png'):
- print(path)
-```
+Program bude vypadat takhle:
-My z každého souboru potřebujeme nejlépe jméno, tedy místo
-`snake-tiles/right-head.png` jenom `right-head`.
-Na to naštěstí existuje atribut `stem` (*kořen*, t.j. jméno bez přípony).
-Místo `print(path)` použij:
+* Začni s prázdným slovníkem.
+* Pro každý *začátek* (`bottom`, `end`, `left`, `right`, `top`):
+ * Pro každý *konec* (`bottom`, `end`, `left`, `right`, `top`, `dead`, `tongue`):
+ * Budeme načítat obrázek „začátek-konec“; tento
+ klíč si dej do proměnné
+ * Načti obrázek klíč.png
+ * Ulož obrázek do slovníku pod klíč.
```python
- print(path.stem)
+snake_tiles = {}
+for start in ['bottom', 'end', 'left', 'right', 'top']:
+ for end in ['bottom', 'end', 'left', 'right', 'top', 'dead', 'tongue']:
+ key = start + '-' + end
+ image = pyglet.image.load('snake-tiles/' + key + '.png')
+ snake_tiles[key] = image
```
-Funguje? Máš vypsané všechny možné kousky hada?
-
-Teď budeme chtít načíst obrázky do *slovníku*.
-*Klíče* slovníku, podle kterých budeme vyhledávat, budou jména, která jsi
-právě vypsal{{a}}.
-*Hodnoty* pak budou pygletí obrázky, které ve hře můžeš rovnou vykreslit.
-
-Začni s prázdným slovníkem, `{}`, a v cyklu `for` do něj postupně přidávej
-záznamy.
-Pak slovník vypiš.
-
-Až to budeš mít, měl by výpis vypadat asi takhle:
+Pak celý slovník vypiš.
+Výpis vypadat asi takhle:
```
{'right-tongue': , 'top-tongue': ,
'right-top': , 'left-bottom': ,
- 'tail-left': , 'bottom-tongue': ,
+ 'end-left': , 'bottom-tongue': ,
'left-top': , 'bottom-bottom': ,
...
```
-{% filter solution %}
-```python
-from pathlib import Path
-
-import pyglet
-
-TILES_DIRECTORY = Path('snake-tiles')
-
-snake_tiles = {}
-for path in TILES_DIRECTORY.glob('*.png'):
- snake_tiles[path.stem] = pyglet.image.load(path)
-
-print(snake_tiles)
-```
-{% endfilter %}
-
## Housenka
A teď zkus načtení obrázků začlenit do programu s hadem!
Všechny importy patří nahoru, konstanty pod ně, a dál pak zbytek kódu.
-Vypisovat načtený slovník ve hře nemusíš, zato místo `green_image`
-pak ve vykreslovací funkci použij třeba `snake_tiles['tail-head']`.
+Vypisovat načtený slovník ve hře nemusíš.
+Zato ve vykreslovací funkci použij místo `green_image`
+třeba `snake_tiles['end-end']`.
Místo čtverečků se teď objeví kuličky – místo hada budeš mít „housenku“.
@@ -441,7 +410,7 @@ def on_draw():
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
for x, y in snake:
- snake_tiles['tail-head'].blit(
+ snake_tiles['end-end'].blit(
x * TILE_SIZE, y * TILE_SIZE, width=TILE_SIZE, height=TILE_SIZE)
for x, y in food:
red_image.blit(
@@ -458,9 +427,9 @@ Místo toho, aby byl všude stejný kousek hada,
ale budeme chtít vybrat vždycky ten správný.
Jak na to?
-
Podle čeho ho vybrat?
+Pojďme si to vyzkoušet vedle.
Vytvoř soubor `smery.py` a napiš do něj:
```python
@@ -516,13 +485,13 @@ for a, b, c in zip([None] + snake, snake, snake[1:] + [None]):
```
-1 2 tail right
+1 2 end right
2 2 left right
3 2 left top
3 3 bottom top
3 4 bottom top
3 5 bottom right
-4 5 left head
+4 5 left end
```
Toto je **těžký úkol**.
@@ -533,16 +502,15 @@ vrať se k materiálům k předchozím lekcím (hlavně k úvodu do Pythonu),
zkoušej a objevuj… A časem na to přijdeš.
Až se to stane, zkus své řešení co nejvíc *zjednodušit* a pak ho zakomponovat
-do vykreslovací funkce.
-To by už nemělo být příliš složité:
+do vykreslovací funkce místo existujícího cyklu `for x, y in snake`.
```python
- for ??? in ???snake???:
+ for ... in ...:
...
- x = ???
- y = ???
- odkud = ???
- kam = ???
+ x = ...
+ y = ...
+ odkud = ...
+ kam = ...
...
snake_tiles[odkud + '-' + kam].blit(
diff --git a/lessons/snake/drawing/static/screenshot-dir.png b/lessons/snake/drawing/static/screenshot-dir.png
index 62382a3284..ca4f169464 100644
Binary files a/lessons/snake/drawing/static/screenshot-dir.png and b/lessons/snake/drawing/static/screenshot-dir.png differ
diff --git a/lessons/snake/drawing/static/snake-tiles.png b/lessons/snake/drawing/static/snake-tiles.png
index 6b7b1c8d52..05182e7bf6 100644
Binary files a/lessons/snake/drawing/static/snake-tiles.png and b/lessons/snake/drawing/static/snake-tiles.png differ
diff --git a/lessons/snake/drawing/static/snake-tiles.zip b/lessons/snake/drawing/static/snake-tiles.zip
index 7faf9e4105..dbcccc23a1 100644
Binary files a/lessons/snake/drawing/static/snake-tiles.zip and b/lessons/snake/drawing/static/snake-tiles.zip differ
diff --git a/lessons/snake/drawing/static/snake-tiles/bottom-head.png b/lessons/snake/drawing/static/snake-tiles/bottom-end.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/bottom-head.png
rename to lessons/snake/drawing/static/snake-tiles/bottom-end.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-bottom.png b/lessons/snake/drawing/static/snake-tiles/end-bottom.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-bottom.png
rename to lessons/snake/drawing/static/snake-tiles/end-bottom.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-dead.png b/lessons/snake/drawing/static/snake-tiles/end-dead.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-dead.png
rename to lessons/snake/drawing/static/snake-tiles/end-dead.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-head.png b/lessons/snake/drawing/static/snake-tiles/end-end.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-head.png
rename to lessons/snake/drawing/static/snake-tiles/end-end.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-left.png b/lessons/snake/drawing/static/snake-tiles/end-left.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-left.png
rename to lessons/snake/drawing/static/snake-tiles/end-left.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-right.png b/lessons/snake/drawing/static/snake-tiles/end-right.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-right.png
rename to lessons/snake/drawing/static/snake-tiles/end-right.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-tongue.png b/lessons/snake/drawing/static/snake-tiles/end-tongue.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-tongue.png
rename to lessons/snake/drawing/static/snake-tiles/end-tongue.png
diff --git a/lessons/snake/drawing/static/snake-tiles/tail-top.png b/lessons/snake/drawing/static/snake-tiles/end-top.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/tail-top.png
rename to lessons/snake/drawing/static/snake-tiles/end-top.png
diff --git a/lessons/snake/drawing/static/snake-tiles/left-head.png b/lessons/snake/drawing/static/snake-tiles/left-end.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/left-head.png
rename to lessons/snake/drawing/static/snake-tiles/left-end.png
diff --git a/lessons/snake/drawing/static/snake-tiles/right-head.png b/lessons/snake/drawing/static/snake-tiles/right-end.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/right-head.png
rename to lessons/snake/drawing/static/snake-tiles/right-end.png
diff --git a/lessons/snake/drawing/static/snake-tiles/top-head.png b/lessons/snake/drawing/static/snake-tiles/top-end.png
similarity index 100%
rename from lessons/snake/drawing/static/snake-tiles/top-head.png
rename to lessons/snake/drawing/static/snake-tiles/top-end.png
diff --git a/lessons/snake/logic/index.md b/lessons/snake/logic/index.md
index 94951ad568..4f426c3b09 100644
--- a/lessons/snake/logic/index.md
+++ b/lessons/snake/logic/index.md
@@ -1,8 +1,8 @@
# Logika hry
-Už umíš vykreslit „fotku“ hada.
-Hadí videohra ale nebude jen statický obrázek.
-Had se bude hýbat!
+Už umíš vykreslit hada ze seznamu souřadnic.
+Hadí videohra ale nebude jen „fotka“.
+Seznam se bude měnit a had se bude hýbat!
+
+
diff --git a/lessons/snake/toroid/index.md b/lessons/snake/toroid/index.md
new file mode 100644
index 0000000000..f0aabda06d
--- /dev/null
+++ b/lessons/snake/toroid/index.md
@@ -0,0 +1,101 @@
+# Nekonečná klec
+
+Místo konce hry při naražení do zdi můžeme nechat hada „projít“ a objevit se na
+druhé straně.
+
+Z pohledu logiky hry to není tak složité, jak to může znít.
+Stačí v `move` místo ukončení hry správně nastavit příslušnou hodnotu.
+Je ale potřeba si dát pozor kde použít `new_x` a kde `new_y`, kde `width` a kde
+`height`, a kde přičíst nebo odečíst jedničku, aby při číslování od nuly
+všechno sedělo.
+Zkus to!
+
+{% filter solution %}
+```python
+ # Kontrola vylezení z hrací plochy
+ if new_x < 0:
+ new_x = self.width - 1
+ if new_y < 0:
+ new_y = self.height - 1
+ if new_x >= self.width:
+ new_x = 0
+ if new_y >= self.height:
+ new_y = 0
+```
+{% endfilter %}
+
+> [note]
+> Jestli už vykresluješ hada místo housenky, možná teď narazíš na problém
+> s vybíráním správných dílků – okraj herní plochy hada vizuálně rozdělí
+> na dva menší.
+> Zatím tenhle vizuální problém ignoruj.
+
+
+## Zbytkové řešení
+
+Jde to jednodušeji? Jde!
+Matematikové vymysleli operaci, která se jmenuje *zbytek po dělení*.
+Ta dělá přesně to, co potřebujeme – zbytek po dělení nové souřadnice velikostí
+hřiště dá souřadnici, která leží v hřišti.
+Když byla předchozí souřadnice o jedna větší než maximum,
+zbytek po dělení bude nula; když byla -1, dostaneme maximum.
+
+Python moužívá pro zbytek po dělení ooperátor `%`. Zkus si to:
+
+``` pycon
+>>> 6 % 10 # Zbytek po dělení šesti desíti
+6
+>>> 10 % 10
+0
+>>> -1 % 10
+9
+```
+
+Celý kód pro kontrolu a ošetření vylézání z hrací plochy tak jde
+nahradit dvěma řádky:
+
+```python
+ new_x = new_x % self.width
+ new_y = new_y % self.height
+```
+
+Podobné matematické „zkratky“ umí programátorům často usnadnit život.
+Jen přijít na ně nebývá jednoduché.
+Ale nevěš hlavu: neláká-li tě studovat informatiku na škole, věz, že to jde
+i bez „zkratek“. Jen občas trochu krkoloměji.
+
+> [note]
+> To, že existuje přesně operace kterou potřebujeme, není až tak úplně náhoda.
+> Ona matematická jednoduchost je spíš *důvod*, proč se hrací plocha
+> u spousty starých her chová právě takhle.
+> Odborně se tomu „takhle“ říká
+> [toroidální topologie](https://en.wikipedia.org/wiki/Torus#Topology).
+
+> [note] Pro matematiky
+> Zkušení matematici si teď možná stěžují na nutnost definovat zbytek po
+> dělení záporných čísel. Proto dodám, že ho Python schválně
+> [definuje vhodně](https://docs.python.org/3/reference/expressions.html#binary-arithmetic-operations)
+> pro tento účel; `a % b` má vždy stejné znaménko jako `b`.
+
+
+{# XXX
+
+## Vykreslování
+
+> Volné chvilce se pokus problém opravit.
+> Doporučuji se vrátit k „abstraktní“ funkci, která jen vypisuje souřadnice
+> a směry:
+>
+> ```
+> 1 2 tail right
+> 2 2 left right
+> 3 2 left top
+> 3 3 bottom top
+> 3 4 bottom top
+> 3 5 bottom right
+> 4 5 left head
+> ```
+> Jdeš-li podle návodu, tuhle funkci máš uloženou v souboru `smery.py`
+> Oprav nejdřív tu, a řešení „transplantuj“ do hry.
+#}
+
diff --git a/lessons/snake/toroid/info.yml b/lessons/snake/toroid/info.yml
new file mode 100644
index 0000000000..c22d27aa61
--- /dev/null
+++ b/lessons/snake/toroid/info.yml
@@ -0,0 +1,4 @@
+title: Rozšíření Hada – Nekonečná klec
+style: md
+attribution: Pro PyLadies CZ napsal Petr Viktorin, 2018.
+license: cc-by-sa-40