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
for n in range(5):
print(n)
0 1 2 3 4
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 = -3
y = abs(x)
y
3
y = print("ahoj")
ahoj
print(y)
None
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'.")
Funkce print_demo1 má jeden parametr:
# definice funkce s jedním parametrem
def print_demo1(param):
print("Hodnota parametru je", param)
Funkce print_demo2 má dva parametry:
# definice funkce se dvěma parametry
def print_demo2(param1, param2):
print("Hodnota prvního parametru je", param1)
print("Hodnota druhého parametru je", param2)
print_demo2(2, 3)
Hodnota prvního parametru je 2 Hodnota druhého parametru je 3
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.
# 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
# mrkněte na proměnné v debbugeru
x = 7
# výpis hodnoty, na kterou odkazuje proměnná 'x': číslo
print(x)
7 <function print_demo at 0x7f2dd4703740>
Výpis samotného objektu reprezentujícího funkci vypadá takto:
# výpis hodnoty, na kterou odkazuje proměnná 'print_demo':
# objekt, který reprezentuje funkci
print(print_demo)
# volání (spuštění) funkce (už známe):
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
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ě:
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(10, 5)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[10], line 1 ----> 1 print_demo1(10, 5) TypeError: print_demo1() takes 1 positional argument but 2 were given
# funkci musíme volat se správným počtem argumentů
print_demo1()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[11], line 1 ----> 1 print_demo1() TypeError: print_demo1() missing 1 required positional argument: 'param'
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("Jane")
say_hello("Tom")
for i in range(5):
say_hello(i)
Hello Jane Hello Tom 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 polynom(x):
y = x ** 2 - 3 * x
y += 1
return y
# výslednou (návratovou) hodnotu funkce mohu např. vložit do proměnné:
vysledek = polynom(2.5)
print(vysledek)
# nebo rovnou vypsat:
print(polynom(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ů
vysledek = polynom(2.5) + 3 * abs(polynom(3)) - 4
print(vysledek)
-1.25
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:
# příkaz return okamžitě ukončí funkci (jako break u cyklu)
def polynom(x):
y = x ** 2 - 3 * x
return
y += 1
return y
vysledek = polynom(2.5)
print(vysledek)
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(10)
print("Výsledek je", vysledek)
Výsledek je 71
# pokud funkce neobsahuje za příkazem return hodnotu, je její návratovou hodnotou None:
vysledek = polynom(-1)
print("Výsledek je", vysledek)
Definiční obor této funkce nezahrnuje záporná čísla. Výsledek je 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
if x < 0:
return -1
return 0
# Ukázka: pokud chci otestovat funkci, obvykle ji zavolám opakovaně pro různé vstupy
# a zkontroluji výsledek (není třeba volat input())
print(signum(10), signum(1.5), signum(0), signum(-0.5), signum(-10))
1 1 0 -1 -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("Výsledek je", x)
Hello Anna Výsledek je None
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 == 1:
return False
else:
return True
print(je_sude(56))
print(je_sude(5))
print(je_sude(0))
True False True
def je_sude(n):
return n % 2 == 0
print(je_sude(56))
print(je_sude(5))
print(je_sude(0))
True False True
def je_sude(n):
return not n % 2
print(je_sude(56))
print(je_sude(5))
print(je_sude(0))
True False True
- 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(56))
print(je_liche(5))
print(je_liche(0))
False True False
def je_liche(n):
return not je_sude(n)
print(je_liche(56))
print(je_liche(5))
print(je_liche(0))
False True False
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:
# 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)
lokalni 11 globalni 10
# Proměnné dělíme na globální (definované na úrovni programu)
# a lokální (definované na úrovni funkce)
# globální proměnná
globalni = 10
def f():
# lokální proměnná
lokalni = 1
lokalni += 3
# 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)
# ukázka pytutor
lokalni 4 globalni 10 globalni 10
# Parametry funkce jsou také lokální proměnné
# globální proměnná
globalni = 10
# parametry funkce jsou také lok. proměnné
def f(parametr):
# lokální proměnná
lokalni = 1
lokalni += parametr
parametr *= 10
# výpis lokálních proměnných
print("lokalni", lokalni, parametr)
# použití funkce
f(globalni)
# výpis globálních proměnných
print("globalni", globalni)
lokalni 11 100 globalni 10
# lokální proměnná žije jen uvnitř funkce, když funkce skončí, zanikne:
# globální proměnná
globalni = 10
# parametry funkce jsou také lok. proměnné
def f(parametr):
# lokální proměnná
lokalni = 1
lokalni += parametr
parametr *= 10
# výpis lokálních proměnných
print("lokalni", lokalni, parametr)
# použití funkce
f(globalni)
# 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)
lokalni 11 100 globalni 10
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[31], line 23 19 # výpis globálních proměnných 20 print("globalni", globalni) 21 22 # lokální proměnné definované uvnitř funkce nejsou k dispozici na globální úrovni ---> 23 print(lokalni) NameError: name 'lokalni' is not defined
# Globální proměnné mohu uvnitř funkce
# používat, ale nemohu je tam měnit
# 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)
# výpis globálních proměnných
print("globalni", globalni)
# 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)
lokalni 11 globalni 10 globalni 10
# Uvnitř funkce nelze měnit globální proměnné
# tj. jakmile uvnitř funkce použiju globální proměnnou, již nesmím definovat
# lokální proměnnou stejného jména:
# 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)
--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) Cell In[36], line 19 15 # výpis lokálních proměnných 16 print("lokalni", lokalni) 17 18 # použití funkce ---> 19 f() 20 21 # výpis globálních proměnných 22 print("globalni", globalni) Cell In[36], line 10, in f() 6 # lokální proměnná 7 lokalni = 1 8 9 # použití globální proměnné ---> 10 lokalni += globalni 11 12 # uvnitř funkce nelze měnit globální proměnné 13 globalni += 1 UnboundLocalError: cannot access local variable 'globalni' where it is not associated with a value
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:
# 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
# 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)
hodnota uvnitř funkce: 1 hodnota mimo funkci: 10
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.
# Výhooda: uvnitř funkce si mohu pojmenovávat proměnné, jak chci
y = 8
from math import cos
def f(x, y):
min = "minimum"
cos = "cosi"
print("uvnitř:", x + y, min, cos)
return min
print(min(4, 6), cos(0))
y = f(6, y)
print(y)
print(min(4, 6), cos(0))
4 1.0 uvnitř: 14 minimum cosi minimum 4 1.0
# 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
Příklady¶
- Definujte a zavolejte funkci
je_dělitelné(n, d), která vracíTrueneboFalsepodle toho, jestli je zadané přirozené číslondělitelné číslemd.
def je_delitelne(n, d):
if d == 0:
return False
if n % d == 0:
return True
return False
print(je_delitelne(15, 3))
print(je_delitelne(15, 5))
print(je_delitelne(15, 4))
print(je_delitelne(15, 15))
print(je_delitelne(15, 0))
print(je_delitelne(0, 3))
True True False True False True
def je_delitelne(n, d):
if d == 0:
return False
return n % d == 0
print(je_delitelne(15, 3))
print(je_delitelne(15, 5))
print(je_delitelne(15, 4))
print(je_delitelne(15, 15))
print(je_delitelne(15, 0))
print(je_delitelne(0, 3))
True True False True False True
- 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.
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(56))
print(pocet_delitelu(1))
print(pocet_delitelu(15))
8 1 4
- Napište a zavolejte funkci
vypiš_dělitele(n), která vypíše všechny dělitele přirozeného číslan.
def vypis_delitele(n):
for d in range(1, n + 1):
if je_delitelne(n, d):
print(d, end = " ")
print("")
vypis_delitele(56)
vypis_delitele(1)
vypis_delitele(15)
1 2 4 7 8 14 28 56 1 1 3 5 15
for i in range(10):
print(i, ": ", end="")
vypis_delitele(i)
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(m, h):
vysledek = m / (h / 100) ** 2
return vysledek
hmotnost = 60
vyska = 160
print(bmi(hmotnost, vyska))
print(bmi(80, 190))
23.437499999999996 22.1606648199446
- Naprogramujte funkci
součet_číslic(n), která spočítá součet číslic v desítkovém zápisu přirozeného číslan.
n = 7684
cislice = n % 10
n1 = n // 10
print(n, n1, cislice)
7684 768 4
n = 7684
while n != 0:
cislice = n % 10
n = n // 10
print(cislice)
4 8 6 7
def soucet_cislic(n):
soucet = 0
while n != 0:
cislice = n % 10
n = n // 10
soucet += cislice
return soucet
print(soucet_cislic(7684))
print(soucet_cislic(10002))
25 3
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
n = 7684
nove_cislo = 0
nasobek = 1
while n != 0:
cislice = n % 10
n = n // 10
print(cislice)
nove_cislo += cislice * nasobek
nasobek = nasobek * 10
nove_cislo
4 8 6 7
7684
n = 7684
digit = 6
nove_cislo = 0
nasobek = 1
while n != 0:
cislice = n % 10
n = n // 10
print(cislice)
if cislice != digit:
nove_cislo += cislice * nasobek
nasobek = nasobek * 10
nove_cislo
4 8 6 7
784
def remove(n, digit):
nove_cislo = 0
nasobek = 1
while n != 0:
cislice = n % 10
n = n // 10
if cislice != digit:
nove_cislo += cislice * nasobek
nasobek = nasobek * 10
return nove_cislo
print(remove(764484, 4))
print(remove(764484, 5))
print(remove(764484, 7))
768 764484 64484
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.