Python - zajęcia 12
- klasy i dziedziczenie c.d
- GUI w webapp
- aplikacja webowa z użyciem Streamlit - podstawowe komponenty i użycie
The AI workspace that works for you. | Notion
A tool that connects everyday work into one space. It gives you and your teams AI tools—search, writing, note-taking—inside an all-in-one, flexible workspace.

Moje notatki
Zadania
✏️
Gra - Zgadnij liczbę
Założenia:
- 10 podejść
- info większa/mniejsza
- pamietać o session_state
"""
import streamlit as st
import random
st.set_page_config(page_title="Zgadnij liczbę!", layout="wide")
# ========= Podstawowe zmienne przechowywane w sesji =========
if "zgadywana_liczba" not in st.session_state:
st.session_state.zgadywana_liczba = random.randint(1, 100) # los 1..100
if "liczba_podejsc" not in st.session_state:
st.session_state.liczba_podejsc = 10
if "locked" not in st.session_state:
st.session_state.locked = False
if "komunikat" not in st.session_state:
st.session_state.komunikat = "" # ostatni komunikat dla użytkownika
if "wybrana_liczba" not in st.session_state:
st.session_state.wybrana_liczba = 1 # wartość suwaka na początek
# ========== Funkcjonalność ==========
def sprawdz() -> None:
if st.session_state.locked:
return # gra zakończona - nie idź dalej
st.session_state.liczba_podejsc -= 1 # zmienjszam o 1 liczbę podejść
wybor = st.session_state.wybrana_liczba
cel = st.session_state.zgadywana_liczba
if wybor == cel:
st.session_state.komunikat = "🎉 **Wygrałaś/eś!** Trafiłaś/eś liczbę."
st.session_state.locked = True # blokuję dalszę grę
st.balloons()
else:
if wybor < cel:
st.session_state.komunikat = "⬆️ Zgadywana liczba jest **większa**. Spróbuj jeszcze raz."
else:
st.session_state.komunikat = "⬇️ Zgadywana liczba jest **mniejsza**. Spróbuj jeszcze raz."
if st.session_state.liczba_podejsc <= 0:
st.session_state.locked = True
st.session_state.komunikat = "❌ **Limit prób wyczerpany.** Przegrałaś/eś."
# ========= Wygląd =========
st.title("🎯 Zgadnij liczbę 1–100")
st.write(
"Masz 10 podejść. Po każdym strzale dostaniesz podpowiedź „większa/mniejsza”.")
# aby szybko wyłączyć widoczność kiedy gra zakończona
disabled = st.session_state.locked
# tworzy 2 kolumny, z czego pierwsza ma szerokość 3.4, a druga 1/4
col1, col2 = st.columns([3, 1])
with col1:
wybrana_liczba = st.slider(
"Wybierz liczbę przesuwając suwak",
min_value=1, max_value=100,
disabled=disabled, key="wybrana_liczba" # trzymamy w session_state
)
with col2:
st.metric("Pozostałe podejścia", st.session_state.liczba_podejsc)
# >>> Pamiętaj! Trzeba przekazać referencję do funkcji, bez nawiasów, bo "pożera " od razu próbę bez kliknięcia w button
st.button("Sprawdź", on_click=sprawdz, disabled=disabled, type="primary")
# Komunikaty po próbie
if st.session_state.komunikat:
if st.session_state.locked and st.session_state.liczba_podejsc >= 0 and "Wygrała" in st.session_state.komunikat:
st.success(st.session_state.komunikat)
elif st.session_state.locked:
st.error(st.session_state.komunikat)
else:
st.info(st.session_state.komunikat)

💡
To do: --> button "nowa gra"
✏️
Formularz -> nowe pytania do quizu
Aplikacja do dodwania pytań do quizu - zawiera pola do wprowadzania nowych pytań odpowiedzi i punktracji.
- wyświetla dodane pytania
- zapisuje do pliku
-
"""
import streamlit as st
import random
import json
import os
# ======= f-cje =======
def zapisz_nowe_pytania_do_pliku():
with open("dane\kwestionariusz_nowe.json", "w", encoding="utf8") as plik:
json.dump(st.session_state.pytania, plik, indent=4,
sort_keys=True, ensure_ascii=False)
# ======= Załadowanie dotychczasowych pytań =======
st.session_state.setdefault("pytania", [])
with open("dane\kwestionariusz.json", "r", encoding="utf8") as plik_z_pytaniami:
st.session_state.pytania = json.load(plik_z_pytaniami)
# --> wyciągnięcie pytania do testów
# st.write(st.session_state.pytania[0]["pytanie"])
# ======= Formularz =======
with st.form("formularz_quiz", clear_on_submit=True):
st.subheader("Nowe pytanie")
pytanie = st.text_area("Wpisz pytanie", label_visibility='hidden')
col1, col2 = st.columns([3, 1])
with col1:
st.write("**Odpowiedzi**")
odp_a = st.text_input(" a: ")
odp_b = st.text_input(" b: ")
odp_c = st.text_input(" c: ")
with col2:
st.write("**Punkty**")
pkt_a = st.number_input(
"Punkty A", label_visibility='hidden', min_value=0, max_value=1, value=0)
pkt_b = st.number_input(
"Punkty B", label_visibility='hidden', min_value=0, max_value=1, value=0)
pkt_c = st.number_input(
"Punkty C", label_visibility='hidden', min_value=0, max_value=1, value=0)
submitted = st.form_submit_button("➕ Dodaj pytanie")
pokaz_pytania = st.button("Pokaż pytania")
# ======= Button - obsługa =======
# ======= Zapisz pytania =======
if submitted:
if not pytanie or not odp_a or not odp_b or not odp_c:
st.warning("Uzupełnij treść pytania oraz wszystkie odpowiedzi.")
else:
nowe_pytanie_wiersz = {
"pytanie": pytanie.strip(),
"odpowiedzi": [
[
odp_a.strip(),
int(pkt_a)
],
[
odp_b.strip(),
int(pkt_b)
],
[
odp_c.strip(),
int(pkt_c)
],
]
}
st.session_state.pytania.append(nowe_pytanie_wiersz)
zapisz_nowe_pytania_do_pliku()
# ====== Sprwdzenie ======
if pokaz_pytania:
st.write(st.session_state.pytania)

✏️
[UPDATE] Formularz -> nowe pytania do quizu
-> dodanie upload i download
-> dodanie upload i download
Aplikacja do dodawania pytań do quizu - zawiera pola do wprowadzania nowych pytań odpowiedzi i punktacji.
- pozwala wczytać pytania z pliku
- wyświetla wczytane i dodane pytania
- zapisuje do pliku json
- zapisuje do pliku txt ( z ładnym formatowaniem)
TODO: Ostrzeżenie przy zaczytywaniu na nowo przed nadpisaniem danych
"""
import streamlit as st
import json
# ======= session_state =======
st.session_state.setdefault("pytania", [])
st.session_state.setdefault("zaladowane_z_pliku", None)
# ======= f-cje =======
def zapisz_nowe_pytania_do_pliku():
with open("dane\kwestionariusz_nowe.json", "w", encoding="utf8") as plik:
json.dump(st.session_state.pytania, plik, indent=4,
sort_keys=True, ensure_ascii=False)
def wyczysc_pytania():
st.session_state.pytania = []
# @st.dialog("⚠️ Potwierdzenie")
# def bt_upload_on_change():
# if st.session_state.pytania != []:
# st.warning(
# "Ta operacja nadpisze wprowadzone i zaczytane do tej pory dane. Czy na pewno chcesz kontynuować?")
# k1, k2 = st.columns(2)
# with k1:
# if st.button("✅ Tak"):
# st.session_state.pytania = json.load(
# st.session_state.zaladowane_z_pliku)
# st.success("✅ Dane zostały nadpisane.")
# st.rerun() # zamknie dialog i odświeży stronę
# with k2:
# if st.button("❌ Anuluj"):
# st.info("🔙 Operacja została anulowana.")
# st.rerun()
# elif st.session_state.zaladowane_z_pliku is not None:
# st.session_state.pytania = json.load(
# st.session_state.zaladowane_z_pliku)
st.session_state.zaladowane_z_pliku = st.file_uploader(
"Załaduj pytania z pliku", type="json", on_change=wyczysc_pytania)
if st.session_state.zaladowane_z_pliku and not st.session_state.pytania:
st.session_state.pytania = json.load(
st.session_state.zaladowane_z_pliku)
# ======= Formularz =======
with st.form("formularz_quiz", clear_on_submit=True):
st.subheader("Nowe pytanie")
pytanie = st.text_area("Wpisz pytanie", label_visibility='hidden')
# Gdybyśmy dodali do test_input parametr key - wtedy automatycznie dodamy te dane do session state
# Przykład:
# st.text_input("Your name", key="name")
# # This exists now:
# st.session_state.name
col1, col2 = st.columns([3, 1])
with col1:
st.write("**Odpowiedzi**")
odp_a = st.text_input(" a: ")
odp_b = st.text_input(" b: ")
odp_c = st.text_input(" c: ")
with col2:
st.write("**Punkty**")
pkt_a = st.number_input(
"Punkty A", label_visibility='hidden', min_value=0, max_value=1, value=0)
pkt_b = st.number_input(
"Punkty B", label_visibility='hidden', min_value=0, max_value=1, value=0)
pkt_c = st.number_input(
"Punkty C", label_visibility='hidden', min_value=0, max_value=1, value=0)
submitted = st.form_submit_button("➕ Dodaj pytanie")
# end of form
# ======= Button - obsługa =======
col1, col2, col3, col4 = st.columns([1, 1, 1, 1])
with col1:
pokaz_pytania = st.button("📋 Pokaż pytania")
with col2:
usun_nowe = st.button(
"➖ Usuń pytania", help="Usuń dodane pytania, zaczytaj pierwotny zestaw z pliku")
with col3:
# ====== Pobierz pytania json ======
with open("dane\kwestionariusz_nowe.json", "r") as plik_do_pobrania:
st.download_button(label="📥 Pobierz pytania", data=plik_do_pobrania,
file_name="pobrane_ze_streamlit.json",
help="Zapisuje pytania i odpowiedzi w formacie json")
with col4:
# ====== Pobierz pytania txt ======
plik_do_pobrania_txt = ''
podpunkt = ["a", "b", "c"]
for i, elementy in enumerate(st.session_state.pytania, start=1):
if i != 1:
plik_do_pobrania_txt += "\n"
plik_do_pobrania_txt += f'Pytanie {i}: {elementy["pytanie"]}'
for j, odpowiedzi in enumerate(elementy["odpowiedzi"]):
plik_do_pobrania_txt += f'\n \t {podpunkt[j]}) {odpowiedzi[0]}'
st.download_button(label="📝 Pobierz pytania ", data=plik_do_pobrania_txt,
file_name="pobrane_ze_streamlit.txt",
help="Zapisuje pytania i odpowiedzi w formacie txt")
# ======= Dodaj pytanie =======
if submitted:
if not pytanie or not odp_a or not odp_b or not odp_c:
st.warning("Uzupełnij treść pytania oraz wszystkie odpowiedzi.")
else:
nowe_pytanie_wiersz = {
"pytanie": pytanie.strip(),
"odpowiedzi": [
[
odp_a.strip(),
int(pkt_a)
],
[
odp_b.strip(),
int(pkt_b)
],
[
odp_c.strip(),
int(pkt_c)
],
]
}
st.session_state.pytania.append(nowe_pytanie_wiersz)
zapisz_nowe_pytania_do_pliku()
# ====== Pokaż pytania ======
if pokaz_pytania and st.session_state.pytania != []:
ramka = st.container(border=True)
for i, elementy in enumerate(st.session_state.pytania, start=1):
if "pytanie" in elementy:
ramka.write(f'Pytanie {i}: {elementy["pytanie"]}')
# ====== Usuń pytania ======
if usun_nowe:
del st.session_state["pytania"]
