Porządek w większym kodzie
🎯 Po co Ci to?
Programy z tego działu miały po 10–20 linijek. Projekt maturalny może mieć 200, aplikacja studencka 2000, a system, w którym kiedyś będziesz pracować — 2 000 000. Przy takiej skali problemem przestaje być „czy umiem napisać pętlę", a staje się: jak nie utonąć. Na to pytanie informatyka wypracowała trzy odpowiedzi — narzędzia (środowiska programistyczne), styl (programowanie strukturalne) i architekturę (programowanie obiektowe) — oraz jedną supermoc: nie pisać tego, co już napisali inni (biblioteki). Zakres rozszerzony wymaga świadomego używania całej czwórki.
✅ Czego się nauczysz
Po tej jednostce potrafisz:
- wykorzystywać możliwości zintegrowanego środowiska (IDE), z debuggerem na czele;
- wyjaśnić zasady programowania strukturalnego i stosować je w swoich programach;
- opisać ideę programowania obiektowego (klasa, obiekt, metoda) i przeczytać prosty kod obiektowy;
- korzystać z bibliotek przez
import— standardowych i zewnętrznych.
📘 Wyjaśnienie
IDE — warsztat z prawdziwego zdarzenia. Zintegrowane środowisko programistyczne (IDE) to edytor, interpreter i narzędzia diagnostyczne w jednym. Trzy funkcje zmieniają życie. Podświetlanie i podpowiadanie: literówki widać, zanim uruchomisz, a lista dostępnych funkcji wyskakuje w trakcie pisania. Debugger: to, co robiłeś wstawkami print (3.6), tylko cywilizowanie — ustawiasz punkt wstrzymania (breakpoint) na wybranej linijce, program zatrzymuje się tam, a Ty oglądasz wartości wszystkich zmiennych i wykonujesz kod krok po kroku. Tabelka śledzenia z działu 1 okazuje się być zawodowym narzędziem — tyle że maszyna prowadzi ją za Ciebie. Praca z projektem: wiele plików, szukanie po całości, zmiana nazwy funkcji wszędzie naraz. Którego IDE użyć? Dowolnego — różnią się skrótami, nie ideami.
Programowanie strukturalne — styl, który ratuje życie. Stare programy pisało się jak leci, ze skokami „idź do linii 340" — po kilku latach nikt, z autorem włącznie, nie wiedział, co się dzieje (mówiło się: kod-spaghetti). Programowanie strukturalne to umowa: program budujemy wyłącznie z trzech klocków — sekwencji (po kolei), wyboru (if/elif/else) i pętli (for/while) — zagnieżdżanych w sobie, pakowanych w funkcje, bez dzikich skoków. Brzmi znajomo? Tak — cały ten dział pisałeś strukturalnie, nie wiedząc o tym, jak Molierowski pan Jourdain mówił prozą. Rozszerzenie dokłada świadomość reguł: jedna funkcja — jedno zadanie; dane podawaj parametrami, wyniki zwracaj return (nie przez zmienne „wspólne dla wszystkich" — te tworzą niewidzialne sznurki między funkcjami); zagnieżdżenia płycej niż na 3–4 poziomy, bo głębiej nikt nie czyta ze zrozumieniem.
Programowanie obiektowe — dane i czynności w jednym pudełku. W programie strukturalnym dane (lista ocen) i funkcje na nich (srednia, dodaj_ocene) żyją osobno — przy dużych programach gubi się, co pasuje do czego. Pomysł obiektowy: sklej je. Klasa to projekt takiego pudełka; obiekt — konkretny egzemplarz zbudowany według projektu:
class Uczen:
def __init__(self, imie): # konstruktor: uruchamia się przy tworzeniu
self.imie = imie # dane obiektu (self = „ten konkretny uczeń")
self.oceny = []
def dodaj(self, ocena): # metoda: funkcja należąca do obiektu
self.oceny.append(ocena)
def srednia(self):
return sum(self.oceny) / len(self.oceny)
ala = Uczen("Ala") # dwa OBIEKTY tej samej KLASY
bartek = Uczen("Bartek")
ala.dodaj(5)
ala.dodaj(4)
bartek.dodaj(3)
print(ala.imie, ala.srednia()) # Ala 4.5 — każdy obiekt ma WŁASNE dane
Składnia ala.dodaj(5) czyta się: „Alu, dodaj sobie piątkę" — wywołujesz czynność na obiekcie, a on operuje na własnych danych. Używasz tego od dawna: oceny.append(5) to metoda obiektu-listy, "abc".upper() — metoda napisu. Obiektowość świeci przy programach, w których „mieszkańców" jest wielu i każdy nosi swój stan: uczniowie w dzienniku, postacie w grze, konta w banku. Dla trzydziestolinijkowego skryptu bywa armatą na muchę — dobór stylu do skali też jest umiejętnością.
Biblioteki — nie odkrywaj koła. Miliony programistów przed Tobą napisały i przetestowały kod na większość typowych potrzeb. Bierzesz go jednym słowem:
import math
import random
print(math.sqrt(2)) # 1.4142... — pierwiastek
print(math.log2(1024)) # 10.0 — znajomy z działu 2!
kostka = random.randint(1, 6) # losowa liczba całkowita 1-6
Biblioteka standardowa (dostarczana z Pythonem) ma moduły od matematyki, losowości, dat, plików; biblioteki zewnętrzne (instalowane osobno) — od wykresów po sztuczną inteligencję. Zawodowa zasada brzmi: zanim napiszesz — sprawdź, czy nie istnieje. W dziale 9 wykorzystasz gotowe implementacje struktur danych właśnie stąd. Uwaga na równowagę: na nauce algorytmów (działy 4–10) będziemy rzeczy pisać samodzielnie, żeby zrozumieć — a bibliotek używać tam, gdzie problemem jest co innego. Wiedzieć, kiedy które — to też rzemiosło.
🐞 Znajdź błąd
Fragment programu obiektowego:
class Licznik:
def __init__(self):
self.stan = 0
def zwieksz(self):
stan = stan + 1
a = Licznik()
a.zwieksz()
print(a.stan)
Program pada z błędem w metodzie zwieksz. Dlaczego — i jak naprawić?
Sprawdź odpowiedź
W metodzie napisano stan zamiast self.stan — Python szuka lokalnej zmiennej stan, której nie ma (a nawet gdyby przeszło, zmieniałby lokalną kopię, nie stan obiektu). Poprawnie: self.stan = self.stan + 1. Zgubione self to błąd numer jeden początkujących obiektowców; czytaj self.stan jako „mój stan".
⚠️ Uwaga, pułapka
Świeżo poznana obiektowość kusi, żeby wszystko na siłę pakować w klasy. Opieraj się: klasa ma sens, gdy istnieje naturalne „coś", co ma dane i zachowania (uczeń, konto, postać). Program liczący średnią z listy nie stanie się lepszy od opakowania w class KalkulatorSredniej — stanie się dłuższy. Styl dobiera się do problemu, nie do mody.
🛠️ Teraz Ty
W swoim IDE (jakimkolwiek) ustaw punkt wstrzymania wewnątrz pętli programu-zgadywanki z 3.3 i przejdź trzy obroty krok po kroku, obserwując zmienne — poczuj różnicę względem wstawek print. Potem przerób dziennik z 3.5 na wersję obiektową: klasa Uczen jak w 📘, program główny tworzy dwóch uczniów i porównuje ich średnie. Na deser: import random i wylosuj „ucznia tygodnia".
📐 Definicje tej lekcji
- IDE / debugger / punkt wstrzymania — zintegrowany warsztat; narzędzie wykonywania kodu krok po kroku; miejsce planowego zatrzymania.
- Programowanie strukturalne — budowanie wyłącznie z sekwencji, wyboru i pętli, w funkcjach, bez skoków.
- Klasa / obiekt / metoda /
self— projekt pudełka; egzemplarz; czynność obiektu; „ja" wewnątrz metody. - Biblioteka /
import— gotowy, przetestowany kod; sposób jego włączenia.
📌 Najważniejsze w pigułce
- Debugger to tabelka śledzenia prowadzona przez maszynę — naucz się go raz, korzystaj zawsze.
- Strukturalnie: trzy klocki, funkcje o jednym zadaniu, dane przez parametry i
return. - Obiektowo: dane + czynności razem, gdy program ma wielu „mieszkańców" ze stanem; biblioteki: najpierw sprawdź, potem pisz.
🎒 Zadania
- Zaprojektuj (sama definicja + dwa wywołania) klasę
KontoOszczednosciowez metodamiwplac(kwota),wyplac(kwota)(odmawia przy braku środków) isaldo(). Które dane muszą być wself, a które wystarczą jako parametry?
Wskazówka i odpowiedź
W self: stan konta (trwa między wywołaniami — to pamięć obiektu). Parametrami: kwoty operacji (jednorazowe). Szkielet: __init__ ustawia self.stan = 0; wplac dodaje; wyplac sprawdza kwota <= self.stan, w razie odmowy komunikat/False. Test na brzegach: wypłata dokładnie całego salda (ma przejść) i o grosz więcej (ma odmówić) — brzegi z działu 1 obowiązują także w obiektach.
- Program kolegi to jedna 80-linijkowa ściana kodu z trzema pętlami i pięcioma
if. Wypisz w punktach plan przebudowy strukturalnej — co po kolei zrobisz, żeby nie zepsuć działania?
Wskazówka i odpowiedź
(1) Najpierw testy „przed": zapisz kilka wejść i wyników obecnego programu — to sieć asekuracyjna. (2) Znajdź spójne kawałki (wczytywanie, liczenie, raport) i wydziel je w funkcje po jednej odpowiedzialności. (3) Dane przekazuj parametrami, wyniki zwracaj. (4) Po każdym kroku uruchom testy z punktu 1 — wynik ma być identyczny. (5) Na końcu program główny powinien czytać się jak spis treści. Przebudowa bez zmiany zachowania ma zawodową nazwę: refaktoryzacja — i zawsze zaczyna się od testów.
import randomdaje teżrandom.choice(lista)(losowy element) irandom.shuffle(lista)(tasowanie w miejscu). Napisz program losujący 3-osobowe dyżury z listy klasy tak, by nikt nie wypadł dwa razy — i wyjaśnij, czemu tasowanie + branie po kolei jest tu lepsze niż trzykrotnychoice.
Wskazówka i odpowiedź
random.shuffle(klasa) a potem klasa[0:3] (albo kolejne trójki dla kolejnych tygodni). Trzykrotny choice może wylosować tę samą osobę dwa razy — musiałbyś dokładać sprawdzanie i powtarzanie losowań. Tasowanie raz i czytanie po kolei daje różnorodność „za darmo" — dobór właściwego narzędzia z biblioteki bywa całym rozwiązaniem problemu.
🔍 Sprawdź, czy umiesz
- Zatrzymać program w debuggerze i odczytać stan zmiennych w środku pętli.
- Wymienić trzy klocki programowania strukturalnego i pokazać je we własnym kodzie.
- Przeczytać cudzą klasę i powiedzieć: jakie ma dane, jakie czynności, ile obiektów tworzy program.
CZĘŚĆ II — Algorytmika — sztuka rozwiązywania problemów