====== Dilema I ====== * diskuse problémů * procvičování ''for'' cyklů * třída pro komplexní čísla a jejich sčítání, násobení, ... * procvičování základních datových typů ====== Hádanka ======= > {{page>courses:b4b33rph:internal:puzzles#cviceni_2}} ====== Typické dvouhráčové hry ====== Na přednášce byl prezentován problém vězňova dilematu. Přečtěte si pozorně zadání úlohy: [[..:veznovo_dilema:start| Vězňovo dilema]]. další čtení pro vaši inspiraci * [[http://en.wikipedia.org/wiki/Rock,_Paper,_Scissors|Rock paper scissors]] * [[http://en.wikipedia.org/wiki/Chicken_(game)|Game of chicken]] * [[http://en.wikipedia.org/wiki/Matching_pennies|Matching pennies]] * [[http://en.wikipedia.org/wiki/Coordination_game|Coordination game]] * [[http://en.wikipedia.org/wiki/Ultimatum_game|Ultimatum game]] * [[http://en.wikipedia.org/wiki/Pirate_game|Pirate game]] ====== Úkoly pro cvičení ====== ===== For cykly ===== > {{page>courses:b4b33rph:internal:cviceni:python#cykly&noheader}} ''for'' přes indexy seznamu, po elementech, zjištění délky seznamu, prázdný seznam. Implementujte jednoduchou funkci ''find_max'' def find_max(in_list): """ find maximum value in a list or tuple :param in_list: a list or tuple of elements that allow < comparison :return: a tuple max_value, index of the max_value within the list """ ===== Základní datové typy ===== základní datové typy: čísla, znaky, True, False, řetězce, platnost jednotlivých proměnných. Vylepšete funkci ''find_max'' tak, aby v případě, že vstupní seznam je prázdný vrátila hodnotu ''None''. Vhodně otestujte. > {{page>courses:b4b33rph:internal:cviceni:python#boolean&noheader}} ===== Jednoduchá třída ===== Navrhněte a implementujte třídu ''ComplexNumber''. Nejprve se zamyslete: * Čím je instance komplexního čísla definována? Jaké bude mít členské proměnné? * Jaké má vlastnosti? * Jaké má schopnosti? Jaké operace lze dělat s komplexním číslem? > {{page>courses:b4b33rph:internal:cviceni:python#vlastnosti&noheader&firstseconly}} Pokuste se třídu implementovat a postupně rozšiřujte její schopnosti. Neděste se, vyučující vám na cvičení ukáží jak na to. * ++ Inicializace | Implementujte metodu ''__init__(self, re, im)''. Co vidíte při spuštění příkazů: >>> a = ComplexNumber(3,4) >>> print(a.re) >>> print(a.im) >>> print(a)++ * ++ Čitelná reprezentace | Nebylo by hezké, kdyby instance komplexního čísla uměla vytvořit hezky čitelnou řetězcovou reprezentaci? Implementujte metodu ''to_string(self)'' tak, aby kód fungoval takto: >>> a = ComplexNumber(3,4) >>> print(a.to_string()) 3+4i++ * ++ Velikost (absolutní hodnota) komp. čísla | Implementujte metodu ''size(self)'', která vypočte a vrátí velikost komplexního čísla: >>> a = ComplexNumber(3,4) >>> print(a.size()) 5++ * ++ Inkrement reálné a imaginární části | Implementujte metodu ''inc_parts(self, re, im)'', která zvětší hodnoty reálné a imaginární části o zadaná čísla: >>> a = ComplexNumber(1,2) >>> a.inc_parts(2,2) >>> print(a.to_string()) 3+4i++ * ++ Inkrement komp. čísla jiným komplexním číslem | Implementujte metodu ''inc(self, other)'', která zvětší hodnoty reálné a imaginární části o hodnoty reálné a imaginární části druhého komplexního čísla předaného jako argument: >>> a = ComplexNumber(1,2) >>> b = ComplexNumber(2,2) >>> a.inc(b) >>> print(a.to_string()) 3+4i++ * ++ Součet komplexních čísel | Implementujte metodu ''add(self, other)'', která sečte komplexní číslo ''self'' s komplexním číselm ''other'' a výsledek vrátí jako novou instanci komplexního čísla: >>> a = ComplexNumber(1,2) >>> b = ComplexNumber(2,2) >>> c = a.add(b) >>> print(c.to_string()) 3+4i++ Možnost hezky vypsat komplexní číslo, zjistit jeho velikost, nebo sečíst 2 komplexní čísla pomocí námi definovaných metod je šikovná, ale ještě šikovnější by bylo, kdybychom mohli * místo ''print(a.to_string())'' napsat prostě ''print(a)'', * místo ''a.size()'' využít funkci ''abs(a)'', což je obvyklý způsob, jak zjistit absolutní hodnotu tam, kde to dává smysl, nebo * místo ''a.add(b)'' psát prostě ''a+b''. Python k tomu nabízí prostředky ve formě tzv. [[https://www.geeksforgeeks.org/dunder-magic-methods-python/|dunder metod]] (double underscore), kterým se taky někdy říká //magické metody//, ale nic magického na nich není (viz též [[https://docs.python.org/3/reference/datamodel.html#special-method-names|oficiální dokumentace]]). Jsou to metody, které se obvykle nevolají přímo, ale volá je interpret Python v jistých situacích. Jednu z nich už jste poznali - metodu ''__init__()'', kterou Python volá po vytvoření nové instance nějaké třídy a jejímž úkolem je instanci inicializovat. Pokuste se naši třídu ''ComplexNumber'' vybavit těmito metodami: * ++ __str__(self) | Buď přejmenujte metodu ''to_string()'' nebo ji v metodě ''__str__'' zavolejte. Měl by pak fungovat následující kód: >>> a = ComplexNumber(3,4) >>> print(a) 3+4i++ * ++ __abs__(self) | Buď přejmenujte metodu ''size(self)'' nebo ji v metodě ''__abs__'' zavolejte. Měl by pak fungovat následující kód: >>> a = ComplexNumber(3,4) >>> print(abs(a)) 5++ * ++ __add__(self, other) | Buď přejmenujte metodu ''add(self, other)'' nebo ji v metodě ''__add__'' zavolejte. Měl by pak fungovat následující kód: >>> a = ComplexNumber(1,2) >>> b = ComplexNumber(2,2) >>> c = a + b >>> print(c) 3+4i++ * Dokážete nyní odhadnout, k čemu slouží metoda ''__mul__(self, other)'' a pro jaký kód ji Python zavolá? Uměli byste tuto metodu implementovat pro třídu ''ComplexNumber''? Zkuste to, není to nic těžkého. * Když umíme dvě komplexní čísla sečíst, umíme je i odečíst, nebo ne? Zkuste, co udělá následující kód: >>> a = ComplexNumber(1,2) >>> b = ComplexNumber(2,2) >>> c = a - b >>> print(c)Dokážete třídu upravit tak, aby tento kód fungoval? > {{page>courses:b4b33rph:internal:cviceni:python#complex_number&noheader&firstseconly}} ====== Domácí úkol, příprava na příště ====== ===== DÚ na příští týden - modul pro výpočet skalárního součinu 2 vektorů ===== * vytvořte modul ''vectors.py'' * v něm bude definice třídy MyVector * konstruktor bude akceptovat (navíc k ''self'') jeden parametr, kterým bude jednodimenzionální pole. * metoda ''get_vector(self)'' navrátí jednodimenzionální pole obsahující prvky vektoru. * pomocí speciální metody ''__mul__(self,other)'' implementujte [[http://cs.wikipedia.org/wiki/Skalární_součin|skalární součin]] dvou objektů typu ''MyVector''. Výstupem je tedy skalár (jedno číslo). * soubor ''vectors.py'' nesmí importovat jiné moduly * soubor nahrajte do upload systému do požadovaného termínu * Upload systém vám kód ihned ohodnotí, případně několik sekund počkejte. * Za správně vyřešenou úlohu získáte až 2 body. Nazapomeňte na vlastní kontrolu kódu, nespoléhejte pouze na kontrolu UploadSystému. Třeba něco jako: if __name__ == "__main__": vec1 = MyVector([1,2,3]) # vektory mohou byt i jine dimenze nez 3! vec2 = MyVector([3,4,5]) print(vec1.get_vector()) # priklad ziskani seznamu dot_product = vec1*vec2 # vypocet, pretizeny operator *, vola se __mul__ print(dot_product) # jen kontrolni vytisk ===== Čtení ===== Přečtěte zbytek vašeho vybraného Python tutorial. V případě doporučeného jsou to kapitoly 3-9. Nemusíte úplně rozumět všemu, ani si pamatovat vše zpaměti. Měli byste mít natrénován postup jak si dohledat potřebné informace, mít natrénovanu práci s např. [[http://docs.python.org/py3k/tutorial/index.html|Python 3 tutoriálem]], nebo jiným podobným zdrojem veškeré moudrosti ;-) ===== Interaktivní cvičení ===== Na //codecademy// pokračujte v [[https://www.codecademy.com/learn/learn-python|interaktivním kurzu]]. Předpokládáme, že otázky, které jste měli po části kurzu z minulého týdne, jste položili na fóru nebo právě dnes na cvičení a že tudíž můžete pokračovat dál sekcemi: * Functions * Taking a vacation * Python lists and dictionaries * A day at the supermarket * Student becomes the teacher * Lists and functions * Loops Opět se pokuste dostat co nejdál. Stále platí, že tato cvičení vám mají především pomoci **identifikovat věci, kterým nerozumíte**. **Pokládejte otázky na fóru nebo na cvičení!**