comment up next how to englisch dex

3. Funkce

  1. Definice a použití
  2. Průběh výpočtu
  3. Parametry, argumenty a příkaz ' import '
  4. Složené funkce
  5. Proměnné a parametry jsou lokální
  6. Schema zásobníku
  7. Glosář
  8. Cvičení

3.1 Definice a použití

V souvislosti s programováním je funkce pevně určené pořadí příkazů, které provádějí požadovanou operaci. Tato operace je popsána v definici funkce. Syntaxe pro definování funkce je tato:

def jmeno_funkce ( zoznam parametrov ):
    prikazy

Jméno funkce může být libovolné, kromě klíčového slova Pythonu. Seznam parametrů je výčet informací, které musíme funkci poskytnout. Tento výčet může být i prázdný ().

Uvnitř funkce může být libovolný počet příkazů, ale všechny musí být odsazeny od levého okraje. Doporučovány jsou 4 mezery.

Definice funkce je prvním ze složených příkazů, s kterými se postupně seznámíme. Všechy mají společný vzor:

  1. Záhlaví, které začíná klíčovým slovem a končí dvojtečkou.
  2. Tělo, skládající se z jednoho či více stejně odsazených příkazů.
Klíčovým slovem v záhlaví funkce je def, které je následováno jménem funkce a v závorkách uzavřeným výčtem parametrů. Závorky jsou požadovány, i když je výčet prázdný.

Uvedeme si příklady několika funkcí bez parametrů:

def novy_riadok ():
    print

Tato funkce se jmenuje novy_riadok. Prázdné závorky udávají, že je bez parametru. Její tělo obsahuje jediný příkaz jehož výstupem je prázdný řádek. (Použitím přikazu print bez argumentu se generuje znak pro prázdný řádek, který překladač vyhodnotí jako povel k posunu o jeden řádek.)

Definování nové funkce nespustí její provádění. K tomu musíme funkci volat. Při volání funkce zadáváme její jméno a výčet hodnot, kterým v tomto případě říkáme argumenty. Ty jsou přiřazeny k definovaným parametrům funkce. Naše první příklady funkcí nemají parametry, tudíž se při jejich volání nezadávají žádné argumenty. Závorky jsou ovšem povinné:

print "First Line"
novy_riadok()
print "Second Line"
Výstupen tohoto programu je:
First Line
Second Line

Mezera mezi řádky je výsledek volání funkce novy_riadok. Kdybychom chtěli více místa mezi řádky, můžeme volat funkci opakovaně.

print "First Line"
novy_riadok()
novy_riadok()
novy_riadok()
print "Second Line"

Nebo můžeme napsat funkci nazvanou tri_riadky, která vytiskne tři nové řádky:

def tri_riadky ():
    novy_riadok()
    novy_riadok()
    novy_riadok()

print "First Line"
tri_riadky()
print "Second Line"

Tato funkce obsahuje tři příkazy odsazené o čtyři mezery. Protože další příkaz není odsazen, Python pozná, že ten již není součástí definované funkce.

Měli bychom si zapamatovat:

V této chvíli nemusí být zcela zřejmé, jaký význam má veškeré koptění s funkcemi. Důvodů může být celá řada, ale náš přiklad demonstruje dva:

  1. Vytvoření funkce nám dává příležitost pojmenovat skupinu příkazů. Funkce zjednoduší program tím, že schovají složité počítání za jediný povel a tím, že nepřehledný kód nahradí smysluplným jménem.
  2. Vytvoření funkce zmenší velikost programu tím, že se vyloučí opakovaný kód. Devět nových řádků například vytvoříme trojím voláním fce tri_riadky.

Zapíšeme-li útržky kódů z předchozích odstavců do jednoho skriptu (test1.py), může celý program vypadat takto:

def novy_riadok ():
    print

def tri_riadky ():
    novy_riadok
    novy_riadok
    novy_riadok

print "First Line."
tri_riadky()
print "Second Line."

V tomto programu jsou dvě definice funkcí: novy_riadok a tri_riadky. Příkazy uvnitř funkce jsou prováděny až poté, co je funkce volána. Samotná definice funkce negeneruje žádný výstup.

Z čehož tedy vyplývá, že funkce musí být vytvořena před tím, než je volána.

3.2 Průběh výpočtu

Abychom si byli jisti, že funkce je definována před jejím prvním užitím, potřebujeme znát pořadí, ve kterém jsou příkazy prováděny, neboli průběh výpočtu či průběh provádění.

Provádění vždy začíná prvním příkazem programu. Příkazy jsou prováděny jeden za druhým, většinou od shora dolů.

Definice funkcí nemění průběh výpočtu, ale připomeňme si, že příkazy uvnitř definice se provádějí až po volání funkce. I když je to neobvyklé, můžeme definovat funkci uvnitř jiné funkce. V tomto případě není vnitřní funkce provedena dřív, než je volána vnější funkce.

Volání funkce při běhu programu je jako příkaz k objížďce. Místo přechodu k následujícímu příkazu přeskočí průběh k prvnímu řádku volané funkce, provede tam všechny příkazy a vrátí se tam, kde odbočil.

To zní docela prostě, dokud si neuvědomíme, že jedna funkce může volat druhou. Nacházejíce se uvnitř jedné funkce, může mít program přikázáno provést příkaz v jiné funkci. Provádějíc příkaz v oné jiné funkci, může přijít přikaz k přechodu do ještě jiné funkce ... !

Naštěstí si Python důkladně zaznamenává, kudy při provádění programu prochází, takže se vždy správně vrací tam, odkud při volání funkce vyšel a to tak dlouho, dokud nedojde na konec programu.

Jaké je poučení z tohoto skličujícího příběhu? Čteme-li program, nečteme jej nutně shora dolů, nýbrž sledujeme průběh jeho provádění (výpočtu, exekuce).

3.3 Parametry, argumenty a příkaz ' import '

Většina funkcí musí mít pro své provedení zadány argumenty, to jest hodnoty, s nimiž fce pracuje. Chceme-li například nalézt absolutní hodnotu čísla např. 5, můžeme použít vestavěnou funkci abs(n):

>>> abs (5)
5
>>> abs (-5)
5

V tomto příkladě jsou argumenty funkce abs(n) čísla 5 a -5.

Některé funkce přjímají více než jeden argument. Například vestavěná funkce pow přijímá dva argumenty, základ a mocnitel. Zadané hodnoty jsou uvnitř funkce přiřazeny proměnným s názvem parametry.

>>> pow (2, 3)
8
>>> pow (7, 4)
2401

Jinou funkcí, která přijímá více než jedem argument je vestavěná funkce max, která vrátí největší ze zadaných argumentů.

>>> max (7, 11)
11
>>> max (4, 1, 17, 2, 12)
17
>>> max (3*11, 5**3, 512-9, 1024*0)
503

Nyní si uvedeme příklad uživatelsky definované funkce s argumentem.

 def print_twice(bruce):
     print  bruce, bruce

Tato funkce přijímá jeden argument a přiřadí jej k parametru se jménem bruce. Hodnota parametru (v této chvíli nevíme jaká bude) je tištěna dvakrát. Je vhodné, když název parametru naznačuje typ zadávané hodnoty.

V interaktivním rozhraní Pythonu (IRP) naše funkce snadno vyzkoušíme s použitím příkazu import. Mějme definici funkce print_twice uloženou v souboru kap03.py. Pokud tento soubor a program Python jsou ve stejném adresáři, můžeme tuto funkci importovat do otevřeného IRP:

>>> from kap03 import *
>>> print_twice ('Spam')
Spam Spam
>>> print_twice (5)
5 5
>>> print_twice (3.14159)
3.14159 3.14159

Hodnota argumentu (postupně 'Spam', 5, 3.14159) je při volání funkce přiřazována parametru bruce. Funkci lze zadat libovolný tisknutelný typ argumentu. V našem příkladě jsme postupně zadali řetězec, celé číslo a desetinné číslo.

Stejně jako u vestavěných funkcí můžeme i naši fci print_twice zadat výraz jako argument:

>>> print_twice ('Spam' * 4)
SpamSpamSpamSpam SpamSpamSpamSpam

Výraz 'Spam' * 4 je nejprve převeden na tvar SpamSpamSpamSpam, který je potom zadán funkci jako argument.

3.4 Složené funkce

Stejně jako u matematických funkcí i funkce Pythonu lze skládat, to jest použít výstup z jedné funkce jako argument pro druhou.

>>> print_twice(abs(-7))
7 7
>>> print_twice(max(3, 1, abs(-11), 7))
11 11

V prvním příkladu se vypočítané číslo 7 z fce abs(-7) zadá jako argument fci print_twice. Ve druhém příkladě máme dvě úrovně skladby, neboť výsledek z abs(-11) vstoupí do fce max(3, 1, 11, 7) a její výstup 11 je zpracován fcí print_twice.

Jako argument můžeme také použít proměnnou:

>>> michal = 'Male selatko.'
>>> print_twice(michal)
Male selatko. Male selatko.

Povšimněme si zde jedné důležité věci. Jméno proměnné michal, kterou zadáváme jako argument, nemá nic společného se jménem parametru bruce. Funkce print_twice říká každému bruce.

3.5 Proměnné a parametry jsou lokální

Vytvoříme-li proměnnou uvnitř funkce, má platnost pouze uvnitř této funkce a mimo ní ji nelze použít. Říkáme, že je to lokální proměnná. Například:

def cat_twice(part1, part2):
    cat = part1 + part2
    print_twice(cat)

Tato funkce přijímá dva argumenty, zřetězí je a posléze je dvakrát vytiskne. Použijeme dva řetězce:

>>> chant1 = "Pie Jesu domine, "
>>> chant2 = "Dona eis requiem."
>>> cat_twice(chant1, chant2)
Pie Jesu domine, Dona eis requiem. Pie Jesu domine, Dona eis requiem.

Proměnná cat je zničena po ukončení funkce cat_twice. Pokusíme-li se ji vytisknout, dostaneme chybové hlášení:

>>> print cat
NameError: name 'cat' is not defined

Parametry jsou také lokální. Mimo funkci print_twice například neexistuje žádné jméno bruce. Pokusíme-li se jej použít, bude si Python stěžovat.

3.6 Zobrazení zásobníku

Abychom mohli sledovat, která proměnná je kde použita, bývá užitečné vytvořit si schematické zobrazení zásobníku (stack diagram). Podobně jako u zobrazení vztahů i v zobrazení zásobníku se uvádí hodnota pro každou proměnnou, zde navíc se jménem funkce, ke které proměnná patří.

Každá funkce je reprezentována svým rámcem. Rámec tvoří jméno funkce s přilehlým obdélníkem, ve kterém jsou uvedeny její parametry a proměnné. Schéma zásobníku pro předchozí příklad vypadá takto:

Uspořádání schematu ukazuje průběh provádění. Funkce print_twice byla volána funkcí cat_twice a cat_twice byla volána funkcí __main__, což je speciální jméno pro nejvrchnější funkci. Když vytvoříme proměnnou vně jakékoliv funkce, patří do __main__.

Každý parametr se vztahuje k téže hodnotě jako jeho odpovídající argument. Tudíž part1 má stejnou hodnotu jako chant1, part2 má stejnou hodnotu jako chant2 a bruce má stejnou hodnotu jako cat.

Objeví-li se chyba při volání funkce, vytiskne Python jména všech funkcí, které se na tomto volání podílely; počínaje poslední, konče první zúčastněnou.

Vyzkoušejme si to. Vytvoříme skript se jménem test2.py, který vypadá takto:

def print_twice(bruce):
    print bruce, bruce 
    print cat

def cat_twice(part1, part2):
    cat = part1 + part2
    print_twice(cat)

chant1 = "Pie Jesu domine, "
chant2 = "Dona eis requim."
cat_twice(chant1, chant2)

Do funkce print_twice jsme přidali příkaz print cat, ale tam není proměnná cat definována. Běh skriptu vyvolá takovéto chybové hlášení:

Traceback (innermost last):
  File "test2.py", line 11, in <module>
    cat_twice(chant1, chant2)
  File "test2.py", line 7, in catTwice
    print_twice(cat)
  File "test2.py", line 3, in printTwice
    print cat
NameError: global name 'cat' is not defined

Tento seznam funkcí se nazývá zpětný záznam (traceback). Říká nám ve kterém souboru se chyba vyskytla, který řádek a které funkce byly právě prováděny. Také označí číslo řádku na kterém k chybě došlo

Všimněme si podobnosti mezi zpětným záznamem a zobrazením zásobníku, není náhodná.

3.7 Glosář

Python 2.5.2.2 (...)
...
>>>
Ve skriptu máme definována tři jména: print_thrice, n a s. Pokusíme-li se je použít předtím, než je importujeme, dostaneme chybové hlášení:
funkce (function)
Pojmenovaný sled příkazů, který provede nějakou užitečnou operaci. Funkce mohou nebo nemusí mít parametry a mohou nebo nemusí produkovat výsledek.
definice funkce (function definition)
Příkaz, který pro novou funkci určí jméno, parametry a příkazy, jež má provádět.
složený příkaz (compound statement)
Příkaz, který se skládá ze dvou částí:
  1. záhlaví - začíná klíčovým slovem pro příkaz a končí dvojtečkou
  2. tělo - obsahuje jeden nebo více příkazů, které jsou stejně odsazené zleva
Skladba složeného příkazu vypadá takto:
klíčové_slovo_příkazu:
    příkaz
    příkaz ... 
volání funkce (function call)
Příkaz k provedení funkce. Skladá se z jména funkce před závorkou se seznamem argumentů.
průběh výpočtu (flow of execution)
Pořadí, ve kterém jsou příkazy prováděny během běhu programu.
parameter
Jméno uvnitř (definice) funkce, které se vztahuje k hodnotě, poskytnuté ji (při volání) jako argument.
IRP (Python shell)
Interaktivní rozhranní Pythonu.
import
Příkaz, kterým do skriptu nebo otevřeného IRP vložíme (importujeme) funkci nebo proměnnou, definovanou v jiném skriptu.

Mějme například následující kód ve skriptu test.py:

def print_thrice(thing):

n = 42
s = "A teraz z jineho soudku ..."
Nyní si otevřeme IRP (který je ve stejném adresáři jako test.py):
>>> n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined
>>> print_thrice("ouch!")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'print_thrice' is not defined
Poté, co importujeme z test.py vše, můžeme vše použít:
>>> from test import *
>>> n
42
>>> s
"A teraz z jineho soudku ..."
>>> print_thrice("Yupee!")
Yupee! Yupee! Yupee!
>>>
Všimněme si toho, že jsme do příkazu import nezahrnuli příponu .py.
argument
Hodnota, poskytovaná volané funkci. Tato hodnota je přiřazena odpovídajícímu parametru funkce.
spojení funkcí (function composition)
Výstup z jedné funkce použijeme jako vstup pro druhou.
lokální proměnná (local variable)
Proměnná, která je definovaná uvnitř funkce, kde pouze smí být užita.
schematické zobrazení zásobníku (stack diagram)
Grafické zobrazení řady funkcí, jejich proměnných i příslušných hodnot.
rámec (frame)
Obdélník ve schematu zásobníku, který představuje volání fce. Obsahuje lokální proměnné a parametry fce.
zpětný záznam (traceback)
Seznam prováděných funkcí, který se zobrazí na obrazovce, když se vyskytne chyba při běhu programu. Zpětný záznam je také uváděn jako záznam zásobníku, protože probírá funkce v pořadí, ve kterém byly do zásobníku pro běh programu (runtime stack) zařazeny.

3.8 Cvičení

  1. S použitím textového editoru vytvoř skript test3.py Napiš funkci jménem nine_lines, která použije funkci tri_riadky k vytištění devíti prázdných řádek. Nyní přidej fci clear_screen, která vytiskne 25 prázdných řádek. Poslední řádkou skriptu by mělo být volání fce clear_screen.
  2. Poslední řádek programu test3.py přesuň úplně nahoru, takže se volání funkcíe clear_screen dostane před jeji definici. Spusť program a sleduj, jaké chybové hlášení dostaneš. Jaké z toho plyne pravidlo?
  3. V chodící verzi test3.py přesuň definici novy_riadok za definici tri_riadky. Sleduj chování spuštěného programu. Nyní přesuň definici novy_riadok za volání fce tri_riadky. Posuď souvislost s pravidlem z předchozího cvičení.
  4. Doplň tělo definované fce cat_n_times tak, aby n krát vytiskla řetězec s:
    def cat_n_times(s,n):
        <zde zapiš svůj kód>
    Ulož skript import_test.py do adresáře, ve kterém máš uložen exe soubor IRP. Spusť IRP a zkus následující:
    >>> from import_test import *
    >>> cat_n_times('Spam, 7')
    SpamSpamSpamSpamSpamSpamSpam
    
    Chodí? Vyzkoušej si funkci i pro jiné argumenty.

comment up next how to englisch dex