Funkce

Dříve jsme volaly funkce, které napsal někdo jiný:

print('Ahoj světe!')

Dnes si ukážeme, jak psát funkce vlastní.

Není to tak složité:

def obvod_obdelnika(sirka, vyska):
    "Vrátí obvod obdélníka daných rozměrů"
    return 2 * (sirka + vyska)

print(obvod_obdelnika(4, 2))

Jak to funguje?

Funkce se definuje příkazem def, za nějž napíšeš jméno funkce, pak do závorky seznam argumentů, které funkce bere, a pak dvojtečku.

Potom následuje odsazené tělo funkce – příkazy, které funkce provádí. Tělo může začít dokumentačním řetězcem, který popisuje, co funkce dělá.

Příkazem return pak můžeš z funkce vrátit nějakou hodnotu.

Tělo funkce může mít více příkazů, včetně podmínek, cyklů a podobně:

def napis_hlasku(nazev, skore):
    "Popíše skóre. Název má být přivlastňovací přídavné jméno."

    print(nazev, 'skóre je', skore)
    if skore > 1000:
        print('Světový rekord!')
    elif skore > 100:
        print('Skvělé!')
    elif skore > 10:
        print('Ucházející.')
    elif skore > 1:
        print('Aspoň něco')
    else:
        print('Snad příště.')

napis_hlasku('Tvoje', 256)
napis_hlasku('Protivníkovo', 5)

Při volání funkce se hodnoty, se kterými funkci zavoláš, přiřadí jednotlivým argumentům. Takže když zavoláš třeba napis_hlasku('Tvoje', 256), můžeš si představit, že funkce dělá následující:

nazev = 'Tvoje'
skore = 256

print(nazev, 'skóre je', skore)
if skore > 1000:
    ... # atd.

Vracení

Speciální příkaz return, který jde použít jenom ve funkcích, ukončí funkci a vrátí danou hodnotu ven z funkce.

Chová se tedy trochu jako break, jen místo cyklu opouští celou funkci.

def ano_nebo_ne(otazka):
    "Vrátí True nebo False, podle odpovědi uživatele"
    while True:
        odpoved = input(otazka)
        if odpoved == 'ano':
            return True
        elif odpoved == 'ne':
            return False
        else:
            print('Nerozumím! Odpověz "ano" nebo "ne".')

if ano_nebo_ne('Chceš si zahrát hru? '):
    print('OK! Ale napřed si ji musíš naprogramovat.')
else:
    print('Škoda.')

Stejně jako if nebo break je return příkaz, ne funkce. Kolem „své“ hodnoty nepotřebuje závorky.

Zkus napsat funkci, která vrátí obsah elipsy daných rozměrů. Příslušný vzoreček je A = πab, kde a a b jsou délky os.

Funkci zavolej a výsledek vypiš.

Řešení

Vrátit nebo vypsat?

Předchozí program se dá napsat i takto:

from math import pi

def obsah_elipsy(a, b):
    print('Obsah je', pi * a * b)  # Pozor, `print` místo `return`!

obsah_elipsy(3, 5)

Program takhle funguje, ale přichází o jednu z hlavních výhod funkcí: možnost vrácenou hodnotu použít i jinak jež jen v print.

Funkci, která výsledek vrací, můžeš použít v dalších výpočtech:

def objem_eliptickeho_valce(a, b, vyska):
    return obsah_elipsy(a, b) * vyska

print(objem_eliptickeho_valce(3, 5, 3))

... ale kdyby výsledek přímo vypsala, nešlo by to.

Další důvod, proč hodnoty spíš vracet než vypisovat, je ten, že jedna funkce se dá použít v různých situacích. Funkci s print by nešlo rozumně použít tehdy, když nás příkazová řádka vůbec nezajímá. Třeba v grafické hře, webové aplikaci, nebo pro ovládání robota.

Podobně je to se vstupem: když použiju v rámci své funkce input, bude se moje funkce dát použít jen v situacích, kdy je u počítače klávesnice a za ní člověk. Proto je lepší funkcím potřebné informace předávat jako argumenty a input (nebo textové políčko či měření z čidla robota) nemít ve funkci, ale vně:

from math import pi

def obsah_elipsy(a, b):
    """Vrátí obsah elipsy s poloosami daných délek"""
    # Jen samotný výpočet:
    return pi * a * b

# print a input jsou "venku":
x = input('Zadej délku poloosy 1: ')
y = input('Zadej délku poloosy 2: ')
print('Obsah je', obsah_elipsy(x, y))

Samozřejmě existují výjimky: funkce která přímo vytváří textový výpis, může používat print; funkce která načítá textové informace zase input. Když ale funkce něco počítá, je dobré v ní print ani input nemít.

None

Když funkce neskončí příkazem return, automaticky se vrátí hodnota None.

Je to hodnota zabudovaná přímo do Pythonu, podobně jako True nebo False, a znamená „nic“.

def nic():
    "Tahle funkce nic nedělá"

print(nic())

Lokální proměnné

Gratuluji, umíš definovat vlastní funkce! Zbývá ještě vysvětlit jednu věc: lokální a globální proměnné.

Funkce může používat proměnné „zvnějšku“:

pi = 3.1415926

def obsah_kruhu(polomer):
    return pi * polomer ** 2

print(obsah_kruhu(100))

Ale všechny argumenty a všechny proměnné, do kterých funkce přiřazuje, jsou úplně nové proměnné, které nemají nic společného s tím, co je „venku“ kolem funkce.

Těm úplně novým proměnným se říká lokální proměnné (angl. local variables), protože existují jen místně, v rámci volání jedné jediné funkce. Takže tohle nebude fungovat tak, jak se zdá:

x = 0

def nastav_x(hodnota):
    x = hodnota  # Přiřazení do lokální proměnné!

nastav_x(40)
print(x)

Proměnné, které nejsou lokální, jsou globální – ty existují v celém programu. (Jen ve funkcích, které mají náhodou lokální proměnnou stejného jména, „nejsou vidět“ – to jméno označuje lokální proměnnou.)

Pojďme si to ukázat. Než spustíš tenhle program, zkus předpovědět, co bude dělat. Pak ho pusť, a pokud dělal něco jiného, zkus vysvětlit proč. Pozor, je tam chyták!

from math import pi
obsah = 0
a = 30

def obsah_elipsy(a, b):
    obsah = pi * a * b  # Přiřazení do `obsah`
    a = a + 3  # Přiřazení do `a`
    return obsah

print(obsah_elipsy(a, 20))
print(obsah)
print(a)

Zkus odpovědět na tyto otázky:

  • Je proměnná pi lokální, nebo globální?
  • Je proměnná obsah lokální, nebo globální?
  • Je proměnná a lokální, nebo globální?
  • Je proměnná b lokální, nebo globální?

Řešení

Jestli ti to celé připadá zmatené a složité, dá se tomu zatím vyhnout dodržováním jednoho pravidla: nepřiřazuj ve funkcích do proměnných, které existují i vně funkce. (Parametr funkce se počítá jako přiřazení.)

{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2017/pyladies-praha-podzim-ntk:def-str:0",
      "title": "VlastnĂ­ funkce",
      "html": "\n          \n    \n\n    <h1>Funkce</h1>\n<p><a href=\"/2017/pyladies-praha-podzim-ntk/beginners/functions/\">D&#x159;&#xED;ve</a> jsme\nvolaly funkce, kter&#xE9; napsal n&#x11B;kdo jin&#xFD;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Ahoj sv&#x11B;te!&apos;</span><span class=\"p\">)</span>\n</pre></div><p>Dnes si uk&#xE1;&#x17E;eme, jak ps&#xE1;t funkce vlastn&#xED;.</p>\n<p>Nen&#xED; to tak slo&#x17E;it&#xE9;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">obvod_obdelnika</span><span class=\"p\">(</span><span class=\"n\">sirka</span><span class=\"p\">,</span> <span class=\"n\">vyska</span><span class=\"p\">):</span>\n    <span class=\"s2\">&quot;Vr&#xE1;t&#xED; obvod obd&#xE9;ln&#xED;ka dan&#xFD;ch rozm&#x11B;r&#x16F;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"mi\">2</span> <span class=\"o\">*</span> <span class=\"p\">(</span><span class=\"n\">sirka</span> <span class=\"o\">+</span> <span class=\"n\">vyska</span><span class=\"p\">)</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obvod_obdelnika</span><span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n</pre></div><p>Jak to funguje?</p>\n<p>Funkce se <em>definuje</em> p&#x159;&#xED;kazem <code>def</code>, za n&#x11B;j&#x17E; nap&#xED;&#x161;e&#x161; jm&#xE9;no funkce,\npak do z&#xE1;vorky seznam <em>argument&#x16F;</em>, kter&#xE9; funkce bere, a pak dvojte&#x10D;ku.</p>\n<p>Potom n&#xE1;sleduje odsazen&#xE9; <em>t&#x11B;lo funkce</em> &#x2013; p&#x159;&#xED;kazy, kter&#xE9; funkce prov&#xE1;d&#xED;.\nT&#x11B;lo m&#x16F;&#x17E;e za&#x10D;&#xED;t <em>dokumenta&#x10D;n&#xED;m &#x159;et&#x11B;zcem</em>, kter&#xFD; popisuje, co funkce d&#x11B;l&#xE1;.</p>\n<p>P&#x159;&#xED;kazem <code>return</code> pak m&#x16F;&#x17E;e&#x161; z&#xA0;funkce\nvr&#xE1;tit n&#x11B;jakou hodnotu.</p>\n<p>T&#x11B;lo funkce m&#x16F;&#x17E;e m&#xED;t v&#xED;ce p&#x159;&#xED;kaz&#x16F;, v&#x10D;etn&#x11B; podm&#xED;nek, cykl&#x16F; a podobn&#x11B;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">napis_hlasku</span><span class=\"p\">(</span><span class=\"n\">nazev</span><span class=\"p\">,</span> <span class=\"n\">skore</span><span class=\"p\">):</span>\n    <span class=\"s2\">&quot;Pop&#xED;&#x161;e sk&#xF3;re. N&#xE1;zev m&#xE1; b&#xFD;t p&#x159;ivlast&#x148;ovac&#xED; p&#x159;&#xED;davn&#xE9; jm&#xE9;no.&quot;</span>\n\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">nazev</span><span class=\"p\">,</span> <span class=\"s1\">&apos;sk&#xF3;re je&apos;</span><span class=\"p\">,</span> <span class=\"n\">skore</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"n\">skore</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1000</span><span class=\"p\">:</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Sv&#x11B;tov&#xFD; rekord!&apos;</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"n\">skore</span> <span class=\"o\">&gt;</span> <span class=\"mi\">100</span><span class=\"p\">:</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Skv&#x11B;l&#xE9;!&apos;</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"n\">skore</span> <span class=\"o\">&gt;</span> <span class=\"mi\">10</span><span class=\"p\">:</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Uch&#xE1;zej&#xED;c&#xED;.&apos;</span><span class=\"p\">)</span>\n    <span class=\"k\">elif</span> <span class=\"n\">skore</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Aspo&#x148; n&#x11B;co&apos;</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Snad p&#x159;&#xED;&#x161;t&#x11B;.&apos;</span><span class=\"p\">)</span>\n\n<span class=\"n\">napis_hlasku</span><span class=\"p\">(</span><span class=\"s1\">&apos;Tvoje&apos;</span><span class=\"p\">,</span> <span class=\"mi\">256</span><span class=\"p\">)</span>\n<span class=\"n\">napis_hlasku</span><span class=\"p\">(</span><span class=\"s1\">&apos;Protivn&#xED;kovo&apos;</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)</span>\n</pre></div><p>P&#x159;i vol&#xE1;n&#xED; funkce se hodnoty, se kter&#xFD;mi funkci\nzavol&#xE1;&#x161;, p&#x159;i&#x159;ad&#xED; jednotliv&#xFD;m argument&#x16F;m.\nTak&#x17E;e kdy&#x17E; zavol&#xE1;&#x161; t&#x159;eba <code>napis_hlasku(&apos;Tvoje&apos;, 256)</code>,\nm&#x16F;&#x17E;e&#x161; si p&#x159;edstavit, &#x17E;e funkce d&#x11B;l&#xE1; n&#xE1;sleduj&#xED;c&#xED;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">nazev</span> <span class=\"o\">=</span> <span class=\"s1\">&apos;Tvoje&apos;</span>\n<span class=\"n\">skore</span> <span class=\"o\">=</span> <span class=\"mi\">256</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">nazev</span><span class=\"p\">,</span> <span class=\"s1\">&apos;sk&#xF3;re je&apos;</span><span class=\"p\">,</span> <span class=\"n\">skore</span><span class=\"p\">)</span>\n<span class=\"k\">if</span> <span class=\"n\">skore</span> <span class=\"o\">&gt;</span> <span class=\"mi\">1000</span><span class=\"p\">:</span>\n    <span class=\"o\">...</span> <span class=\"c1\"># atd.</span>\n</pre></div><h2>Vracen&#xED;</h2>\n<p>Speci&#xE1;ln&#xED; p&#x159;&#xED;kaz <code>return</code>, kter&#xFD; jde pou&#x17E;&#xED;t jenom ve funkc&#xED;ch,\n<em>ukon&#x10D;&#xED;</em> funkci a vr&#xE1;t&#xED; danou hodnotu ven z&#xA0;funkce.</p>\n<p>Chov&#xE1; se tedy trochu jako <code>break</code>, jen m&#xED;sto cyklu opou&#x161;t&#xED; celou funkci.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">ano_nebo_ne</span><span class=\"p\">(</span><span class=\"n\">otazka</span><span class=\"p\">):</span>\n    <span class=\"s2\">&quot;Vr&#xE1;t&#xED; True nebo False, podle odpov&#x11B;di u&#x17E;ivatele&quot;</span>\n    <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span>\n        <span class=\"n\">odpoved</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"n\">otazka</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">odpoved</span> <span class=\"o\">==</span> <span class=\"s1\">&apos;ano&apos;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"bp\">True</span>\n        <span class=\"k\">elif</span> <span class=\"n\">odpoved</span> <span class=\"o\">==</span> <span class=\"s1\">&apos;ne&apos;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"bp\">False</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Nerozum&#xED;m! Odpov&#x11B;z &quot;ano&quot; nebo &quot;ne&quot;.&apos;</span><span class=\"p\">)</span>\n\n<span class=\"k\">if</span> <span class=\"n\">ano_nebo_ne</span><span class=\"p\">(</span><span class=\"s1\">&apos;Chce&#x161; si zahr&#xE1;t hru? &apos;</span><span class=\"p\">):</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;OK! Ale nap&#x159;ed si ji mus&#xED;&#x161; naprogramovat.&apos;</span><span class=\"p\">)</span>\n<span class=\"k\">else</span><span class=\"p\">:</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;&#x160;koda.&apos;</span><span class=\"p\">)</span>\n</pre></div><div class=\"admonition note\"><p>Stejn&#x11B; jako <code>if</code> nebo <code>break</code> je <code>return</code> <em>p&#x159;&#xED;kaz</em>, ne funkce.\nKolem &#x201E;sv&#xE9;&#x201C; hodnoty nepot&#x159;ebuje z&#xE1;vorky.</p>\n</div><p>Zkus napsat funkci, kter&#xE1; vr&#xE1;t&#xED; obsah elipsy\ndan&#xFD;ch rozm&#x11B;r&#x16F;.\nP&#x159;&#xED;slu&#x161;n&#xFD; vzore&#x10D;ek je <var>A</var> = &#x3C0;<var>a</var><var>b</var>,\nkde <var>a</var> a <var>b</var> jsou d&#xE9;lky os.</p>\n<p>Funkci zavolej a v&#xFD;sledek vypi&#x161;.</p>\n<div class=\"solution\" id=\"solution-0\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2017/pyladies-praha-podzim-ntk/beginners/def/index/solutions/0/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Obsah elipsy s osami 3 cm a 5 cm je&apos;</span><span class=\"p\">,</span> <span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"s1\">&apos;cm2&apos;</span><span class=\"p\">)</span>\n</pre></div>\n    </div>\n</div><h3>Vr&#xE1;tit nebo vypsat?</h3>\n<p>P&#x159;edchoz&#xED; program se d&#xE1; napsat i takto:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Obsah je&apos;</span><span class=\"p\">,</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span><span class=\"p\">)</span>  <span class=\"c1\"># Pozor, `print` m&#xED;sto `return`!</span>\n\n<span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)</span>\n</pre></div><p>Program takhle funguje, ale p&#x159;ich&#xE1;z&#xED; o jednu z hlavn&#xED;ch v&#xFD;hod funkc&#xED;:\nmo&#x17E;nost vr&#xE1;cenou hodnotu pou&#x17E;&#xED;t i jinak je&#x17E; jen v&#xA0;<code>print</code>.</p>\n<p>Funkci, kter&#xE1; v&#xFD;sledek vrac&#xED;, m&#x16F;&#x17E;e&#x161; pou&#x17E;&#xED;t v&#xA0;dal&#x161;&#xED;ch v&#xFD;po&#x10D;tech:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">objem_eliptickeho_valce</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">vyska</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"n\">vyska</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">objem_eliptickeho_valce</span><span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">))</span>\n</pre></div><p>... ale kdyby v&#xFD;sledek p&#x159;&#xED;mo vypsala, ne&#x161;lo by to.</p>\n<p>Dal&#x161;&#xED; d&#x16F;vod, pro&#x10D; hodnoty sp&#xED;&#x161; vracet ne&#x17E; vypisovat, je ten, &#x17E;e jedna funkce se\nd&#xE1; pou&#x17E;&#xED;t v&#xA0;r&#x16F;zn&#xFD;ch situac&#xED;ch.\nFunkci s&#xA0;<code>print</code> by ne&#x161;lo rozumn&#x11B; pou&#x17E;&#xED;t tehdy, kdy&#x17E; n&#xE1;s p&#x159;&#xED;kazov&#xE1;\n&#x159;&#xE1;dka v&#x16F;bec nezaj&#xED;m&#xE1;.\nT&#x159;eba v&#xA0;grafick&#xE9; h&#x159;e, webov&#xE9; aplikaci, nebo pro ovl&#xE1;d&#xE1;n&#xED; robota.</p>\n<p>Podobn&#x11B; je to se vstupem: kdy&#x17E; pou&#x17E;iju v&#xA0;r&#xE1;mci sv&#xE9; funkce <code>input</code>, bude se\nmoje funkce d&#xE1;t pou&#x17E;&#xED;t jen v situac&#xED;ch, kdy je u po&#x10D;&#xED;ta&#x10D;e kl&#xE1;vesnice a za n&#xED;\n&#x10D;lov&#x11B;k.\nProto je lep&#x161;&#xED; funkc&#xED;m pot&#x159;ebn&#xE9; informace p&#x159;ed&#xE1;vat jako argumenty\na <code>input</code> (nebo textov&#xE9; pol&#xED;&#x10D;ko &#x10D;i m&#x11B;&#x159;en&#xED; z&#xA0;&#x10D;idla robota) nem&#xED;t ve funkci,\nale vn&#x11B;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Vr&#xE1;t&#xED; obsah elipsy s poloosami dan&#xFD;ch d&#xE9;lek&quot;&quot;&quot;</span>\n    <span class=\"c1\"># Jen samotn&#xFD; v&#xFD;po&#x10D;et:</span>\n    <span class=\"k\">return</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span>\n\n<span class=\"c1\"># print a input jsou &quot;venku&quot;:</span>\n<span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zadej d&#xE9;lku poloosy 1: &apos;</span><span class=\"p\">)</span>\n<span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"nb\">input</span><span class=\"p\">(</span><span class=\"s1\">&apos;Zadej d&#xE9;lku poloosy 2: &apos;</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Obsah je&apos;</span><span class=\"p\">,</span> <span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">))</span>\n</pre></div><p>Samoz&#x159;ejm&#x11B; existuj&#xED; v&#xFD;jimky: funkce kter&#xE1; p&#x159;&#xED;mo vytv&#xE1;&#x159;&#xED; textov&#xFD; v&#xFD;pis,\nm&#x16F;&#x17E;e pou&#x17E;&#xED;vat <code>print</code>; funkce kter&#xE1; na&#x10D;&#xED;t&#xE1; textov&#xE9; informace zase <code>input</code>.\nKdy&#x17E; ale funkce n&#x11B;co po&#x10D;&#xED;t&#xE1;, je dobr&#xE9; v&#xA0;n&#xED; <code>print</code> ani <code>input</code> nem&#xED;t.</p>\n<h2>None</h2>\n<p>Kdy&#x17E; funkce neskon&#x10D;&#xED; p&#x159;&#xED;kazem <code>return</code>,\nautomaticky se vr&#xE1;t&#xED; hodnota <code>None</code>.</p>\n<p>Je to hodnota zabudovan&#xE1; p&#x159;&#xED;mo do Pythonu, podobn&#x11B; jako <code>True</code> nebo <code>False</code>,\na znamen&#xE1; &#x201E;nic&#x201C;.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">nic</span><span class=\"p\">():</span>\n    <span class=\"s2\">&quot;Tahle funkce nic ned&#x11B;l&#xE1;&quot;</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">nic</span><span class=\"p\">())</span>\n</pre></div><h2>Lok&#xE1;ln&#xED; prom&#x11B;nn&#xE9;</h2>\n<p>Gratuluji, um&#xED;&#x161; definovat vlastn&#xED; funkce!\nZb&#xFD;v&#xE1; je&#x161;t&#x11B; vysv&#x11B;tlit jednu v&#x11B;c: lok&#xE1;ln&#xED; a glob&#xE1;ln&#xED; prom&#x11B;nn&#xE9;.</p>\n<p>Funkce m&#x16F;&#x17E;e pou&#x17E;&#xED;vat prom&#x11B;nn&#xE9; &#x201E;zvn&#x11B;j&#x161;ku&#x201C;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">pi</span> <span class=\"o\">=</span> <span class=\"mf\">3.1415926</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_kruhu</span><span class=\"p\">(</span><span class=\"n\">polomer</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">polomer</span> <span class=\"o\">**</span> <span class=\"mi\">2</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obsah_kruhu</span><span class=\"p\">(</span><span class=\"mi\">100</span><span class=\"p\">))</span>\n</pre></div><p>Ale v&#x161;echny argumenty a v&#x161;echny prom&#x11B;nn&#xE9;, do kter&#xFD;ch funkce p&#x159;i&#x159;azuje,\njsou <em>&#xFA;pln&#x11B; nov&#xE9;</em> prom&#x11B;nn&#xE9;, kter&#xE9; nemaj&#xED; nic\nspole&#x10D;n&#xE9;ho s t&#xED;m, co je &#x201E;venku&#x201C; kolem funkce.</p>\n<p>T&#x11B;m &#xFA;pln&#x11B; nov&#xFD;m prom&#x11B;nn&#xFD;m se &#x159;&#xED;k&#xE1;\n<em>lok&#xE1;ln&#xED; prom&#x11B;nn&#xE9;</em> (angl. <em>local variables</em>), proto&#x17E;e existuj&#xED;\njen m&#xED;stn&#x11B;, v r&#xE1;mci vol&#xE1;n&#xED; jedn&#xE9; jedin&#xE9; funkce.\nTak&#x17E;e tohle nebude fungovat tak, jak se zd&#xE1;:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">nastav_x</span><span class=\"p\">(</span><span class=\"n\">hodnota</span><span class=\"p\">):</span>\n    <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"n\">hodnota</span>  <span class=\"c1\"># P&#x159;i&#x159;azen&#xED; do lok&#xE1;ln&#xED; prom&#x11B;nn&#xE9;!</span>\n\n<span class=\"n\">nastav_x</span><span class=\"p\">(</span><span class=\"mi\">40</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span>\n</pre></div><p>Prom&#x11B;nn&#xE9;, kter&#xE9; nejsou lok&#xE1;ln&#xED;, jsou <em>glob&#xE1;ln&#xED;</em> &#x2013; ty\nexistuj&#xED; v cel&#xE9;m programu.\n(Jen ve funkc&#xED;ch, kter&#xE9; maj&#xED; n&#xE1;hodou\nlok&#xE1;ln&#xED; prom&#x11B;nnou stejn&#xE9;ho jm&#xE9;na, &#x201E;nejsou vid&#x11B;t&#x201C; &#x2013;\nto jm&#xE9;no ozna&#x10D;uje lok&#xE1;ln&#xED; prom&#x11B;nnou.)</p>\n<p>Poj&#x10F;me si to uk&#xE1;zat.\nNe&#x17E; spust&#xED;&#x161; tenhle program,\nzkus p&#x159;edpov&#x11B;d&#x11B;t, co bude d&#x11B;lat.\nPak ho pus&#x165;, a pokud d&#x11B;lal n&#x11B;co jin&#xE9;ho,\nzkus vysv&#x11B;tlit pro&#x10D;.\nPozor, je tam chyt&#xE1;k!</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">math</span> <span class=\"kn\">import</span> <span class=\"n\">pi</span>\n<span class=\"n\">obsah</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n<span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"mi\">30</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n    <span class=\"n\">obsah</span> <span class=\"o\">=</span> <span class=\"n\">pi</span> <span class=\"o\">*</span> <span class=\"n\">a</span> <span class=\"o\">*</span> <span class=\"n\">b</span>  <span class=\"c1\"># P&#x159;i&#x159;azen&#xED; do `obsah`</span>\n    <span class=\"n\">a</span> <span class=\"o\">=</span> <span class=\"n\">a</span> <span class=\"o\">+</span> <span class=\"mi\">3</span>  <span class=\"c1\"># P&#x159;i&#x159;azen&#xED; do `a`</span>\n    <span class=\"k\">return</span> <span class=\"n\">obsah</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obsah_elipsy</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"mi\">20</span><span class=\"p\">))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">obsah</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span>\n</pre></div><p>Zkus odpov&#x11B;d&#x11B;t na tyto ot&#xE1;zky:</p>\n<ul>\n<li>Je prom&#x11B;nn&#xE1; <code>pi</code> lok&#xE1;ln&#xED;, nebo glob&#xE1;ln&#xED;?</li>\n<li>Je prom&#x11B;nn&#xE1; <code>obsah</code> lok&#xE1;ln&#xED;, nebo glob&#xE1;ln&#xED;?</li>\n<li>Je prom&#x11B;nn&#xE1; <code>a</code> lok&#xE1;ln&#xED;, nebo glob&#xE1;ln&#xED;?</li>\n<li>Je prom&#x11B;nn&#xE1; <code>b</code> lok&#xE1;ln&#xED;, nebo glob&#xE1;ln&#xED;?</li>\n</ul>\n<div class=\"solution\" id=\"solution-1\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2017/pyladies-praha-podzim-ntk/beginners/def/index/solutions/1/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <ul>\n<li><code>pi</code> je glob&#xE1;ln&#xED; &#x2013; nep&#x159;i&#x159;azuje se do n&#xED; ve funkci;\nje &#x201E;vid&#x11B;t&#x201C; v&#xA0;cel&#xE9;m programu.</li>\n<li>Prom&#x11B;nn&#xE9; <code>obsah</code> jsou v programu dv&#x11B; &#x2013; jedna glob&#xE1;ln&#xED;,\na jedna je lok&#xE1;ln&#xED; pro funkci <code>obsah_elipsy</code>,\nproto&#x17E;e do n&#xED; tahle funkce p&#x159;i&#x159;azuje.</li>\n<li>Prom&#x11B;nn&#xE9; <code>a</code> jsou taky dv&#x11B;, podobn&#x11B; jako <code>obsah</code>.\nTady byl chyt&#xE1;k: p&#x159;&#xED;kaz <code>a = a + 3</code> nem&#xE1; &#x17E;&#xE1;dn&#xFD; smysl;\ndo <code>a</code> se sice ulo&#x17E;&#xED; v&#x11B;t&#x161;&#xED; &#x10D;&#xED;slo, ale vz&#xE1;p&#x11B;t&#xED; funkce <code>obsah_elipsy</code> skon&#x10D;&#xED;\na jej&#xED; lok&#xE1;ln&#xED; prom&#x11B;nn&#xE1; <code>a</code> p&#x159;estane existovat.</li>\n<li>Prom&#x11B;nn&#xE1; <code>b</code> je jenom lok&#xE1;ln&#xED; &#x2013; jako argument funkce <code>obsah_elipsy</code>.</li>\n</ul>\n    </div>\n</div><p>Jestli ti to cel&#xE9; p&#x159;ipad&#xE1; zmaten&#xE9; a slo&#x17E;it&#xE9;, d&#xE1; se tomu zat&#xED;m vyhnout\ndodr&#x17E;ov&#xE1;n&#xED;m jednoho pravidla:\n<em>nep&#x159;i&#x159;azuj ve funkc&#xED;ch do prom&#x11B;nn&#xFD;ch, kter&#xE9; existuj&#xED; i vn&#x11B; funkce.</em>\n(Parametr funkce se po&#x10D;&#xED;t&#xE1; jako p&#x159;i&#x159;azen&#xED;.)</p>\n\n\n        "
    }
  }
}