IB113 Radek Pelánek 2019 Rozcvička I a = [3, 1, 7] print(sorted(a)) print(a) b = [4, 3, 1] print(b.sort()) print(b) 2/70 Rozcvička a = ["magic"] a.append(a) print (a [1] [1] [1] [1] [1] [0] [1] [0] [0] [0]) „záludnější partie" • globální a lokální proměnné • reprezentace dat v paměti, kopírování • předávání parametrů funkcím • typy • rekurze základní témata obecně důležitá detaily specifické pro Python Dnešní programy Varování: Dnešní ukázky programů jsou často „ • minimalistické ukázky důležitých jevů • nikoliv pěkný, prakticky používaný kód Python Tutor - vizualizace Vizualizace použité ve slidech: http://www.pythontutor.com Odkazy na dnešní ukázky: https://www.fi.muni.cz/~xpelanek/IB113/tutor-codes.html Doporučeno projít si interaktivně. 6/70 Názvy proměnných - konvence • konstanty - velkými písmeny a běžné proměnné: • smysluplná slova • víceslovné názvy: lower_case_with_undersc • krátké (jednopísmenné) názvy: • indexy • souřadnice: x, y • pomocné proměnné s velmi lokálním využitím Globální a lokální proměnné Globální proměnné • definovány globálně (tj. ne uvnitř fun • jsou viditelné kdekoli v programu Lokální proměnné • definovány uvnitř funkce • jsou viditelné jen ve své funkci Rozsah proměnných obecněji • proměnné jsou viditelné v rámci svého „rozsahu" • rozsahem mohou být: • funkce • moduly (soubory se zdrojovým kódem) • třídy (o těch se dozvíme později) • a jiné (závisí na konkrétním jazyce) relevantní terminologie: „namespace", „scope" 9/70 Globální a lokální proměnné a = "This is global." def examplel(): b = "This is local." print(a) print(b) examplel() # This is global. # This is local. print(a) # This is global. print(b) # ERROR! # NameError: name 'b' is not defined Globální a lokální proměnné Python 3.6 a = "This is global." def examplel(): b = "This is local." print ta) print (b) # This is global # This is local. # This is global # ERROR! 1 2 3 4 5 6 7 examplel() 9 print(a) 11 printib) Edit code I Live programming Print output (drag lower right corner to resize) This i 5 global. Fra rnes Global frame examplel This is global examplel b "Thi ü 1ü local Objects function examplel() 1 vytváříme novou lokální proměnnou, neměníme tu globální a = "Think global." def example2(): a = "Act local." print(a) print(a) # Think global. example2() # Act local. print(a) # Think global. 12/70 Globální a lokální proměnné Python 3.6 a = "Think global." 2 def example?(): a = "Act local." —► 5 print(a) 6 print(a) # Think global, example2O # Act local. 3 print(a) # Think global. Edit code | Live programming st executed ^cute ) set a breakpoint; use the Back and Forward buttons to jump there. Print output (drag lower right corner to resize) Think global Frames Global frame example2 example2 Think global Objects fL"CtÍO" example2() a "Act local." 13/70 Globální a lokální proměnné Jak měnit globální proměnné? a = "Think global." def example3(): global a a = "Act local." print(a) print(a) # Think global example3() # Act local. print(a) # Act local. Lokální proměnné: deklarace lokální proměnná vzniká, pokud je přirazení kdekoli uvnitř f u n kce a = "Think global, def example4(change_opinion=False): print(a) if change_opinion: a = "Act local." print("Changed opinion:", a) print(a) # Think global. example4() # ERROR! # UnboundLocalError: local variable 'a' reference # assignment < □ ► 37/70 def test(b): b.append(3) b = [4, 5] b.append(6) a = [1, 2] test(a) print(a) 38/70 Datové typy Datové typy určují: • význam dat • operace, které lze s daty provádět • hodnoty, kterých mohou data nabývat • bool • int, float, complex - číselné typy • str - řetězec • list - seznam • tuple - n-tice • diet - slovník • set - množina (vyber nejdulezitejsichj 40/70 print(type(3)) print(type(3.0)) print(type(3==0)) print(type("3")) print(type([3])) print(type((3,0))) print(type({3:0})) print(type({3})) Typy: kvíz type(3) type(3.0) type(3==0) type("3") type ([3]) type((3,0)) type({3:0}) type({3}) # 'float •> 'bool '> 'str'> 'list '> 'tuple '> 'diet '> 'set '> 42/70 • neměnitelné (immutable): bool, int, float, str, tuple • měnitelné (mutable): list, diet, set Příklady, kde důležité: • změna indexováním • předávání parametrů funkcím 9 indexování slovníku 43/70 • None - jedinečná hodnota typu NoneType • význam: „prázdné", „žádná hodnota" • využití: napr. defaultní hodnota parametrů funkcí • implicitní návratová hodnota z funkcí (pokud nepoužijeme return) 44/70 ravdivostnŕ hodnota if value: print("foo") Pro které z těchto hodnot value se vypíše f < True, False, 3, 0, 3.0, -3, [3], [] , None ravdivostnŕ hodnota test je úspěšný ("tme") vždy, kromě následujících případů • konstanty: None, Falše • nulové hodnoty u numerických typů: 0, 0.0, Oj • prázdné sekvence (nulová délka měřená pomocí len) D. (). (mírně zjednodušeno, např. u objektů může být komplikovanější) Dynamická kontrola typů • type(x) - zjištění typu • isinstance(x, t) - test, zdaje proměnná určitého typu values = [3, 8, "deset", 4, "dva", "sedm", 6] s = 0 for value in values: if isinstance(value, int): s += value else: print("Not int:", value) print("Sum of ints:", s) 47/70 • použití funkce při její vlastní definici • volání sebe sama (s jinými parametry) To iterate is human, to recurse divine. (L. Peter Deutsch) 48/70 xkcd: Tabletop Roleplaying YOUR PARTY ENTERS THE TAVERN. I GATHER EVERYONE AROUND / A TABLE. 2 HAVE THE ELVES / START WHITTLING PICE AND / GET OOT SOME FflRCHMEWT / FOR CHARACTER 5HEETS. / \ HEY; NO RZC0R5W. \ / https://xkcd.com/244/ 49/70 https://xkcd.com/688/ 50/70 Sebereferenčnř test O Které písmeno není správnou odpovědí na žádnou otázku: (A) A (B) C (C) B O Odpověď na 3. otázku je: (A) stejná jako na 1. otázku (B) stejná jako na 2. otázku (C) jiná než odpovědi na 1. a 2. otázku O První otázka, na kterou je odpověď A, je otázka: (A)l (B)2 (C)3 Hlavolamikon 51/70 Rekurze a sebereference Rekurze a sebereference - klíčové myšlenky v informatice některé souvislosti: • matematická indukce • funkcionální programování • rekurzivní datové struktury (např. stromy) • gramatiky • logika, neúplnost • nerozhodnutelnost, diagonalizace 52/70 Rekurze a sebereference nejen v informatice M. C. Escher; Drawing Gödel, Escher, Bach: An Eternal Golden Braid; Douglas Hofstadter Faktoriá n! = 1 • 2 • • • (n — 1) • n f{n) = 1 pokud n = 1 n • f (n — 1) pokud n > 1 54/70 Faktoriál iterativně (pomocí cyklu) def fact(n): f = 1 for i in range(1,n+l): f = f * i return f 55/70 def fact(n): if n == 1: return 1 else: return n * fact(n-l) initial < = = 0 "^O 56/70 Faktoriál rekurzivně - ilustrace výpočtu fact (4) 24 4 * fact(3 3 * fact (2 '2 57/70 Vymyslete funkci, která: • vypíše čísla od 1 do N • pomocí rekurze - bez použití cyklů f or, while 58/70 Vymyslete funkci, která: • vypíše čísla od 1 do N • pomocí rekurze - bez použití cyklů f or, while def sequence(n): if n > 1: sequence(n-1) print(n) 59/70 def test(n): print(n) if n > 1: test (n print(-n) test(5) Ilustrace zanořování test(3) 3 test(2) def def a rekurze even(n): print("even", n) odd(n-l) odd(n): print("odd", n) if n > 1: even(n-l) even(lO) 62/70 •<□► 4 ^ t < -Ž ► 4 S ► 63/70 Rekurzivní stromeček nakreslit stromeček znamená: • udělat stonek • nakreslit dva menší stromečky (pootočené) • vrátit se na původní pozici Stromeček želví grafikou def tree(length): forward(length) if length > 10: left(45) tree(0.6 * length) right(90) tree(0.6 * length) left(45) back(length) 65/70 oby rekurze, odstranění rekurze • koncová rekurze (tail recursion) • rekurzivní volání je poslední příkaz funkce • lze vesměs přímočaře nahradit cyklem • „plná" rekurze • „zanořující se" volání • např. stromeček o lze přepsat bez použití rekurze za použití zásobníku • rekurzivní podoba často výrazně elegantnější 66/70 anojské věže aneb 0 konci světa • video: • https://www.fi.muni.cz/~xpelanek/IBlll/hanojske_veze/ • https://www.youtube.com/watch?v=8yaoED8jc8Y o klášter kdesi vysoko v horách u města Hanoj • velká místnost se třemi vyznačenými místy • 64 různě velkých zlatých disků • podle věštby mají mniši přesouvat disky z prvního na třetí místo • a až to dokončí ... 67/70 Hanojské věže: pravidla • N disků různých velikostí naskládaných na sobě • vždy může být jen menší disk položen na větším • možnost přesunout jeden horní disk na jiný kolíček • cíl: přesunout vše z prvního na třetí 68/70 Hanojské věže: řešení 69/70 Hanojské věže: výstup programu »> solve(3, "A", "B", "C") A -> B A -> C B -> C A -> B C -> A C -> B A -> B Hanojské věže: rekurzivní řešení def solve(n, start, end, auxiliary): if n == 1: print(start, "->", end) else: solve(n-1, start, auxiliary, end) solved, start, end, auxiliary) solve(n-1, auxiliary, end, start) 71/70 • Předpokládejme, že b je seznam. Jaký je rozdíl mezi a = b a a = b[:]? • Jaký je význam pojmů „globální proměnná" a „lokální proměnná "? • Jaké jsou nevýhody použití globálních proměnných? • Jaký je význam pojmů „hluboká kopie" a „mělká kopie"? • Jaké jsou v Pythonu hlavní vestavěné typy? Které z nich jsou měnitelné a které neměnitelné? • Co je to rekurze? • Jak zapíšeme výpočet faktoriálu: a) za použití rekurze, b) bez použití rekurze? •<□► 4 ^ t < -ž ► < -š ► 72/70 a představa o reprezentaci v paměti je potřeba • globální, lokální proměnné • předávání parametrů funkcím • mělká vs. hluboká kopie • typy, měnitelné, neměnitelné • rekurze 73/70