Definiowanie funkcji, parametry, return, zasięg zmiennych, rekurencja.
Funkcja własna to nazwany blok kodu, który możesz wywołać wielokrotnie. Definiujesz ją słowem kluczowym def.
def nazwa(parametry):# Schemat definicji
def nazwa_funkcji(parametr1, parametr2):
"""Opis funkcji (docstring) — opcjonalny."""
# ciało funkcji
wynik = parametr1 + parametr2
return wynik
# Wywołanie
rezultat = nazwa_funkcji(3, 5)
print(rezultat) # 8
# Funkcja bez parametrów i bez return
def przywitaj():
print("Cześć!")
przywitaj() # Cześć!
przywitaj() # Cześć! — można wywołać wiele razy
Parametr — nazwa w definicji funkcji. Argument — wartość przekazana przy wywołaniu.
f(x=5)# Parametry pozycyjne
def dodaj(a, b):
return a + b
print(dodaj(3, 5)) # 8
print(dodaj(b=5, a=3)) # 8 — nazwane, kolejność nieważna
# Parametry z wartością domyślną
def przywitaj(imie, pozdrowienie="Cześć"):
print(f"{pozdrowienie}, {imie}!")
przywitaj("Kasia") # Cześć, Kasia!
przywitaj("Marek", "Hej") # Hej, Marek!
# *args — dowolna liczba argumentów
def suma(*liczby):
return sum(liczby)
print(suma(1, 2, 3)) # 6
print(suma(1, 2, 3, 4, 5)) # 15
# **kwargs — argumenty nazwane
def info(**dane):
for klucz, wartosc in dane.items():
print(f"{klucz}: {wartosc}")
info(imie="Kasia", wiek=17, miasto="Kraków")
return kończy działanie funkcji i zwraca wartość do miejsca wywołania. Bez return funkcja zwraca None.
return — wykona się pierwsza napotkanareturn bez wartości — kończy funkcję, zwraca Noneprint() wewnątrz funkcji wypisuje na ekran, ale nic nie zwraca. Jeśli potrzebujesz użyć wyniku później — użyj return, nie print().
# Funkcja z return
def kwadrat(x):
return x ** 2
wynik = kwadrat(5)
print(wynik) # 25
print(kwadrat(3) + 1) # 10 — wynik od razu użyty
# Wiele return — warunki
def znak(x):
if x > 0:
return "dodatnia"
elif x < 0:
return "ujemna"
else:
return "zero"
print(znak(-5)) # ujemna
print(znak(0)) # zero
# Zwracanie wielu wartości
def min_max(lista):
return min(lista), max(lista)
mini, maxi = min_max([3, 1, 7, 2, 9])
print(mini, maxi) # 1 9
# Funkcja bez return → None
def nic_nie_zwraca():
print("Działam!")
x = nic_nie_zwraca() # Działam!
print(x) # None
Zmienna zdefiniowana wewnątrz funkcji istnieje tylko w tej funkcji (zasięg lokalny). Zmienna poza funkcją ma zasięg globalny.
globalglobal — rzadko używane, zazwyczaj lepiej przekazać wartość przez parametr i returnglobal. Przekazuj dane przez parametry i odbieraj przez return. Funkcje powinny być niezależne od stanu zewnętrznego.
x = 10 # zmienna globalna
def pokaz():
print(x) # można CZYTAĆ globalną
pokaz() # 10
def sprobuj_zmienic():
x = 99 # to NOWA zmienna lokalna, nie globalna!
print(x) # 99
sprobuj_zmienic()
print(x) # 10 — globalna niezmieniona
# Użycie global (niezalecane)
def zmien_global():
global x
x = 99
zmien_global()
print(x) # 99 — teraz zmieniona
# Lepsze podejście: parametr + return
def dodaj_do(wartosc, ile):
return wartosc + ile
x = 10
x = dodaj_do(x, 5)
print(x) # 15
Lambda to krótka funkcja jednolinijkowa bez nazwy. Przydatna gdy potrzebujesz prostej funkcji na chwilę — np. jako argument do sorted() czy map().
lambda parametry: wyrażeniereturn)sorted(key=...), map(), filter(). Dla złożonej logiki zawsze lepiej napisać normalną funkcję def.
# Zwykła funkcja vs lambda
def kwadrat(x):
return x ** 2
kwadrat_l = lambda x: x ** 2
print(kwadrat(5)) # 25
print(kwadrat_l(5)) # 25
# Lambda z wieloma parametrami
dodaj = lambda a, b: a + b
print(dodaj(3, 4)) # 7
# Lambda jako key w sorted
osoby = [("Kasia", 17), ("Marek", 15), ("Zofia", 19)]
wg_wieku = sorted(osoby, key=lambda osoba: osoba[1])
print(wg_wieku)
# [('Marek', 15), ('Kasia', 17), ('Zofia', 19)]
wg_imienia = sorted(osoby, key=lambda osoba: osoba[0])
print(wg_imienia)
# Lambda w filter i map
liczby = [1, 2, 3, 4, 5, 6]
parzyste = list(filter(lambda x: x % 2 == 0, liczby))
kwadraty = list(map(lambda x: x ** 2, liczby))
print(parzyste) # [2, 4, 6]
print(kwadraty) # [1, 4, 9, 16, 25, 36]
Rekurencja to technika, w której funkcja wywołuje samą siebie. Każde wywołanie rekurencyjne rozwiązuje mniejszy fragment problemu.
RecursionError# Silnia: n! = n * (n-1)! ; 0! = 1
def silnia(n):
if n == 0: # warunek bazowy
return 1
return n * silnia(n - 1)
print(silnia(5)) # 120
# 5 * 4 * 3 * 2 * 1 * 1
# Fibonacci: F(n) = F(n-1) + F(n-2) ; F(0)=0, F(1)=1
def fibonacci(n):
if n <= 1: # warunek bazowy
return n
return fibonacci(n - 1) + fibonacci(n - 2)
for i in range(8):
print(fibonacci(i), end=" ")
# 0 1 1 2 3 5 8 13
# NWD — algorytm Euklidesa
def nwd(a, b):
if b == 0: # warunek bazowy
return a
return nwd(b, a % b)
print(nwd(48, 18)) # 6
print(nwd(100, 75)) # 25
Napisz funkcję czy_pierwsza(n), która zwraca True jeśli liczba jest pierwsza, lub False w przeciwnym razie. Następnie wypisz wszystkie liczby pierwsze od 2 do 50.
def czy_pierwsza(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
# Wypisanie liczb pierwszych od 2 do 50
pierwsze = []
for n in range(2, 51):
if czy_pierwsza(n):
pierwsze.append(n)
print("Liczby pierwsze:", pierwsze)
print("Ile ich jest:", len(pierwsze))
False.
int(n ** 0.5) + 1 — wystarczy sprawdzić dzielniki do √n. Jeśli n ma dzielnik większy niż √n, to ma też dzielnik mniejszy. Optymalizacja zmniejsza liczbę operacji.
False. Nie ma sensu sprawdzać dalej.
return True jest poza pętlą.
Napisz cztery funkcje: dodaj(a,b), odejmij(a,b), mnoz(a,b), dziel(a,b). Funkcja dzielenia powinna zwrócić komunikat błędu gdy b=0. Stwórz prosty kalkulator wczytujący dwie liczby i działanie.
def dodaj(a, b):
return a + b
def odejmij(a, b):
return a - b
def mnoz(a, b):
return a * b
def dziel(a, b):
if b == 0:
return "Błąd: dzielenie przez zero!"
return a / b
# Kalkulator
a = float(input("Pierwsza liczba: "))
dzial = input("Działanie (+, -, *, /): ")
b = float(input("Druga liczba: "))
if dzial == "+":
wynik = dodaj(a, b)
elif dzial == "-":
wynik = odejmij(a, b)
elif dzial == "*":
wynik = mnoz(a, b)
elif dzial == "/":
wynik = dziel(a, b)
else:
wynik = "Nieznane działanie"
print(f"Wynik: {wynik}")
float lub str. To nie idealne rozwiązanie — lepiej byłoby użyć wyjątków — ale na poziomie INF.04 jest akceptowalne.
if dzial == "+" decyduje którą funkcję wywołać. Wynik trafia do zmiennej wynik i jest wypisany na końcu — raz, wspólnie.
float() zamiast int() — kalkulator powinien działać też dla liczb z przecinkiem.
Napisz rekurencyjną funkcję potega(podstawa, wykladnik) obliczającą wartość podstawa^wykladnik dla nieujemnych wykładników całkowitych — bez użycia operatora ** ani pow(). Wypisz tabelę potęg dla podstawy 2 od 0 do 10.
def potega(podstawa, wykladnik):
# warunek bazowy: x^0 = 1
if wykladnik == 0:
return 1
# wywołanie rekurencyjne: x^n = x * x^(n-1)
return podstawa * potega(podstawa, wykladnik - 1)
# Tabela potęg dwójki
print(f"{'n':<5} {'2^n':>6}")
print("-" * 12)
for n in range(11):
print(f"{n:<5} {potega(2, n):>6}")
podstawa * potega(podstawa, wykladnik - 1) — rozkładamy problem: 2^5 = 2 * 2^4 = 2 * 2 * 2^3 = ... aż dojdziemy do 2^0 = 1.
potega(2, 3): wywołuje potega(2, 2) → potega(2, 1) → potega(2, 0) → zwraca 1. Następnie wyniki są mnożone wstecz: 1 → 2 → 4 → 8.
:<5 wyrównuje do lewej, :>6 do prawej. Wynik wygląda jak profesjonalna tabela.
Pisz funkcje — nie wklejaj całego kodu w jedno miejsce. Każde zadanie to przynajmniej jedna funkcja z def.
Pole figur
Napisz trzy funkcje: pole_kola(r), pole_prostokata(a, b), pole_trojkata(a, h). Każda zwraca pole zaokrąglone do 2 miejsc.
import math, math.piFunkcja powitalna
Napisz funkcję powitaj(imie, godzina) zwracającą "Dzień dobry", "Dobry wieczór" lub "Dobranoc" w zależności od godziny (0–23).
if/elif/else, returnWalidator hasła
Napisz funkcję sprawdz_haslo(haslo) zwracającą listę błędów. Hasło musi mieć min. 8 znaków, wielką literę, cyfrę i znak specjalny.
any(), isupper(), isdigit()Sortowanie własne
Napisz funkcję posortuj_wg_dlugosci(lista_slow) zwracającą listę słów posortowaną od najkrótszego do najdłuższego. Przy równej długości — alfabetycznie.
sorted() z key=lambda x: (len(x), x)Suma cyfr rekurencyjnie
Napisz rekurencyjną funkcję suma_cyfr(n) obliczającą sumę cyfr liczby całkowitej. Np. suma_cyfr(1234) → 10.
n % 10 daje ostatnią cyfrę, n // 10 usuwa ostatniąLiczby doskonałe
Napisz funkcję czy_doskonala(n) — liczba doskonała to taka, której suma dzielników właściwych (bez niej samej) jest równa jej wartości. Wypisz wszystkie takie do 1000.
n % i == 0