Funkcia je pomenovaný kúsok programu, ktorý môžeme spustiť (zavolať) toľkokrát, koľkokrát potrebujeme. Funkcie už poznáš – print, input, len, round sú funkcie, ktoré pripravili autori Pythonu. V tejto téme sa naučíš písať vlastné. Vďaka funkciám sa program dá rozdeliť na menšie časti, z ktorých každá rieši jednu úlohu, a ten istý kód netreba písať viackrát.
Čo sa naučíš
- definovať funkciu príkazom
defa zavolať ju, - odovzdať funkcii údaje cez parametre,
- vrátiť výsledok príkazom
returna odlíšiť ho odprint, - rozumieť lokálnym a globálnym premenným.
1Definícia a volanie funkcie
Výstup:
Ahoj!
Vitaj na hodine informatiky.
Ahoj!
Vitaj na hodine informatiky.- Riadok
def pozdrav():funkciu definuje:defje kľúčové slovo,pozdravmeno funkcie, za ním zátvorky a dvojbodka. - Odsadený blok pod ním je telo funkcie.
- Definícia funkciu nespustí – iba si ju Python zapamätá. Telo sa vykoná až pri volaní
pozdrav(), a to pri každom volaní znova.
Funkcia musí byť definovaná skôr, než ju zavoláš (program sa vykonáva zhora nadol). Preto sa definície funkcií píšu na začiatok programu a samotný „hlavný program“ až pod ne.
Výstup (program skončí chybou):
Traceback (most recent call last):
File "program.py", line 1, in <module>
vypis()
^^^^^
NameError: name 'vypis' is not definedPri volaní nezabudni na zátvorky: pozdrav bez zátvoriek funkciu nezavolá – iba sa na ňu odkáže.
2Parametre
Funkcia je užitočnejšia, keď jej môžeš odovzdať údaje. V definícii ich zapíšeš ako parametre – mená v zátvorkách. Pri volaní do zátvoriek napíšeš argumenty – konkrétne hodnoty, ktoré sa do parametrov dosadia.
Výstup:
Ahoj, Ema!
Ahoj, Tomáš!Pri prvom volaní má parameter meno hodnotu "Ema", pri druhom "Tomáš".
2.1Viac parametrov
Parametre sa oddeľujú čiarkou. Argumenty sa do nich dosadia podľa poradia:
Výstup:
######
######
ooo
ooo
oooAk sa počet argumentov nezhoduje s počtom parametrov, vznikne chyba:
Výstup (program skončí chybou):
Traceback (most recent call last):
File "program.py", line 5, in <module>
obdlznik(6, 2)
TypeError: obdlznik() missing 1 required positional argument: 'znak'2.2Pomenované argumenty a predvolené hodnoty
Argument sa dá zadať aj menom parametra – potom na poradí nezáleží. Parameter môže mať aj predvolenú hodnotu, ktorá sa použije, ak argument chýba:
Výstup:
****
****
========Takto funguje aj print(..., end="") – end a sep sú pomenované parametre s predvolenou hodnotou.
3Návratová hodnota: return
Doteraz naše funkcie iba vypisovali. Často však chceme, aby funkcia niečo vypočítala a výsledok odovzdala ďalej – rovnako ako len("abc") odovzdá číslo 3. Na to slúži príkaz return:
Výstup:
Obsah je 20
Dva také obdĺžniky: 40Volanie funkcie sa vo výraze nahradí vrátenou hodnotou: obsah_obdlznika(4, 5) sa správa ako číslo 20. S výsledkom môžeme ďalej počítať, uložiť ho do premennej alebo ho poslať inej funkcii.
3.1return verzus print
Toto je jedna z najdôležitejších vecí v celej téme:
printvýsledok ukáže na obrazovke – program ho však nemá kde použiť.returnvýsledok odovzdá tomu, kto funkciu zavolal – môže ho uložiť, porovnať, vypísať.
Výstup:
9
a = None
b = 9Prvá funkcia vypísala 9, ale do a uložila None – špeciálnu hodnotu, ktorá znamená „nič“. Funkcia bez return vráti None. Ak by sme chceli s a počítať (a + 1), vznikla by chyba.
3.2return ukončí funkciu
Po vykonaní return sa funkcia okamžite skončí; ďalšie riadky jej tela sa už nevykonajú. To sa hodí vo funkciách s podmienkami:
Výstup:
kladné záporné nulaTu nepotrebujeme elif ani else: ak platí prvá podmienka, funkcia skončí a ďalšie riadky sa nevykonajú.
3.3Funkcia vracajúca True alebo False
Funkcie, ktoré odpovedajú na otázku áno/nie, vracajú logickú hodnotu. Zvyknú sa pomenovať je_…:
Výstup:
2 je párne
4 je párneZápis return n % 2 == 0 je kratší ako if n % 2 == 0: return True a else: return False – porovnanie samo už je True alebo False.
3.4Viac návratových hodnôt
Funkcia môže vrátiť aj viac hodnôt oddelených čiarkou. V skutočnosti vráti jednu n-ticu (téma N-tice), ktorú možno rozbaliť do viacerých premenných:
Výstup:
2 94Lokálne a globálne premenné
Premenné vytvorené vo vnútri funkcie (aj parametre) sú lokálne: existujú iba počas behu funkcie a mimo nej o nich nikto nevie. Premenné vytvorené v hlavnom programe sú globálne.
Výstup (program skončí chybou):
vo funkcii: 42 Traceback (most recent call last): File "program.py", line 6, in <module> print("mimo funkcie:", vysledok) ^^^^^^^^ NameError: name 'vysledok' is not defined
Lokálna premenná môže mať aj rovnaké meno ako globálna – sú to však dve rôzne premenné. Priradenie vo funkcii zmení iba tú lokálnu:
Výstup:
vo funkcii x = 10
mimo funkcie x = 5Globálnu premennú funkcia čítať môže, ak lokálnu s rovnakým menom nevytvorí. Zmeniť ju by mohla iba po príkaze global x. To sa však neodporúča – program, v ktorom funkcie menia globálne premenné, sa ťažko číta aj opravuje. Lepšie je údaje funkcii odovzdať parametrami a výsledok vrátiť cez return.
5Ako písať dobré funkcie
- Jedna funkcia = jedna úloha. Funkcia
nacitaj_cisla, ktorá iba načíta,spocitaj_priemer, ktorá iba počíta. - Výstižné meno so slovesom:
vypocitaj_obsah,je_prvocislo,vypis_tabulku. - Údaje dnu parametrami, výsledok von cez return – nie cez globálne premenné ani
input/printvo vnútri, ak to nie je úlohou funkcie. - Na začiatok tela môžeš napísať dokumentačný reťazec (docstring) – krátky popis v trojitých úvodzovkách:
Výstup:
12.576Riešené úlohy
6.1Je číslo prvočíslo?
Zadanie: Napíš funkciu je_prvocislo(n), ktorá vráti True, ak je n prvočíslo, inak False. Pomocou nej vypíš prvočísla do 30.
Riešenie: Čísla menšie ako 2 nie sú prvočísla. Inak skúšame delitele od 2; keď nájdeme delitela, môžeme hneď vrátiť False. Ak cyklus prebehne celý, delitela niet a vrátime True.
Výstup:
2 3 5 7 11 13 17 19 23 29 Všimni si, kde je posledné return True: za cyklom, nie v ňom. Keby bolo v cykle v else vetve, funkcia by sa rozhodla už pri prvom deliteľovi.
6.2Faktoriál
Zadanie: Napíš funkciu faktorial(n), ktorá vráti n! = 1 · 2 · … · n (a 0! = 1).
Výstup:
1 120 36288006.3Najväčší spoločný deliteľ
Zadanie: Napíš funkciu nsd(a, b), ktorá vráti najväčší spoločný deliteľ dvoch kladných čísel, a pomocou nej skráť zlomok 84/126.
Riešenie: Euklidov algoritmus: kým b nie je 0, nahradíme dvojicu (a, b) dvojicou (b, a % b). Keď je b nula, v a je výsledok.
Výstup:
NSD = 42
84/126 = 2/36.4Program rozdelený na funkcie
Zadanie: Načítaj body troch písomiek (max. 50 bodov každá), vypočítaj priemerné percento a vypíš známku.
Riešenie: Program rozdelíme na funkcie podľa úloh: výpočet percent, výpočet známky a hlavný program, ktorý ich použije. Každú funkciu možno samostatne vyskúšať.
Výstup:
Body z písomky 1: 41 Body z písomky 2: 35 Body z písomky 3: 47 Úspešnosť: 82.0 %, známka: 2
7Časté chyby
- Volanie bez zátvoriek:
pozdravnamiestopozdrav()nič nespustí;print(obsah)vypíše niečo ako<function obsah at 0x…>. - print namiesto return: funkcia vypíše výsledok, ale vráti
None. Výrazvysledok + 1potom skončí chybouTypeError. - Volanie pred definíciou:
NameError– definície funkcií patria na začiatok. - Zlý počet argumentov:
TypeError: … missing 1 required positional argument. - return v cykle priskoro:
returnv tele cyklu ukončí celú funkciu už pri prvom opakovaní. - Chýbajúci return v niektorej vetve: ak funkcia v niektorom prípade nedôjde k
return, vrátiNone.
Výstup:
4 NonePre 0 neplatí žiadna podmienka, funkcia skončí bez return a vráti None. Oprava: if x >= 0.
Zhrnutie
def meno(parametre):+ odsadené telo; funkcia sa vykoná až pri volanímeno(argumenty).- Argumenty sa dosadia do parametrov podľa poradia alebo podľa mena; parameter môže mať predvolenú hodnotu.
return hodnotafunkciu ukončí a vráti hodnotu; volanie sa vo výraze nahradí touto hodnotou.- Funkcia bez
returnvrátiNone. Počítajúce funkcie majú výsledok vracať, nie vypisovať. - Premenné vo funkcii (aj parametre) sú lokálne; globálne premenné vo funkcii nemeň.
- Jedna funkcia = jedna úloha, výstižné meno, údaje dnu parametrami a výsledok von cez
return.
Úlohy na precvičenie
- Napíš funkciu
obvod_obdlznika(a, b)a použi ju pre tri rôzne obdĺžniky. - Napíš funkciu
max3(a, b, c), ktorá vráti najväčšie z troch čísel bez použitiamax. - Napíš funkciu
je_priestupny(rok)a vypíš všetky priestupné roky od 1990 do 2030. - Napíš funkciu
ciferny_sucet(n)a nájdi trojciferné číslo s najväčším ciferným súčtom. - Napíš funkciu
riadok(n, znak), ktorá vypíše n znakov za sebou, a pomocou nej nakresli štvorec. - Napíš funkciu
nsn(a, b)– najmenší spoločný násobok. Pomôcka:nsn(a, b) = a * b // nsd(a, b).