Funkcje — program z klocków
🎯 Po co Ci to?
Twoje programy mają już po kilkanaście linijek. Prawdziwe mają po kilkaset tysięcy — i nikt nie ogarnia ich „od góry do dołu". Ogarnia się je tak, jak projektowałeś gazetkę w jednostce 1.4: krojąc na kawałki, z których każdy robi jedną rzecz i ma nazwę. W programowaniu taki nazwany kawałek to funkcja. Kilka funkcji już znasz (print, input, len, int) — dziś nauczysz się budować własne. To moment, w którym dekompozycja z działu 1 przestaje być rysunkiem, a staje się kodem.
✅ Czego się nauczysz
Po tej jednostce potrafisz:
- definiować funkcje z parametrami i bez oraz wywoływać je wielokrotnie;
- rozróżniać
returnodprint— i wiedzieć, kiedy którego użyć; - dzielić program na funkcje tak, żeby główna część czytała się jak plan działania.
📘 Wyjaśnienie
Definicja i wywołanie. Funkcję definiuje się słowem def, nazwą i listą parametrów — danych, które dostaje do pracy:
def pole_prostokata(a, b):
return a * b
print(pole_prostokata(3, 4)) # 12
print(pole_prostokata(2.5, 10)) # 25.0
x = pole_prostokata(5, 5) + 1 # z wynikiem można liczyć dalej: 26
Sama definicja niczego nie wykonuje — to spisanie przepisu do książki kucharskiej. Dopiero wywołanie pole_prostokata(3, 4) gotuje z przepisu: parametry a, b dostają wartości 3 i 4, ciało się wykonuje, a return zwraca wynik w miejsce wywołania. Jedna definicja, tysiąc użyć — na tym polega interes.
return to nie print. To najważniejsze rozróżnienie tej jednostki. return oddaje wartość programowi — do zmiennej, do warunku, do dalszych obliczeń. print pokazuje coś człowiekowi — i program nic z tego nie ma. Funkcja, która zamiast return robi print, jest jak kelner, który zamiast przynieść danie do stolika, pokazuje je gościom przez szybę: miło, ale nie da się tego zjeść.
def podwoj_zle(x):
print(x * 2) # pokazuje...
def podwoj_dobrze(x):
return x * 2 # ...a to ODDAJE
wynik = podwoj_dobrze(21) # wynik == 42, można liczyć dalej
cos = podwoj_zle(21) # wypisze 42, ale cos jest puste (None)!
Funkcje logiczne. Wyjątkowo pożyteczna odmiana: funkcja zwracająca True/False. Nazywaj je jak pytania — kod zacznie czytać się jak proza:
def przestepny(rok):
if rok % 400 == 0:
return True
if rok % 100 == 0:
return False
return rok % 4 == 0 # wynik porównania JEST wartością logiczną
if przestepny(2024):
print("Luty ma 29 dni")
Dwie rzeczy warte spojrzenia: return natychmiast kończy funkcję (dlatego nie potrzeba elif — jeśli program dotarł do trzeciej linijki, tamte warunki na pewno nie zaszły), a ostatnia linijka zwraca wprost wynik porównania — rok % 4 == 0 już jest True albo False, opakowywanie go w if byłoby masłem maślanym.
Funkcje bez parametrów też bywają potrzebne — gdy kawałek pracy jest zawsze taki sam: def przywitaj(): z powitaniem na ekranie. Wywołuje się je z pustymi nawiasami: przywitaj(). Nawiasy są częścią wywołania — przywitaj bez nawiasów to tylko wskazanie na przepis, nie gotowanie.
Program z klocków. Spójrz, jak funkcje zmieniają architekturę — dziennik z poprzedniej jednostki, wersja dojrzała:
def wczytaj_oceny(ile):
oceny = []
for i in range(ile):
oceny.append(int(input("Ocena: ")))
return oceny
def srednia(lista):
suma = 0
for x in lista:
suma = suma + x
return suma / len(lista)
# --- program główny: czyta się jak PLAN, nie jak instrukcja obsługi ---
oceny = wczytaj_oceny(6)
print("Średnia:", srednia(oceny))
Główna część to dwie linijki mówiące co się dzieje; jak — siedzi w funkcjach. To jest metoda zstępująca i wstępująca z jednostki 1.6 w praktyce: planujesz z góry („wczytam, policzę, wypiszę"), budujesz z dołu (każdą funkcję z osobna da się przetestować, zanim złożysz całość).
🐞 Znajdź błąd
Funkcja ma zwracać większą z dwóch liczb:
def wieksza(a, b):
if a > b:
return a
if b > a:
return b
print(wieksza(7, 3)) # 7 — działa
print(wieksza(4, 4)) # ???
Co zwróci drugie wywołanie i jak to naprawić?
Sprawdź odpowiedź
Dla a == b żaden warunek nie zachodzi, funkcja kończy się bez return — a wtedy Python po cichu zwraca None („nic"). Wypisze się None, a rachunki na tym „niczym" wybuchną błędem. Dane brzegowe znów zaatakowały remisem — jak w dziale 1! Naprawa: drugi warunek zamienić na return b bez if (skoro nie a > b, to b jest większe lub równe — i w obu przypadkach b jest poprawną odpowiedzią). Reguła zawodowa: każda ścieżka przez funkcję zwracającą wartość musi kończyć się jakimś return.
⚠️ Uwaga, pułapka
Zmienne stworzone wewnątrz funkcji (w tym parametry) żyją tylko na czas jej wykonania — z zewnątrz ich nie widać. To nie złośliwość, to błogosławieństwo: funkcje nie wchodzą sobie nawzajem w szufladki, więc możesz w dwóch funkcjach spokojnie używać nazwy suma i nic się nie pogryzie. Jeśli funkcja ma coś przekazać światu — niech to zwróci.
🛠️ Teraz Ty
Rozbij na funkcje program BMI z jednostki 3.2: def bmi(masa, wzrost) zwraca wartość, def kategoria(wartosc) zwraca napis z klasyfikacją, a program główny tylko wczytuje dane i skleja wywołania. Potem — bez zmiany funkcji! — dopisz pętlę liczącą BMI dla trzech osób. Poczuj, jak klocki się opłacają.
📐 Definicje tej lekcji
- Funkcja — nazwany fragment programu z parametrami; definiowana
def, uruchamiana wywołaniem. - Parametr — dana wejściowa funkcji; przy wywołaniu dostaje konkretną wartość (argument).
return— zwrócenie wyniku i natychmiastowe zakończenie funkcji; brakreturn= zwróconeNone.
📌 Najważniejsze w pigułce
- Definicja to przepis, wywołanie to gotowanie; jedna definicja — wiele wywołań.
returnoddaje wartość do dalszych obliczeń;printtylko pokazuje. Funkcje liczące mają zwracać.- Dobre funkcje robią jedną rzecz i nazywają się tak, że program główny czyta się jak plan.
🎒 Zadania
- Prześledź program i podaj, co wypisze — uwaga na kolejność wykonywania:
def f(x):
return x + 10
def g(x):
return f(x) * 2
print(g(5))
print(f(g(1)))
Wskazówka i odpowiedź
g(5): liczy f(5) = 15, razy 2 = 30. f(g(1)): najpierw wnętrze — g(1) = f(1)·2 = 22, potem f(22) = 32. Wypisze 30, potem 32. Funkcje wywołujące funkcje to chleb powszedni — a w dziale 7 zobaczysz funkcję, która wywołuje samą siebie.
- Napisz funkcję
ile_samoglosek(napis), zwracającą liczbę samogłosek (a, e, i, o, u, y) w napisie. Wykorzystaj wzorzec licznika i sprawdź na słowie „algorytmika". Dodatkowo: jak obsłużyć wielkie litery?
Wskazówka i odpowiedź
def ile_samoglosek(napis):
licznik = 0
for znak in napis:
if znak in "aeiouy":
licznik = licznik + 1
return licznik
(znak in "aeiouy" sprawdza, czy znak występuje w napisie samogłosek — wygodny pythonowy idiom.) „algorytmika": a-o-y-i-a → 5. Wielkie litery: sprawdzaj znak in "aeiouyAEIOUY" — albo elegancko obniż cały napis przed pętlą; o gotowych narzędziach do tego typu zabiegów powiemy przy bibliotekach (3.8).
- Kolega napisał
def srednia(lista):zprintzamiastreturni dziwi się, żeif srednia(oceny) > 4.0:wybucha błędem. Wyjaśnij mu w trzech zdaniach, co się dzieje i jak naprawić.
Wskazówka i odpowiedź
Twoja funkcja pokazuje średnią na ekranie, ale programowi zwraca None — bo bez return Python zwraca „nic". Warunek próbuje porównać None > 4.0, a „niczego" nie da się porównywać z liczbą — stąd błąd. Zamień print na return, a wypisywanie zostaw temu, kto funkcję wywołuje: liczenie i pokazywanie to dwie różne odpowiedzialności.
🔍 Sprawdź, czy umiesz
- Napisać funkcję z parametrami, wywołać ją trzykrotnie z różnymi argumentami i użyć wyniku w obliczeniu.
- Wyjaśnić różnicę
return/printmetaforą i przykładem kodu. - Przerobić 20-linijkowy program „z góry na dół" na trzy funkcje + krótki program główny.