Cvičení č. 7 rozšířené o poznámky ze cvičení a řešení některých příkladů (ZS 2025/26)¶
V minulém díle jste viděli...¶
Podmíněný příkaz if s volitelnými bloky elif a else:
a = 0
if a > 0:
print("číslo je kladné")
elif a == 0:
print("číslo se rovná 0")
else:
print("číslo není kladné")
číslo se rovná 0
Podmíněný výraz:
x = -1
y = 2
z = x if x + y > 0 else y
Příkaz while:
n = 0
while n <= 4:
print(n)
n += 1
0 1 2 3 4
Příkazy break a continue sloužící pro podrobnější kontrolu provádění cyklů.
Příkaz for využívající funkci range jako zdroj hodnot:
for n in range(10, 0, -3):
print(n)
10 7 4 1
Strukturování programu: funkce¶
Funkce jsou patrně nejdůležitější prvek programovacích jazyků, který slouží ke strukturování programu. Umožňují totiž pojmenovat určitou skupinu příkazů, které potom lze použít opakovaně s různými vstupními parametry. Pokud tedy programujeme algoritmus pro řešení nějaké úlohy, můžeme jej umístit do samostatné funkce, abychom při opakovaném řešení úlohy s jinými daty nemuseli znovu programovat ten samý algoritmus. Funkce tedy programátorům umožňují dodržovat princip don't repeat yourself (DRY).
# již známe 2 druhy funkcí: funkce, co mají nějaké parametry a vrací hodnotu
# a funkci print pro vypisování
x = abs(-7)
print(x)
7
Příkaz def – definice funkce¶
Příkaz def je složený příkaz, který se skládá z hlavičky a těla funkce.
Hlavička se skládá z klíčového slova def, názvu funkce, seznamu parametrů uvnitř kulatých závorek a závěrečné dvojtečky.
Tělo funkce následující za dvojtečkou tvoří blok příkazů se správným odsazením dle univerzálního syntaktického pravidla.
Zápis se nejlépe vysvětlí pomocí příkladů.
Následující funkce print_demo nemá žádný parametr:
# definice funkce: hlavička a tělo
# Tato funkce nemá žádný parametr a vrací hodnotu None
def print_demo():
print("Byla spuštěna funkce 'print_demo'.")
# příkaz definice funkce je podobný jako příkaz definice proměnné:
# také nic nevypíše, ale vytvoří se objekt reprezentující funkci a proměnná (zde print_demo),
# která na objekt odkazuje
x = 7
# ukázka: debugger
Funkce print_demo1 má jeden parametr:
# Tato funkce má jeden parametr a vrací hodnotu None
def print_demo1(param):
print("Hodnota parametru je", param)
Funkce print_demo2 má dva parametry:
# Tato funkce má dva parametry a vrací hodnotu None
def print_demo2(param1, param2):
print("Hodnota prvního parametru je", param1)
print("Hodnota druhého parametru je", param2)
Všimněte si, že při spuštění příkazu def nedošlo ke spuštění příkazů v těle dané funkce.
Při definici funkce dojde pouze k vytvoření objektu, který reprezentuje danou funkci a obsahuje kód definovaný v těle funkce.
Odkaz na tento objekt se uloží do proměnné s názvem dané funkce.
Výpis samotného objektu reprezentujícího funkci vypadá takto:
# výpis hodnoty, na kterou odkazuje proměnná 'x': číslo
print(x)
7
# výpis hodnoty, na kterou odkazuje proměnná 'print_demo':
# objekt, který reprezentuje funkci
print(print_demo)
<function print_demo at 0x7fe82ad63e20>
Pokud chceme funkci použít, musíme ji zavolat pomocí kulatých závorek, přičemž musíme předat správný počet argumentů odpovídající definici funkce, jinak dojde k chybě:
# Volání funkce:
print_demo()
Byla spuštěna funkce 'print_demo'.
# Volání funkce s jedním parametrem, "ahoj" je argument pro parametr 'param'
print_demo1("ahoj")
print_demo1(12)
Hodnota parametru je ahoj Hodnota parametru je 12
print_demo() # zde nepředáváme žádný argument
print_demo1(10) # číslo 10 je argument pro parametr 'param'
print_demo2(10, 20) # čísla 10 je argument pro parametr 'param1', 20 je argument pro parametr 'param2'
Byla spuštěna funkce 'print_demo'. Hodnota parametru je 10 Hodnota prvního parametru je 10 Hodnota druhého parametru je 20
# funkci musíme volat se správným počtem argumentů
print_demo1()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[14], line 1 ----> 1 print_demo1() TypeError: print_demo1() missing 1 required positional argument: 'param'
# funkci musíme volat se správným počtem argumentů
print_demo1(1, 2, 3)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[18], line 1 ----> 1 print_demo1(1, 2, 3) TypeError: print_demo1() takes 1 positional argument but 3 were given
Syntaxe příkazu def má mnoho různých variant, které souvisí zejména s definicí seznamu parametrů funkce.
Zatím se jimi nebudeme zabývat a postupně se k tomuto tématu budeme vracet.
Příklad¶
Napište funkci say_hello(name), která vypíše pozdrav pro uživatele se zadaným jménem. (Anglicky, abychom nemuseli skloňovat...). Funkci několikrát zavolejte, vyzkoušejte různé hodnoty argumentu.
def say_hello(name):
print("Hello", name)
say_hello("Petr")
say_hello("Anna")
Hello Petr Hello Anna Hello 0 Hello 1 Hello 2 Hello 3 Hello 4
for i in range(5):
say_hello(i)
Hello 0 Hello 1 Hello 2 Hello 3 Hello 4
Příkaz return – vrácení výsledku funkce¶
V matematice se pojmem funkce označuje předpis, který ze vstupní hodnoty (případně vstupních hodnot) počítá nějakou výstupní hodnotu.
Předchozí příklady funkcí print_demo atd. nemají žádný výsledek.
K vrácení výsledné hodnoty zevnitř funkce na místo, kde byla funkce zavolána, slouží příkaz return.
Volání funkce je výraz, může tedy vystupovat např. napravo od přiřazovacího operátoru:
# K vrácení výsledné (návratové) hodnoty funkce slouží příkaz return:
def polynom(x):
return x ** 2 - 3 * x + 1
vysledek = polynom(2.5)
print(vysledek)
-0.25
# před příkazem return může být složitější výpočet:
def polynom1(x):
vysl = x ** 2 - 3 * x
vysl += 1
return vysl
# výslednou (návratovou) hodnotu funkce mohu např. vložit do proměnné:
vysledek = polynom1(2.5)
print(vysledek)
# nebo rovnou vypsat:
print(polynom1(2.5))
# ukázka: debugger + pytutor
-0.25 -0.25
# volání funkcí může být součástí složitějších výrazů
x = polynom(5) + 4 * polynom1(0.3)
print(x)
11.76
# příkaz return okamžitě ukončí funkci (jako break u cyklu)
def polynom2(x):
vysl = 1
return vysl
print("ahoj")
vysl = x ** 2 - 3 * x
return vysl
vysledek = polynom2(2.5)
print(vysledek)
1
Příkazem return končí vykonávání dané funkce a žádné další příkazy z těla funkce se nevykonají.
To je důležité zejména pokud funkce obsahuje příkazy return uvnitř podmínek nebo cyklů.
Pokud funkce neobsahuje žádný příkaz return nebo pokud dojde k vykonání prázdného příkazu return (tj. ukončení funkce bez vrácení hodnoty), je výsledkem funkce hodnota None:
def polynom(x):
if x < 0:
print("Definiční obor této funkce nezahrnuje záporná čísla.")
return
return x ** 2 - 3 * x + 1
vysledek = polynom(-1)
print(vysledek)
Definiční obor této funkce nezahrnuje záporná čísla. None
# ukázka signum: další příklad použití příkazu return v různých větvích výpočtu:
def signum(x):
if x > 0:
return 1
elif x == 0:
return 0
return -1
print(signum(-6))
-1
# pokud funkce neobsahuje příkaz return, je její návratovou hodnotou None:
def say_hello(name):
print("Hello", name)
x = say_hello("anna")
print(x)
Hello anna None
if say_hello("Petr"):
print("ano")
else:
print("Hodnota None se vyhodnotí jako False")
Hello Petr Hodnota None se vyhodnot9 jako False
# tato funkce vypisuje pozdrav a vrací hodnotu 2
def say_hello(name):
print("Hello", name)
return 2
x = say_hello("anna")
print(x)
Hello anna None
# funkce vrací pro hodnotu argumentu 'petr' hodnotu 1 a jindy 'None'
def say_hello(name):
print("hello", name)
if name == "petr":
return 1
x = say_hello("petra")
print(x)
hello petra None
x = say_hello("petr")
print(x)
hello petr 1
Příklad¶
- Napište funkci
je_sudé(n), která vracíTrueneboFalsepodle toho, jestli je zadané přirozené číslonsudé nebo není. Funkci zavolejte.
def je_sude(n):
if n % 2 == 0:
return True
else:
return False
print(je_sude(2), je_sude(3))
n = 10
if je_sude(n):
print("ano")
True False ano
def je_sude(n):
return n % 2 == 0
print(je_sude(2), je_sude(3))
n = 10
if je_sude(n):
print("ano")
True False ano
def je_sude(n):
return not (n % 2)
print(je_sude(2), je_sude(3))
n = 10
if je_sude(n):
print("ano")
True False ano
- Analogicky napište funkci
je_liché(n). Využijte při tom předchozí funkci. Funkci zavolejte.
def je_liche(n):
if je_sude(n):
return False
else:
return True
print(je_liche(2), je_liche(3))
False True
def je_liche(n):
return not je_sude(n)
print(je_liche(2), je_liche(3))
False True
Proměnné a obor platnosti¶
Lokální proměnná je proměnná, která je definovaná uvnitř funkce. Jakmile skončí vykonávání dané funkce, zaniknou i všechny lokální proměnné definované uvnitř dané funkce.
Uvnitř funkce máme naopak přístup objektům s širším oborem platnosti, jako jsou např. globální proměnné, ale i globálně importované moduly, jiné funkce definované na stejné úrovni, apod. Názvy definované na vyšší úrovni ale můžeme pouze použít, nemůžeme je změnit – viz následující příklad:
# Proměnné dělíme na globální (definované na úrovni programu)
# a lokální (definované na úrovni funkce)
a = 10 # globální proměnná
def f():
x = 1 # lokální proměnná
print("lokalni", x) # výpis lokálních proměnných
f() # použití funkce
# výpis globálních proměnných
print("globalni", a)
lokalni 1 globalni 10
# lokální proměnná žije jen uvvnitř funkce, když funkce skončí, zanikne:
a = 10 # globální proměnná
def f():
x = 1 # lokální proměnná
print("lokalni", x) # výpis lokálních proměnných
f() # použití funkce
# výpis globálních proměnných
print("globalni", a)
# chyba:
print("lokalni", x)
lokalni 1 globalni 10
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[1], line 14 11 print("globalni", a) 13 # chyba: ---> 14 print("lokalni", x) NameError: name 'x' is not defined
# Proměnné dělíme na globální (definované na úrovni programu)
# a lokální (definované na úrovni funkce)
a = 10 # globální proměnná
def f(x): # parametr ... lokální proměnná
y = 1 + x # lokální proměnná
print("lokalni", x, y) # výpis lokálních proměnných
f(2) # použití funkce
# výpis globálních proměnných
print("globalni", a)
# ukázka pytutor
lokalni 2 3 globalni 10
# lokální proměnnou mohu pojmenovat stejně jako globální proměnnou
# uvnitř funkce lokální proměnná překryje globální proměnnou stejného jména
a = 10 # globální proměnná
x = "ahoj"
y = "lidi"
def f(x): # parametr ... lokální proměnná
y = 1 + x # lokální proměnná
print("lokalni", x, y) # výpis lokálních proměnných
f(2) # použití funkce
# výpis globálních proměnných
print("globalni", a, x, y)
# ukázka pytutor
lokalni 2 3 globalni 10 ahoj lidi
# Výhooda: uvnitř funkce si mohu pojmenovávat proměnné, jak chci
a = 10 # globální proměnná
from math import cos
x = "ahoj"
y = "lidi"
def f(x): # parametr ... lokální proměnná
cos = 9
min = 7
y = 1 + x # lokální proměnná
print("lokalni", x, y, min, cos) # výpis lokálních proměnných
f(2) # použití funkce
# výpis globálních proměnných
print("globalni", a, x, y, cos)
# funguje dle očekávání
print(min(10, 9))
# ukázka pytutor
lokalni 2 3 7 9 globalni 10 ahoj lidi <built-in function cos> 9
# uvnitř funkce mohu provést lokální import:
a = 10 # globální proměnná
def f(x): # parametr ... lokální proměnná
from math import cos
y = 1 + cos(x) # lokální proměnná
print("lokalni", x, y, cos) # výpis lokálních proměnných
f(90) # použití funkce
# výpis globálních proměnných
print("globalni", a)
# y = cos(90) # chyba
# ukázka pytutor
lokalni 90 0.5519263838708299 <built-in function cos> globalni 10
# uvnitř funkce mohu použít globání import
a = 10 # globální proměnná
import math
def f(x): # parametr ... lokální proměnná
y = 1 + x + math.cos(math.pi) # lokální proměnná
print("lokalni", x, y) # výpis lokálních proměnných
f(90) # použití funkce
# výpis globálních proměnných
print("globalni", a)
# y = cos(90) # chyba
# ukázka pytutor
lokalni 90 90.0 globalni 10
# uvnitř funkce mohu použít globální proměnné (ale nedoporučuji to)
a = 10 # globální proměnná
def f(x): # parametr ... lokální proměnná
y = 1 + x + a# lokální proměnná
print("lokalni", x, y) # výpis lokálních proměnných
f(2) # použití funkce
# výpis globálních proměnných
print("globalni", a)
# ukázka pytutor
lokalni 2 13 globalni 10
# uvnitř funkce nemohu globální proměnné měnit
# tj. jakmile uvnitř funkce použiju globální proměnnou, již nesmím definovat
# lokální proměnnou stejného jména:
a = 10 # globální proměnná
def f(x): # parametr ... lokální proměnná
y = 1 + x + a # lokální proměnná
print("lokalni", x, y) # výpis lokálních proměnných
a = 10
f(2) # použití funkce
# výpis globálních proměnných
print("globalni", a)
# ukázka pytutor
--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) Cell In[16], line 10 7 print("lokalni", x, y) # výpis lokálních proměnných 8 a = 10 ---> 10 f(2) # použití funkce 12 # výpis globálních proměnných 13 print("globalni", a) Cell In[16], line 6, in f(x) 5 def f(x): # parametr ... lokální proměnná ----> 6 y = 1 + x + a # lokální proměnná 7 print("lokalni", x, y) # výpis lokálních proměnných 8 a = 10 UnboundLocalError: cannot access local variable 'a' where it is not associated with a value
# globální proměnná
a = 10
import math
def f(y):
from math import sin
# lokální proměnná
z = sin(y)
x = 1 + y + math.pi + a + z
# výpis lokálních proměnných
print("lokalni", x, y)
print(math.pi)
# použití funkce
f(8)
# výpis globálních proměnných
print("globalni", a)
sin(math.pi)
3.141592653589793 lokalni 23.130950900213175 8 globalni 10
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[4], line 22 19 # výpis globálních proměnných 20 print("globalni", a) ---> 22 sin(math.pi) NameError: name 'sin' is not defined
# původní příklad
# globální proměnná
globalni = 10
def f():
# lokální proměnná
lokalni = 1
# použití globální proměnné
lokalni += globalni
# uvnitř funkce nelze měnit globální proměnné
#globalni += 1
# výpis lokálních proměnných
print("lokalni", lokalni)
# použití funkce
f()
# výpis globálních proměnných
print("globalni", globalni)
# lokální proměnné definované uvnitř funkce nejsou k dispozici na globální úrovni
#print(lokalni)
Tip: Kliknutím na tlačítko pytutor v rozhraní JupyterLab se zobrazí grafická interpretace toho, co se v programu děje.
Pokud bychom uvnitř funkce použili přiřazení jako např. globalni = 1 v následujícím příkladu, není to chyba, ale je důležité si uvědomit, co se v programu děje.
Příkaz přiřazení totiž vytváří novou proměnnou, ke které připojí daný název.
V tomto případě tedy vzniká nová lokální proměnná s názvem globalni a hodnotou 1 a její název na lokální úrovni překryje globální proměnnou se stejným názvem, jde však o dva různé objekty:
# globální proměnná
globalni = 10
def f():
# zde dojde k vytvoření lokální proměnné, která překryje proměnnou na globální úrovni
globalni = 1
print("hodnota uvnitř funkce:", globalni)
# použití funkce
f()
# funkce f nezměnila globální proměnnou
print("hodnota mimo funkci:", globalni)
K podobné shodě názvu proměnných může docházet poměrně často, ale není třeba se tohoto chování bát. Vykonávání příkazů dané funkce probíhá ve svém vlastním lokálním světě, který s globálním světem komunikuje především pomocí vstupních parametrů a výstupní návratové hodnoty (viz dále). Spíš by bylo nepříjemné, kdyby funkce modifikovala okolní stav nějakým jiným, nepřehledným způsobem.
Příklady¶
- Definujte a zavolejte funkci
je_dělitelné(n, d), která vracíTrueneboFalsepodle toho, jestli je zadané přirozené číslondělitelné číslemd.
# zadny print uvnitr funkce!
def je_delitelne(n, d):
if n % d == 0:
return True
return False
def je_delitelne(n, d):
return n % d == 0
print(je_delitelne(10, 2))
print(je_delitelne(10, 1))
print(je_delitelne(10, 3))
print(je_delitelne(13, 2))
- Napište a zavolejte funkci
počet_dělitelů(n), která spočítá a vrátí počet dělitelů přirozeného číslan. Využijte funkci naprogramovanou v předchozím příkladu.
# zadny print uvnitr funkce!
def pocet_delitelu(n):
pocet = 0
for d in range(1, n + 1):
if je_delitelne(n, d):
pocet += 1
return pocet
print(pocet_delitelu(30))
for n in range(21):
print(n, ":", pocet_delitelu(n))
8 0 : 0 1 : 1 2 : 2 3 : 2 4 : 3 5 : 2 6 : 4 7 : 2 8 : 4 9 : 3 10 : 4 11 : 2 12 : 6 13 : 2 14 : 4 15 : 4 16 : 5 17 : 2 18 : 6 19 : 2 20 : 6
- Napište a zavolejte funkci
vypiš_dělitele(n), která vypíše všechny dělitele přirozeného číslan.
# tady naopak print bude
def vypis_delitele(n):
for d in range(1, n + 1):
if je_delitelne(n, d):
print(d, end = " ")
vypis_delitele(30)
print()
vypis_delitele(1)
print()
vypis_delitele(-1)
1 2 3 5 6 10 15 30 1
for i in range(10):
print(i, ": ", end="")
vypis_delitele(i)
print("")
0 : 1 : 1 2 : 1 2 3 : 1 3 4 : 1 2 4 5 : 1 5 6 : 1 2 3 6 7 : 1 7 8 : 1 2 4 8 9 : 1 3 9
- Napište a zavolejte funkci
bmi(hmotnost, výška), která ze zadaných parametrů spočítá index BMI a vrátí výsledek jako číselnou hodnotu.
# zadny print uvnitr funkce!
def bmi(hmotnost, výška):
return hmotnost / (výška**2)
bmi(60, 1.7)
20.761245674740486
- Naprogramujte funkci
součet_číslic(n), která spočítá součet číslic v desítkovém zápisu přirozeného číslan.
n = 12345
cislice = n % 10
n = n // 10
print(cislice, n)
5 1234
# zadny print uvnitr funkce!
n = 145
def soucet_cislic(n):
soucet = 0
while n > 0:
cislice = n % 10
n = n // 10
soucet += cislice
return soucet
print(soucet_cislic(12345), n)
Naprogramujte funkci
remove(n, digit), která z desítkového zápisu zadaného přirozeného číslanodstraní všechny číslice, které se rovnají hodnotědigit. Např.:remove(123, 2)→13remove(243132, 3)→2412
Pro procvičení můžete dále zkusit upravit libovolný příklad z předchozích cvičení a definovat v něm vhodnou funkci.