Python


Zložené príkazy

Zložené príkazy (compound statements) slúžia na vetvenie programu. V Pythone je to podmienený príkaz if a cykly while a for, pričom je nielen u if (ako je to aj v iných programovacích jazykoch), ale aj u cyklov for a while je dostupná časť else:, ktorá sa vykoná, ak nebude splnená podmienka hlavného cyklu. Pred tým, než sa pozrieme na konkrétne príkazy, si však musíme vysvetliť, čo sú to bloky, ktoré hodnoty v Pythone spŀňajú podmienky a musíme sa pozrieť na relačné a logické operátory.

Bloky

Bloky sú vlastne zoskupenia príkazov (môže sa jednať aj iba o 1 príkaz), ktoré sa využívajú v zložených príkazoch a tiež ako telá funkcií. V blokoch sa vytvárajú lokálne premenné. Znamená to, že ak ste v zdrojovom kóde vášho programu pred blokom použili určitú premennú, tak tým, že ju uvediete v bloku, zostane pôvodný obsah tejto premennej zachovaný! Jednoducho povedané, identifikátory premenných v bloku sa môžu prekrývať s tými mimo bloku bez toho, aby sa zmenil obsah rovnomenných premenných mimo bloku. Bloku sú odsadené určitým konštantným počtom medzier alebo tabulátorov. V odsadení jedného bloku nie je možné striedať medzi medzerami a tabulátormi, ani medzi ich počtom. Ak sme teda prvý riadok bloku odsadili 2 medzerami, tak i druhý musí byť odsadený dvoma. Ďalšie odsadenie vo vnútri bloku (napr. vnorenie ďalšieho zloženého príkazu) musíme vykonať dvojnásobnou hodnotou predchádzajúceho odsadenia, teda v príklade z predchádzajúceho riadku by to boli 4 medzery.

Podmienky

Pred tým, než sa môžeme pustiť do samotných zložených príkazov, musíme vedieť, ktoré hodnoty sú v Pythone považované ako pravdivé a ktoré nie sú.
Nepravdivé hodnoty: None (vysvetlenie ďalej pri príkaze return), číselné nuly, prázdne sekvenčné dátové typy (reťazce, polia, tuple) a prázdne slovníky.
Pravdivé hodnoty: všetky ostatné hodnoty.

Relačné a logické operátory

Na rozdiel od C všetky relačné (porovnávacie) operátory majú tú istú prioritu, ktorá je nižšia ako u aritmetických operátorov. Čísla sa porovnávajú aritmeticky, znaky podľa ASCII hodnoty, preto napr. platí, že "a" > "A". Reťazce sa porovnávajú lexikografiky, čo znamená, že prvý znak ľavého reťazca sa porovná s prvým znakom pravého reťazca, druhý s druhým, tretí s tretím atď až do konca jedného z reťazcov, alebo do prvého rozdielu medzi týmito reťazcami. Preto napr. platí: "abcd" < "abcde", "abcd2" > "abcd1".
relačné operátory
operátor význam
< menšie ako
> väčšie ako
== rovná sa
<= menšie ako, alebo sa rovná
>= väčšie ako, alebo sa rovná
!= nerovná sa
in je v sekvenčnom dátovom type
not in nie je v sekvenčnom dátovom type

Logické operátory sa nám hodia v prípade, že potrebujeme v jednom výraze vyjadriť viac podmienok. Výrazom a > b and b < c hovoríme Pythonu, že obidve podmienky musia byť splnené (musí platiť, že a je väčšie ako b a súčasne že b je menšie ako c). A a > b or b > c pre zmenu udáva, že stačí, aby platila jedna podmienka (a je väčšie ako b, alebo je b väčšie ako c). Tretím a posledným logickým operátorom je not, ktorým negujeme pravdivosť výrazu. Napr. ak je v premennej a hodnota 3 (pravdivá hodnota), tak výraz not a je nepravdivá hodnota. Logické operátory majú v Pythone úplne najnižšiu prioritu.

logické operátory
operátor význam
and logické and("a")
or logické or ("alebo")
not neguje pravdivosť operandu

príkaz if

Podmienený príkaz if je dostupný skoro v všetkých programovacích jazykoch, Python nie je výnimka. Príkaz if funguje nasledovne: ak je splnená podmienka1, tak sa vykoná blok1 a príkaz if skončí. Ďalšie podmienky sa zapisujú pomocou časti elif: a ak je jedna z týchto podmienok splnená, tak sa vykoná blok u príslušnej časti elif: a príkaz if skončí. Časti elif: nie sú povinné a môže ich byť v kóde programu viac. Pomocou konštrukcií s viacerými elif: sa nahradzuje príkaz switch z iných jazykov (napr. C). Blok v časti else: sa vykoná, ak ani jedna z predchádzajúcich podmienok nebola splnená, táto časť tiež nie je povinná. Príkaz if sa zapisuje takto:
if podmienka1:
    blok1
elif podmienka2:
    blok2
elif ...
    blok ...
else:
    blok
Príklad:
>>> cislo=-2
>>> if cislo < 0:
...     print 'cislo je zaporne'
... elif cislo > 0:
...     print 'cislo je kladne'
... else:
...     print 'cislo je 0'
...
cislo je zaporne

cyklus while

Cyklus while má za úlohou opakovať blok, pokým má podmienka pravdivú hodnotu. Časť else: nie je povinná a blok stojaci pri tejto časti sa vykoná, ak podmienka nie je splnená. Zápis:
while podmienka:
    blok
else:
    blok
Príklad:
>>> a, b = 0, 1
>>> while b < 100:
...     print b,
...     a, b = b, a+b
...
1 1 2 3 5 8 13 21 34 55 89

cyklus for

V Pythone sa cyklus for trošku odlišuje od implementácie v C alebo Pascale. Hlavnou úlohou pythonovského for príkazu je prechádzať medzi prvkami sekvenčného dátového typu (reťazec, pole, tuple). Časť else: je nepovinná a vykoná sa vtedy, ak zlyhalo vykonanie hlavnej časti cyklu for (napr. keď je sekvenčný_dátový_typ prázdny). Cyklus for sa zapisuje takto:
for premenná in sekvenčný_dátový_typ:
    blok
else:
    blok
Príklad:
>>> a='Python', 'Perl', 'C++', 'Java'
>>> for i in range(len(a)):
...     print i, a[i]
...
0 Python
1 Perl
2 C++
3 Java

príkazy skoku

V cykloch for a while sú dovolené nasledovné príkazy skoku, pre mnohých z nás známe aj z iných programovacích jazykov:

break

Príkaz break ukončí najbližší príkaz for alebo while. Ak ukončený príkaz obsahuje časť else:, tá bude ignorovaná. Trošku nezmyselný (ďalší príklad nájdete v funkcii prvocislo2() v odstavci "príkaz return"), ale funkčný príklad, ktorý veľmi pekne ukazuje činnosť break:
>>> for a in range(1,11):
...     if a > 3:
...             break
...     print a
...
1
2
3

continue

Príkaz continue okamžite ukončí práve vykonávanú slučku a pokračuje ďalšou slučkou (ak je stále splnená podmienka - cyklus while, alebo ak sa ešte neprešli všetky prvky v sekvenčnom dátovom type - cyklus for) v najbližšom cykle for alebo while.
>>> for a in range(1,11):
...     if a%2 == 0:
...             continue
...     print a
...
1
3
5
7
9

príkaz pass

Príkaz pass nerobí nič. Používa sa ako prázdny blok, keď je syntakticky nevyhnutné uviesť blok a my v našom programe nepotrebujeme žiaden príkaz. Príklad:


>>> while 1:
... pass #cakame na prerusenie z klavesnice

Funkcie

Pomocou funkcií "rozkladáme" veľké, ťažko riešiteľné problémy na menšie časti, ktorých riešenie je hračkou. Toto je prvá výhoda použitia funkcií. Druhá spočíva v tom, že časť kódu programu, ktorú využívame viackrát, píšeme len raz.

Definovanie funkcii

Funkcie sa definujú kľúčovým slovom def, za ktorým musí nasledovať identifikátor s menom funkcie. Za menom musia byť v klasických zátvorkách uvedené argumenty (ak funkcia nemá argumenty, uvedieme prázdne zátvorky) a za argumentami nasleduje dvojbodka. Prvý riadok by mal byť dokumentačný reťazec. Na ďalšom riadku nasleduje blok s telom funkcie. Príklad:
>>> def prvocislo(n):
...        for x in range(2,n):
...                if n % x == 0:
...                        print n, '=', x, '*', n/x
...                        break
...        else:
...                print n, 'je prvocislo'
...
>>> prvocislo(8)
8 = 2 * 4
>>> prvocislo(7)
7 je prvocislo

Uvedením mena funkcie bez zátvoriek s argumentami získame adresu funkcie. Túto hodnotu je možné priradiť k novému identifikátoru. Získame tak možnosť volať tú istú funkciu dvoma menami.

>>> prvocislo #adresa funkcie
<function a at 80c84a0>
>>> druhe_meno=prvocislo
>>> druhe_meno(16)
16 = 2 * 8

Štandardné hodnoty argumentov

Argumentom funkcií je možné priradiť štandardné hodnoty. Ak potom voláme funkciu s menej argumentami, ako bolo definované, použijú sa hodnoty argumentov uvedené v definícii funkcie. Príklad:

>>> def pozdrav(s='ahoj!'):
... print s
...
>>> pozdrav()
ahoj!
>>> pozdrav('dobry den!')
dobry den!

Ak poznáme v definícii funkcie mená argumentov so štandardnou hodnotou, je možné pri volaní funkcie uviesť tieto argumenty s novou hodnotou. Najlepšie sa to ukáže na príklade:

>>> def pozdrav2(koho, ako='Dobry den, '):
... print ako + koho + '!'
...
>>> pozdrav2('Peter') #klasicke volanie funkcie
Dobry den, Peter!
>>> pozdrav2('Martin', ako='Ahoj, ') #argument "ako" dostane novu hodnotu
Ahoj, Martin!

Pri definovaní funkcie je nevyhnutné uviesť argumenty bez štandardnej hodnoty pred argumentami so štandardnou hodnotou!

príkaz return

Procedúry sú v Pythone koncipované podobne ako v C. Sú to vlastne funkcie, ktoré nevracajú žiadnu hodnotu. Aby funkcia vracala hodnotu, existuje príkaz return. Tento príkaz okamžite ukončí funkciu a spôsobí, že funkcia vráti hodnotu, ktorú dostane príkaz return ako argument. Vrátiť sa dajú celé objekty, ako napr. pole v tomto príklade upravenej funkcie prvocilso():
>>> def prvocislo2(n):
...         "vrati pole s prvocislami do n"
...         vysledok=[]
...         for n in range(2, n):
...                 for x in range(2,n):
...                         if n% x == 0:
...                                 break
...                 else:
...                         vysledok.append(n)
...         return vysledok
...
>>> a=prvocislo2(30)
>>> a
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Pred chvíľou ste čítali, že procedúry nevracajú žiadnu hodnotu, čo však nie je celkom pravda. Ak nie je funkcia ukončená príkazom return, alebo ak return nevracia nič (žiaden objekt), tak funkcia vracia implicitne hodnotu None, ktorá slúži ako nepravdivá hodnota.

Funkcie s premenným počtom argumentov

Ak chceme v Pythone vytvoriť funkciu s premenným počtom argumentov, v definícii funkcie uvedieme pred argumentom znak hviezdičky. Hodnoty argumentu s hviezdičkou sú uložené v tuple. Príklad:
>>> def fun_s_prem_poctom_arg(*arg):
...     print 'tuple s hodnotami *arg: ', arg
...     print 'jednotlive hodnoty:'
...     for a in range(len(arg)):
...             print a, arg[a]
...
>>> fun_s_prem_poctom_arg("arg1",23,'Python')
tuple s hodnotami *arg:  ('arg1', 23, 'Python')
jednotlive hodnoty:
0 arg1
1 23
2 Python

V prípade, že uvedieme namiesto jednej hviezdičky dve, tak bude od nás Python očakávať argumenty s priradenými hodnotami pomocou znaku "=". Pri volaní funkcie sa hodnoty takto definovaného argumentu odovzdajú ako slovník, ktorého kľúče budú argumenty a hodnoty kľúčov budú hodnoty argumentov. Najlepšie sa to pochopí na príklade:
>>> def vypis_udaje(**udaje):
...     for kluc in udaje.keys():
...             print kluc, ': ', udaje[kluc]
...
>>> vypis_udaje(Meno='Janko Hrasko', Povolanie='student')
Meno :  Janko Hrasko
Povolanie :  student

Je možné ľubovolne kombinovať klasické argumenty s "hviezdičkovými" argumentami. V definícii funkcie je však nutné uviesť najprv klasické argumenty, za nimi argument s jednou hviezdičkou a potom argument s dvoma hviezdičkami. Príklad je spojený s príkladom na dokumentačný reťazec v ďalšom odstavci.

Dokumentačné reťazce

S dokumentačným reťazcom sme sa už stretli pri programe lincal a pred chvíľou vo funkcii prvocislo2(). Ako sme si už povedali v minulej časti seriálu, dokumentačné reťazce slúžia na dokumentovanie ľubovoľných objektov v Pythone, teda aj funkcií, ktoré sú v Pythone tiež reprezentované ako objekty. Dokumentačný reťazec by mal byť na ďalšom riadku hneď po definícii funkcie a mal by byť koncipovaný stručne. Ak je v dokumentačom reťazci viac riadkov, tak by mal byť druhý riadok prázdny, aby oddeľoval prvý riadok (maximálne stručné zhrnutie) od ostatného textu. Uvádzanie dokumentačných reťazcov u každého objektu je nepísaným pravidlom všetkých programátorov v Pythone a bolo by veľmi dobre si z neho spraviť z tohto pravidla zvyk. K dokumentačnému reťazcu pristupujeme pomocou konštrukcie objekt.__doc__. Dokumentačné reťazce sa zvyknú označovať aj ako "docstrings". Obligátny príklad:
>>> def inventar(institucia,*adresa,**objekty):
...     """Vypise inventar institucie z adresy s objektami a ich poctom.
...
... Objekty sa zadavaju v style: meno_objektu=pocet."""
...     print institucia
...     print '-'*len(institucia)
...     for a in adresa:
...             print a
...     print #prazdny riadok
...     for a in objekty.keys():
...             print objekty[a], a
...
>>> inventar('Firma A', 'Hraskova 23', '85101 Bratislava', stol=1, stolicky=4)
Firma A
-------
Hraskova 23
85101 Bratislava

4 stolicky
1 stol
>>> print inventar.__doc__
Vypise inventar institucie z adresy s objektami a ich poctom.

Objekty sa zadavaju v style: meno_objektu=pocet.

Martin Uzak

[Pridať príspevok k článku][Verzia pre tlač]