Uživatelské nástroje

Nástroje pro tento web


prog:funkce2

Vlastní funkce

Po vysvětlení pojmu funkce, jejich významu, použití, interakce s ostatními částmi programu pomocí parametrů a návratové hodnoty nám již nic nebrání, abychom si ukázali, jak v Pythonu lze vytvářet vlastní funkce.

Výpočet faktoriálu

Postup si ukážeme na konkrétním příkladu - výpočet faktoriálu nezáporného celého čísla.

faktorial3.py
# definice funkce na výpočet faktoriálu
 
def faktorial(n):
    """
    výpočet faktoriálu
 
    návratová hodnota (typu int) je vypočtena jako n!
    pro zadané n (nezáporný int)
    """
    if n == 0:
        return 1
    vysledek = n
    for i in range(2, n):
        vysledek = vysledek * i
    return vysledek
 
# příklad použití právě definované funkce:
# výpis tabulky hodnot n! v rozsahu 0 až 20
 
# hlavní program
 
for i in range(21):
    print(i, '! = ', faktorial(i), sep = '')

Povšimněte si následujících skutečností:

  • Definice funkce začíná klíčovým slovem def, za nímž následuje jméno funkce1) a v kulatých závorkách jsou uvedeny parametry2).
  • Řádek definice je ukončen dvojtečkou a od dalšího řádku v odsazeném bloku následuje tělo funkce. Rozsah funkce opět určuje odsazení počátku řádků. Jako u jiných bloků (podmínky, cykly) může tělo funkce obsahovat vnořené bloky.
  • Hned za hlavičkou funkce může (ale nemusí) následovat dokumentační řetězec. Jedná se o běžně zapsaný řetězec (uvozený apostrofy, uvozovkami nebo trojitými uvozovkami pro víceřádkové řetězce). Pro činnost funkce nemá žádný význam, slouží k vysvětlení činnosti funkce, významu parametrů, upozorňuje na případná omezení apod. Některé vývojové nástroje využívají dokumentačních řetězců ke zvýšení komfortu programátorů.
  • Pokud Python při provádění jednotlivých příkazů narazí na klíčové slovo return, ukončí vykonávání funkce a vrátí řízení za místo volání funkce. Případný výraz (konstanta, proměnná) za return se považuje za návratovou hodnotu funkce. V definici funkce může být i více příkazů return, nemusí tam být však žádný - v takovém případě se funkce ukončí za posledním příkazem odsazeného bloku. Pokud není návratová hodnota určena, použije se hodnota None datového typu NoneType.
  • Když v těle funkce přiřadíme nějaké proměnné hodnotu, jedná se o lokální proměnnou, která je odlišná od lokálních proměnných v ostatních funkcích i od globálních proměnných v hlavním programu. Tyto lokální proměnné jsou mimo funkci nepřístupné. Pokud uvnitř funkce použijeme proměnnou ve výrazu či jako argument volání jiné funkce, použije se aktuální hodnota lokální proměnné. Takto je realizováno ono dříve zmíněné „oddělení světa funkce a okolí“. Pouze v případě, že lokální proměnná požadovaného jména neexistuje, použije se hodnota globální proměnné. :!: Kromě zvláštních situací je obecně využití globálních proměnných uvnitř funkce považováno za nevhodné! Brání totiž přenositelnosti funkcí a je zdrojem obtížně odhalitelných chyb.
  • Pojmenování formálních parametrů v hlavičce funkce je důležité pouze uvnitř funkce. Nemá žádnou spojitost s dosazenými skutečnými parametry (též argumenty).
  • Použití naší nové funkce v hlavním programu (nebo v jiných funkcích) by nás již nemělo ničím překvapit, je stejné jako u vestavěných funkcí.

Definici funkce bychom mohli ještě zjednodušit, např. do tvaru

def faktorial(n):
    if n == 0:
        return 1
    for i in range(2, n):
        n = n * i
    return n

Vidíme, že i proměnnou odpovídající některému z parametrů můžeme použít pro výpočty uvnitř funkce, jedná se stále o lokální proměnnou.3)

Skládá-li se náš program z více funkcí, uvádíme je postupně za sebou. Na pořadí přitom nezáleží, je pouze nutné mít definice funkcí před jejich prvním použitím. Proto se hlavní program uvádí až na konci souboru za ostatními funkcemi.

Juliánské datum

Pro určení časových okamžiků v běžném životě používáme občanský kalendář (v současné době gregoriánský). Pro použití např. v astronomii však není příliš vhodný4), tam se spíše setkáme s časovými údaji v juliánských dnech či z nich odvozených veličin.

Jako další příklad napíšeme funkci, která pro platné datum dle současného kalendáře určí číslo juliánského dne5). Použijeme algoritmus dle uvedeného odkazu na Wikipedii (tam hledejte i případné podrobnější vysvětlení).

Naše funkce jul_datum vyžaduje tři celočíselné parametry (den, měsíc, rok) dle požadovaného data a její návratová hodnota je vypočtené číslo juliánského dne JDN (typu int). V hlavním programu je ukázáno použití pro zjištění JDN pro zadané datum i určení časového intervalu v dnech mezi dvěma daty.

julian.py
def jul_datum(den, mesic, rok):
    """
    výpočet juliánského data
 
    pro zadaný den, měsíc a rok vypočte juliánské datum (JDN),
    předpokládá vstupní parametry dle gregoriánského kalendáře
    (datum musí být platné, parametry kladné int)
    viz. https://cs.wikipedia.org/wiki/Juli%C3%A1nsk%C3%A9_datum
    """
    if mesic <= 2:
        r = rok + 4799
        n = mesic + 9
    else:
        r = rok + 4800
        n = mesic - 3
    e = den + (153 * n + 2) // 5
    # návratová hodnota typu int
    return e + 365 * r + r // 4 - r // 100 + r // 400 - 32045
 
# hlavní program
print("1.1.2000 =>", jul_datum(1, 1, 2000))
print("Dní mezi 15.9.2009 a 15.9.2010:", \
        jul_datum(15, 9, 2010) - jul_datum(15, 9, 2009))
print("Dní mezi 15.9.2011 a 15.9.2012:", \
        jul_datum(15, 9, 2012) - jul_datum(15, 9, 2011))
1)
Pro pojmenování funkcí platí stejná pravidla jako pro proměnné, mj. je potřeba vyhnout se klíčovým slovům jazyka apod.
2)
Již víme, že více parametrů je odděleno čárkou, seznam parametrů může být i prázdný (kulaté závorky však uvádíme i v tomto případě).
3)
V tomto případě snad stojí za vysvětlení, že parametr n se funkci range předává pouze jednou (tj. před změnou své hodnoty), takže výpočet proběhne podle našeho očekávání.
4)
např. není na první pohled zřejmé, kolik dní je mezi dvěma zadanými daty
5)
přesněji řečeno se jedná o číslo dne začínajícího uvedeného data v poledne UTC
prog/funkce2.txt · Poslední úprava: 11.01.2018 06:26 autor: Ivana Stefanová

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki