← Přehled všech hodin

Paměť aplikace a první souboj

Cíl hodiny: Naučíš se, proč se hodnoty ztrácejí, a jak je udržet pomocí st.session_state. Vzniká první souboj, který má víc kol.
Jak stránku používat: vpravo nahoře je tlačítko Prezentace — schová všechno kromě jednoho bloku a přepíná se šipkami. U ukázek a cvičení je kód vlevo editovatelný: uprav ho a klikni na Spustit (nebo Ctrl+Enter), výsledek se objeví vpravo. Běží to přímo v prohlížeči, bez instalace.

1. Pochopení tématu

Blok 1Zásadní věc, kterou je dobré pochopit jako první1. Pochopení tématu

Streamlit funguje jinak než běžný program. Při každé změně se celý skript spustí znovu od prvního řádku.

Představ si, že máš papír s postupem. Pokaždé, když někde klikneš, papír se roztrhá a ty ho čteš celý znovu od začátku. Všechno, co sis mezitím poznamenal na okraj, je pryč.

Podívej se na praktickou ukázku. Napiš:

Klikni opakovaně. Vždycky vyjde 90. Nikdy 80, nikdy 70.

Proč? Protože po kliknutí se skript spustil znovu a řádek zivoty = 100 znovu přepsal životy na sto. Program nemá paměť.

Tohle je „aha moment" hodiny. Dopřej si čas ho opravdu vstřebat.

Blok 2Řešení: session_state1. Pochopení tématu

st.session_state je slovník, který přežije restart skriptu. Je to jediné místo v aplikaci, které si něco pamatuje.

session_state je jako trezor. Skript se restartuje, ale trezor zůstává. Cokoliv dáš dovnitř, tam bude i po dalším kliknutí.

Blok 3Proč ten `if "zivoty" not in st.session_state`1. Pochopení tématu

Nejčastější nepochopení — podívej se přesně proč:

Kdybys to napsal bez podmínky, tak by se ti při každém kliknutí zase nastavilo sto a byl bys tam, kde předtím. Podmínka znamená: nastav to jenom poprvé.

Alternativní zápis, který dělá totéž a je kratší:

Blok 4Dva zápisy, jedna věc1. Pochopení tématu

Tečka je pohodlnější, ale závorky potřebuješ, když je název v proměnné nebo obsahuje mezeru. Používej tečku, dokud ti nepřekáží.

Blok 5Tlačítka a jak fungují1. Pochopení tématu

st.button() vrátí True jenom v jediném běhu — hned po kliknutí. V dalším běhu už zase vrátí False. Proto musíš změnu uložit do session_state, jinak by zmizela.

Důležité: dvě tlačítka se stejným textem způsobí DuplicateWidgetID. Řeší se parametrem key="unikatni_nazev".

Blok 6Widgety se samy ukládají do session_state1. Pochopení tématu

Tohle bývá překvapivé a je to užitečné:

Když widgetu dáš key, jeho hodnota se automaticky objeví v session_state pod tímto klíčem. Nemusíš ji nikam ukládat sám.

Blok 7Reset hry1. Pochopení tématu

Podívej se na dva způsoby a jejich rozdíl:

st.rerun() znamená „spusť skript hned znovu". Bez něj by se změna projevila až po dalším kliknutí, což vypadá jako chyba.

Blok 8Historie akcí — seznam v session_state1. Pochopení tématu

Předehra k příští hodině o seznamech:

Teď není potřeba řešit, jak seznam funguje uvnitř. Stačí si to představit jako „přidávám řádky do zápisníku".

Poznámky pro učiteleTechnické pozadí pro učitele (děti to nepotřebují)1. Pochopení tématu
  • Session je vázaná na jednu záložku prohlížeče. Nová záložka = nová hra.
  • Data jsou v paměti serveru. Restart streamlit run je smaže.
  • Streamlit spouští skript v samostatném vlákně (ScriptRunner). Proto nefungují globální proměnné mezi běhy — každý běh má vlastní jmenný prostor modulu.
  • Pro C# programátora: chová se to jako Session v ASP.NET, ale kompletní Page_Load se pouští při každé interakci.
Poznámky pro učiteleČasté chyby1. Pochopení tématu
Chyba Příčina Řešení
Hodnota se pořád vrací na výchozí Chybí if ... not in Inicializovat podmíněně
KeyError: 'zivoty' Čtení před inicializací Inicializovat na začátku souboru
DuplicateWidgetID Dvě tlačítka se stejným textem Přidat key=
Tlačítko „nefunguje" Změna se neuložila do state Ukládat do session_state
Změna se projeví až po dalším kliku Chybí st.rerun() Doplnit st.rerun()
StreamlitAPIException u key key koliduje s ručně nastaveným klíčem Přejmenovat klíč

2. Ukázky pro projekci

Blok 9Ukázka 1 — Proč se to nepamatuje2. Ukázky pro projekci
demo/demo1_bez_pameti.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 10Ukázka 2 — Co je uvnitř session_state2. Ukázky pro projekci
demo/demo2_nahled_state.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 11Ukázka 3 — Souboj na víc kol2. Ukázky pro projekci
demo/demo3_souboj_kola.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.

3. Cvičení na hodinu

Blok 12Cvičení 1 — Počítadlo zabitých příšer (15 min)3. Cvičení na hodinu

Tvoje zadání:

  1. Vytvoř st.session_state.zabito s výchozí hodnotou 0 (nezapomeň na if ... not in)
  2. Přidej tlačítko „Zabít příšeru", které hodnotu zvýší o 1
  3. Přidej tlačítko „Reset", které ji vrátí na 0
  4. Zobraz počet pomocí st.metric
  5. Když je zabito 5 a víc, vypiš „Jsi lovec příšer!" pomocí st.success
Úroveň Co má zvládnout
Minimum Body 1–4
Rozšíření Bod 5 + tlačítko „Zabít bosse" za 3 body
Výzva Titul podle počtu (Nováček / Lovec / Legenda) přes if/elif/else
cviceni/cviceni1_pocitadlo.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Tip — na co si dát pozor

Očekávaný výsledek: číslo roste s každým kliknutím a nevrací se na nulu.

Řešení 1 — jedna z možných variant
reseni/reseni1_pocitadlo.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 13Cvičení 2 — Peněženka hrdiny (20 min)3. Cvičení na hodinu

Tvoje zadání:

  1. Ulož do stavu zlato s hodnotou 100
  2. Přidej tlačítka: „Najít poklad (+50)", „Koupit lektvar (−30)", „Koupit meč (−80)"
  3. Nákup povol jen tehdy, když má hrdina dost zlata
  4. Když nemá dost, vypiš st.error s tím, kolik mu chybí
  5. Přidej st.progress ukazující zlato vůči cíli 500
Úroveň Co má zvládnout
Minimum Body 1–3
Rozšíření Body 4–5
Výzva Zakázat tlačítko pomocí disabled= místo chybové hlášky
cviceni/cviceni2_penezenka.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Tip — na co si dát pozor

Očekávaný výsledek: zlato se mění, mínusové jít nemůže.

Řešení 2 — jedna z možných variant
reseni/reseni2_penezenka.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 14Cvičení 3 — Deník dobrodružství (20 min)3. Cvičení na hodinu

Tvoje zadání:

  1. Vytvoř v session_state prázdný seznam denik = []
  2. Přidej st.text_input na zápis události
  3. Tlačítko „Zapsat" přidá text do seznamu pomocí .append()
  4. Vypiš celý deník pod sebe
  5. Přidej tlačítko „Vymazat deník"
Úroveň Co má zvládnout
Minimum Body 1–4
Rozšíření Bod 5 + číslování řádků
Výzva Nezapisovat prázdný text a nedovolit dva stejné zápisy za sebou
cviceni/cviceni3_denik.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Tip — na co si dát pozor

Očekávaný výsledek: seznam zápisů roste a zůstává i po dalších akcích.

Řešení 3 — jedna z možných variant
reseni/reseni3_denik.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 15Cvičení 4 — Automat na lektvary (20 min)3. Cvičení na hodinu

Tvoje zadání:

  1. Ulož do stavu zivoty (100) a lektvary (3)
  2. Tlačítko „Dostal jsi ránu" ubere 25 životů
  3. Tlačítko „Vypít lektvar" přidá 30 životů a ubere jeden lektvar
  4. Životy nesmí přesáhnout 100 ani klesnout pod 0 — ošetři podmínkami
  5. Když nejsou lektvary, tlačítko nesmí nic udělat a vypíše varování
Úroveň Co má zvládnout
Minimum Body 1–3
Rozšíření Body 4–5
Výzva Přidat, že při 0 životech je konec hry a obě tlačítka přestanou fungovat
cviceni/cviceni4_lektvary.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Tip — na co si dát pozor

Očekávaný výsledek: ukazatel životů se pohybuje mezi 0 a 100 a lektvary docházejí.

Řešení 4 — jedna z možných variant
reseni/reseni4_lektvary.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 16Cvičení 5 — PyQuest: hrdina s pamětí (25 min)3. Cvičení na hodinu

Tvoje zadání:

  1. Přesuň jméno, životy a zlato hrdiny do session_state
  2. V postranním panelu ukaž aktuální stav pomocí st.metric
  3. Přidej výběr místa (Les / Jeskyně / Věž) a tlačítko „Vyrazit"
  4. Po kliknutí se podle úspěchu změní životy a zlato v session_state
  5. Zapiš každou výpravu do deníku a přidej tlačítko „Nová hra"
Úroveň Co má zvládnout
Minimum Body 1–4
Rozšíření Bod 5
Výzva Přidat počet výprav a konec hry při 0 životech
cviceni/cviceni5_pyquest_pamet.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Tip — na co si dát pozor

Očekávaný výsledek: hra se dá hrát opakovaně, stav se hromadí.

Řešení 5 — jedna z možných variant
reseni/reseni5_pyquest_pamet.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.

4. Domácí úkol

Blok 17Domácí úkol na příští hodinu4. Domácí úkol

Přidej do své hry odpočinek: tlačítko, které vrátí 20 životů, ale stojí 10 zlata a jde použít nejvýš třikrát za hru. Počet zbývajících odpočinků drž v session_state.

Zobrazit ukázkové řešení domácího úkolu

Toto je jedna z možných variant, jak mohl úkol dopadnout. Tvoje řešení se může lišit a to je v pořádku.

domaci/domaci_ukol05.py
Tady se objeví výsledekKlikni na Spustit. Kód vlevo můžeš měnit a spouštět opakovaně klávesami Ctrl+Enter.
Kód vlevo jde upravovat. Tab odsazuje o čtyři mezery.
Blok 18Oficiální dokumentace4. Domácí úkol

Oficiální dokumentace se vyplatí, když si chceš ověřit, jak Streamlit ukládá stav, co přesně vrací tlačítko nebo jak vynutit nové spuštění aplikace. U téhle hodiny se hodí hlavně reference ke session_state a k základním ovládacím prvkům.

Co jsme použili Oficiální dokumentace Co tam najdeš
st.session_state st.session_state ukládání hodnot mezi jednotlivými běhy skriptu
st.button st.button tlačítko, návratovou hodnotu a key
st.rerun st.rerun ruční znovuspuštění skriptu
st.metric st.metric zobrazení číselné hodnoty a změny
st.json st.json přehledné vypsání obsahu session_state
st.slider s key= st.slider jak widget ukládá hodnotu pod vlastním klíčem
slovníky v Pythonu Mapping types — dict práci s klíči a hodnotami podobně jako u stavu
dict.setdefault() dict.setdefault kratší způsob, jak nastavit výchozí hodnotu

5. Umíme informatiku

Blok 19Navazující cvičení na Umíme informatiku5. Umíme informatiku
Cvičení Odkaz Proč se hodí
Programování v Pythonu umimeinformatiku.cz Práce s proměnnými v čase
Úkolovka umimeinformatiku.cz Sledování stavu úkolu
Algoritmické myšlení umimeinformatiku.cz Krokování a změna stavu