st.session_state. Vzniká první souboj, který má víc kol.
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 = 100znovu přepsal životy na sto. Program nemá paměť.
Tohle je „aha moment" hodiny. Dopřej si čas ho opravdu vstřebat.
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_stateje jako trezor. Skript se restartuje, ale trezor zůstává. Cokoliv dáš dovnitř, tam bude i po dalším kliknutí.
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ší:
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áží.
st.button()vrátíTruejenom v jediném běhu — hned po kliknutí. V dalším běhu už zase vrátíFalse. Proto musíš změnu uložit dosession_state, jinak by zmizela.
Důležité: dvě tlačítka se stejným textem způsobí DuplicateWidgetID.
Řeší se parametrem key="unikatni_nazev".
Tohle bývá překvapivé a je to užitečné:
Když widgetu dáš
key, jeho hodnota se automaticky objeví vsession_statepod tímto klíčem. Nemusíš ji nikam ukládat sám.
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.
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".
streamlit run je smaže.Session v ASP.NET, ale kompletní Page_Load
se pouští při každé interakci.| 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íč |
Tvoje zadání:
- Vytvoř
st.session_state.zabitos výchozí hodnotou 0 (nezapomeň naif ... not in)- Přidej tlačítko „Zabít příšeru", které hodnotu zvýší o 1
- Přidej tlačítko „Reset", které ji vrátí na 0
- Zobraz počet pomocí
st.metric- 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 |
Očekávaný výsledek: číslo roste s každým kliknutím a nevrací se na nulu.
Tvoje zadání:
- Ulož do stavu
zlatos hodnotou 100- Přidej tlačítka: „Najít poklad (+50)", „Koupit lektvar (−30)", „Koupit meč (−80)"
- Nákup povol jen tehdy, když má hrdina dost zlata
- Když nemá dost, vypiš
st.errors tím, kolik mu chybí- Přidej
st.progressukazují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 |
Očekávaný výsledek: zlato se mění, mínusové jít nemůže.
Tvoje zadání:
- Vytvoř v session_state prázdný seznam
denik = []- Přidej
st.text_inputna zápis události- Tlačítko „Zapsat" přidá text do seznamu pomocí
.append()- Vypiš celý deník pod sebe
- 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 |
Očekávaný výsledek: seznam zápisů roste a zůstává i po dalších akcích.
Tvoje zadání:
- Ulož do stavu
zivoty(100) alektvary(3)- Tlačítko „Dostal jsi ránu" ubere 25 životů
- Tlačítko „Vypít lektvar" přidá 30 životů a ubere jeden lektvar
- Životy nesmí přesáhnout 100 ani klesnout pod 0 — ošetři podmínkami
- 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 |
Očekávaný výsledek: ukazatel životů se pohybuje mezi 0 a 100 a lektvary docházejí.
Tvoje zadání:
- Přesuň jméno, životy a zlato hrdiny do
session_state- V postranním panelu ukaž aktuální stav pomocí
st.metric- Přidej výběr místa (Les / Jeskyně / Věž) a tlačítko „Vyrazit"
- Po kliknutí se podle úspěchu změní životy a zlato v
session_state- 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 |
Očekávaný výsledek: hra se dá hrát opakovaně, stav se hromadí.
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.
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.
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 |
| 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 |