Kategória: Python gyerekeknek.
Elmélet
Ha egy kódrészletet több helyről szeretnénk használni, akkor érdemes azokat külön helyre szervezni, és csak hivatkozni rá. Ezt a "külön helyet" hívjuk függvénynek, a hivatkozást pedig függvényhívásnak.
Ha a program elér egy akkora méretet, amit mér nehéz átlátni, akkor is érdemes függvényekbe szervezni a kódot. Ez utóbbi esetben a logikailag jól elkülöníthető részeket érdemes egy függvénybe írni.
Már idáig is használtunk függvényeket, csak nem neveztük nevén. Pl. a print() utasítás egy függvényhívás volt. A függvénynek tehát van egy neve. Amikor meghívjuk, akkor nyitó és csukó zárójeleket kell írnunk. Vannak esetek, amikor agy, vagy akár több valamit be kell írni a zárójelbe. Ezeket a valamiket argumentumoknak hívjuk. Például ott, hogy print('Szia') az, hogy 'Szia', a függvény argumentuma.
Elképzelhető, hogy a függvény visszaad valamit. Ezt úgy hívjuk, hogy a függvény visszatérési értéke. Az input() függvény például ilyen: visszaadja azt, amit a felhasználó beírt.
A Scratch-nen a függvényekhez nagyon hasonló fogalom a blokk, amelyekből számos van, és mi magunk is tudunk létre hozni blokkot.
Lássuk most, hogy hogyan tudunk mi magunk készíteni függvényt, és azt hogyan tudjuk meghívni! A szabály a következő:
- Függvény írását a def kulcsszóval kezdjük
- Utána szóközzel elválasztva jön a függvény neve.
- Utána zárójelet kell tenni. A zárójelben fel kell sorolni a függvény paramétereit. Ami a hívó oldalon az argumentum, az a függvény oldalán a paraméter. Erre majd látni fogunk példát. A zárójelet akkor is ki kell tenni, ha a függvénynek nincs paramétere.
- A fejléc kettősponttal zárul.
- A függvény törzsét ugyanolyan mélységben kell behúzni. Ha azon belül van elágazás agy ciklus, annak a törzsét tovább be kell húzni.
- Ha van a függvénynek visszatérési értéke, akkor azt a return utasítással kell megadni.
Példák
Kezdjük egy egyszerű példával: a print_hello() függvény kiírja azt, hogy Helló, világ!.
def print_hello(): print('Helló, világ!') print_hello()
Ennek megfelelő Scratch kód az alábbi:
Paramétert a következőképpen adhatunk hozzá:
def greet(name): print(f'Szia, {name}!') greet('Csaba')
A paraméter és az argumentum rokon fogalmak, és sokszor felcserélik a kettőt. A jelentése:
- A paraméter a hívott oldali megnevezése; a fenti példában ez a name.
- Az argumentum az az érték, amit a hívó oldalon átadunk, a példában ez 'Csaba'.
A fenti kódrészletnek megfelelő Scratch program az alábbi:
A következő példában van a függvénynek visszatérési értéke. Ez egy összeadó függvény, melynek már kettő paramétere is van, és a visszatérési értéke a kettő szám összege:
def add(a, b): result = a + b return result c = add(3, 2) print(c)
Láthatjuk, hogy a hívó oldalon egyenlőség jellel értékül adjuk a függvény eredményét a c változónak, majd kiíratjuk.
A Scratch-ben ennek megfelelő kód már nincs, viszont egy kis trükközéssel ezt még meg tudjuk oldani: felveszünk egy változót, beletesszük az eredményt, majd kiíratjuk a változó értékét:
A függvényekkel kapcsolatban még nagyon sok tudnivaló van; mindegyikre most nem térünk ki. Néhány fontosabb:
- Megadhatjuk a paraméterek típusát, kettősponttal elválasztva.
- Megadhatjuk a visszatérési érték típusát, nyíllal (->).
- Híváskor megadhatjuk azt, hogy melyik paraméternek adunk értéket, a paraméter nevének megadásával és egy egyenlőségjellel.
- A paramétereknek adhatunk alapértelmezett értéket.
Mindezekre példa:
def add(a: int, b: int = 1) -> int: result = a + b return result c = add(a=3, b=2) print(c) d = add(2) print(d)
Van még egy probléma, amit megnézünk, mivel szükség lesz rá. Ezt az alábbi program segítségével illusztráljuk:
a = 1 def f(): a = 2 f() print(a)
Vajon mi lesz a futás eredménye: 1 vagy 2? Valójában 1, mert az első sorban levő a változóra azt mondjuk, hogy globális, az f() függvényen belülire pedig azt, hogy lokális. Ahhoz, hogy a globális változót tudjuk függvényen belülről módosítani, a global kulcsszót kell használnunk:
a = 1 def f(): global a a = 2 f() print(a)
Ez utóbbinak az eredménye 2 lesz.
Beépített függvények
A Pythonban vannak alapértelmezett függvények. Az alábbiakban megnézünk ezekből párat:
- print(x): kiírja a paraméterül kapott értéket.
- input(x): kiírja a paraméterül kapott értéket, majd beolvas a konzolról egy értéket.
- abs(x): az x abszolút értékét adja vissza, pl. az abs(-3.7) eredménye 3.7.
- max(x1, x2, …, xn): a paraméterül átadott számok maximumát adja vissza, pl. max(5, 3, 6) eredménye 6.
- min(x1, x2, …, xn): a paraméterül átadott számok minimumét adja vissza, pl. min(5, 3, 6) eredménye 3.
- sum([x1, x2, …, xn]): a paraméterül kapott struktúra összegét adja vissza, pl. sum([5, 3, 6]) eredménye 14. Itt csak listát, tuple-t vagy halmazt adhatunk át, közvetlenül elemeket nem.
- pow(a, b): kiszámolja az $a^b$ értékét, pl. pow(3, 4) eredménye 81.
- len([x1, x2, … xn]): a paraméterként átadott struktúra hosszát adja vissza. Pl. len([5, 3, 6]) eredménye 3.
- round(x[, y]): a paraméterül kapott számot adja vissza kerekítve a kerekítés szokásos szabályai szerint, pl. round(3.7342) eredménye 4. A második, opcionális paraméter azt adja meg, hogy hány tizedespontig kerekítsen, pl. round(3.7342, 2) eredménye 3.73.
- int(x): a paraméterül kapott érték számértékét adja vissza. Ha a kapott érték tört szám, akkor annak egész része lesz az eredmény, pl. int(3.7342) eredménye 3. Ha szöveges formátumú a kapott érték, akkor egésszé alakítja, ha tudja, pl. int('15') eredménye a 15 lesz, mint szám.
- str(x): szöveggé alakítja a paraméterként kapott értéket. Pl. a str(3) + str(2) eredménye '32' lesz.
A teljes lista megtalálható a https://docs.python.org/3/library/functions.html oldalon.
Feladat
Írjuk át a kvíz szótár változatát úgy, hogy függvényt használunk. A függvénynek legyen két paramétere:
- question: az aktuális kérdés,
- correct_answer: a helyes válasz.
Kérje be a felhasználó válaszát, és a visszatérési értéke pedig legyen True vagy False attól függően, hogy a válasz helyes-e vagy helytelen. A kódot szervezzük át úgy, hogy ezt a függvényt hívja a fő ciklus.
def check_answer(question, correct_answer): answer = input(question) if answer == correct_answer: print('Helyes!') return True else: print(f'A válasz helytelen; a helyes válasz {correct_answer} lett volna.') return False points = 0 question_answer_dict = { 'Mi Magyarország fővárosa? ': 'Budapest', 'Hány fokon forr a víz? ': '100', 'Melyik az az állat, amelyiknek nagy füle és hosszú ormánya van? ': 'elefánt', 'Hogy mondjuk angolul azt, hogy alma? ': 'apple', 'Mi volt Petőfi vezetéknevű költőnk keresztneve? ': 'Sándor', } for question in question_answer_dict: correct_answer = question_answer_dict[question] result = check_answer(question, correct_answer) if result: points = points + 1 print() percentage = str(100 * points / len(question_answer_dict)) + '%' print('Az eredmény: ' + percentage)
Önálló feladat lehetőségek
- Fejlesszük tovább a programot úgy, hogy a teljes logika egy másik függvénybe kerül, pl. ask_quiz_questions, ami levezérli az egész kvízt, és a százalékos végeredményt adja vissza. Így a főprogram mindössze egyetlen sorból áll, ami kiírja az eredményt.
- Készítsünk egy olyan kvíz motort, ami tartalmazhat kérdezz-felelek, számszerű és ABCD válasz lehetőségeket is.
Teszt
1. feladat
Mit lesz az alábbi kódrészlet eredménye?
def create_salute(name): return f'Szia, {name}!' def say_hello(name): salute = create_salute(name) print(salute) say_hello('Csaba')
A salute
B Szia, {name}!
C create_salute(Csaba)
D Szia, Csaba!
2. feladat
Mit lesz az alábbi kódrészlet eredménye?
def f(n): result = 1 for i in range(1, n+1): result = result * i return result print(f(5))
A f(5)
B 120
C 1, 2, 3, 4, 5
D 1, 2, 6, 24, 120
3. feladat
Mit lesz az alábbi kódrészlet eredménye?
def f(n): if n <= 1: return 1 else: return n * f(n-1) print(f(5))
A A f(n-1) rész hibás
B 120
C 1
D f(5)