comment up next how to englisch dex

4. Větvení a rekurze

  1. Operátor "modulo"
  2. Booleovské hodnoty a výrazy
  3. Logické operátory
  4. Podmíněné provedení
  5. Alternativní provedení
  6. Zřetězené podmínky
  7. Vnořené podmínky
  8. Příkaz ' return '
  9. Vstup z klávesnice
  10. Přeměna typu
  11. Gasp
  12. Glosář
  13. Cvičení

4.1 Operátor "modulo"

Modulo operátor pracuje s čísly (číselnými výrazy) a poskytuje zbytek při dělení prvního operandu druhým. V Pythonu jej označujeme znakem pro procento (%). Syntaxe je stejná, jako u jiných operátorů:

>>> quotient = 7 / 3
>>> print quotient
2
>>> zbytek = 7 % 3
>>> print zbytek
1

Takže 7 děleno 3 je 2 a 1 zbude.

Ukazuje se, že modulo operátor je překvapivě užitečný. Na příklad, můžeme zjistit, zda jedno číslo je dělitelné druhým: je-li x % y totožné 0, pak x je dělitelné číslem y.

Lze jím také oddělit krajní číslice zprava od zadaného čísla. Například, x % 10 vyčlení nejkrajnější číslici čísla x zprava (při základu 10). Podobně x % 100 vyčlení dvě poslední číslice.

4.2 Booleovské hodnoty a výrazy

Pythonovský typ pro uložení hodnoty True nebo False zvaný bool je pojmenován po britském matematikovi George Booleovi. George Boole vytvořil booleovu algebru, která je základem moderní počítačové aritmetiky.

Jsou pouze dvě booleovské hodnoty: True a False. Velká počáteční písmena jsou důležitá, neboť true a false booleovskými hodnotami nejsou.

>>>type (True)
<type 'bool'>
>>>type (true)
Traceback (most recent call last):
>>File "<stdin>", line 1, in <module>
NameError: name 'true' is not defined

Booleovský výraz je výraz, který vede k boooleovské hodnotě. Operátor == (je totožné) porovná dvě hodnoty a předá booleovskou hodnotu:

>>> 5 == 5
True
>>> 5 == 6
False

V prvním tvrzení jsou oba operandy stejné, takže se výraz vyhodnotí coby True; ve druhém tvrzení 5 není totožné 6, takže obdržíme False.

Operátor == je jedním z relačních operátorů, dalšími jsou tyto:

      x != y               # x není totožné y
      x > y                # x je větší než y
      x < y                # x je menší než y
      x >= y               # x je větší nebo rovno y
      x <= y               # x je menší nebo rovno y

I když jsou nám tyto operace patrně známé, symboly v Pythonu se liší od symbolů v matematice. Obvyklou chybou je použití jednoduchého rovnítka (=) místo zdvojeného rovnítka (==). Pamatujme si, že = je operátor přiřazení a == je porovnávací operátor. Také si pamatujme, že neexistuje znak =< nebo =>

4.3 Logické operátory

Jsou tři logické operátory: and (a), or (nebo) a not (ne). Význam (sémantika ) těchto operátorů je podobný jejich významu v angličtině (a, nebo, ne). Například, výrazy x > 0 and x < 10 jsou pravdivé pouze tehdy, jestliže x je větší než 0 a menší než 10.

Tvrzení n%2 == 0 or n%3 == 0 je pravdivé, je-li alespoň jedna z podmínek pravdivá, to jest, je-li číslo dělitelné dvěma nebo třemi.

Konečně, operátor not neguje booleovský výraz, takže not(x > y) je pravda, je-li x > y nepravda; to jest je-li x menší než - nebo rovno y.

4.4 Podmíněné provedení

K napsání užitečného programu potřebujeme teměř vždy mít možnost měnit chování programu v závislosti na jistých podmínkách. Tuto možnost nám dávají podmíněné příkazy. Nejjednoduší tvar má příkaz if:

if x > 0:
    print "x is positive"

Booelovský výraz za příkazem if se nazývá podmínka. Je-li pravdivá, odsazený výraz se provede, není-li, neprovede se nic.

Skladba příkazu if vypadá takto:

if booleovský výraz:
    příkazy 

Stejně jako funkce a jiné složené příkazy se příkaz if skládá ze záhlaví a těla. Záhlaví začíná klíčovým slovem if, pokračuje booleovským výrazem a končí dvojtečkou.

Počet příkazů v těle příkazu if není omezen, ale musí být alespoň jeden. Někdy bývá užitečné tělo bez příkazů (obvykle jako obsazení místa pro kód, který ještě není napsán). V tom případě můžeme použít příkaz pass, který nedělá nic.

if True:  # což je vždy
    pass     # takže se neprovede nic

4.5 Alternativní provedení

Druhou formou příkazu if je alternativní provedení, při němž existují dvě možnosti a podmínka určí, která z nich se provede. Syntaxe vypadá takto:

if x%2 == 0:
   print x, "je sude" 
else:
   print x, "je liche" 

Je-li zbytek po dělení dvěma roven nule, potom víme, že x je sudé a program tuto zprávu zobrazí. Není-li tato podmínka pravdivá, provede se druhá sada příkazů. Protože podmínka může být pouze pravdivá nebo nepravdivá, provede se určitě jedna z obou možností. Alternativám říkáme větve protože jsou rozvětvením toku programu.

Mimochodem, kdybychom potřebovali často posuzovat "lichost" či "sudost" čísel, mohli bychom si tento prográmek "zabalit" do funkce:

def print_parity(x):
  if x%2 == 0:
    print x, "je sude"
  else:
    print x, "je liche"

Pro každou hodnotu x vrátí print_parity příslušnou zprávu. Při volání můžeme zadat jako argument jakýkoliv celočíselný výraz:

>>> print_parity(17)
17 je liche
>>> y = 41
>>> print_parity(y+1)
42 je sude

4.6 Zřetězené podmínky

Někdy je více než dvě možností a my potřebujeme více než dvě větve. Použijeme seriově uspořádané (zřetězené) podmínky:

if x < y:
  print x, "is less than", y
elif x > y:
  print x, "is greater than", y
else:
  print x, "und", y, "are equal"

elif je zkratka "else if". Opět je provedena pouze jedna větev. Počet elif není omezen, příkaz else však smí být pouze jeden a musí být uveden jako poslední.

if choice == 'a':
  function_a()
elif choice == 'b':
  function_b()
elif choice == 'c':
  function_c()
elif choice == 'd':
  function_d()
else:
  print "invalid choice."

Podmínky jsou zkoumány jedna za druhou. Je-li první nepravdivá, prověřuje se další. Je-li některá pravdivá, provede se bezprostředně následující větev programu. Jestliže je pravdivých podmínek více, provede se jen první z nich.

4.7 Vnořené podmínky

Jedna podmínka může být vnořena do druhé. Předchozí trojitou rozbočku můžeme realizovat také takto:

if x == y:
  print x, "and", y, "are equal"
else:
  if x < y:
    print x, "is less than", y
  else:
    print x, "is greater than", y

Vnější podmínka má dvě větve. První větev obsahuje prostý příkaz k tisku. Druhá větev obsahuje další podmínku if, která má své vlastní dvě větve. Obě tyto větve jsou prostým příkazem print.

I když odsazení příkazů činí strukturu zápisu zřejmou, vnořené podmínky se velmi rychle stávají méně přehledné. Pokud můžeme, tak se jim raději vyhneme.

Vnořené podmínky můžeme často zjednodušit logickými operátory. Následující kód bude v další ukázce přepsán pro použití jen jedné podmínky:

if 0 < x:
  if x < 10:
    print "x is a positive single digit."

Příkaz print se provede pouze tehdy, splníme-li obě podmínky, můžeme tedy použít operátor and.

if 0 < x and x < 10:
  print "x is a positive single digit."

Pro toto docela běžné seskupení podmínek poskytuje Python alternativní syntaxi, která je podobná zápisu v matematice:

if 0 < x < 10:
  print"x is a positive single digit."

Tato podmínka je významově stejná jako složený booleovský výraz s vnořenou podmínkou.

4.8 Příkaz  return

Příkaz return nám umožňuje ukončit provádění funkce před jejím koncem. Použijeme jej k označení chybové události:

def print_square_root(x):
  if x <= 0:
    print "Positive numbers only, please."
    return
  result = x**0.5
  print "The square root of x is", result

Funkce print_square_root má parametr x. První věcí, kterou udělá je, že zkontroluje, zda x je menší nebo rovno nule. Pokud ano, zobrazí chybové hlášení a použije return k ukončení funkce. Tok výpočtu se okamžitě vrací k místu volání funkce (caller) a zbývající řádky funkce se neprovedou.

4.9 Vstup z klávesnice

Ve druhé kapitole jsme se setkali s vestavěnými funkcemi, které přjímají vstupy z klávesnice: raw_input a input. Nyní se jimi budeme zabývat zevrubněji.

Je-li některá z těchto funkcí volána, program se zastaví a čeká na zápis od uživatele. Poté co uživatel stiskne Return nebo Enter, běh programu se obnoví a raw_input vrací vstup uživatele jako řetězec:

>>> input = raw_input()
What are you waiting for?
>>> print input
What are you waiting for?
Před voláním raw_input je dobré vypsat pokyn pro uživatele, co má vložit. Této zprávě se říká výzva (prompt). Můžeme ji zadat jako argument funkce raw_input:

>>> name = raw_input ("What...is your name? ")
What...is your name? Arthur, King of the Britons!
>>> print name
Arthur, King of the Britons!

Pamatujme si, že promptem je řetězec v uvozovkách.

Očekáváme-li odpověď ve tvaru celého čísla, můžeme použít funkce input:

prompt = "What ... is the airspeed velocity of an unladen
swallow? "
speed = input(prompt)

Zapíše-li uživatel číslo ve tvaru řetězce, přemění jej program na celé číslo a přiřadí jej proměnné speed. Pokud však uživatel zapíše litery, které netvoří platný výraz Pythonu, program se zastaví:

>>> speed = input (prompt)
What ... is the airspeed velocity of an unladen swallow?
What do you mean, an African or a European swallow?
...
SyntaxError: invalid syntax

Kdyby však uživatel dal svoji odpověď do závorek, vytvořil by platný výraz a nebyla by hlášena chyba:

>>> speed = input (prompt)
What ... is the airspeed velocity of an unladen swallow?
"What do you mean, an African or a European swallow?"
>>> speed
'What ... is the airspeed velocity of an unladen swallow?'

Abychom se vyhnuli tomuto druhu chyb, bývá vhodné použít raw_input k získání řetězce, který lze konverzní funkcí přeměnit na jiný typ.

4.10 Přeměna typu

Python poskytuje řadu vestavěných (built-in) funkcí, které mění typ hodnot. Funkce int(argument) například přjímá libovolnou hodnotu a je-li to možné, přemění ji na typ integer (celé číslo), jinak si postěžuje:

>>> int("32")
32
>>> int("Hello")
ValueError: invalid literal for int(): Hello

int také přemění hodnotu typu float (desetinné číslo) na integer, ale v tom případě odsekne desetinnou část čísla:

>>>int(3.99999)
3
>>> int(-2.3)
-2
>>> int("42")
42
>>> int(1.0)
1

Funkce float(argument) přemění celá čísla a řetězce na čísla v plovoucí čárce:

>>> float(32)
32.0
>>> float("3.14159")
3.14159
>>> float(1)
1.0

Může se zdát divné, že Python rozlišuje mezi celočíselnou hodnotou 1 a desetinnou hodnotou 1.0. Obě hodnoty představují stejné číslo, ale patří k rozdílným datovým typům.

Funkce str(argument) přemění zadaný argument na typ řetězec:

>>> str(32)
'32'
>>> str(3.14149)
'3.14149'
>>>str(True)
'True'
>>> str(true)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'true' is not defined

Záležitost s booleovskými hodnotami je obzvlášť zajímavá:

>>> bool(1)
True
>>> bool(0)
False
>>> bool("No !")
True
>>> bool("")
False
>>> bool(3.14159)
True
>>> bool(0.0)
False

Python přiřadí booleovské hodnoty hodnotám jiných typů. U číselných typů generují nulové hodnoty False, nenulové hodnoty True. Prázdné řetězce dávají False, neprázdné řetězce dávají True.

4.11 Gasp

Gasp (Graphics API for Students of Python) nám umožní psát programy včetně grafiky.

Aplikaci gasp spustíme jednoduše:

>>> from gasp import *
>>> begin_graphics()
>>> Circle((200, 200), 60)
Circle instance at (200, 200) with radius 60
>>> Line((100, 400), (580, 200))
Line instance from (100, 400) to (590, 250)
>>> Box((400, 350), 120, 100)
Box instance at (400, 350) with width 120 and height 100
>>> end_graphics()
>>>

Před zadáním posledního příkazu, který zavírá náčrtník, bychom měli vidět něco jako toto:

Gasp illustration 1

Gasp budeme používat pro ilustraci programátorských postupů a také trochu pro zábavu.

4.12 Glosář

operátor modulo (modulus operator)
Operátor označovaný znakem % který poskytne zbytek dělení jednoho čísla druhým.
booleovská hodnota (boolean value)
Jsou pouze dvě, True a False. Mají typ bool a jsou výsledkem booleovského výrazu.
booleovský výraz (boolean expression)
Výraz, který je buď pravdivý nebo nepravdivý.
relační operátor (comparison operator)
Jeden z operátorů, který porovnává dvě hodnoty: ==, !=, >, <, >= a <= .
logický operátor (logical operator)
Jeden z operátorů, který spojuje booleovské výrazy: and, or a not.
podmíněný příkaz (conditional statement)
Příkaz, který řídí tok výpočtu v závislosti na nějaké podmínce. V Pythonu se pro podmíněné příkazy používají klíčová slova if, elif a   else.
podmínka (condition)
Booleovský výraz v podmíněném výrazu, který rozhoduje o tom, která větev se provede.
blok (block)
Skupina po sobě jsoucích příkazů se stejným odsazením.
tělo (body)
Blok příkazů ve složeném příkazu pod záhlavím.
větev (branch)
Jedna z možných cest výpočtu určená vyhodnocením podmínky.
řetězená podmínka (chained conditional)
Podmíněné větvení s více než dvěma toky výpočtu. V Pythonu se řetězené podmínky píší pomocí příkazů if ... elif ... else.
vnoření (nesting)
Jedna programová struktura vnořená do druhé, jako je podmíněný příkaz ve větvi jiného podmíněného příkazu.
výzva (prompt)
Pokyn pro uživatele, aby zadal data. Také znak (>>>) v překladačí.
přeměna typu (type conversion)
Explicitní příkaz, který hodnotu jednoho typu přemění na hodnotu jiného typu.

4.13 Cvičení

  1. Následující číselné výrazy vypočítej z hlavy a výsledky si ověř v IRP.
    1. >>>  5 % 2
    2. >>>  9 % 5
    3. >>>  15 % 12
    4. >>>  12 % 15
    5. >>>  6 % 6
    6. >>>  0 % 7
    7. >>>  7 % 0

    Co se stalo s posledním příkladem a proč? Měl-li jsi všechny výsledky kromě posledního správně, můžeš jít dál. Pokud ne, sestav si vlastní příklady a pohrávej si s modulo operátorem tak dlouho, dokud mu zcela neporozumíš.

  2. Zabal následující kód do funkce:  compare(x,y):
    if x < y :
      print x, "je mensi nez", y
    elif x > y :
      print x, "je vetsi nez", y
    else: 
      print x, "a", y "jsou stejne"
    
    Importuj si ji do IRP a volej ji třikrát, s prvním argumentem menším, větším a stejným než / jako druhý argument.
  3. Pro lepší porozumění booleovským výrazům jsou dobré pravdivostní tabulky. Dva booleovské výrazy jsou logicky rovnocenné tehdy a jen tehdy, mají-li stejné pravdivostní tabulky.
    Následující skript vytiskne pravdivostní tabulku pro libovolný booleovský výraz s proměnnou p a q.
    expression = raw_input("Zadej booleovsky vyraz 
    pro 'p' a 'q' : " )
    print " p    q    %s"   % expression
    delka = len(" p    q    %s"   % expression)
    print delka* "="
    
    for p in True, False:
      for q in True, False:
        print "%-7s %-7s %-7s" % (p, q, eval(expression))
    
    Skladbu skriptu si vysvětlíme v pozdějších kapitolách. Nyní jej použijeme pro osvojení booleovských výrazů. Ulož program do souboru p_and_q.py, importuj jej do IRP a zadej p or q. Měl bys dostat následující výstup:
      p       q      p or q
    ------------------------
    True    True      True
    True    False     True
    False   True      True
    False   False     False
    
    Nyní, když víme jak kód pracuje, zabalíme jej pro lepší použití do funkce (a uložíme do truth_table.py):
    def truth_table(expression): 
      print " p    q    %s"   % expression
      delka = len(" p    q    %s"   % expression)
      print delka* "="
    
      for p in True, False:
        for q in True, False:
          print "%-7s %-7s %-7s" % (p, q, eval(expression))
    
    Provedeme import do IRP a zadáme booleovský výraz jako řetězec:
     >>>  from truth_table import *
     >>>  truth_table ("p or q")
     
      p       q      p or q
    ------------------------
    True    True      True
    True    False     True
    False   True      True
    False   False     False
    
    Vyzkoušej si fci truth_table na následujících booleovských výrazech a zapiš si pravdivostní tabulky:
    1.   not (p or q)
    2.   p and q
    3.   not (p and q)
    4.   not(p) or not(q)
    5.   not(p) and not(q)

    Které výrazy jsou logicky eqvivalentní?

  4. Následující výrazy zapisuj na příkazovou řádku IRP:
    True or False
    True and False
    not(False) and True
    True or 7
    False or 7
    True and 0
    False or 8
    "happy" and "sad"
    "happy" or "sad"
    "" and "sad"
    "happy" and ""
    
    Analýzuj výstupy. Uměl bys shrnout výsledky pozorování do jednoduchých zásad o používání booleovských výrazů and a or?
  5. Zabal následující kód do funkce:  dispatch (choice)
    if choice == 'a':
      function_a()
    elif choice == 'b':
      function_b()
    elif choice == 'c':
      function_c()
    else: 
      print "Neplatna volba"
    
    Potom definuj fci function_a, function_b a function_c tak, aby vytiskly zprávu že byly volány. Například:
    def function_a():
      print "function_a was called ..."
    
    Všechny čtyři funkce (dispatch, function_a, function_b, function_c) ulož do souboru ch4e5.py. Na konec skriptu přidej volání fce dispatch('b'). Výstupem by mělo být:
    function_b was called ...
    Nakonec skript uprav tak, aby uživatel mohl přímo zadávat 'a, b' nebo 'c'. Skript otestuj importem do IRP.
  6. Napiš fci is_divisible_by_3, která přijme celé číslo jako argument a podle situace vytiskne "Toto cislo je delitelné tremi" nebo "Toto cislo neni delitelné tremi".

    Nyní napiš podobnou fci is_divisible_by_5.

  7. Generalizuj fce, které jsi napsal v předchozím cvičení ve funkci is_divisible_by_n(x,n), která přijme dva argumenty a vytiskne zprávu, že první je/není dělitelný druhým. Ulož ji do souboru ch4e7.py. Importuj ji do IRP a vyzkoušej. Výstup může vypadat takto:
    >>> from ch4e7 import *
    >>> is_divisible_by_n(20,4)
    Yes, 20 is divisible by 4
    >>> is_divisible_by_n(21,8)
    No, 21 is not divisible by 8
    
  8. Jaký bude výstup následujcího kódu?
    if "Ni!":
      print "We are the Knights who say, 'Ni!'"
    else:
      print "Stop it! No more of this!"
    if 0:
      print "And now for something completely different..."
    else:
      print "What´s all this, then?"
    
    Zamysli se nad výstupy a pokus se je vysvětlit.

  9. Následující skript v souboru house.py nakreslí jednoduchý domek na náčrtník gaspu:
    from gasp import *             # import everything from the gasp library
    
    begin_graphics()               # open the graphics canvas
    
    Box((20, 20), 100, 100)        # the house
    Box((55, 20), 30, 50)          # the door
    Box((40, 80), 20, 20)          # the left window
    Box((80, 80), 20, 20)          # the right window
    Line((20, 120), (70, 160))     # the left roof
    Line((70, 160), (120, 120))    # the right roof
    
    pause()                        # keep the canvas open until a key is pressed
    end_graphics()                 # close the canvas (which would happen anyway,
                                   # since the script ends here, but it is better
                                   # to be explicit).
    

comment up next how to englisch dex