🔩 Nowy Rekrut
0 / 58 umiejętności

PODSTAWY PYTHONA

dla Twórców Gier

Naucz się Pythona od zera — przez pisanie, nie czytanie. Każda sekcja to przykład, zadania z oczekiwanym wynikiem i projekt końcowy. 7 modułów, które dają solidne podstawy przed kursem Pygame.

Python 3 7 modułów 7 projektów 420 pytań MC Język polski
Krok 1 z 2: instalacja Python i VS Code — zajmuje 15 minut
M00

Przygotowanie środowiska

Zanim napiszesz pierwszą linię kodu — zainstaluj narzędzia. Zajmie to 10–15 minut i zrobisz to tylko raz.
Co musisz zainstalować:
1
Python 3 — interpreter który uruchamia Twój kod. Pobierz ze strony python.org (wersja 3.12 lub nowsza).
2
VS Code — edytor kodu z terminalem i podpowiedziami. Pobierz ze strony code.visualstudio.com.
3
Rozszerzenie Python w VS Code — otwórz VS Code → Extensions (Ctrl+Shift+X) → wyszukaj „Python" (Microsoft) → Install.

Szczegółowa instrukcja krok po kroku z obrazkami (Windows / Mac / Linux):

📦 Otwórz pełną instrukcję instalacji →
✔️ Sprawdź że masz gotowe:
  • W terminalu wpisujesz python --version i widzisz np. Python 3.12.4
  • VS Code otwiera się i widzisz edytor z paskiem bocznym
  • Rozszerzenie Python (Microsoft) jest zainstalowane w VS Code
M01

Twój Pierwszy Program

Napiszesz swój pierwszy program i nauczysz się fundamentów: wypisywanie tekstu, zmienne, obliczenia i rozmowę z użytkownikiem. Każdy program na świecie używa tych właśnie elementów.
Wyobraź sobie przepis kulinarny — lista kroków dla kucharza. Program to lista kroków dla komputera. Python wykonuje je linia po linii, od góry do dołu.
Plik .py to zwykły plik tekstowy z instrukcjami. Terminal to miejsce gdzie widzisz wynik. Każda linia kodu = jedna instrukcja dla Pythona.
⌨️ Krok 0 — Przygotuj środowisko
Przed każdą sekcją:
1
Otwórz VS Code → Plik → Otwórz Folder → [folder kursu]
2
Prawy klik → Nowy Plik → cwiczenie_m01_1.py
3
Wpisuj kod ręcznie — nie kopiuj. Zapisz Ctrl+S
4
Terminal → Nowy Terminal → python cwiczenie_m01_1.py
👾 W grze Asteroidy użyjesz tego tak:
zycia = 3           # ile żyć ma gracz
punkty = 0          # wynik w HUD
statek_x = 400      # pozycja x statku (środek ekranu 800px)
predkosc = 5        # pikseli na klatkę
SZEROKOSC = 800     # stała — szerokość okna gry
Każda zmienna w grze to element z tego modułu!
1.1

print() — wyświetlanie tekstu

print() to funkcja która "drukuje" tekst na ekranie terminala — jak drukarka, tylko zamiast kartki papieru masz okno terminala.
print() to najważniejsza funkcja na początku nauki. Możesz wypisać tekst (w cudzysłowie), liczbę, a nawet kilka rzeczy naraz oddzielając je przecinkami. Pusta linia print() bez argumentów daje wolny wiersz.
print("Witaj, Python!")
print(42)
print("Imie:", "Anna")
print()  # pusta linia
print("Koniec")
> python cwiczenie_m01_1.py
Witaj, Python!
42
Imie: Anna

Koniec
NameError: name 'Witaj' is not defined
print(Witaj) bez cudzysłowu — Python myśli że Witaj to nazwa zmiennej. Tekst ZAWSZE w cudzysłowie: "tekst" lub 'tekst'.
✏️ Zadania do samodzielnego napisania:
  1. Wypisz swoje imię, wiek i miasto — każde w osobnym print(). Dodaj pustą linię między każdą informacją. Oczekiwany wynik: trzy linie z informacjami, oddzielone pustymi liniami.
  2. Wypisz tabliczkę mnożenia przez 3 (od 1 do 5) używając osobnego print() dla każdej linii. Oczekiwany wynik: 3 x 1 = 3, 3 x 2 = 6 ... 3 x 5 = 15. Liczby wpisz ręcznie — nie używaj zmiennych.
✔️ Po tej sekcji powinieneś umieć:
  • wywoływać print() z tekstem i liczbą
  • wypisywać kilka wartości w jednym print() przez przecinek
  • tworzyć pustą linię przez print() bez argumentów
🧠 Sprawdź wiedzę — 1.1
1.2

Komentarze — notatki w kodzie

Komentarz to żółta karteczka przyklejona do kodu — dla Ciebie i innych programistów. Komputer jej nie czyta, ale Ty za miesiąc będziesz jej wdzięczny.
Komentarze zaczynają się od znaku #. Python całkowicie je ignoruje. Dobry komentarz mówi DLACZEGO, nie CO — bo co kod robi widać z samego kodu.
# To jest komentarz — Python go ignoruje
print("Ten kod sie wykona")
# print("Ten sie NIE wykona")

# Wyjasniaj DLACZEGO, nie CO:
# ZLE:   # dodajemy 1 do x
# DOBRE: # punkty rosna o 1 co klatke gry
> python cwiczenie_m01_2.py
Ten kod sie wykona
✏️ Zadania do samodzielnego napisania:
  1. Wróć do ćwiczenia z sekcji 1.1. Dodaj komentarz nad każdym print() wyjaśniający dlaczego wypisujesz akurat tę informację. Upewnij się że program działa tak samo jak wcześniej.
  2. Napisz program z 5 linii print(). Zakomentuj dwie z nich (dodaj # na początku). Uruchom i sprawdź że wypisują się tylko 3. Oczekiwany wynik: tylko te 3 linie które nie mają #.
✔️ Po tej sekcji powinieneś umieć:
  • pisać komentarze znakiem #
  • wiedzieć że Python komentarze całkowicie ignoruje
  • wiedzieć że dobry komentarz opisuje DLACZEGO, nie CO
🧠 Sprawdź wiedzę — 1.2
1.3

Zmienne — pudełka na dane

Zmienna to pudełko z naklejką. Naklejka to nazwa, w pudełku jest wartość. Możesz zmienić zawartość pudełka w dowolnym momencie — nazwa zostaje, wartość się zmienia.
Zmienną tworzymy wpisując nazwa = wartość. Znak = to przypisanie (nie równość!). Nazwy piszemy małymi literami, słowa łączymy podkreśleniem — to konwencja snake_case.
imie = "Anna"      # str — tekst
wiek = 25          # int — liczba calkowita
wzrost = 1.68      # float — liczba z przecinkiem
student = True     # bool — prawda lub falsz

print(imie)
print(wiek)
print(wzrost)
print(student)
> python cwiczenie_m01_3.py
Anna
25
1.68
True
SyntaxError przy złej nazwie zmiennej:
1imie = "Anna" lub moje imie = "Anna" — nazwa zaczyna się cyfrą albo ma spację.
Poprawnie: moje_imie = "Anna" — małe litery, słowa połączone podkreśleniem (snake_case).
✏️ Zadania do samodzielnego napisania:
  1. Stwórz zmienne opisujące siebie: imie (str), wiek (int), miasto (str), lubi_python (bool). Wypisz każdą osobno. Oczekiwany wynik: cztery linie z Twoimi danymi.
  2. Stwórz zmienną wynik = 10. Wypisz ją. Potem zmień jej wartość na 99 i wypisz ponownie. Oczekiwany wynik: 10, potem 99. Udowodnij sobie że zmienne można nadpisywać.
✔️ Po tej sekcji powinieneś umieć:
  • tworzyć zmienne i przypisywać im wartości
  • znać 4 podstawowe typy: str, int, float, bool
  • stosować konwencję snake_case
🧠 Sprawdź wiedzę — 1.3
1.4

Typy danych — cztery podstawowe

Każda wartość w Pythonie ma swój typ — jak etykieta na pudełku mówiąca co w środku: cukier, mąka, sól. Typ decyduje co możesz z daną wartością zrobić.
Funkcja type() sprawdza typ dowolnej wartości. Ważna pułapka: cyfra w cudzysłowie to tekst, nie liczba! "5" to str, 5 to int — zupełnie inne rzeczy.
imie    = "Anna"
wiek    = 25
wzrost  = 1.68
student = True

print(type(imie))     # <class 'str'>
print(type(wiek))     # <class 'int'>
print(type(wzrost))   # <class 'float'>
print(type(student))  # <class 'bool'>

a = 5      # int — liczba
b = "5"    # str — tekst z cyfra
print(a + 10)   # 15  — OK
# print(b + 10) # TypeError!
> python cwiczenie_m01_4.py
<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>
15
Pułapka: liczba w cudzysłowie
wiek = "25" to TEKST, nie liczba — wiek + 5 da błąd. Zawsze sprawdzaj czy Twoja liczba ma cudzysłów!
✏️ Zadania do samodzielnego napisania:
  1. Stwórz po dwie zmienne każdego typu (str, int, float, bool). Sprawdź każdą przez type(). Oczekiwany wynik: 8 linii z <class '...'>.
  2. Stwórz a = 5 (int) i b = "5" (str). Wypisz type(a) i type(b). Spróbuj dodać a + 10 (powinno działać) i b + 10 (powinno rzucić błąd). Zapisz komunikat błędu w komentarzu.
✔️ Po tej sekcji powinieneś umieć:
  • używać type() do sprawdzania typów
  • rozróżniać "5" (str) od 5 (int)
  • wiedzieć że typ decyduje co możesz z wartością zrobić
🧠 Sprawdź wiedzę — 1.4
1.5

Arytmetyka — Python jako kalkulator

Python to najpotężniejszy kalkulator jaki masz. Może liczyć natychmiast i nigdy się nie myli — ale musisz mu powiedzieć dokładnie co obliczyć.
Python obsługuje 7 operatorów arytmetycznych. Kluczowa różnica: / zawsze daje float (np. 10/2 = 5.0), a // to dzielenie całkowite bez reszty (np. 10//3 = 3).
a = 10
b = 3

print(a + b)   # 13   — dodawanie
print(a - b)   # 7    — odejmowanie
print(a * b)   # 30   — mnozenie
print(a / b)   # 3.333... — dzielenie (zawsze float!)
print(a // b)  # 3    — dzielenie calkowite
print(a % b)   # 1    — reszta z dzielenia
print(a ** b)  # 1000 — potegowanie
> python cwiczenie_m01_5.py
13
7
30
3.3333333333333335
3
1
1000
10 / 3 = 3.333..., nie 3!
Operator / zawsze daje float. Gdy chcesz liczbę całkowitą bez reszty, użyj //: 10 // 3 == 3.
✏️ Zadania do samodzielnego napisania:
  1. Oblicz i wypisz: ile minut jest w tygodniu (7*24*60), czy 17 jest parzyste (17 % 2 == 0), wartość 2**10. Oczekiwany wynik: 10080, False, 1024.
  2. Wczytaj od użytkownika dwie liczby całkowite. Wypisz dla nich wszystkie 7 operacji (+, -, *, /, //, %, **) z opisem. Wejście: 7 i 2. Oczekiwany wynik np.: 7 // 2 = 3, 7 % 2 = 1 itd.
✔️ Po tej sekcji powinieneś umieć:
  • używać wszystkich 7 operatorów: +, -, *, /, //, %, **
  • wiedzieć że / daje float, a // liczbę całkowitą
🧠 Sprawdź wiedzę — 1.5
1.6

Kolejność operatorów

Jak w matematyce: najpierw nawiasy, potem potęgi, potem mnożenie i dzielenie, na końcu dodawanie i odejmowanie. Python tego przestrzega dokładnie!
Python stosuje kolejność: nawiasy → potęga → mnożenie/dzielenie → dodawanie/odejmowanie. Gdy nie jesteś pewien — użyj nawiasów. Nawiasy nic nie kosztują, a eliminują nieporozumienia.
wynik1 = 2 + 3 * 4    # 14, nie 20!
wynik2 = (2 + 3) * 4  # 20 — nawiasy wygrazaja kolejnosc

print(wynik1)   # 14
print(wynik2)   # 20

pensja = 3000
premia_proc = 10
premia = pensja * premia_proc / 100
print(f"Premia: {premia} zl")  # 300.0
> python cwiczenie_m01_6.py
14
20
Premia: 300.0 zl
✏️ Zadania do samodzielnego napisania:
  1. Przewidź wynik każdego wyrażenia, potem sprawdź w Pythonie: 2+3*4, (2+3)*4, 10-2**3, (10-2)**3. Oczekiwane wyniki: 14, 20, 2, 512.
  2. Oblicz objętość pudełka (dlugosc=5, szerokosc=3, wysokosc=2). Użyj zmiennych i jednej linii obliczenia. Oczekiwany wynik: Objetosc: 30.
✔️ Po tej sekcji powinieneś umieć:
  • przewidzieć kolejność operacji bez nawiasów
  • świadomie używać nawiasów do zmiany kolejności
🧠 Sprawdź wiedzę — 1.6
1.7

f-stringi — łączenie tekstu ze zmiennymi

f-string to szablon z dziurkami — wstawiasz zmienne w odpowiednie miejsca i Python uzupełnia je wartościami. Litera "f" przed cudzysłowem mówi: "patrz na {klamry} i wstaw tam zmienne".
Piszesz f"..." i umieszczasz zmienne lub wyrażenia w nawiasach klamrowych {}. W klamrach możesz nawet obliczać wyrażenia matematyczne. Formatowanie: {wartosc:.2f} — dwa miejsca po przecinku.
imie = "Anna"
wiek  = 25

print(f"Czesc, mam na imie {imie}!")
print(f"Mam {wiek} lat.")
print(f"Za 10 lat bede miec {wiek + 10} lat.")

pi = 3.14159265
print(f"Pi = {pi:.2f}")  # 2 miejsca po przecinku
> python cwiczenie_m01_7.py
Czesc, mam na imie Anna!
Mam 25 lat.
Za 10 lat bede miec 35 lat.
Pi = 3.14
TypeError: can only concatenate str (not "int") to str
"Mam " + wiek + " lat" — Python nie łączy automatycznie tekstu z liczbą.
Zamiast tego użyj f-stringa: f"Mam {wiek} lat".
✏️ Zadania do samodzielnego napisania:
  1. Stwórz zmienne: imie, wiek, miasto. Wypisz jedno zdanie f-stringiem łączące wszystkie trzy: Czesc, jestem [imie], mam [wiek] lat i mieszkam w [miasto]. W klamrach oblicz też rok urodzenia (2025 - wiek).
  2. Stwórz zmienne: cena_netto = 49.99, vat = 0.23. Oblicz cena_brutto i wypisz paragon używając f-stringów z formatowaniem :.2f. Oczekiwany wynik: Netto: 49.99 zl, VAT: 11.50 zl, Brutto: 61.49 zl.
✔️ Po tej sekcji powinieneś umieć:
  • pisać f-stringi z f"..."
  • wstawiać zmienne i wyrażenia w {}
  • formatować liczby przez :.2f
🧠 Sprawdź wiedzę — 1.7
1.8

Konwersja typów

Konwersja to tłumaczenie między typami — jak przetłumaczenie tekstu "42" na liczbę 42, z którą możesz liczyć. Python nigdy nie robi tego automatycznie — musisz to zrobić sam.
Funkcje int(), float() i str() zmieniają typ wartości. Ważne: nie każdy string da się zamienić — int("trzy") rzuci błąd. Konwersja float → int ucina część dziesiętną (nie zaokrągla).
tekst = "42"
liczba = int(tekst)          # str → int
ulamek = float("3.14")       # str → float

wiek = 25
opis = "Mam " + str(wiek) + " lat"  # int → str

print(type(tekst))   # <class 'str'>
print(type(liczba))  # <class 'int'>
print(opis)          # Mam 25 lat

print(int(3.9))      # 3 — ucina, nie zaokragla!
> python cwiczenie_m01_8.py
<class 'str'>
<class 'int'>
Mam 25 lat
3
ValueError: invalid literal for int()
int("trzy") lub int("3.14") — string musi zawierać same cyfry.
Dla liczby zmiennoprzecinkowej: najpierw float("3.14"), potem ewentualnie int().
✏️ Zadania do samodzielnego napisania:
  1. Stwórz liczba_tekst = "15". Zamień na int, dodaj 10 i wypisz wynik. Następnie zamień wynik z powrotem na str i połącz z tekstem "Wynik: ". Oczekiwany wynik: 25, potem Wynik: 25.
  2. Sprawdź co zwraca int(7.9), int(7.1), int(-3.5). Wypisz wszystkie trzy. Oczekiwany wynik: 7, 7, -3. Jaki wniosek z tego wyciągasz?
✔️ Po tej sekcji powinieneś umieć:
  • konwertować między typami: int(), float(), str()
  • wiedzieć że int() ucina część dziesiętną
  • wiedzieć kiedy konwersja rzuci ValueError
🧠 Sprawdź wiedzę — 1.8
1.9

input() — dane od użytkownika

input() to sposób rozmowy programu z użytkownikiem — program zadaje pytanie, zatrzymuje się i czeka na Enter. Bez input() program zawsze robi to samo. Z input() — reaguje na dane.
input() zatrzymuje program, wyświetla pytanie i czeka. Zawsze zwraca str — nawet jeśli wpiszesz liczbę! Gdy potrzebujesz liczby, od razu konwertuj: int(input(...)) lub float(input(...)).
imie = input("Jak masz na imie? ")
print(f"Czesc, {imie}!")

wiek = int(input("Ile masz lat? "))
rok_ur = 2025 - wiek
print(f"Urodziles/as sie w {rok_ur} roku.")
print(f"Za 10 lat bedziesz miec {wiek + 10} lat.")
> python cwiczenie_m01_9.py
Jak masz na imie? Anna
Czesc, Anna!
Ile masz lat? 20
Urodziles/as sie w 2005 roku.
Za 10 lat bedziesz miec 30 lat.
TypeError przy obliczeniach na input()
wiek = input("Wiek: ") zwraca str, więc wiek + 5 da błąd.
Zawsze: wiek = int(input("Wiek: ")) gdy chcesz liczbę.
✏️ Zadania do samodzielnego napisania:
  1. Napisz program który pyta o imię i wiek. Wypisz: Czesc [imie], masz [wiek] lat. Za 5 lat bedziesz miec [wiek+5] lat. Wejście: Anna, 20. Oczekiwany wynik: Czesc Anna, masz 20 lat. Za 5 lat bedziesz miec 25 lat.
  2. Napisz kalkulator: wczytaj dwie liczby (float) od użytkownika, wypisz ich sumę, różnicę, iloczyn i iloraz. Użyj f-stringów z :.2f. Wejście: 7.5 i 2. Oczekiwany wynik: suma 9.50, różnica 5.50, iloczyn 15.00, iloraz 3.75.
✔️ Po tej sekcji powinieneś umieć:
  • używać input() do pobierania danych od użytkownika
  • konwertować wynik na int lub float gdy potrzeba
  • wiedzieć że input() zawsze zwraca str
🧠 Sprawdź wiedzę — 1.9
1.10

Moduły i import — gotowe narzędzia

Misja: naucz się importować gotowe narzędzia Pythona — zaraz w grze Asteroidy użyjesz random.randint() żeby asteroida pojawiała się w losowym miejscu!
Wyobraź sobie sklep z narzędziami. Python ma tysiące gotowych "zestawów" — modułów. Zamiast budować młotek od zera, piszesz import tools i masz cały warsztat. Moduł random to zestaw do losowania — dokładnie tego czego potrzebujemy w grze!
Moduł to plik z gotowymi funkcjami napisanymi przez innych programistów. Importujesz go raz na górze pliku i używasz przez nazwa_modułu.funkcja().

Importy muszą być na samej górze pliku — przed resztem kodu. To konwencja całego świata programistów.
import random      # moduł do losowania
import math        # moduł matematyczny

# Używamy przez: nazwa_modulu.funkcja()
print(random.randint(1, 10))   # losowa liczba 1–10
print(math.sqrt(16))           # pierwiastek = 4.0
print(math.pi)                 # 3.14159...
> python cwiczenie_m01_10.py
7
4.0
3.141592653589793
Najważniejsze funkcje modułu random:

random.randint(a, b) — losuje całkowitą od a do b (obie granice włączone)
random.choice(lista) — losuje jeden element z listy
random.uniform(a, b) — losuje zmiennoprzecinkową między a i b
import random

# W grze Asteroidy te 3 linie to podstawa!
pozycja_x = random.randint(0, 800)       # gdzie pojawi się asteroida
rozmiar = random.randint(20, 55)         # jak duża
predkosc = random.uniform(2.0, 4.5)     # jak szybko spada

print(f"Asteroida: x={pozycja_x}, r={rozmiar}, v={predkosc:.1f}")
> python cwiczenie_m01_10b.py
Asteroida: x=347, r=38, v=3.2
NameError: name 'random' is not defined
Zapomniałeś import random na górze pliku! Python nie wie co to random dopóki go nie zaimportujesz.

✅ Zawsze na górze: import random musi być przed pierwszym użyciem random.randint().
✏️ Zadania do samodzielnego napisania:
  1. Napisz program który losuje 5 razy "HP wroga" od 10 do 100 i wypisuje każde. Oczekiwany wynik: 5 różnych liczb w zakresie 10–100.
  2. Napisz program który losuje kolor ze listy ["czerwony", "zielony", "niebieski", "żółty"] i wypisuje "Kolor lasera: [wylosowany]". Użyj random.choice().
✔️ Po tej sekcji powinieneś umieć:
  • importować moduł przez import nazwa
  • używać random.randint(a, b) do losowania liczby całkowitej
  • używać random.choice(lista) do losowania elementu
  • wiedzieć że importy są zawsze na górze pliku
🧠 Sprawdź wiedzę — 1.10
M01

Twój Pierwszy Program — Podsumowanie

✔️ Co umiasz po tym module:
  • wypisywać tekst i liczby przez print()
  • pisać komentarze znakiem #
  • tworzyć zmienne wszystkich 4 typów (str, int, float, bool)
  • sprawdzać typ przez type()
  • wykonywać obliczenia wszystkimi 7 operatorami arytmetycznymi
  • rozumieć kolejność działań i używać nawiasów
  • łączyć tekst ze zmiennymi przez f-stringi
  • konwertować typy przez int(), float(), str()
  • wczytywać dane od użytkownika przez input()
  • importować moduły przez import random i używać random.randint()
🎯 Brawo! Masz już fundament — każdy program na świecie używa tych właśnie elementów. Zmienne, obliczenia, wejście i wyjście to serce każdego kodu!
🏗️ Projekt końcowy — „Karta Osoby"

Napisz program który pyta użytkownika o jego dane i wypisuje elegancką kartę w ramce ASCII.

  1. Krok 1: Wczytaj dane: imię i nazwisko, wiek (int), miasto, ulubione hobby.
  2. Krok 2: Oblicz rok urodzenia (2025 - wiek) i wiek za 10 lat.
  3. Krok 3: Wypisz górną ramkę z "=" * 35 i tytułem wyśrodkowanym.
  4. Krok 4: Wypisz każdą informację w osobnej linii ramki, używając f-stringów.
  5. Krok 5: Zamknij ramkę dolną linią.
Wymagania:
  • Imię wypisane wielkimi literami (użyj .upper())
  • Wszystkie informacje wyrównane — użyj formatowania :<16
  • Rok urodzenia obliczony z wczytanego wieku
  • Wiek za 10 lat obliczony i wypisany
📝 Test końcowy — Moduł 01
Sprawdź całą wiedzę z modułu. Odpowiedz na wszystkie pytania, potem sprawdź wynik.
M02

Decyzje — Warunki i if/else

Nauczysz się tworzyć programy które podejmują decyzje — reagują inaczej na różne dane. To serce każdego algorytmu.
Wyobraź sobie skrzyżowanie z sygnalizacją: zielone → jedź, czerwone → stój. Program też może reagować inaczej na różne sytuacje — wybierać jedną z wielu ścieżek.
W Pythonie decyzje realizujesz słowem if (jeśli) i else (w przeciwnym razie). Dzięki temu program może być przydatny dla różnych użytkowników z różnymi danymi.
⌨️ Krok 0 — Przygotuj plik
Przed każdą sekcją utwórz nowy plik:
1
Otwórz VS Code → folder kursu
2
Prawy klik → Nowy Plik → cwiczenie_m02_1.py
3
Wpisuj kod ręcznie — nie kopiuj. Zapisz Ctrl+S
4
Terminal → python cwiczenie_m02_1.py
👾 W grze Asteroidy użyjesz tego tak:
if zycia <= 0:
    stan_gry = "game_over"   # koniec gry!

if laser_trafil_wroga:
    punkty += 20             # wróg trudniejszy = więcej pkt
elif laser_trafil_asteroide:
    punkty += 10             # asteroida łatwiejsza = mniej pkt

if trafiony and not nietykalny:
    zycia -= 1               # traci życie tylko gdy nie jest nietykalny
Każda decyzja w grze to if/elif/else z tego modułu!
2.1

Wartości True i False

True i False to jak odpowiedź TAK i NIE. Każde porównanie w Pythonie daje jedną z tych dwóch odpowiedzi — nie ma "może".
Typ bool ma tylko dwie możliwe wartości: True (prawda) i False (fałsz). Każde porównanie liczb lub wartości zwraca bool. To jest podstawa wszystkich warunków.
prawda = True
falsz  = False

print(prawda)           # True
print(falsz)            # False
print(type(prawda))     # <class 'bool'>

# Wynik porownania to zawsze bool
print(5 > 3)    # True
print(5 < 3)    # False
print(5 == 5)   # True
print(5 != 5)   # False
> python cwiczenie_m02_1.py
True
False
<class 'bool'>
True
False
True
False
✏️ Zadania do samodzielnego napisania:
  1. Przewidź wynik (True/False) dla 6 wyrażeń: 10 > 5, 3 == 4, 7 != 7, 100 >= 100, 0 < -1, "ala" == "ala". Wpisz przewidywania w komentarzach, potem sprawdź w Pythonie.
  2. Stwórz zmienne: a = 15, b = 20. Wypisz wyniki 6 porównań między nimi (używając wszystkich 6 operatorów). Oczekiwany wynik: np. a > b = False, a < b = True itd.
✔️ Po tej sekcji powinieneś umieć:
  • wiedzieć że bool to True lub False — tylko dwie wartości
  • rozumieć że każde porównanie zwraca bool
🧠 Sprawdź wiedzę — 2.1
2.2

Operatory porównania — pełna lista

Operatory porównania to pytania które zadajesz Pythonowi — a on odpowiada True albo False. Możesz zapytać: czy to większe? równe? różne?
Python ma 6 operatorów porównania: >, <, >=, <=, ==, !=. Możesz je łączyć w łańcuch: 0 < hp <= 100 — elegancka forma sprawdzająca dwa warunki naraz.
hp = 75

print(hp > 50)      # True  — powyzej polowy
print(hp < 0)       # False — czy martwy
print(hp >= 100)    # False — pelne HP
print(hp <= 30)     # False — krytyczny
print(hp == 75)     # True  — dokladnie 75
print(hp != 100)    # True  — nie maksymalne

print(0 < hp <= 100)  # True — zakres prawidlowy
> python cwiczenie_m02_2.py
True
False
False
False
True
True
True
✏️ Zadania do samodzielnego napisania:
  1. Stwórz temperatura = 22. Sprawdź i wypisz (True/False): mróz (< 0), gorąco (> 30), komfortowo (18 <= temperatura <= 24). Oczekiwany wynik: False, False, True.
  2. Stwórz haslo = "python123". Sprawdź czy ma więcej niż 8 znaków (len(haslo) > 8) i czy jest równe "python123". Wypisz oba wyniki.
✔️ Po tej sekcji powinieneś umieć:
  • używać wszystkich 6 operatorów: >, <, >=, <=, ==, !=
  • łączyć porównania w łańcuch: a <= x < b
🧠 Sprawdź wiedzę — 2.2
2.3

Pułapka: = vs ==

= to polecenie "daj mi to" — ustawiasz wartość. == to pytanie "czy to jest tamto?" — sprawdzasz wartość. Zupełnie różne znaczenia, podobny wygląd — klasyczna pułapka.
= to przypisanie — ustawia wartość zmiennej. == to porównanie — zwraca True lub False. W warunkach if zawsze potrzebujesz ==. Python zgłosi SyntaxError gdy użyjesz = w if — to chroni przed błędem.
x = 5          # PRZYPISANIE: x wynosi 5
print(x == 5)  # POROWNANIE: True
print(x == 10) # POROWNANIE: False

# if x = 5:   <-- SyntaxError! (dobra wiadomosc)
if x == 5:     # poprawnie
    print("x wynosi 5")
> python cwiczenie_m02_3.py
True
False
x wynosi 5
SyntaxError: invalid syntax
if imie = "Anna": — Python natychmiast zgłasza błąd. W warunkach zawsze ==.
Zapamiętaj: jeden znak = przypisanie, dwa znaki == porównanie.
✏️ Zadania do samodzielnego napisania:
  1. Znajdź i napraw błędy w 3 przykładach (wpisz je jako komentarze obok): if imie = "Anna":, if wynik = 100:, if zyje = True:. Napisz poprawne wersje i sprawdź że działają.
  2. Stwórz zmienną haslo = "abc". Używając if/else sprawdź czy jest równe "python123". Wypisz odpowiednio "Dostep przyznany" lub "Bledne haslo". Oczekiwany wynik dla "abc": Bledne haslo.
✔️ Po tej sekcji powinieneś umieć:
  • nigdy nie mylić = (przypisanie) z == (porównanie)
  • wiedzieć że w warunkach zawsze używamy ==
🧠 Sprawdź wiedzę — 2.3
2.4

if — prosta decyzja

if to "jeśli" — Python sprawdza warunek i jeśli jest prawdziwy, wykonuje blok kodu. Jeśli fałszywy — pomija ten blok i idzie dalej.
Po if warunek: piszemy blok kodu z wcięciem (4 spacje lub Tab). Wcięcie jest OBOWIĄZKOWE — Python używa go zamiast nawiasów klamrowych. Kod poza wcięciem wykonuje się zawsze.
temperatura = 35

if temperatura > 30:
    print("Goraco! Pij duzo wody.")
    print("Unikaj slonca.")

print("Ten kod wykonuje sie zawsze.")  # poza if
> python cwiczenie_m02_4.py
Goraco! Pij duzo wody.
Unikaj slonca.
Ten kod wykonuje sie zawsze.
IndentationError: expected an indented block
Brak wcięcia po if — Python wymaga dokładnie 4 spacje (lub 1 Tab). Mieszanie spacji i tabów też powoduje błąd.
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj liczbę całkowitą od użytkownika. Jeśli większa od 0, wypisz "Liczba dodatnia". Jeśli równa 0, wypisz "Zero". Zawsze wypisz "Koniec programu". Wejście: 5 → Liczba dodatnia, Koniec programu.
  2. Wczytaj wiek od użytkownika. Jeśli >= 18, wypisz "Pelnoletni — mozesz wejsc". Wypisz też zawsze "Sprawdzono." bez względu na wiek. Wejście: 16 → nic z if, tylko Sprawdzono.
✔️ Po tej sekcji powinieneś umieć:
  • pisać if z prawidłowym wcięciem (4 spacje)
  • rozumieć że blok if może się nie wykonać wcale
  • rozróżniać kod wewnątrz bloku od kodu poza nim
🧠 Sprawdź wiedzę — 2.4
2.5

if / else — dwie ścieżki

if/else to rozstaje dróg — idziesz lewą (warunek prawdziwy) lub prawą (warunek fałszywy). Zawsze tylko jedną ścieżką — nigdy obiema naraz.
else to "w przeciwnym razie" — wykonuje się gdy warunek w if jest fałszywy. Dokładnie jedna z dwóch gałęzi zawsze się wykona.
liczba = int(input("Podaj liczbe: "))

if liczba % 2 == 0:
    print(f"{liczba} jest parzysta.")
else:
    print(f"{liczba} jest nieparzysta.")

# Dokladnie jedna galaz ZAWSZE sie wykona
> python cwiczenie_m02_5.py
Podaj liczbe: 7
7 jest nieparzysta.
✏️ Zadania do samodzielnego napisania:
  1. Program sprawdza hasło. Wczytaj hasło od użytkownika. Jeśli wpisze "python123" → wypisz "Dostep przyznany", w przeciwnym razie → "Bledne haslo. Sprobuj ponownie." Wejście: "abc" → Bledne haslo. Sprobuj ponownie.
  2. Wczytaj wynik punktowy (int) gracza. Jeśli >= 50 → "WYGRALES! Wynik: [wynik]", w przeciwnym razie → "Przegrales. Wynik: [wynik]. Potrzeba 50 punktow." Przetestuj dla 75 i 30.
✔️ Po tej sekcji powinieneś umieć:
  • pisać if/else
  • rozumieć że dokładnie jedna gałąź się zawsze wykona
🧠 Sprawdź wiedzę — 2.5
2.6

elif — wiele opcji

elif to jak lista pytań zadawanych po kolei: Czy pada? → parasol. Czy wietrznie? → kurtka. Czy słonecznie? → okulary. Sprawdzamy aż znajdziemy pasujące — i na tym się kończy.
elif to skrót od "else if" — kolejny warunek do sprawdzenia. Python wykonuje pierwszy pasujący blok i pomija resztę. Możesz mieć dowolną liczbę elif. Różnica od wielu if: elif przerywa po pierwszym dopasowaniu.
ocena = int(input("Podaj ocene (1-6): "))

if ocena == 6:
    wynik = "Celujacy!"
elif ocena == 5:
    wynik = "Bardzo dobry"
elif ocena == 4:
    wynik = "Dobry"
elif ocena == 3:
    wynik = "Dostateczny"
elif ocena == 2:
    wynik = "Dopuszczajacy"
else:
    wynik = "Niedostateczny"

print(f"Ocena {ocena}: {wynik}")
> python cwiczenie_m02_6.py
Podaj ocene (1-6): 5
Ocena 5: Bardzo dobry
Wiele if zamiast elif — subtelny błąd:
Kilka osobnych if sprawdza każdy warunek niezależnie. elif przerywa po pierwszym dopasowaniu. Gdy warunki mogą się nakładać, to robi dużą różnicę.
✏️ Zadania do samodzielnego napisania:
  1. Program powitania według pory dnia: wczytaj godzinę (int). 6–11 → "Dzien dobry!", 12–17 → "Witaj!", 18–21 → "Dobry wieczor!", else → "Dobranoc!" Wejście: 14 → Witaj!
  2. Kalkulator kategorii temperatury: wczytaj temperaturę (float). Poniżej -10 → "Mroz", -10 do 0 → "Zimno", 0 do 15 → "Chlodno", 15 do 25 → "Przyjemnie", powyżej 25 → "Goraco". Przetestuj dla -15, 5, 20, 30.
✔️ Po tej sekcji powinieneś umieć:
  • pisać łańcuch if/elif/else
  • rozumieć że wykonuje się tylko pierwszy pasujący blok
  • wiedzieć różnicę między wieloma if a elif
🧠 Sprawdź wiedzę — 2.6
2.7

Operatory logiczne: and, or, not

and to "i" — oba muszą być spełnione (wyjść z domu i mieć klucz). or to "lub" — wystarczy jedno (gotówka lub karta). not to "nie" — odwraca odpowiedź.
and — True tylko gdy oba warunki True. or — True gdy przynajmniej jeden True. not — odwraca: not True == False, not False == True.
wiek = 20
prawo_jazdy = True

if wiek >= 18 and prawo_jazdy:
    print("Mozesz prowadzic!")

gotowka = 0
karta   = 50
if gotowka > 0 or karta > 0:
    print("Masz czym zaplacic.")

deszcz = False
if not deszcz:
    print("Nie bierz parasola.")
> python cwiczenie_m02_7.py
Mozesz prowadzic!
Masz czym zaplacic.
Nie bierz parasola.
✏️ Zadania do samodzielnego napisania:
  1. Warunek wejścia na kurs: wiek >= 16 AND (zna_podstawy OR ma_doswiadczenie). Stwórz zmienne i sprawdź 3 kombinacje: (18, True, False), (14, True, True), (16, False, False). Oczekiwane wyniki: True, False, False.
  2. Napisz program który pyta o hasło i PIN (int). Dostęp tylko gdy hasło == "admin" AND PIN >= 1000 AND PIN <= 9999. Wypisz "Dostep" lub "Odmowa". Przetestuj poprawną i niepoprawną kombinację.
✔️ Po tej sekcji powinieneś umieć:
  • łączyć warunki przez and, or, not
  • znać tabelę prawdy: and wymaga obu True, or wymaga jednego
🧠 Sprawdź wiedzę — 2.7
2.8

Zagnieżdżone if

Jedziesz do parku: JEŚLI nie pada → JEŚLI jest ciepło → zostań dłużej, JEŚLI zimno → idź do domu. Warunek w warunku — jak rosyjska matrioszka.
Można umieszczać if wewnątrz innego if. Każdy poziom = dodatkowe wcięcie. Maksymalnie 2–3 poziomy dla czytelności. Głębsze zagnieżdżenia zastąp and.
wiek  = int(input("Wiek: "))
bilet = input("Masz bilet? (tak/nie): ")

if wiek >= 18:
    if bilet == "tak":
        print("Wejdz, prosze.")
    else:
        print("Kup bilet przy kasie.")
else:
    print("Przepraszam, tylko dla doroslych.")
> python cwiczenie_m02_8.py
Wiek: 20
Masz bilet? (tak/nie): tak
Wejdz, prosze.
Zbyt głębokie zagnieżdżenie:
4+ poziomy = nieczytelny kod. Zamień if A: if B: na if A and B:. Mniej wcięć, ten sam efekt.
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj liczbę. Sprawdź najpierw czy jest dodatnia (zagnieżdżony if: czy jest parzysta/nieparzysta). Dla ujemnych wypisz "Ujemna". Przetestuj dla 4, 7, -3. Następnie przepisz to samo używając and bez zagnieżdżenia.
  2. System logowania: wczytaj login i hasło. Dostęp gdy login == "admin" AND hasło == "1234". Użyj zagnieżdżonego if (najpierw sprawdź login, potem hasło). Dla błędnego loginu wypisz "Nieznany uzytkownik", dla błędnego hasła — "Bledne haslo".
✔️ Po tej sekcji powinieneś umieć:
  • pisać if w if z max 2–3 poziomami
  • wiedzieć kiedy użyć and zamiast zagnieżdżenia
🧠 Sprawdź wiedzę — 2.8
M02

Decyzje — Podsumowanie

✔️ Co umiasz po tym module:
  • rozumieć typ bool i wartości True/False
  • używać wszystkich 6 operatorów porównania
  • nigdy nie mylić = (przypisanie) z == (porównanie)
  • pisać if z prawidłowym wcięciem
  • pisać if/else dla dwóch ścieżek
  • pisać łańcuch if/elif/else dla wielu opcji
  • łączyć warunki przez and, or, not
  • pisać zagnieżdżone if i wiedzieć kiedy użyć and zamiast
🎯 Brawo! Twoje programy mogą teraz podejmować decyzje — reagować inaczej na różne dane. To serce każdego algorytmu!
🏗️ Projekt końcowy — „Kalkulator BMI"

Napisz program który oblicza BMI i wypisuje kategorię z poradą.

  1. Krok 1: Wczytaj wagę (float) i wzrost (float) od użytkownika.
  2. Krok 2: Oblicz BMI: waga / (wzrost ** 2).
  3. Krok 3: Użyj if/elif/else do określenia kategorii (4 kategorie).
  4. Krok 4: Dla każdej kategorii przypisz krótką poradę.
  5. Krok 5: Wypisz BMI (1 miejsce po przecinku), kategorię i poradę.
Wymagania:
  • Niedowaga: BMI < 18.5
  • Waga prawidłowa: 18.5 ≤ BMI < 25.0
  • Nadwaga: 25.0 ≤ BMI < 30.0
  • Otyłość: BMI ≥ 30.0
  • BMI wypisane z jednym miejscem po przecinku (:.1f)
📝 Test końcowy — Moduł 02
Sprawdź całą wiedzę z modułu o warunkach. Odpowiedz na wszystkie pytania, potem sprawdź wynik.
M03

Listy — Przechowywanie Wielu Danych

Nauczysz się przechowywać wiele wartości w jednej zmiennej, kroić listy, sortować je i iterować po nich. Po tym module zbudujesz rejestr uczestników kursu.
Wyobraź sobie listę zakupów — zamiast 10 oddzielnych kartek masz jedną z kolejnymi punktami. Lista w Pythonie działa tak samo: jedna zmienna przechowuje wiele wartości.
Bez listy przechowywanie 10 wyników wymagałoby 10 zmiennych: wynik1, wynik2... wynik10. Z listą: jedna zmienna wyniki przechowuje wszystkie. Listy to jedna z najważniejszych struktur w Pythonie.
⌨️ Krok 0 — Przygotuj plik
Przed każdą sekcją utwórz nowy plik:
1
Otwórz VS Code → folder kursu
2
Prawy klik → Nowy Plik → cwiczenie_m03_1.py
3
Wpisuj kod ręcznie — nie kopiuj. Zapisz Ctrl+S
4
Terminal → python cwiczenie_m03_1.py
👾 W grze Asteroidy użyjesz tego tak:
lasery = []                      # pusta lista — na początku bez laserów
asteroidy = [[400, 50, 30],      # każda asteroida = [x, y, rozmiar]
             [200, 80, 45],
             [600, 20, 55]]

lasery.append([statek_x, statek_y])  # nowy laser po SPACJI!
print(len(lasery), "laserów w powietrzu")
Każdy laser, każda asteroida, każdy wróg — to lista z tego modułu!
3.1

Tworzenie listy i dostęp po indeksie

Lista to rząd ponumerowanych szufladek. Numeracja zaczyna się od 0 — nie 1! Ostatnia szufladka ma numer -1 licząc od końca.
Listę tworzymy w nawiasach kwadratowych [...], elementy oddzielamy przecinkami. Dostęp do elementu: lista[indeks]. Indeks 0 to pierwszy element, -1 to ostatni. len() zwraca liczbę elementów.
owoce   = ["jablko", "banan", "gruszka", "mango"]
liczby  = [10, 20, 30, 40, 50]
mieszana = [1, "dwa", 3.0, True]  # rozne typy!

print(owoce[0])   # jablko (pierwszy)
print(owoce[-1])  # mango (ostatni)
print(owoce[-2])  # gruszka (przedostatni)
print(len(owoce)) # 4
> python cwiczenie_m03_1.py
jablko
mango
gruszka
4
IndexError: list index out of range
owoce[4] gdy lista ma 4 elementy — indeksy to 0, 1, 2, 3.
Ostatni poprawny indeks: len(lista) - 1.
✏️ Zadania do samodzielnego napisania:
  1. Stwórz listę 5 ulubionych filmów. Wypisz: pierwszy (indeks 0), ostatni (indeks -1), środkowy (indeks 2) i długość listy. Oczekiwany wynik: cztery linie z danymi filmów i liczbą.
  2. Stwórz listę temperatury = [22, 18, 25, 30, 15, 20, 28]. Wypisz temperaturę z poniedziałku (indeks 0), piątku (indeks 4) i ostatniego dnia (indeks -1). Oczekiwany wynik: 22, 15, 28.
✔️ Po tej sekcji powinieneś umieć:
  • tworzyć listę z wartościami różnych typów
  • pobierać element przez [i] i [-i]
  • używać len() do sprawdzenia rozmiaru
🧠 Sprawdź wiedzę — 3.1
3.2

Slicing — wycinki listy

Slice to jak kroienie chleba — bierzesz kawałek od plastra X do plastra Y. Oryginał zostaje nienaruszony, dostajesz tylko wycięty fragment.
Składnia: lista[start:stop] — od indeksu start do stop-1. Pominięty start = od początku. Pominięty stop = do końca. Krok: [::2] co drugi element, [::-1] odwrócona lista.
liczby = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

print(liczby[2:5])   # [20, 30, 40]
print(liczby[:3])    # [0, 10, 20]  — pierwsze 3
print(liczby[7:])    # [70, 80, 90] — od 7 do konca
print(liczby[::2])   # [0, 20, 40, 60, 80] — co drugi
print(liczby[::-1])  # [90, 80, ..., 0] — odwrocona
print(liczby[-3:])   # [70, 80, 90] — ostatnie 3
> python cwiczenie_m03_2.py
[20, 30, 40]
[0, 10, 20]
[70, 80, 90]
[0, 20, 40, 60, 80]
[90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
[70, 80, 90]
✏️ Zadania do samodzielnego napisania:
  1. Stwórz listę [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. Wypisz: pierwsze 3, ostatnie 3, środkowe 4 (indeksy 3–6), co drugi element. Oczekiwane wyniki: [1, 2, 3], [8, 9, 10], [4, 5, 6, 7], [1, 3, 5, 7, 9].
  2. Stwórz listę 6 imion. Wypisz je w odwróconej kolejności ([::-1]) i wypisz co drugie imię z oryginalnej listy. Oczekiwany wynik: odwrócona lista i lista co 2 imion.
✔️ Po tej sekcji powinieneś umieć:
  • używać [a:b], [:n], [n:]
  • używać kroku [::2] i odwrócenia [::-1]
  • pobierać ostatnie n elementów: [-n:]
🧠 Sprawdź wiedzę — 3.2
3.3

Dodawanie i usuwanie elementów

append to dorzucenie czegoś do koszyka. remove to wyjęcie konkretnego przedmiotu po nazwie. pop to wzięcie ostatniej rzeczy z koszyka i zabranie jej ze sobą.
append(val) dodaje na końcu, insert(i, val) wstawia na pozycji i, remove(val) usuwa pierwsze wystąpienie wartości, pop() usuwa i zwraca ostatni element (lub pop(0) — pierwszy).
koszyk = ["chleb", "mleko"]

koszyk.append("maslo")        # dodaj na koncu
koszyk.insert(1, "jajka")    # wstaw na pozycji 1
print(koszyk)  # ['chleb', 'jajka', 'mleko', 'maslo']

koszyk.remove("mleko")       # usun po wartosci
ostatni = koszyk.pop()       # usun i zwroc ostatni
print(ostatni) # maslo
print(koszyk)  # ['chleb', 'jajka']
> python cwiczenie_m03_3.py
['chleb', 'jajka', 'mleko', 'maslo']
maslo
['chleb', 'jajka']
ValueError: list.remove(x): x not in list
koszyk.remove("banan") gdy banan nie istnieje.
Zawsze sprawdzaj: if "banan" in koszyk: przed usunięciem.
✏️ Zadania do samodzielnego napisania:
  1. Symuluj kolejkę w kasie: stwórz listę 4 osób. W pętli 3 razy: "obsłuż" pierwszą osobę przez pop(0), wypisz kto odszedł i aktualną kolejkę. Potem dodaj 2 nowe osoby przez append() i wypisz końcowy stan.
  2. Stwórz listę zakupów z 5 produktami. Sprawdź (if + in) czy "mleko" jest na liście — jeśli tak, usuń je. Dodaj "ser" i "jogurt". Wypisz końcową listę. Oczekiwany wynik: lista bez mleka, z serem i jogurtem.
✔️ Po tej sekcji powinieneś umieć:
  • używać append(), insert(), remove(), pop()
  • sprawdzać istnienie przed usunięciem: if x in lista
🧠 Sprawdź wiedzę — 3.3
3.4

Przydatne metody i funkcje

Python daje Ci darmowe narzędzia analityczne — jak kalkulator który sam liczy sumę, minimum i maksimum całej listy jednym wywołaniem.
Funkcje wbudowane: sum(), min(), max(), len() działają na listach. Metody listy: count(val) — ile razy wartość wystąpiła, index(val) — na jakiej pozycji. Operator in sprawdza czy element istnieje.
oceny = [4, 5, 3, 5, 4, 2, 5, 3]

print(len(oceny))       # 8
print(sum(oceny))       # 31
print(min(oceny))       # 2
print(max(oceny))       # 5
print(oceny.count(5))   # 3 — ile razy 5
print(oceny.index(2))   # 5 — pozycja wartosci 2
print(5 in oceny)       # True

srednia = sum(oceny) / len(oceny)
print(f"Srednia: {srednia:.2f}")  # 3.88
> python cwiczenie_m03_4.py
8
31
2
5
3
5
True
Srednia: 3.88
✏️ Zadania do samodzielnego napisania:
  1. Stwórz listę temperatur z 7 dni tygodnia (np. [22, 18, 25, 30, 15, 20, 28]). Oblicz i wypisz: max, min, sumę, średnię (z 2 miejscami po przecinku). Oczekiwane wyniki: 30, 15, 158, 22.57.
  2. Stwórz listę wyniki = [85, 92, 71, 88, 95, 71, 60]. Sprawdź: ile razy wynik 71 się powtarza, na jakiej pozycji jest wartość 88, czy 100 jest na liście. Oczekiwane wyniki: 2, 3, False.
✔️ Po tej sekcji powinieneś umieć:
  • używać sum(), min(), max(), len()
  • używać count(), index(), in
🧠 Sprawdź wiedzę — 3.4
3.5

Sortowanie

sort() to przesuwanie książek na półce według tytułu — zmienia oryginał na miejscu. sorted() to zrobienie fotografii półki i ułożenie kopii — oryginał zostaje niezmieniony.
Metoda .sort() modyfikuje oryginalną listę w miejscu i zwraca None. Funkcja sorted() zwraca nową posortowaną listę bez zmiany oryginału. Parametr reverse=True sortuje malejąco.
imiona = ["Zofia", "Anna", "Bartek", "Marek"]

imiona.sort()                         # modyfikuje!
print(imiona)   # ['Anna', 'Bartek', 'Marek', 'Zofia']

wyniki = [85, 92, 71, 88, 95]
posortowane = sorted(wyniki, reverse=True)
print(posortowane)  # [95, 92, 88, 85, 71]
print(wyniki)       # [85, 92, 71, 88, 95] bez zmian!
> python cwiczenie_m03_5.py
['Anna', 'Bartek', 'Marek', 'Zofia']
[95, 92, 88, 85, 71]
[85, 92, 71, 88, 95]
Pułapka: posortowane = lista.sort()
sort() zmienia listę w miejscu i zwraca None — zmienna będzie None!
Użyj sorted(lista) gdy potrzebujesz przypisać wynik do zmiennej.
✏️ Zadania do samodzielnego napisania:
  1. Stwórz listę [64, 25, 12, 22, 11]. Posortuj ją rosnąco (przez .sort()) i wypisz. Potem stwórz osobną zmienną z posortowaną malejąco kopią (przez sorted(..., reverse=True)) i wypisz obie. Oczekiwane wyniki: [11, 12, 22, 25, 64] i [64, 25, 22, 12, 11].
  2. Wczytaj 5 liczb od użytkownika (każdą osobnym input() z konwersją na int) do listy. Wypisz je posortowane rosnąco, malejąco i w oryginalnej kolejności. Oczekiwany wynik: trzy linie z listami.
✔️ Po tej sekcji powinieneś umieć:
  • używać .sort() — modyfikuje oryginał
  • używać sorted() — tworzy nową listę
  • sortować malejąco przez reverse=True
🧠 Sprawdź wiedzę — 3.5
3.6

for po liście — wprowadzenie

Pętla for po liście to jak czytanie listy zakupów — bierzesz każdą pozycję po kolei i robisz z nią coś konkretnego. Nie musisz znać indeksów — Python sam podaje każdy element.
Pętla for element in lista: przechodzi przez każdy element po kolei. enumerate(lista) daje pary (indeks, wartość) — gdy potrzebujesz numeru. Pełna nauka pętli czeka w M04!
owoce = ["jablko", "banan", "wisnia"]

for owoc in owoce:
    print(f"Lubie {owoc}!")

print()
for i, owoc in enumerate(owoce):
    print(f"{i+1}. {owoc}")
> python cwiczenie_m03_6.py
Lubie jablko!
Lubie banan!
Lubie wisnie!

1. jablko
2. banan
3. wisnia
✏️ Zadania do samodzielnego napisania:
  1. Stwórz listę 5 miast. Użyj pętli for i wypisz każde z numerem porządkowym przez enumerate(). Oczekiwany wynik: 1. Warszawa, 2. Krakow itd.
  2. Stwórz listę ceny = [12.5, 8.0, 25.99, 5.5, 18.0]. Użyj pętli for i oblicz sumę ręcznie (przez akumulację: suma += cena). Wypisz każdą cenę i końcową sumę. Oczekiwana suma: 69.99.
✔️ Po tej sekcji powinieneś umieć:
  • iterować po liście: for x in lista:
  • używać enumerate() gdy potrzebujesz numeru
🧠 Sprawdź wiedzę — 3.6
3.7

Zagnieżdżone listy — 2D

Lista list to jak tabela w Excelu — wiersze i kolumny. Dostęp: najpierw numer wiersza, potem numer kolumny. Używasz do tabel wyników, map gier, siatek danych.
Lista może zawierać inne listy jako elementy. Dostęp do elementu: lista[wiersz][kolumna]. Każdy wewnętrzny element to pełnoprawna lista — możesz na niej wywoływać wszystkie metody list.
wyniki = [
    ["Anna",   92],
    ["Bartek", 85],
    ["Zofia",  97]
]

print(wyniki[0])       # ['Anna', 92]
print(wyniki[0][0])    # Anna
print(wyniki[1][1])    # 85

mapa = [
    [0, 0, 1],
    [0, 1, 0],
    [1, 0, 0]
]
print(mapa[1][1])      # 1 — srodek mapy
> python cwiczenie_m03_7.py
['Anna', 92]
Anna
85
1
✏️ Zadania do samodzielnego napisania:
  1. Stwórz tabelę 3 produktów: każdy to lista [nazwa, cena] np. ["chleb", 3.5]. Wypisz każdy produkt w formacie Produkt: chleb | Cena: 3.50 zl używając pętli for i :.2f.
  2. Stwórz planszę gry kółko-krzyżyk: lista 3 list po 3 elementy, każde ".". Ustaw: plansza[0][0] = "X", plansza[1][1] = "O", plansza[2][2] = "X". Wypisz planszę (każdy wiersz w osobnej linii przez " ".join(wiersz)).
✔️ Po tej sekcji powinieneś umieć:
  • tworzyć listę list (tablicę 2D)
  • dostęp przez lista[i][j]
  • iterować po wierszach i kolumnach
🧠 Sprawdź wiedzę — 3.7
3.8

Krotki — dane niezmienne

Krotka to lista "zapieczętowana" — możesz czytać, ale nie możesz zmieniać. Jak etykieta na przesyłce — raz naklejona, trwa niezmiennie przez całą drogę.
Krotka (tuple) używa nawiasów okrągłych (). Po stworzeniu nie można jej modyfikować — to celowe! Używaj krotek gdy dane NIE powinny się zmieniać: współrzędne, kolory RGB, stałe konfiguracyjne. Unpacking pozwala przypisać elementy do zmiennych jedną linią.
wspolrzedne = (52.23, 21.01)  # Warszawa
rgb_czerwony = (255, 0, 0)

print(wspolrzedne[0])  # 52.23
print(rgb_czerwony)    # (255, 0, 0)

# Unpacking
x, y = wspolrzedne
print(f"Szerokosc: {x}, Dlugosc: {y}")

r, g, b = rgb_czerwony
print(f"R={r}, G={g}, B={b}")

# wspolrzedne[0] = 100  <-- TypeError!
> python cwiczenie_m03_8.py
52.23
(255, 0, 0)
Szerokosc: 52.23, Dlugosc: 21.01
R=255, G=0, B=0
TypeError: 'tuple' object does not support item assignment
Próba zmiany elementu krotki. Jeśli dane mają się zmieniać — użyj listy.
Krotkę stosuj gdy dane są stałe i niezmienne przez cały czas działania programu.
✏️ Zadania do samodzielnego napisania:
  1. Stwórz listę 3 miast jako krotek: (nazwa, populacja_mln). Użyj pętli for i unpackingu (nazwa, pop = miasto) żeby wypisać każde w formacie Warszawa: 1.8 mln mieszkancow.
  2. Stwórz krotkę wymiary = (1920, 1080) reprezentującą rozdzielczość ekranu. Wypakuj do zmiennych szerokosc i wysokosc. Oblicz i wypisz proporcje (szerokosc / wysokosc z 2 miejscami po przecinku) i całkowitą liczbę pikseli. Oczekiwany wynik: 1.78 i 2073600.
✔️ Po tej sekcji powinieneś umieć:
  • tworzyć krotki z ()
  • używać unpackingu: a, b = krotka
  • wiedzieć kiedy użyć krotki zamiast listy
🧠 Sprawdź wiedzę — 3.8
M03

Listy — Podsumowanie

✔️ Co umiasz po tym module:
  • tworzyć listy i dostęp do elementów przez indeks (w tym ujemny)
  • wycinać fragmenty listy przez slicing [a:b], [::2], [::-1]
  • dodawać elementy: append(), insert()
  • usuwać elementy: remove(), pop()
  • analizować listę: sum(), min(), max(), count(), index(), in
  • sortować: .sort() (modyfikuje) vs sorted() (nowa lista)
  • iterować przez for x in lista i enumerate()
  • tworzyć listy zagnieżdżone (2D) i krotki niezmienne
🎯 Brawo! Listy to jeden z najważniejszych elementów Pythona. Niemal każdy program używa list — teraz masz fundament do pracy z kolekcjami danych!
🏗️ Projekt końcowy — „Rejestr Uczestników"

Napisz program który zarządza listą uczestników kursu: dodaje ich, sortuje i wyświetla sformatowaną listę.

  1. Krok 1: W pętli while True wczytuj imiona uczestników aż do wpisania "koniec".
  2. Krok 2: Każde niepuste imię dodaj do listy (append), wypisz potwierdzenie.
  3. Krok 3: Po wyjściu z pętli posortuj listę alfabetycznie.
  4. Krok 4: Wypisz sformatowaną listę z numerami przez enumerate.
  5. Krok 5: Wypisz podsumowanie: liczba uczestników, pierwsze i ostatnie imię.
Wymagania:
  • Pomijaj puste wejście (sprawdź przez if imie:)
  • Numeracja od 1 (użyj enumerate(lista, 1))
  • Po posortowaniu wypisz pierwsze i ostatnie imię (indeksy 0 i -1)
  • Jeśli lista jest pusta — wypisz stosowny komunikat
📝 Test końcowy — Moduł 03
Sprawdź całą wiedzę z modułu o listach. Odpowiedz na wszystkie pytania, potem sprawdź wynik.
M04

Pętle — Powtarzanie bez Nudy

Nauczysz się powtarzać kod bez kopiowania — od prostej pętli for, przez while, aż po elegancki list comprehension. Po tym module zbudujesz analizator danych.
Wyobraź sobie że musisz napisać "Przepraszam" 100 razy. Bez pętli: 100 linii kodu. Z pętlą: 2 linie. Pętle to serce każdego algorytmu.
Dwa rodzaje pętli: for — gdy z góry wiesz ile razy powtórzyć lub po jakim zbiorze iterować. while — gdy powtarzasz dopóki jakiś warunek jest spełniony.
⌨️ Krok 0 — Przygotuj plik
Przed każdą sekcją utwórz nowy plik:
1
Otwórz VS Code → folder kursu
2
Prawy klik → Nowy Plik → cwiczenie_m04_1.py
3
Wpisuj kod ręcznie — nie kopiuj. Zapisz Ctrl+S
4
Terminal → python cwiczenie_m04_1.py
👾 W grze Asteroidy użyjesz tego tak:
while True:                              # game loop — 60 klatek na sekundę!
    for laser in lasery:
        laser[1] -= laser_predkosc       # przesuń każdy laser w górę

    # Usuń lasery poza ekranem (wzorzec filtrowania!)
    lasery = [l for l in lasery if l[1] > -30]

    for wrog in wrogowie:
        wrog[0] += wrog_predkosc * wrog[2]   # ruch AI wszystkich wrogów
Cała logika gry żyje w while True — każdy ruch to pętla z tego modułu!
4.1

for + range() — wszystkie warianty

range() to generator liczb — jak ktoś kto liczy głośno: "jeden, dwa, trzy...". Mówisz "licz od 1 do 5" i dostajesz po kolei 1, 2, 3, 4, 5.
range(n) generuje 0, 1, ..., n-1. range(start, stop) od start do stop-1. range(start, stop, krok) z podanym krokiem (ujemny krok = odliczanie wstecz).
for i in range(5):
    print(i, end=" ")    # 0 1 2 3 4
print()

for i in range(1, 6):
    print(i, end=" ")    # 1 2 3 4 5
print()

for i in range(0, 11, 2):
    print(i, end=" ")    # 0 2 4 6 8 10
print()

for i in range(5, 0, -1):
    print(i, end=" ")    # 5 4 3 2 1
print("START!")
> python cwiczenie_m04_1.py
0 1 2 3 4
1 2 3 4 5
0 2 4 6 8 10
5 4 3 2 1 START!
range(5) zaczyna od 0, nie od 1!
Jeśli chcesz 1, 2, 3, 4, 5 — użyj range(1, 6). To bardzo częsty błąd na początku.
✏️ Zadania do samodzielnego napisania:
  1. Napisz trzy pętle: (a) wypisz liczby od 1 do 20, (b) wypisz tylko parzyste od 2 do 20, (c) odlicz od 10 do 1 każdą w nowej linii. Oczekiwane wyniki: kolejne liczby zgodnie z opisem.
  2. Wypisz tabliczkę mnożenia przez 7 (od 7×1 do 7×10) w formacie 7 x 1 = 7. Użyj pętli for i in range(1, 11). Oczekiwany wynik: 10 linii.
✔️ Po tej sekcji powinieneś umieć:
  • używać range(n), range(a, b), range(a, b, krok)
  • odliczać w dół ujemnym krokiem
🧠 Sprawdź wiedzę — 4.1
4.2

for po liście, enumerate() i zip()

enumerate() to czytanie listy obecności — "1. Anna, 2. Bartek". zip() to zamek błyskawiczny — łączy dwie listy w pary: pierwszą z pierwszą, drugą z drugą.
enumerate(lista) daje pary (indeks, wartość) — gdy potrzebujesz numeru przy każdym elemencie. zip(lista1, lista2) łączy dwie listy element po elemencie — przydatne gdy masz powiązane dane w dwóch listach.
miasta     = ["Warszawa", "Krakow", "Gdansk"]
populacje  = [1.8, 0.8, 0.5]

for miasto in miasta:
    print(f"Miasto: {miasto}")

print()
for i, miasto in enumerate(miasta):
    print(f"{i+1}. {miasto}")

print()
for miasto, pop in zip(miasta, populacje):
    print(f"{miasto}: {pop}M mieszkancow")
> python cwiczenie_m04_2.py
Miasto: Warszawa
Miasto: Krakow
Miasto: Gdansk

1. Warszawa
2. Krakow
3. Gdansk

Warszawa: 1.8M mieszkancow
Krakow: 0.8M mieszkancow
Gdansk: 0.5M mieszkancow
for i in range(len(lista)) zamiast enumerate:
for i in range(len(lista)): lista[i] działa, ale jest mniej czytelne i podatne na błędy.
Zawsze preferuj enumerate() gdy potrzebujesz numeru.
✏️ Zadania do samodzielnego napisania:
  1. Stwórz dwie listy: 5 produktów i 5 cen. Użyj zip() żeby wypisać każdy w formacie 1. Chleb — 3.50 zl (z numerem przez enumerate(zip(...))). Oczekiwany wynik: 5 ponumerowanych linii.
  2. Masz listę imion i listę wyników: ["Anna","Bartek","Zofia"] i [92, 85, 97]. Użyj zip() i enumerate() jednocześnie żeby wypisać miejsce, imię i wynik. Oczekiwany wynik: 1. Zofia: 97 pkt (posortowane malejąco po wynikach — użyj sorted(zip(...), key=...)).
✔️ Po tej sekcji powinieneś umieć:
  • iterować po liście: for x in lista
  • używać enumerate() z numerem
  • łączyć dwie listy przez zip()
🧠 Sprawdź wiedzę — 4.2
4.3

while — pętla z warunkiem

while to "póki co". Póki pada deszcz — stój w domu. Póki nie znasz odpowiedzi — pytaj. Pętla trwa dopóki warunek jest True — nie wiesz z góry ile razy.
while warunek: sprawdza warunek PRZED każdym powtórzeniem. Jeśli jest False od początku — pętla nie wykona się ani razu. Coś w pętli MUSI zmieniać warunek — inaczej pętla nigdy się nie skończy!
licznik = 0
while licznik < 5:
    print(f"Licznik: {licznik}")
    licznik += 1   # BEZ TEGO — petla nieskonczona!

print()
haslo = ""
while haslo != "python123":
    haslo = input("Podaj haslo: ")
print("Zalogowano!")
> python cwiczenie_m04_3.py
Licznik: 0
Licznik: 1
Licznik: 2
Licznik: 3
Licznik: 4

Podaj haslo: python123
Zalogowano!
Pętla nieskończona — program się zawiesza!
Zapomniane licznik += 1 lub brak zmiany warunku → pętla nigdy nie kończy.
Wyjdź przez Ctrl+C w terminalu. Zawsze sprawdź że coś w pętli zmienia warunek.
✏️ Zadania do samodzielnego napisania:
  1. Napisz program zgadywania liczby: "myśl" o liczbie 42, pytaj użytkownika w pętli while dopóki nie wpisze 42. Wypisz ile prób zajęło odgadnięcie. Oczekiwany wynik po wpisaniu 42: Brawo! Odgadles w 3 probach.
  2. Napisz program sumujący liczby: w pętli while wczytuj liczby całkowite od użytkownika dopóki nie wpisze 0. Na końcu wypisz sumę i ile liczb podano (bez zera). Oczekiwany wynik dla 5, 3, 8, 0: Suma: 16, liczb: 3.
✔️ Po tej sekcji powinieneś umieć:
  • pisać while warunek:
  • pamiętać o zmianie warunku wewnątrz pętli
  • rozróżniać kiedy użyć for (znana liczba iteracji) a while (nieznana)
🧠 Sprawdź wiedzę — 4.3
4.4

break i continue — kontrola pętli

break to klawisz STOP — natychmiast wyjdź z pętli, koniec. continue to klawisz POMIŃ — przeskocz tę iterację i zacznij następną.
break natychmiast wychodzi z pętli i kontynuuje kod po niej. continue pomija resztę bieżącej iteracji i skacze do następnej. Razem z while True: tworzą elastyczny wzorzec nieskończonej pętli z kontrolowanym wyjściem.
for i in range(10):
    if i == 5:
        print("Znalazlem 5! Stop.")
        break
    print(i, end=" ")   # 0 1 2 3 4
print()

for i in range(10):
    if i % 2 == 0:      # pominj parzyste
        continue
    print(i, end=" ")   # 1 3 5 7 9
print()

while True:
    opcja = input("Wybierz (1-info, 0-wyjdz): ")
    if opcja == "0":
        print("Do widzenia!")
        break
    elif opcja == "1":
        print("Wersja 1.0")
> python cwiczenie_m04_4.py
0 1 2 3 4 Znalazlem 5! Stop.
1 3 5 7 9
Wybierz (1-info, 0-wyjdz): 0
Do widzenia!
✏️ Zadania do samodzielnego napisania:
  1. Masz listę ocen [4, 5, 2, 3, 1, 5]. Użyj break żeby zatrzymać się gdy napotkasz ocenę mniejszą niż 2. Użyj continue żeby wypisać tylko oceny >= 3. Oczekiwane wyniki: zatrzymanie na ocenie 1, wypisanie [4, 5, 3, 5].
  2. Napisz menu w pętli while True z opcjami: 1 — wypisz powitanie, 2 — wypisz aktualną godzinę (możesz wpisać ją ręcznie), 0 — wyjdź. Pomiń wszystkie inne opcje przez continue. Oczekiwany wynik: menu działa w pętli do wpisania 0.
✔️ Po tej sekcji powinieneś umieć:
  • używać break — natychmiast wychodzi z pętli
  • używać continue — przeskakuje do następnej iteracji
  • stosować wzorzec while True: z break
🧠 Sprawdź wiedzę — 4.4
4.5

Wzorce pętlowe — jak myśleć algorytmicznie

Są 4 podstawowe wzorce które pojawiają się w każdym programie. Jak nauczysz się je rozpoznawać, zaczniesz myśleć jak programista — zobaczysz co zrobić jeszcze zanim zaczniesz pisać.
Cztery fundamentalne wzorce: akumulacja (suma, iloczyn), filtrowanie (zostaw pasujące), szukanie (znajdź i przerwij), transformacja (zmień każdy element). Każdy program to kombinacja tych wzorców.
liczby = [3, -1, 7, -4, 2, 8, -2, 5]

# AKUMULACJA
suma = 0
for x in liczby:
    suma += x
print(f"Suma: {suma}")           # 18

# FILTROWANIE
dodatnie = []
for x in liczby:
    if x > 0:
        dodatnie.append(x)
print(f"Dodatnie: {dodatnie}")   # [3, 7, 2, 8, 5]

# SZUKANIE
for x in liczby:
    if x == -4:
        print("Znaleziono -4!")
        break

# TRANSFORMACJA
kwadraty = [x**2 for x in liczby]
print(f"Kwadraty: {kwadraty}")
> python cwiczenie_m04_5.py
Suma: 18
Dodatnie: [3, 7, 2, 8, 5]
Znaleziono -4!
Kwadraty: [9, 1, 49, 16, 4, 64, 4, 25]
✏️ Zadania do samodzielnego napisania:
  1. Zastosuj wszystkie 4 wzorce do listy temperatur [22, -3, 18, 35, -5, 28, 15]: (a) suma, (b) tylko temperatury > 20, (c) znajdź pierwszą ujemną i wypisz jej pozycję, (d) zamień na Fahrenheit (C*9/5+32).
  2. Masz listę słów ["python", "java", "c", "rust", "go", "javascript"]. Zastosuj wzorce: (a) policz łączną liczbę liter (akumulacja przez len), (b) wypisz tylko słowa dłuższe niż 4 litery (filtrowanie), (c) zmień każde na wielkie litery (transformacja przez .upper()).
✔️ Po tej sekcji powinieneś umieć:
  • rozpoznawać i stosować: akumulacja, filtrowanie, szukanie, transformacja
  • wybrać odpowiedni wzorzec do zadanego problemu
🧠 Sprawdź wiedzę — 4.5
4.6

Zagnieżdżone pętle

Pętla w pętli to jak matrioszka — zewnętrzna pętla to wiersze, wewnętrzna to kolumny. Dla każdego wiersza przelatujemy przez wszystkie kolumny. Dwie linie kodu rysują całą siatkę.
Pętle można zagnieżdżać — każda iteracja zewnętrznej uruchamia całą wewnętrzną. Używane do tabel, siatek, map gier. Koszt: n×m operacji — dla małych danych bez problemu, dla dużych może być wolno.
print("Tabliczka mnozenian:")
for i in range(1, 6):
    for j in range(1, 6):
        print(f"{i*j:3}", end="")
    print()   # nowa linia po kazdym wierszu

print()
mapa = [
    [".", ".", "#", "."],
    [".", "#", "#", "."],
    [".", ".", ".", "."],
]
for wiersz in mapa:
    for pole in wiersz:
        print(pole, end=" ")
    print()
> python cwiczenie_m04_6.py
Tabliczka mnozenian:
  1  2  3  4  5
  2  4  6  8 10
...

. . # .
. # # .
. . . .
Złożoność O(n²) — uważaj przy dużych danych:
Dla listy 1000 elementów daje milion operacji. Dla małych danych (n < kilkaset) bez problemu. Gdy dane są duże, szukaj rozwiązania bez zagnieżdżenia.
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj szerokość i wysokość od użytkownika (int). Narysuj wypełniony prostokąt ze znaków * o podanych wymiarach. Wejście: 5×3. Oczekiwany wynik: 3 linie po 5 gwiazdek.
  2. Wczytaj rozmiar n od użytkownika. Narysuj trójkąt prostokątny ze znaków # o n wierszach (wiersz 1 = 1 znak, wiersz 2 = 2 znaki, ..., wiersz n = n znaków). Wejście: 5. Oczekiwany wynik: trójkąt 5 wierszy.
✔️ Po tej sekcji powinieneś umieć:
  • pisać for w for z prawidłowym wcięciem
  • wypisywać siatki i tabele
  • wiedzieć o koszcie O(n²)
🧠 Sprawdź wiedzę — 4.6
4.7

List comprehension — elegancki zapis

List comprehension to skrócony zapis pętli tworzącej listę — jak przepis "weź wszystkie jabłka, umyj każde, włóż do koszyka" zapisany jednym zdaniem zamiast czterema.
Składnia: [wyrażenie for x in kolekcja]. Z filtrem: [wyrażenie for x in kolekcja if warunek]. Zastępuje pętlę for z append — zwięźle i czytelnie dla prostych operacji.
# Stara metoda — for + append
kwadraty = []
for i in range(1, 6):
    kwadraty.append(i ** 2)

# List comprehension — to samo w 1 linii
kwadraty2 = [i**2 for i in range(1, 6)]

print(kwadraty)   # [1, 4, 9, 16, 25]
print(kwadraty2)  # [1, 4, 9, 16, 25]

# Z filtrem
parzyste = [x for x in range(20) if x % 2 == 0]
print(parzyste)   # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

oceny = [4, 5, 2, 3, 5, 1]
zdane = [o for o in oceny if o >= 3]
print(f"Zdane: {zdane}")  # [4, 5, 3, 5]
> python cwiczenie_m04_7.py
[1, 4, 9, 16, 25]
[1, 4, 9, 16, 25]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Zdane: [4, 5, 3, 5]
✏️ Zadania do samodzielnego napisania:
  1. Używając list comprehension: (a) stwórz listę kwadratów nieparzystych liczb od 1 do 20, (b) z listy imion ["Anna","Bartek","Al","Zofia","Bo"] odfiltruj tylko te dłuższe niż 3 litery. Oczekiwane wyniki: [1, 9, 25, 49, 81, 121, 169, 225, 289, 361] i ["Anna","Bartek","Zofia"].
  2. Masz listę temperatur w Celsjuszach [0, 20, 37, 100, -10]. Używając list comprehension przelicz każdą na Fahrenheit (C*9/5 + 32). Oczekiwany wynik: [32.0, 68.0, 98.6, 212.0, 14.0].
✔️ Po tej sekcji powinieneś umieć:
  • pisać [wyrażenie for x in lista]
  • dodawać filtr: [wyrażenie for x in lista if warunek]
  • wiedzieć kiedy comprehension jest czytelniejszy od pętli
🧠 Sprawdź wiedzę — 4.7
4.8

Wzorzec filtrowania — bezpieczne usuwanie z listy

Misja: naucz się bezpiecznie usuwać elementy z listy — w grze Asteroidy dokładnie tak usuwamy lasery poza ekranem i pokonanych wrogów!
Wyobraź sobie taśmę produkcyjną: elementy jadą po taśmie, inspektor sprawdza każdy — te które spełniają warunek trafiają do nowej skrzynki, reszta do kosza. Na końcu nowa skrzynka zastępuje starą. To właśnie wzorzec filtrowania!
❌ NIGDY tak nie rób — modyfikowanie listy podczas iteracji po niej:

# ŹLE — Python pomija elementy!
liczby = [1, -2, 3, -4, 5]
for x in liczby:
    if x < 0:
        liczby.remove(x)   # BUG: lista zmienia się podczas pętli
print(liczby)  # [1, 3, -4, 5] — -4 nie zostało usunięte!
Gdy usuwasz z listy podczas iteracji po niej, Python traci pozycję — co drugi element może zostać pominięty.
✅ Wzorzec bezpieczny — buduj nową listę:
Zamiast modyfikować oryginał, buduj nową listę tylko z elementów które chcesz zachować, a potem zastąp nią starą.
# DOBRZE — budujemy nową listę
liczby = [1, -2, 3, -4, 5]

nowe = []
for x in liczby:
    if x >= 0:          # zachowaj tylko nieujemne
        nowe.append(x)
liczby = nowe           # zastąp starą listę nową

print(liczby)  # [1, 3, 5]
> python cwiczenie_m04_8a.py
[1, 3, 5]
Lub krócej — ten sam efekt przez list comprehension (poznałeś w 4.7!):
# To samo jedną linią:
liczby = [1, -2, 3, -4, 5]
liczby = [x for x in liczby if x >= 0]
print(liczby)  # [1, 3, 5]
👾 W grze Asteroidy:
Tak usuwamy lasery które wyleciały poza górę ekranu:
lasery = [[400, 500], [200, -40], [600, 200]]

# Zachowaj tylko lasery wciąż na ekranie (y > -30)
lasery = [l for l in lasery if l[1] > -30]

print(lasery)  # [[400, 500], [600, 200]]
# Laser [200, -40] zniknął — wyleciał poza górę!
> python cwiczenie_m04_8b.py
[[400, 500], [600, 200]]
✏️ Zadania do samodzielnego napisania:
  1. Masz listę temperatur [22, -5, 18, -12, 30, 0, 15]. Używając wzorca filtrowania (pętla + nowa lista) zostaw tylko temperatury powyżej zera. Oczekiwany wynik: [22, 18, 30, 15].
  2. Masz listę wrogów [["goblin", 20], ["smok", 0], ["elf", 15], ["troll", 0]]. Używając list comprehension usuń wrogów z HP = 0 (martwych). Oczekiwany wynik: [["goblin", 20], ["elf", 15]].
✔️ Po tej sekcji powinieneś umieć:
  • rozumieć dlaczego lista.remove() w pętli po tej samej liście jest błędem
  • stosować wzorzec: nowe = []; for x in lista: if warunek: nowe.append(x); lista = nowe
  • stosować skróconą wersję: lista = [x for x in lista if warunek]
🧠 Sprawdź wiedzę — 4.8
M04

Pętle — Podsumowanie

✔️ Co umiasz po tym module:
  • używać range(n), range(a, b), range(a, b, krok) w pętli for
  • iterować po listach, używać enumerate() i zip()
  • pisać pętlę while warunek: z bezpieczną zmianą warunku
  • kontrolować pętle przez break i continue
  • rozpoznawać 4 wzorce: akumulacja, filtrowanie, szukanie, transformacja
  • pisać zagnieżdżone pętle do siatek i tabel
  • tworzyć listy przez list comprehension
🎯 Brawo! Pętle to serce każdego algorytmu — właśnie nauczyłeś się jak komputer "myśli". To fundament programowania!
🏗️ Projekt końcowy — „Analizator Danych"

Napisz program który wczytuje od użytkownika ciąg liczb i przeprowadza pełną analizę statystyczną.

  1. Krok 1: W pętli while True wczytuj liczby (float) aż do wpisania "koniec". Obsłuż błędne wejście przez try/except ValueError.
  2. Krok 2: Po wyjściu z pętli — jeśli lista pusta, wypisz komunikat i zakończ.
  3. Krok 3: Oblicz: sumę, średnią, min, max.
  4. Krok 4: Użyj list comprehension żeby wyfiltrować dodatnie i ujemne.
  5. Krok 5: Wypisz top 3 wartości (posortowane malejąco przez sorted(..., reverse=True)[:3]).
Wymagania:
  • Obsługa błędnego wejścia (nie-liczba) — wypisz komunikat i kontynuuj pętlę
  • Wszystkie wartości wypisane z 2 miejscami po przecinku (:.2f)
  • Procent dodatnich i ujemnych (len(podlista)/len(dane)*100:.0f)
  • Jeśli jest mniej niż 3 wartości — wypisz tyle ile jest
📝 Test końcowy — Moduł 04
Sprawdź całą wiedzę z modułu o pętlach. Odpowiedz na wszystkie pytania, potem sprawdź wynik.
M05

Funkcje — Twój Własny Zestaw Narzędzi

Czas na pierwszy duży skok myślowy: zamiast pisać kod, zaczniesz definiować operacje. Funkcje to cegiełki z których zbudowane są wszystkie programy na świecie.
Wyobraź sobie że przepisujesz przepis na ciasto do 5 różnych notatników. Gdy zmienisz jeden składnik, musisz aktualizować 5 miejsc. Funkcja to przepis w jednym miejscu — używasz go ile razy chcesz, a zmiana w jednym miejscu dotyczy wszystkiego.
BEZ funkcji — kopiujesz ten sam kod wielokrotnie. Z funkcją — piszesz raz, wywołujesz wiele razy. Zasada ta ma nawet nazwę: DRY — Don't Repeat Yourself. W tym module nauczysz się definiować funkcje, przekazywać do nich dane, odbierać wyniki i składać złożone programy z małych, czytelnych części.
# BEZ funkcji — powtarzamy kod
print("Cześć, Anna! Witaj w kursie.")
print("Cześć, Bartek! Witaj w kursie.")
print("Cześć, Zofia! Witaj w kursie.")

# Z funkcją — piszemy raz, używamy ile chcemy
def przywitaj(imie):
    print(f"Cześć, {imie}! Witaj w kursie.")

przywitaj("Anna")
przywitaj("Bartek")
przywitaj("Zofia")
> python cwiczenie_m05_0.py
Cześć, Anna! Witaj w kursie.
Cześć, Bartek! Witaj w kursie.
Cześć, Zofia! Witaj w kursie.
⌨️ Krok 0 — Przygotuj plik
Przed każdą sekcją utwórz nowy plik:
1
Otwórz VS Code → folder kursu
2
Prawy klik → Nowy Plik → cwiczenie_m05_1.py
3
Wpisuj kod ręcznie — nie kopiuj. Zapisz Ctrl+S
4
Terminal → python cwiczenie_m05_1.py
👾 W grze Asteroidy użyjesz tego tak:
def ruch_statku(klawisze):
    global statek_x, statek_y        # modyfikuje zmienne globalne
    if klawisze[K_LEFT]:
        statek_x -= predkosc

def sprawdz_kolizje():
    global zycia, punkty             # cała logika kolizji w jednym miejscu
    for laser in lasery:
        if laser_trafil(laser, wrogow):
            punkty += 20

# Główna pętla staje się czytelna:
while True:
    ruch_statku(klawisze)
    sprawdz_kolizje()
Każda funkcja w grze = jedna odpowiedzialność, prosty kod!
5.1

def — definicja i pierwsze wywołanie

Wyobraź sobie że uczysz robota sekwencji kroków: „najpierw podnieś rękę, potem obrót, potem ukłon". Dajesz tej sekwencji nazwę „przywitanie". Potem mówisz tylko „przywitanie!" — robot wie co robić. To właśnie robi def.
def nazwa(): — dwukropek i wcięcie jak w if. Definicja NIE wykonuje kodu — tylko go zapamiętuje. Wywołanie: nazwa() — nawiasy są obowiązkowe! Dwa osobne momenty: definicja (raz) i wywołanie (dowolna liczba razy).
def powiedz_hej():
    print("Hej!")
    print("Jestem funkcją.")
    print("Mogę być wywoływana wielokrotnie.")

# Wywołania — kod z def wykonuje się dopiero teraz
powiedz_hej()
print("---")
powiedz_hej()
print("---")
powiedz_hej()
> python cwiczenie_m05_1.py
Hej!
Jestem funkcją.
Mogę być wywoływana wielokrotnie.
---
Hej!
Jestem funkcją.
Mogę być wywoływana wielokrotnie.
---
Hej!
Jestem funkcją.
Mogę być wywoływana wielokrotnie.
Bez nawiasów — brak wywołania:
powiedz_hej (bez nawiasów) — to referencja do funkcji, NIE wywołanie. Python nie zgłosi błędu, ale nic się nie wykona!
Zawsze: powiedz_hej() z nawiasami.
✏️ Zadania do samodzielnego napisania:
  1. Napisz funkcję rysuj_linie() która wypisuje 20 myślników ("-" * 20). Wywołaj ją 3 razy. Oczekiwany wynik: trzy linie myślników.
  2. Napisz funkcję rysuj_ramke() która rysuje ramkę ASCII z * (4 linie: góra, dwa boki, dół) o szerokości 10 znaków. Wywołaj ją 2 razy. Oczekiwany wynik: dwie ramki jedna pod drugą.
✔️ Po tej sekcji powinieneś umieć:
  • pisać definicję funkcji słowem kluczowym def
  • wywoływać funkcję z nawiasami ()
  • rozumieć że definicja ≠ wywołanie
🧠 Sprawdź wiedzę — 5.1
5.2

Parametry — wejście do funkcji

Parametry to luki w przepisie. „Upiecz ciasto z [X] jabłkami i [Y] szklankami mąki" — X i Y to parametry. Przy każdym wywołaniu podajesz inne wartości dla X i Y.
Parametry idą w nawiasach przy def. Przy wywołaniu podajemy argumenty. Parametr = nazwa w definicji; argument = konkretna wartość przy wywołaniu. Funkcja może mieć jeden, kilka lub zero parametrów.
def przywitaj(imie):
    print(f"Cześć, {imie}!")

przywitaj("Anna")
przywitaj("Bartek")

def przedstaw(imie, wiek):
    print(f"Mam na imię {imie} i mam {wiek} lat.")

przedstaw("Zofia", 22)
przedstaw("Marek", 17)
> python cwiczenie_m05_2.py
Cześć, Anna!
Cześć, Bartek!
Mam na imię Zofia i mam 22 lat.
Mam na imię Marek i mam 17 lat.
TypeError: missing 1 required positional argument
przedstaw("Anna") gdy funkcja wymaga 2 argumentów — Python mówi dokładnie czego brakuje.
Sprawdź ile parametrów ma funkcja i podaj dokładnie tyle argumentów.
✏️ Zadania do samodzielnego napisania:
  1. Napisz funkcję oblicz_pole_prostokata(dlugosc, szerokosc) która wypisuje pole. Wywołaj ją dla (4, 5) i (10, 3). Oczekiwany wynik: Pole prostokata: 20, Pole prostokata: 30.
  2. Napisz funkcję podaj_info(produkt, cena, dostepny) która wypisuje: nazwa, cena z 2 miejscami po przecinku, status „jest" lub „brak". Wywołaj ją dla kawy (8.50, True) i herbaty (6.00, False).
✔️ Po tej sekcji powinieneś umieć:
  • definiować funkcje z jednym i wieloma parametrami
  • wywoływać je z odpowiednią liczbą argumentów
  • rozróżniać: parametr (w definicji) vs argument (przy wywołaniu)
🧠 Sprawdź wiedzę — 5.2
5.3

return — zwracanie wartości

Funkcja bez return to jak kalkulator który pokazuje wynik na wyświetlaczu, ale gdy wyłączasz go — wynik znika. return to przekazanie wyniku do reszty programu, żebyś mógł go zapisać i użyć dalej.
Bez return funkcja zwraca None. Po return funkcja natychmiast kończy działanie. Różnica kluczowa: print() wypisuje na ekran, ale zwraca None. Jeśli chcesz użyć wartości w dalszym kodzie — musisz użyć return.
def powitaj_bez(imie):
    print(f"Cześć, {imie}!")       # wypisuje, ale...

wynik = powitaj_bez("Anna")
print(wynik)                        # None — !

def dodaj(a, b):
    return a + b                    # przekazuje wynik

wynik = dodaj(3, 4)
print(wynik)                        # 7

suma = dodaj(10, 20)
podwojna = dodaj(suma, suma)        # wynik użyty dalej!
print(f"Suma: {suma}, podwojna: {podwojna}")
> python cwiczenie_m05_3.py
Cześć, Anna!
None
7
Suma: 30, podwojna: 60
def sprawdz_wiek(wiek):
    if wiek < 0:
        return "Bledny wiek"   # kończy funkcję tutaj
    if wiek < 18:
        return "Niepelnoletni"
    return "Pelnoletni"        # tylko gdy wiek >= 18

print(sprawdz_wiek(-5))
print(sprawdz_wiek(15))
print(sprawdz_wiek(25))
> python cwiczenie_m05_3.py
Bledny wiek
Niepelnoletni
Pelnoletni
Pułapka: wynik = print("cześć")
print() wypisuje tekst ale zwraca None. Jeśli chcesz używać wartości dalej, zwracaj ją przez return, nie przez print wewnątrz funkcji.
✏️ Zadania do samodzielnego napisania:
  1. Napisz funkcję kwadrat(n) zwracającą n². Napisz szescian(n) zwracającą n³. Wywołaj obie i użyj wyników w obliczeniu: kwadrat(3) + szescian(2). Oczekiwany wynik: 17.
  2. Napisz funkcję max_z_dwoch(a, b) która zwraca większą z dwóch liczb (bez użycia wbudowanego max()). Przetestuj dla (5, 8), (10, 3), (7, 7). Oczekiwany wynik: 8, 10, 7.
✔️ Po tej sekcji powinieneś umieć:
  • pisać funkcje z return
  • używać zwróconej wartości w dalszym kodzie
  • wiedzieć że bez return funkcja zwraca None
  • wiedzieć że return natychmiast kończy funkcję
🧠 Sprawdź wiedzę — 5.3
5.4

Wartości domyślne parametrów

Zamawiasz kawę — „poproszę kawę" oznacza bez cukru (domyślnie). Ale możesz powiedzieć „z dwoma cukrami" i zmienisz domyślne zachowanie. Parametry domyślne działają tak samo.
Domyślna wartość = wartość gdy argument nie zostanie podany przy wywołaniu. Parametry z wartościami domyślnymi muszą być na końcu listy parametrów. Możesz też podawać argumenty po nazwie: funkcja(param=wartosc) — to argumenty kluczowe.
def powitaj(imie, jezyk="pl"):
    if jezyk == "pl":
        print(f"Cześć, {imie}!")
    elif jezyk == "en":
        print(f"Hello, {imie}!")
    else:
        print(f"Hola, {imie}!")

powitaj("Anna")           # domyślny jezyk: pl
powitaj("Tom", "en")      # nadpisuje domyślne
powitaj("Carlos", "es")

def potega(podstawa, wykladnik=2):
    return podstawa ** wykladnik

print(potega(5))           # 25 (domyślnie kwadrat)
print(potega(2, 10))       # 1024
> python cwiczenie_m05_4.py
Cześć, Anna!
Hello, Tom!
Hola, Carlos!
25
1024
SyntaxError: non-default argument follows default argument
def f(x=5, y): — parametry z wartościami domyślnymi muszą być na końcu.
Poprawnie: def f(y, x=5):
✏️ Zadania do samodzielnego napisania:
  1. Napisz funkcję oblicz_vat(cena, stawka=0.23) zwracającą cenę brutto (cena * (1 + stawka)). Przetestuj z domyślną stawką (23%) i z stawka=0.08 (8%). Oczekiwany wynik dla ceny 100: 123.0 i 108.0.
  2. Napisz funkcję wypisz_wiersz(tekst, znak="=", szerokosc=30) która wypisuje tekst wyśrodkowany w ramce ze znakiem. Wywołaj ją z domyślnymi i ze zmienionymi argumentami. Oczekiwany format: ========= TYTUŁ =========.
✔️ Po tej sekcji powinieneś umieć:
  • definiować parametry z wartościami domyślnymi
  • wywoływać funkcję z pominięciem domyślnych i z nadpisaniem
  • używać argumentów kluczowych nazwa=wartość
  • pamiętać że domyślne muszą być na końcu
🧠 Sprawdź wiedzę — 5.4
5.5

Wiele wartości return — tuple unpacking

Idziesz na zakupy i wracasz z torbą z kilkoma produktami naraz — jednym ruchem przynosisz wszystko. Funkcja też może zwrócić kilka wartości jednocześnie, a Python umie je rozpakować do osobnych zmiennych.
return a, b to skrót od return (a, b) — Python pakuje je w krotkę. Można rozpakowywać bezpośrednio: x, y = funkcja(). Konwencja: _ jako nazwa dla wartości którą ignorujemy.
def min_max(lista):
    return min(lista), max(lista)

wynik = min_max([5, 2, 8, 1, 9, 3])
print(wynik)           # (1, 9) — krotka

mn, mx = min_max([5, 2, 8, 1, 9, 3])
print(f"Min: {mn}, Max: {mx}")

def sekundy_na_czas(sekundy):
    godziny = sekundy // 3600
    minuty  = (sekundy % 3600) // 60
    sek     = sekundy % 60
    return godziny, minuty, sek

h, m, s = sekundy_na_czas(3725)
print(f"Czas: {h}:{m:02}:{s:02}")

_, maks = min_max([10, 5, 20, 3])  # ignoruj min
print(f"Maksimum: {maks}")
> python cwiczenie_m05_5.py
(1, 9)
Min: 1, Max: 9
Czas: 1:02:05
Maksimum: 20
✏️ Zadania do samodzielnego napisania:
  1. Napisz funkcję statystyki(lista) zwracającą krotkę (suma, srednia, min, max). Wywołaj ją dla [10, 20, 5, 15, 30] i rozpakuj wszystkie 4 wartości do osobnych zmiennych. Oczekiwany wynik: suma=80, srednia=16.0, min=5, max=30.
  2. Napisz funkcję podziel(a, b) zwracającą krotkę (wynik_calkowity, reszta) — czyli wynik dzielenia całkowitego i resztę (// i %). Dla 17 i 5 oczekiwany wynik: 3, 2.
✔️ Po tej sekcji powinieneś umieć:
  • zwracać wiele wartości przez return a, b
  • rozpakowywać wynik: x, y = funkcja()
  • używać _ do ignorowania niepotrzebnych wartości
🧠 Sprawdź wiedzę — 5.5
5.6

Zasięg zmiennych — lokalne i globalne

Zmienne wewnątrz funkcji żyją tylko podczas jej działania — jak notatki na tablicy podczas lekcji, które po dzwonku znikają. Zmienne na zewnątrz to tablica na korytarzu — widoczna wszędzie, ale żeby ją zmienić musisz mieć specjalne uprawnienie.
Lokalne — istnieją tylko wewnątrz funkcji, niewidoczne na zewnątrz. Globalne — poza funkcjami, widoczne wszędzie (do odczytu). Modyfikacja globalnej wewnątrz funkcji wymaga słowa global. Zasada dobrego kodu: unikaj global — przekazuj przez parametry i return.
def funkcja():
    lokalna = "jestem lokalna"
    print(lokalna)   # OK

funkcja()
# print(lokalna)   <-- NameError!

licznik = 0          # zmienna globalna

def zwieksz():
    global licznik   # deklaracja: modyfikuję globalną
    licznik += 1

zwieksz()
zwieksz()
print(f"Licznik: {licznik}")  # 2

# LEPSZY WZORZEC — bez global
def zwieksz_v2(n):
    return n + 1

licznik2 = 0
licznik2 = zwieksz_v2(licznik2)
licznik2 = zwieksz_v2(licznik2)
print(f"Licznik2: {licznik2}")  # 2
> python cwiczenie_m05_6.py
jestem lokalna
Licznik: 2
Licznik2: 2
Klasyczna pułapka — modyfikacja bez global:
def f(): licznik += 1 — Python tworzy nową zmienną lokalną licznik zamiast modyfikować globalną. Błąd: UnboundLocalError.
Lepsze rozwiązanie: def f(n): return n + 1 + przypisanie poza funkcją.
✏️ Zadania do samodzielnego napisania:
  1. Napisz funkcję akumuluj(lista) która sumuje elementy BEZ użycia global — przez parametr i return. Przetestuj dla [1, 2, 3, 4, 5]. Oczekiwany wynik: 15.
  2. Sprawdź co się stanie gdy spróbujesz odwołać się do zmiennej lokalnej poza funkcją. Napisz funkcję test() z lokalną zmienną x = 42, wywołaj funkcję, a potem spróbuj wypisać x poza nią. Zapisz komunikat błędu.
✔️ Po tej sekcji powinieneś umieć:
  • rozumieć różnicę między zmienną lokalną a globalną
  • wiedzieć że zmienne lokalne znikają po zakończeniu funkcji
  • preferować parametry + return zamiast global
🧠 Sprawdź wiedzę — 5.6
5.7

Funkcje wywołujące funkcje — składanie

Kucharz nie robi wszystkiego sam — woła sous-chefa do sosu, pâtissiera do deseru, keliera do podania. Każdy robi swoją jedną rzecz perfekcyjnie. Dobry program działa tak samo — małe funkcje budują większe operacje.
Funkcja może wywołać inną funkcję. Każda funkcja powinna robić jedną rzecz i robić ją dobrze. Składanie małych funkcji buduje złożone programy — i sprawia że każdą część można rozumieć i testować osobno.
def oblicz_net(cena_brutto, vat=0.23):
    return round(cena_brutto / (1 + vat), 2)

def oblicz_rabat(cena, procent):
    return round(cena * (1 - procent / 100), 2)

def formatuj_cene(kwota):
    return f"{kwota:.2f} zl"

def info_produktu(nazwa, cena_brutto, rabat=0):
    cena_net = oblicz_net(cena_brutto)      # wywołuje inne funkcje
    print(f"=== {nazwa} ===")
    print(f"Brutto: {formatuj_cene(cena_brutto)}")
    print(f"Netto:  {formatuj_cene(cena_net)}")
    if rabat > 0:
        po_rabacie = oblicz_rabat(cena_brutto, rabat)
        print(f"Rabat {rabat}%: {formatuj_cene(po_rabacie)}")

info_produktu("Kawa", 9.99)
print()
info_produktu("Laptop", 2999.00, rabat=10)
> python cwiczenie_m05_7.py
=== Kawa ===
Brutto: 9.99 zl
Netto: 8.12 zl

=== Laptop ===
Brutto: 2999.00 zl
Netto: 2438.21 zl
Rabat 10%: 2699.10 zl
✏️ Zadania do samodzielnego napisania:
  1. Napisz trzy funkcje: pobierz_liczbe(komunikat) (wczytuje i zwraca float), oblicz_bmi(waga, wzrost) (liczy BMI = waga/wzrost²), kategoryzuj_bmi(bmi) (zwraca "Niedowaga"/"Norma"/"Nadwaga"/"Otylosc"). Połącz je w program który pyta użytkownika o wagę i wzrost i wypisuje BMI z kategorią.
  2. Rozbij dowolny program z M01-M04 na co najmniej 3 funkcje: jedna czyta dane, jedna liczy, jedna wypisuje wynik. Każda funkcja = jedna odpowiedzialność.
✔️ Po tej sekcji powinieneś umieć:
  • wywoływać funkcje z wnętrza innych funkcji
  • dzielić logikę na małe, jednozadaniowe funkcje
  • rozumieć że czytelność kodu jest ważniejsza niż oszczędność linii
🧠 Sprawdź wiedzę — 5.7
5.8

Docstring — dokumentowanie funkcji

Docstring to etykieta na puszce konserwowej. Bez etykiety nie wiesz co w środku — musisz otwierać i próbować. Z etykietą czytasz składniki i instrukcję w 3 sekundy. Za miesiąc, gdy zapomnisz co robi Twoja funkcja, docstring ją opisze.
"""Opis funkcji.""" wstawiasz bezpośrednio po linii def, przed pierwszą instrukcją. Wbudowana funkcja help(nazwa_funkcji) wypisuje docstring. Dobry docstring mówi: co robi, jakie parametry przyjmuje, co zwraca.
def oblicz_bmi(waga, wzrost):
    """
    Oblicza wskaznik BMI.

    Parametry:
        waga   (float): waga w kilogramach
        wzrost (float): wzrost w metrach

    Zwraca:
        float: wartosc BMI zaokraglona do 2 miejsc
    """
    return round(waga / wzrost ** 2, 2)

def kategoryzuj_bmi(bmi):
    """Zwraca kategorie BMI jako string."""
    if bmi < 18.5:   return "Niedowaga"
    elif bmi < 25.0: return "Norma"
    elif bmi < 30.0: return "Nadwaga"
    else:            return "Otylosc"

bmi = oblicz_bmi(70, 1.75)
print(f"BMI: {bmi} — {kategoryzuj_bmi(bmi)}")
> python cwiczenie_m05_8.py
BMI: 22.86 — Norma
✏️ Zadania do samodzielnego napisania:
  1. Dodaj docstringi do wszystkich funkcji które napisałeś w sekcjach 5.1–5.7 (co najmniej do 3 wybranych). Każdy docstring powinien opisać: co robi funkcja, jakie parametry przyjmuje (z typem), co zwraca.
  2. Wywołaj help() na jednej z Twoich funkcji i sprawdź jak wygląda wynik. Napisz docstring jako jeden wiersz (krótki opis) i jako wieloliniowy (z sekcjami Parametry i Zwraca).
✔️ Po tej sekcji powinieneś umieć:
  • pisać docstringi bezpośrednio po def
  • używać help() do odczytania dokumentacji funkcji
  • dokumentować parametry i wartość zwracaną
🧠 Sprawdź wiedzę — 5.8
M05

Funkcje — Podsumowanie

✔️ Co umiasz po tym module:
  • definiować funkcje słowem def i wywoływać je z nawiasami
  • przekazywać dane do funkcji przez parametry
  • odbierać wyniki z funkcji przez return
  • definiować wartości domyślne parametrów i używać argumentów kluczowych
  • zwracać wiele wartości naraz i rozpakowywać krotkę
  • rozróżniać zmienne lokalne i globalne
  • składać programy z małych, jednozadaniowych funkcji
  • pisać docstringi dokumentujące funkcje
🎯 Brawo! Właśnie nauczyłeś się najważniejszego narzędzia programisty. Funkcje to język którym architekci oprogramowania myślą o kodzie. Od teraz piszesz nie instrukcje — piszesz operacje!
🏗️ Projekt końcowy — „Kalkulator Rachunków"

Napisz program który zbiera produkty od użytkownika i drukuje sformatowany paragon. Każda operacja to osobna funkcja — żadnego powtarzania kodu.

  1. Krok 1: dodaj_produkt(nazwa, cena) — zwraca słownik {"nazwa": ..., "cena": ...}
  2. Krok 2: oblicz_sume(produkty) — zwraca sumę cen z listy produktów
  3. Krok 3: oblicz_vat(suma, stawka=0.23) — zwraca kwotę VAT
  4. Krok 4: oblicz_rabat(suma, procent) — zwraca sumę po rabacie
  5. Krok 5: drukuj_paragon(produkty, rabat_procent=0) — formatuje i wypisuje cały paragon używając poprzednich funkcji
  6. Krok 6: Pętla główna — wczytuj produkty aż do pustego Enter, zapytaj o rabat, wywołaj drukuj_paragon()
Wymagania:
  • Każda z 4 operacji (dodaj, suma, vat, rabat) to osobna funkcja z return
  • Paragon wypisuje każdy produkt w wyrównanej tabelce (:<20 i :>6.2f)
  • Obsługa błędnego wejścia przez try/except ValueError przy wczytywaniu ceny
  • Jeśli koszyk pusty — wypisz stosowny komunikat zamiast drukować paragon
📝 Test końcowy — Moduł 05
Sprawdź całą wiedzę z modułu o funkcjach. Odpowiedz na wszystkie pytania, potem sprawdź wynik.
🚀
Gotowy na grę Asteroidy!
Znasz już zmienne, warunki, listy, pętle i funkcje — to wszystko czego potrzebujesz.
Kurs Asteroidy nauczy Cię Pygame i krok po kroku zbudujesz własną grę kosmiczną!
✔ zmienne → HP, punkty ✔ if/else → decyzje gry ✔ listy → lasery, asteroidy ✔ while True → game loop ✔ def → funkcje gry
🎮 Zacznij Kurs Asteroidy →
Moduły M06 (Stringi) i M07 (Słowniki) są opcjonalne — nie wymagane do gry.
M06

Stringi — Praca z tekstem

Nauczysz się kroić, szukać, formatować i sprawdzać tekst. Po tym module napiszesz parser komend tekstowych — silnik prostej gry tekstowej.
Stringi to ciągi znaków — każdy tekst w programie to string. Python daje Ci dziesiątki gotowych metod: możesz wyciąć fragment, zamienić litery, podzielić zdanie na słowa i sprawdzić czy tekst zawiera tylko cyfry. Opanowanie stringów to klucz do komunikacji z użytkownikiem i budowania interfejsów tekstowych.
⌨️ Krok 0 — Przygotuj plik
Przygotowanie
1
Otwórz VS Code w swoim folderze z kursem.
2
Na początku każdej sekcji utwórz nowy plik: cwiczenie_m06_1.py, cwiczenie_m06_2.py itd.
3
Wpisuj kod ręcznie — nie kopiuj. Zapisz Ctrl+S
6.1

Indeksowanie i slicing

6.1 Indeksowanie i slicing
Wyobraź sobie naszyjnik z paciorków — każdy paciorek to jedna litera. Możesz wziąć pierwszy paciorek (indeks 0), ostatni (indeks -1) albo środkowy fragment (slice). String w Pythonie działa tak samo.
Każdy znak w stringu ma swój indeks — pozycję liczoną od zera. Python pozwala też liczyć od końca: tekst[-1] to ostatni znak, tekst[-2] to przedostatni. Slicing (tekst[start:stop]) wycina fragment: od indeksu start włącznie do stop wyłącznie. Podanie tylko jednej strony (tekst[3:] lub tekst[:5]) oznacza „od początku" lub „do końca".
tekst = "Python"
print(tekst[0])      # P — pierwszy znak
print(tekst[-1])     # n — ostatni znak
print(tekst[0:3])    # Pyt — od 0 do 2 (3 wyłączone)
print(tekst[2:])     # thon — od 2 do końca
print(tekst[:4])     # Pyth — od początku do 3
print(len(tekst))    # 6 — długość stringu
> python cwiczenie_m06_1.py
P
n
Pyt
thon
Pyth
6
IndexError: string index out of range
Próba odczytania tekst[10] gdy string ma 6 znaków. Indeks musi być w zakresie 0 do len-1 (lub -len do -1).
Zawsze sprawdzaj długość stringu przez len() zanim odczytujesz konkretny indeks.
✏️ Zadania do samodzielnego napisania:
  1. Zadeklaruj string imie = "Aldric". Wypisz osobno: pierwszą literę, ostatnią literę, pierwsze 3 litery, string od drugiego znaku do końca. Oczekiwany wynik: A, c, Ald, ldric.
  2. Zadeklaruj haslo = "SuperTajne123". Wypisz go odwróconego (wskazówka: [::-1]) oraz pierwsze 5 znaków wielką literą (slice + .upper()). Oczekiwany wynik: 321enjaTerepuS i SUPER.
✔️ Po tej sekcji powinieneś umieć:
  • odczytać znak po indeksie (w tym ujemnym)
  • wyciąć fragment stringu slice'em [start:stop]
  • sprawdzić długość stringu przez len()
🧠 Sprawdź wiedzę — 6.1
6.2

Metody: upper / lower / strip / replace

6.2 Metody: upper / lower / strip / replace
Wyobraź sobie autokorektę w telefonie — zamienia małe litery na wielkie w imionach, przycina spacje z obu stron, podmienia wyrazy. Metody stringów w Pythonie robią dokładnie to samo, w jednej linii kodu.
Metody stringów nie zmieniają oryginału — zwracają nowy string. Zawsze przypisz wynik do zmiennej albo użyj go od razu w print(). Najczęściej używane:
  • .upper() — wszystkie litery na wielkie
  • .lower() — wszystkie litery na małe
  • .strip() — usuwa spacje (i znaki nowej linii) z obu końców
  • .replace(stare, nowe) — zamienia wszystkie wystąpienia
napis = "  Witaj Graczu!  "

print(napis.upper())          # wynik:   WITAJ GRACZU!
print(napis.lower())          # wynik:   witaj graczu!
print(napis.strip())          # wynik: Witaj Graczu!
print(napis.strip().upper())  # wynik: WITAJ GRACZU!

tekst = "Ala ma kota. Ala go kocha."
print(tekst.replace("Ala", "Basia"))
> python cwiczenie_m06_2.py
  WITAJ GRACZU!  
  witaj graczu!  
Witaj Graczu!
WITAJ GRACZU!
Basia ma kota. Basia go kocha.
Zapomnienie o przypisaniu wyniku:
napis.strip() — wynik ginie w powietrzu, napis nadal ma spacje!
Poprawnie: napis = napis.strip() albo print(napis.strip())
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj od użytkownika imię (input()). Wypisz je wielką literą (upper), małą (lower) i z przyciętymi spacjami (strip). Wejście:   anna  . Oczekiwany wynik: ANNA, anna, anna.
  2. Zadeklaruj dialog = "Witaj [GRACZ], mam dla ciebie zadanie!". Podmień [GRACZ] na imię podane przez użytkownika przez .replace(). Wejście: Marek. Oczekiwany wynik: Witaj Marek, mam dla ciebie zadanie!
✔️ Po tej sekcji powinieneś umieć:
  • używać .upper(), .lower(), .strip(), .replace()
  • wiedzieć że metody stringów nie zmieniają oryginału
  • łączyć metody w łańcuch: tekst.strip().lower()
🧠 Sprawdź wiedzę — 6.2
6.3

split / join / startswith / endswith

6.3 split / join / startswith / endswith
Wyobraź sobie nożyczki i klej. split() to nożyczki — tnie zdanie na listę słów. join() to klej — skleja listę słów z powrotem w jedno zdanie. startswith i endswith to linijka sprawdzająca czy napis zaczyna lub kończy się konkretnym fragmentem.
.split(sep) dzieli string po separatorze i zwraca listę. Bez argumentu dzieli po białych znakach. sep.join(lista) skleja elementy listy, wstawiając sep między każdą parę. .startswith() i .endswith() zwracają True lub False — przydatne do walidacji i parsowania komend.
zdanie = "idz na polnoc szybko"
slowa = zdanie.split()
print(slowa)          # ['idz', 'na', 'polnoc', 'szybko']
print(slowa[0])       # idz — pierwsza część komendy
print(len(slowa))     # 4

polaczone = " | ".join(slowa)
print(polaczone)      # idz | na | polnoc | szybko

komenda = "atak goblin"
print(komenda.startswith("atak"))   # True
print(komenda.endswith(".py"))      # False
> python cwiczenie_m06_3.py
['idz', 'na', 'polnoc', 'szybko']
idz
4
idz | na | polnoc | szybko
True
False
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj od użytkownika listę zakupów jako jedno zdanie oddzielone przecinkami (np. jablko,chleb,mleko). Użyj split(",") i wypisz każdy element w osobnej linii. Oczekiwany wynik: jablko, chleb, mleko — każde w nowej linii.
  2. Wczytaj komendę od użytkownika. Sprawdź czy zaczyna się od "idz" i jeśli tak, wypisz kierunek (drugie słowo po split). Wejście: idz polnoc. Oczekiwany wynik: Idziesz w kierunku: polnoc.
✔️ Po tej sekcji powinieneś umieć:
  • podzielić string na listę słów przez .split()
  • skleić listę w string przez sep.join(lista)
  • sprawdzić początek/koniec stringu przez startswith / endswith
🧠 Sprawdź wiedzę — 6.3
6.4

f-stringi zaawansowane

6.4 f-stringi zaawansowane
Wyobraź sobie paragon ze sklepu — każda cena ma dwa miejsca po przecinku, nazwy produktów są wyrównane do lewej, kwoty do prawej. f-stringi w Pythonie pozwalają Ci zbudować taki precyzyjny układ jedną linią kodu.
W f-stringu po zmiennej możesz podać format specyfikator po dwukropku. Najważniejsze: {wartosc:.2f} — dwie cyfry po przecinku, {wartosc:>10} — wyrównanie do prawej na 10 znakach, {wartosc:<10} — do lewej. Używasz tego do tabelek, paragonów i pasków postępu.
cena = 9.5
ilosc = 3
suma = cena * ilosc

print(f"Cena jednostkowa: {cena:.2f} zl")
print(f"Suma:             {suma:.2f} zl")

# Wyrównanie w kolumnach
produkty = [("Chleb", 3.5), ("Mleko", 2.8), ("Maslo", 6.99)]
for nazwa, kwota in produkty:
    print(f"{nazwa:<10} {kwota:>6.2f} zl")
> python cwiczenie_m06_4.py
Cena jednostkowa: 9.50 zl
Suma: 28.50 zl
Chleb 3.50 zl
Mleko 2.80 zl
Maslo 6.99 zl
# Pasek postepu (HP, ladowanie)
hp = 65
hp_max = 100
pelne = int(hp / hp_max * 20)
puste = 20 - pelne
pasek = "█" * pelne + "░" * puste
print(f"HP: [{pasek}] {hp}/{hp_max}")
> python cwiczenie_m06_4.py
HP: [█████████████░░░░░░░] 65/100
✏️ Zadania do samodzielnego napisania:
  1. Napisz program który wczyta trzy produkty i ich ceny (input()), a następnie wypisze paragon: kolumna nazwy (15 znaków, lewostronnie :<15), kolumna ceny (8 znaków, prawostronnie, 2 miejsca po przecinku). Oczekiwany format: Chleb     3.50 zl.
  2. Napisz pasek progresu dla HP = 40, HP_MAX = 100. Pasek ma 20 znaków, pełne = , puste = . Oczekiwany wynik: HP: [████████░░░░░░░░░░░░] 40/100.
✔️ Po tej sekcji powinieneś umieć:
  • formatować liczby zmiennoprzecinkowe przez :.2f
  • wyrównywać tekst w kolumnach przez :<N i :>N
  • budować pasek postępu z powtarzaniem znaku
🧠 Sprawdź wiedzę — 6.4
6.5

Szukanie w stringu: in / find / count

6.5 Szukanie w stringu: in / find / count
Wyobraź sobie Ctrl+F w edytorze tekstu: in mówi „znaleziono/nie znaleziono", find() pokazuje na której pozycji jest pierwsze wystąpienie, a count() liczy ile razy słowo pojawia się w tekście.
fragment in tekst zwraca True lub False — najprostszy sposób sprawdzenia czy coś jest w stringu. .find(fragment) zwraca indeks pierwszego wystąpienia lub -1 gdy nie znalazł. .count(fragment) zlicza ile razy fragment pojawia się w tekście.
tekst = "spam jajka spam spam bekon"

print("spam" in tekst)          # True
print("ziemniaki" in tekst)     # False

print(tekst.find("jajka"))      # 5 — indeks pierwszego znaku
print(tekst.find("ziemniaki"))  # -1 — nie znaleziono

print(tekst.count("spam"))      # 3
> python cwiczenie_m06_5.py
True
False
5
-1
3
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj od użytkownika zdanie i słowo do wyszukania. Wypisz: czy słowo jest w zdaniu (True/False), na jakiej pozycji jest pierwsze wystąpienie (lub -1) i ile razy pojawia się w zdaniu. Wejście: zdanie ala ma kota a kot ma ale, szukane: al. Oczekiwany wynik: True, 0, 2.
  2. Wczytaj komendę tekstową od użytkownika. Sprawdź czy zawiera słowo "atak". Jeśli tak — wypisz Atak wykonany!, jeśli nie — Nieznana komenda.
✔️ Po tej sekcji powinieneś umieć:
  • sprawdzić czy fragment jest w stringu przez in
  • znaleźć pozycję pierwszego wystąpienia przez .find()
  • policzyć wystąpienia przez .count()
🧠 Sprawdź wiedzę — 6.5
6.6

String jako sekwencja — pętla for

6.6 String jako sekwencja — pętla for
Wyobraź sobie że czytasz słowo litera po literze na głos — to właśnie robi pętla for po stringu. Możesz przy okazji liczyć, filtrować albo zmieniać każdą literę osobno.
String jest sekwencją, tak jak lista — możesz iterować po nim pętlą for. Każda iteracja daje jedną literę. To pozwala na zliczanie liter, filtrowanie znaków czy budowanie nowych stringów na podstawie warunków.
slowo = "programowanie"

for litera in slowo:
    print(litera, end=" ")
print()    # nowa linia na końcu

# Policz samogloski
samogloski = "aeiouyąęó"
liczba = 0
for litera in slowo:
    if litera in samogloski:
        liczba += 1
print("Samoglosek:", liczba)
> python cwiczenie_m06_6.py
p r o g r a m o w a n i e
Samoglosek: 6
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj słowo od użytkownika. Użyj pętli for i policz ile razy pojawia się litera a (małe i wielkie — użyj .lower()). Wejście: Abrakadabra. Oczekiwany wynik: Litera 'a' pojawia sie 5 razy.
  2. Wczytaj słowo od użytkownika. Użyj pętli for i zbuduj nowy string zawierający tylko spółgłoski (wyrzuć samogłoski: a e i o u y ą ę ó). Wejście: python. Oczekiwany wynik: pythn.
✔️ Po tej sekcji powinieneś umieć:
  • iterować po stringu pętlą for litera in tekst
  • zliczać i filtrować znaki podczas iteracji
  • budować nowy string w pętli przez konkatenację
🧠 Sprawdź wiedzę — 6.6
6.7

Wieloliniowe stringi i escape sequences

6.7 Wieloliniowe stringi i escape sequences
Wyobraź sobie kartkę z instrukcją obsługi — wiele linii tekstu, a niektóre symbole mają specjalne znaczenie (strzałka → kierunek, tabulacja → wcięcie). Escape sequences to właśnie takie specjalne symbole w stringach: \n to nowa linia, \t to tabulator.
Wieloliniowy string piszesz między potrójnymi cudzysłowami """...""". Możesz w nim używać normalnych enterów bez \n. Escape sequences to kombinacje ze znakiem backslash: \n — nowa linia, \t — tabulator, \\ — dosłowny backslash, \' i \" — cudzysłów wewnątrz stringu.
komunikat = """Wyniki rundy:
  Gracz 1: 120 pkt
  Gracz 2:  95 pkt
  Gracz 3: 140 pkt"""
print(komunikat)

# Escape sequences
print("Linia 1\nLinia 2\nLinia 3")
print("Imie:\tAldric")
print("Sciezka: C:\\Games\\Python")
> python cwiczenie_m06_7.py
Wyniki rundy:
  Gracz 1: 120 pkt
  Gracz 2:  95 pkt
  Gracz 3: 140 pkt
Linia 1
Linia 2
Linia 3
Imie:   Aldric
Sciezka: C:\Games\Python
✏️ Zadania do samodzielnego napisania:
  1. Napisz program który wypisuje menu gry tekstowej używając wieloliniowego stringu """...""". Menu ma zawierać co najmniej 4 opcje (Nowa Gra, Wczytaj, Ustawienia, Wyjście), każda w osobnej linii, z numerem na początku.
  2. Napisz string zawierający ścieżkę pliku Windows (C:\Users\Gracz\save.dat) i wypisz go poprawnie (użyj \\ lub surowego stringa r"..."). Oczekiwany wynik: dosłowne backslashe na ekranie.
✔️ Po tej sekcji powinieneś umieć:
  • pisać wieloliniowe stringi przez """..."""
  • używać \n, \t, \\ w stringach
  • wiedzieć kiedy użyć surowego stringa r"..."
🧠 Sprawdź wiedzę — 6.7
6.8

Walidacja: isdigit / isalpha / isupper / islower

6.8 Walidacja: isdigit / isalpha / isupper / islower
Wyobraź sobie bramkarza przy wejściu do klubu — sprawdza czy masz dowód, czy masz odpowiedni wiek, czy jesteś na liście. Metody walidacji stringów to taki bramkarz dla Twoich danych: sprawdzają czy tekst spełnia konkretne warunki zanim go przetworzysz.
Metody sprawdzające zwracają True lub False i działają na całym stringu: .isdigit() — czy same cyfry, .isalpha() — czy same litery, .isupper() — czy wszystkie wielkie, .islower() — czy wszystkie małe, .isspace() — czy same spacje. Przydają się do walidacji danych wejściowych od użytkownika.
wiek = input("Podaj wiek: ")
if wiek.isdigit():
    wiek = int(wiek)
    print("Wiek:", wiek)
else:
    print("Wiek musi byc liczba!")

nick = input("Podaj nick (tylko litery): ")
if nick.isalpha():
    print("Nick OK:", nick)
else:
    print("Nick moze zawierac tylko litery!")
> python cwiczenie_m06_8.py
Podaj wiek: 25
Wiek: 25
Podaj nick (tylko litery): Aldric
Nick OK: Aldric
isdigit() nie obsługuje liczb ujemnych ani zmiennoprzecinkowych.
"-5".isdigit()False (myślnik to nie cyfra)
"3.14".isdigit()False (kropka to nie cyfra)
Do walidacji liczb zmiennoprzecinkowych użyj try/except float().
✏️ Zadania do samodzielnego napisania:
  1. Napisz program który wczyta kod PIN. Sprawdź czy: ma dokładnie 4 znaki (len()) i czy są to same cyfry (isdigit()). Jeśli oba warunki spełnione — wypisz PIN poprawny, w przeciwnym razie — Bledny PIN.
  2. Wczytaj hasło od użytkownika. Sprawdź i wypisz czy hasło: zawiera wielką literę (not haslo.islower()) i ma co najmniej 8 znaków (len()). Wypisz każdy warunek osobno jako True/False.
✔️ Po tej sekcji powinieneś umieć:
  • walidować dane wejściowe przez .isdigit() i .isalpha()
  • sprawdzać wielkość liter przez .isupper() i .islower()
  • wiedzieć że isdigit() nie działa dla liczb ujemnych ani float
🧠 Sprawdź wiedzę — 6.8
M06

Stringi — Podsumowanie

✔️ Co umiasz po tym module:
  • kroić string przez indeksy i slicing [start:stop], [::-1]
  • używać metod .upper(), .lower(), .strip(), .replace()
  • dzielić string na słowa przez .split() i sklejać przez sep.join()
  • formatować liczby i wyrównywać kolumny przez f-stringi (:.2f, :<N, :>N)
  • szukać w stringu przez in, .find(), .count()
  • iterować po stringu pętlą for litera in tekst
  • pisać wieloliniowe stringi """...""" i używać escape sequences
  • walidować wejście przez .isdigit(), .isalpha(), .isupper()
🎯 Brawo! Opanowałeś stringi — od krojenia po walidację. Teraz budujesz prawdziwy interfejs tekstowy!
🏗️ Projekt końcowy — „Parser komend tekstowych"

Napisz program — prostą grę tekstową z systemem komend. Gracz wpisuje komendy takie jak idz polnoc, atak goblin czy stan, a program je interpretuje i odpowiada.

  1. Krok 1: Wypisz dostępne komendy używając wieloliniowego stringu """...""".
  2. Krok 2: W pętli while True wczytaj komendę, użyj .strip().lower().
  3. Krok 3: Użyj .split() żeby wydzielić akcję (słowo[0]) i cel (słowo[1] jeśli istnieje).
  4. Krok 4: Obsłuż komendy: idz (z kierunkiem), atak (z nazwą wroga), stan (wypisz HP i lokację), koniec.
  5. Krok 5: Dla komendy atak wypisz informację z f-stringiem: f"Atakujesz {cel}! Zadajesz 15 obrazen."
Wymagania:
  • Program działa w pętli aż użytkownik wpisze koniec
  • Komendy są czytane bez względu na wielkość liter (użyj .lower())
  • Dla nieznanych komend wypisz Nie rozumiem: [komenda]
  • Komenda stan wypisuje imię gracza, HP i aktualną lokację (przechowaj je w zmiennych)
  • Komenda idz sprawdza czy kierunek to jedno z: polnoc / poludnie / wschod / zachod — jeśli nie, wypisz błąd
📝 Test końcowy — Moduł 06
Sprawdź całą wiedzę z modułu o stringach. Odpowiedz na wszystkie pytania, potem sprawdź wynik.
M07

Słowniki — Dane z nazwą

Nauczysz się przechowywać dane z etykietami — jak kartoteka z szufladami. Po tym module zbudujesz sklep RPG zarządzany przez słowniki.
Lista świetnie sprawdza się gdy masz wiele podobnych rzeczy (np. 100 wyników). Ale co gdy chcesz przechować dane postaci — imię, HP, manę, atak — i odwoływać się do nich po nazwie? Tu wkraczają słowniki: struktury klucz → wartość, gdzie do każdej wartości odwołujesz się przez unikalną nazwę (klucz).
⌨️ Krok 0 — Przygotuj plik
Przygotowanie
1
Otwórz VS Code i utwórz plik: cwiczenie_m07_1.py
2
Na początku każdego pod-rozdziału twórz kolejny plik: cwiczenie_m07_2.py itd.
7.1

Tworzenie i dostęp — {}, dict[key], get()

7.1 Tworzenie i dostęp — {}, dict[key], get()
Wyobraź sobie książkę telefoniczną: szukasz po nazwisku (klucz) i dostajesz numer (wartość). Słownik w Pythonie działa tak samo — podajesz klucz, dostajesz wartość. Nie potrzebujesz wiedzieć na której pozycji ona leży.
Słownik tworzymy nawiasami klamrowymi: {"klucz": wartosc}. Dostęp przez slownik["klucz"]. Jeśli klucz nie istnieje — dostaniesz KeyError. Bezpieczniejsza wersja: slownik.get("klucz") zwraca None gdy klucz nie istnieje, albo slownik.get("klucz", domyslna) zwraca wartość domyślną.
gracz = {
    "imie":   "Aldric",
    "hp":     100,
    "mana":   50,
    "poziom": 1
}

print(gracz["imie"])          # Aldric
print(gracz["hp"])            # 100
print(gracz.get("xp"))        # None
print(gracz.get("xp", 0))     # 0
> python cwiczenie_m07_1.py
Aldric
100
None
0
KeyError: 'xp'
gracz["xp"] gdy klucz "xp" nie istnieje w słowniku — Python rzuca błąd.
Rozwiązanie: użyj gracz.get("xp", 0) — zwróci 0 jeśli nie ma klucza, bez błędu.
✏️ Zadania do samodzielnego napisania:
  1. Stwórz słownik opisujący Twoje ulubione danie: klucze "nazwa", "kalorie", "czas_przygotowania" (minuty), "ocena" (1–5). Wypisz każdą wartość z opisem. Oczekiwany format: Danie: Pizza | Kalorie: 800 | Czas: 30 min | Ocena: 5/5.
  2. Odczytaj z tego słownika klucze "cena" i "skladniki" (których nie ma) używając .get() z wartościami domyślnymi 0 i "brak". Program nie może rzucić KeyError.
✔️ Po tej sekcji powinieneś umieć:
  • tworzyć słownik literałem {}
  • odczytywać wartości przez dict["klucz"]
  • używać .get(klucz, domyslna) zamiast ryzykować KeyError
🧠 Sprawdź wiedzę — 7.1
7.2

Modyfikacja: dodawanie, usuwanie, update

7.2 Modyfikacja: dodawanie, usuwanie, update
Wyobraź sobie notatnik z karteczkami — możesz dokleić nową karteczkę z nową informacją, zamazać starą, albo wkleić całą stronę z aktualizacjami. Słownik Python robi dokładnie to.
Dodanie lub zmiana wartości: slownik["klucz"] = nowa — jeśli klucz istnieje, nadpisuje; jeśli nie — tworzy. Usunięcie: del slownik["klucz"] albo slownik.pop("klucz") (pop zwraca usuniętą wartość). Scalenie dwóch słowników: slownik.update(inny_slownik).
gracz = {"imie": "Aldric", "hp": 100, "poziom": 1}

gracz["hp"] -= 20         # zmiana istniejącego
print(gracz["hp"])         # 80

gracz["xp"] = 50           # dodanie nowego klucza
print(gracz["xp"])         # 50

del gracz["xp"]            # usunięcie klucza

bonusy = {"atak": 15, "obrona": 8}
gracz.update(bonusy)       # scalenie
print(gracz)
> python cwiczenie_m07_2.py
80
50
{'imie': 'Aldric', 'hp': 80, 'poziom': 1, 'atak': 15, 'obrona': 8}
✏️ Zadania do samodzielnego napisania:
  1. Stwórz słownik postac z kluczami "imie", "hp", "poziom". Zasymuluj walkę: odejmij 25 HP, dodaj klucz "xp" = 30, usuń klucz "poziom", dodaj "gold" = 10. Wypisz słownik po każdej operacji.
  2. Masz dwa słowniki: bazowe = {"hp": 100, "mana": 50} i zbroja = {"obrona": 15, "hp": 120}. Użyj .update() żeby scalić je w słownik gracz. Wypisz finalne HP — sprawdź czy zostało nadpisane.
✔️ Po tej sekcji powinieneś umieć:
  • dodawać i zmieniać klucze przez dict["klucz"] = wartość
  • usuwać klucze przez del lub .pop()
  • scalać słowniki przez .update()
🧠 Sprawdź wiedzę — 7.2
7.3

Iterowanie: keys / values / items

7.3 Iterowanie: keys / values / items
Wyobraź sobie przeglądanie segregatora — możesz wyciągnąć tylko listę zakładek (klucze), tylko zawartość kieszeni (wartości), albo przejrzeć zakładkę razem z zawartością (pary klucz-wartość). Python daje Ci dokładnie te trzy tryby.
Trzy sposoby iteracji: for k in slownik.keys() — po kluczach, for v in slownik.values() — po wartościach, for k, v in slownik.items() — po parach (najczęściej używane). Sprawdzenie czy klucz istnieje: k in slownik.
statystyki = {
    "hp":     80,
    "mana":   45,
    "atak":   20,
    "obrona": 12
}

for cecha in statystyki.keys():
    print(cecha)

print("---")
for cecha, wartosc in statystyki.items():
    print(f"  {cecha:8}: {wartosc}")
> python cwiczenie_m07_3.py
hp
mana
atak
obrona
---
  hp      : 80
  mana    : 45
  atak    : 20
  obrona  : 12
✏️ Zadania do samodzielnego napisania:
  1. Stwórz słownik oceny z 5 przedmiotami szkolnymi jako kluczami i ocenami (1–6) jako wartościami. Użyj .items() żeby wypisać każdy przedmiot z oceną. Na końcu wypisz średnią (zsumuj .values(), podziel przez len()).
  2. Masz słownik cennik = {"pizza": 25, "burger": 18, "sushi": 45, "kebab": 15}. Wypisz tylko produkty które kosztują mniej niż 20 zł. Oczekiwany wynik: burger, kebab.
✔️ Po tej sekcji powinieneś umieć:
  • iterować po kluczach, wartościach i parach przez .keys(), .values(), .items()
  • sprawdzić czy klucz istnieje przez k in slownik
  • filtrować wpisy słownika w pętli
🧠 Sprawdź wiedzę — 7.3
7.4

Zagnieżdżone słowniki

7.4 Zagnieżdżone słowniki
Wyobraź sobie szafkę z szufladami, a w każdej szufladzie kolejna mniejsza szafka z szufladami. Zagnieżdżone słowniki to słowniki w środku słowników: masz bazę wrogów, a każdy wróg to oddzielny słownik ze swoimi statystykami.
Wartością w słowniku może być inny słownik. Dostęp: slownik["klucz1"]["klucz2"]. Typowy wzorzec to baza danych jako słownik słowników — zewnętrzny klucz to ID lub nazwa, wewnętrzny słownik to właściwości.
wrogowie = {
    "goblin": {"hp": 20,  "dmg": 5,  "xp": 10},
    "ork":    {"hp": 50,  "dmg": 12, "xp": 25},
    "troll":  {"hp": 100, "dmg": 20, "xp": 60}
}

print(wrogowie["goblin"]["hp"])   # 20
print(wrogowie["ork"]["dmg"])     # 12

for nazwa, stats in wrogowie.items():
    print(f"{nazwa:8} HP:{stats['hp']:4} DMG:{stats['dmg']:3}")
> python cwiczenie_m07_4.py
20
12
goblin HP: 20 DMG: 5
ork HP: 50 DMG: 12
troll HP: 100 DMG: 20
KeyError przy zagnieżdżonym dostępie:
wrogowie["smok"]["hp"] — jeśli "smok" nie istnieje, błąd pojawia się już na pierwszym kluczu.
Bezpiecznie: wrogowie.get("smok", {}).get("hp", 0) — dwa .get() z wartościami domyślnymi.
✏️ Zadania do samodzielnego napisania:
  1. Stwórz słownik ksiazki z 3 tytułami jako kluczami. Każda książka to słownik z kluczami "autor", "rok", "ocena". Wypisz tabelkę: tytuł, autor, rok, ocena dla każdej książki.
  2. Do słownika wrogowie z przykładu dodaj nowego wroga "smok" z hp=500, dmg=80, xp=300. Następnie odejmij 30 hp od goblina. Wypisz końcowe HP goblina i HP smoka.
✔️ Po tej sekcji powinieneś umieć:
  • tworzyć słowniki zagnieżdżone (słownik słowników)
  • odczytywać wartości przez podwójny nawias dict["k1"]["k2"]
  • iterować po zagnieżdżonych danych w pętli
🧠 Sprawdź wiedzę — 7.4
7.5

Słownik vs lista — kiedy co

7.5 Słownik vs lista — kiedy co
Wyobraź sobie dwa sklepy: jeden z numerowanymi półkami — podajesz numer, dostajesz towar (lista). Drugi ma szuflady z etykietami — podajesz nazwę, dostajesz towar (słownik). Który lepszy? Zależy czego szukasz.
Używaj listy gdy: kolejność ma znaczenie, przetwarzasz wiele podobnych elementów, potrzebujesz sort/reverse. Używaj słownika gdy: masz dane z nazwami (imię, hp, atak), potrzebujesz szybkiego dostępu po kluczu, chcesz unikać błędów indeksowania. Sprawdzenie klucz in slownik jest szybsze niż szukanie w liście.
# LISTA — wyniki w kolejności
wyniki = [120, 95, 140, 88]
wyniki.sort(reverse=True)
print("1 miejsce:", wyniki[0])     # 140

# SŁOWNIK — dane z etykietami
gracz = {"imie": "Aldric", "hp": 80, "poziom": 3}
print(gracz["imie"], "- poziom", gracz["poziom"])

# Tworzenie słownika z dwóch list
miasta = ["Warszawa", "Krakow", "Gdansk"]
temp   = [22, 18, 20]
pogoda = dict(zip(miasta, temp))
print(pogoda["Krakow"])            # 18
> python cwiczenie_m07_5.py
1 miejsce: 140
Aldric - poziom 3
18
✏️ Zadania do samodzielnego napisania:
  1. Zapisz oceny 5 uczniów najpierw jako listę list ([["Ania", 5], ...]), potem jako słownik ({"Ania": 5, ...}). Wypisz ocenę ucznia "Bartek" z obu struktur. Która wersja jest czytelniejsza?
  2. Masz listę produktów i cen: produkty = ["pizza", "kebab", "sushi"], ceny = [25, 15, 45]. Stwórz słownik cennik = dict(zip(produkty, ceny)). Wypisz cenę pizzy i najtańszy produkt.
✔️ Po tej sekcji powinieneś umieć:
  • rozróżniać kiedy użyć listy a kiedy słownika
  • wiedzieć że klucz in slownik jest szybsze niż szukanie w liście
  • konwertować dwie listy do słownika przez dict(zip())
🧠 Sprawdź wiedzę — 7.5
7.6

Zliczanie — słownik jako licznik

7.6 Zliczanie — słownik jako licznik
Wyobraź sobie keliera w kawiarni który zaznacza na tablicy ile razy ktoś zamówił każde danie: przy pierwszym zamówieniu pisze „1", przy każdym następnym dodaje kreskę. Słownik jako licznik działa tak samo — klucz to danie, wartość to liczba zamówień.
Standardowy wzorzec licznika: licznik[element] = licznik.get(element, 0) + 1. Sprawdza czy klucz istnieje (jeśli nie — zwraca 0), a następnie dodaje 1 i przypisuje. Używasz tego do zliczania liter, słów, wyborów — wszędzie tam gdzie chcesz wiedzieć „ile razy".
tekst = "abrakadabra"
licznik = {}

for litera in tekst:
    licznik[litera] = licznik.get(litera, 0) + 1

print(licznik)

# Posortuj od najczestszej
posortowane = sorted(licznik.items(),
                     key=lambda x: x[1],
                     reverse=True)
for litera, ile in posortowane:
    print(f"  '{litera}': {ile}")
> python cwiczenie_m07_6.py
{'a': 5, 'b': 2, 'r': 2, 'k': 1, 'd': 1}
  'a': 5
  'b': 2
  'r': 2
  'k': 1
  'd': 1
✏️ Zadania do samodzielnego napisania:
  1. Wczytaj od użytkownika zdanie. Policz ile razy każde słowo pojawia się w zdaniu (użyj .split() i słownika licznika). Wypisz wszystkie słowa z liczbą wystąpień. Wejście: ala ma kota a kot ma ale. Oczekiwany wynik: każde słowo z liczbą.
  2. Napisz program który pyta użytkownika o ulubiony kolor 5 razy. Użyj słownika licznika żeby zliczyć głosy. Na końcu wypisz wyniki i zwycięski kolor.
✔️ Po tej sekcji powinieneś umieć:
  • budować licznik słownikowy wzorcem d.get(k, 0) + 1
  • zliczać litery, słowa lub dowolne elementy
  • sortować słownik po wartościach przez sorted(d.items(), key=...)
🧠 Sprawdź wiedzę — 7.6
7.7

Domyślne wartości: get() i setdefault()

7.7 Domyślne wartości: get() i setdefault()
Wyobraź sobie formularz rejestracyjny z polami opcjonalnymi — jeśli nie wypełnisz pola „telefon", system wpisuje tam „brak". get() czyta z wartością domyślną bez zapisywania. setdefault() czyta I zapisuje wartość domyślną gdy klucza nie ma.
d.get(klucz, domyslna) — zwraca wartość lub domyślną, nie zmienia słownika.
d.setdefault(klucz, domyslna) — jeśli klucz istnieje: zwraca jego wartość; jeśli nie istnieje: wstawia klucz z wartością domyślną i ją zwraca. Przydatne gdy budujesz słownik stopniowo.
gracz = {"imie": "Aldric", "hp": 100}

print(gracz.get("xp", 0))    # 0 — nie ma klucza
print(gracz)                  # "xp" nadal nie ma!

gracz.setdefault("xp", 0)     # dodaje "xp" = 0
gracz.setdefault("hp", 999)   # "hp" juz jest — nie zmienia
print(gracz["xp"])            # 0
print(gracz["hp"])            # 100 (nie nadpisane)
> python cwiczenie_m07_7.py
0
{'imie': 'Aldric', 'hp': 100}
0
100
✏️ Zadania do samodzielnego napisania:
  1. Masz słownik konfiguracja = {"tryb": "pelny"}. Użyj setdefault() żeby ustawić domyślne wartości dla brakujących kluczy: "glosnosc" → 50, "rozdzielczosc" → "1920x1080", "tryb" → "okno". Wypisz cały słownik — sprawdź który klucz NIE został nadpisany.
  2. Masz listę par (uczen, klasa): [("Ania","3A"), ("Bartek","2B"), ("Celina","3A"), ("Damian","2B")]. Użyj setdefault(klasa, []) i .append() żeby zgrupować uczniów według klasy. Oczekiwany wynik: {"3A": ["Ania","Celina"], "2B": ["Bartek","Damian"]}.
✔️ Po tej sekcji powinieneś umieć:
  • rozróżniać get() (nie zmienia) od setdefault() (zapisuje jeśli brak)
  • używać setdefault() do budowania słownika grupującego
🧠 Sprawdź wiedzę — 7.7
7.8

Dict comprehension

7.8 Dict comprehension
Wyobraź sobie fabrykę: wchodzi lista surowców, wychodzi lista gotowych produktów — w jednym zdaniu opisujesz całą linię produkcyjną. Dict comprehension to właśnie taki jeden-liniowy przepis na budowanie słownika.
Dict comprehension: {klucz: wartosc for element in iterable}. Możesz dodać filtr: {k: v for k, v in d.items() if v > 10}. To skrócona forma pętli for tworzącej słownik. Czytelny dla prostych transformacji — przy złożonej logice zostań przy zwykłej pętli.
ceny = {"pizza": 25, "burger": 18, "sushi": 45, "kebab": 15}

# Podwoj wszystkie ceny
drogie = {p: c * 2 for p, c in ceny.items()}
print(drogie)

# Filtruj — tylko produkty do 20 zl
tanie = {p: c for p, c in ceny.items() if c <= 20}
print(tanie)

# Z listy zrob slownik: slowo → dlugosc
slowa = ["python", "gra", "kod", "programowanie"]
dlugosci = {s: len(s) for s in slowa}
print(dlugosci)
> python cwiczenie_m07_8.py
{'pizza': 50, 'burger': 36, 'sushi': 90, 'kebab': 30}
{'burger': 18, 'kebab': 15}
{'python': 6, 'gra': 3, 'kod': 3, 'programowanie': 13}
✏️ Zadania do samodzielnego napisania:
  1. Masz słownik oceny = {"Ania": 5, "Bartek": 3, "Celina": 6, "Damian": 2}. Używając dict comprehension stwórz nowy słownik zawierający tylko uczniów z oceną 4 lub wyższą. Oczekiwany wynik: {"Ania": 5, "Celina": 6}.
  2. Masz listę liczb [1, 2, 3, 4, 5]. Użyj dict comprehension żeby stworzyć słownik {liczba: liczba**2}. Oczekiwany wynik: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}.
✔️ Po tej sekcji powinieneś umieć:
  • pisać dict comprehension {k: v for ...}
  • filtrować słownik przez if w comprehension
  • wiedzieć kiedy comprehension jest czytelniejsze od pętli
🧠 Sprawdź wiedzę — 7.8
M07

Słowniki — Podsumowanie

✔️ Co umiasz po tym module:
  • tworzyć słowniki literałem {} i odczytywać wartości przez dict["klucz"]
  • używać .get(klucz, domyslna) zamiast ryzykować KeyError
  • dodawać, zmieniać i usuwać klucze (del, .pop(), .update())
  • iterować przez .keys(), .values(), .items()
  • tworzyć słowniki zagnieżdżone i odczytywać przez dict["k1"]["k2"]
  • wiedzieć kiedy użyć słownika a kiedy listy
  • budować licznik słownikowy wzorcem d.get(k, 0) + 1
  • używać setdefault() do bezpiecznego tworzenia kluczy
  • pisać dict comprehension {k: v for ...}
🎯 Brawo! Opanowałeś słowniki — teraz budujesz ekwipunek, bestiariusz i sklepy jak profesjonalny gamedev!
🏗️ Projekt końcowy — „Sklep RPG"

Napisz program — sklep RPG gdzie gracz może przeglądać asortyment, kupować i sprzedawać przedmioty. Cały sklep i ekwipunek gracza zarządzany jest przez słowniki.

  1. Krok 1: Stwórz słownik sklep z co najmniej 5 przedmiotami — każdy to zagnieżdżony słownik z kluczami "cena" i "opis".
  2. Krok 2: Stwórz słownik gracz z kluczami "imie", "zloto" = 100, "ekwipunek" = pusty słownik (przedmiot → ilość).
  3. Krok 3: Napisz funkcję wyswietl_sklep(sklep, gracz) — tabelka z cenami i stanem portfela gracza.
  4. Krok 4: Napisz funkcję kup(gracz, sklep, przedmiot) — sprawdza złoto, odejmuje cenę, dodaje do ekwipunku licznikiem (.get() + 1).
  5. Krok 5: Napisz funkcję sprzedaj(gracz, sklep, przedmiot) — sprawdza czy gracz ma przedmiot, dodaje 50% ceny do złota, odejmuje z ekwipunku.
  6. Krok 6: Pętla główna z menu: kup / sprzedaj / stan / wyjdz.
Wymagania:
  • Sklep jako słownik zagnieżdżony (sekcja 7.4)
  • Ekwipunek gracza jako słownik licznik — klucz = przedmiot, wartość = ilość (sekcja 7.6)
  • Obsługa brakujących kluczy przez get() lub setdefault() (sekcja 7.7)
  • Przy zakupie sprawdź czy gracz ma wystarczająco złota — jeśli nie, wypisz ile brakuje
  • Przy sprzedaży sprawdź czy gracz posiada przedmiot (klucz w ekwipunku, wartość > 0)
  • Wypisz stan ekwipunku i złota po każdej transakcji
📝 Test końcowy — Moduł 07
Sprawdź całą wiedzę z modułu o słownikach. Odpowiedz na wszystkie pytania, potem sprawdź wynik.