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

  1. Zaprojektuj (sama definicja + dwa wywołania) klasę KontoOszczednosciowe z metodami wplac(kwota), wyplac(kwota) (odmawia przy braku środków) i saldo(). Które dane muszą być w self, 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.

  1. 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.

  1. import random daje też random.choice(lista) (losowy element) i random.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ż trzykrotny choice.
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

Ucz się tej jednostki z asystentem