====== Dilema I ======
* diskuse problémů
* vyjasnění zadání úlohy Vězňovo dilema
* 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 =======
/* Pro vyplnění formuláře je třeba se přihlásit na Google pod Vaší FEL identitou
[[https://forms.gle/kFqxMq54p7hjByPu6|101]]
[[https://forms.gle/3nLTaoxHoVa3zQVk7|102]]
[[https://forms.gle/QaZvFUtncp1Ne1CH7|103]]
[[https://forms.gle/vzsGD3QyLgcqMk1g7|104]]
[[https://forms.gle/oMqTMgeh4ao4uiwL8|105]]
[[https://forms.gle/uyin2XUR2RuBFCna6|106]]
[[https://forms.gle/MuffuZrZW4u4wWx8A|107]]
[[https://forms.gle/4kfZisGQAbhkvdvHA|108]]
[[https://forms.gle/yARdGc2Gxtt5qAudA|109]]
*/
> {{page>courses:b4b33rph:internal:puzzles#cviceni_2}}
====== Vězňovo dilema ======
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]]. Ptejte se na nejasnosti.
===== Jak splnit zadání úlohy =====
Několik základních kontrolních bodů, kterých je rozumné se držet:
* správně pojmenovat soubor
* správně pojmenovat třídu a metody (pozor na malá a velká písmena)
* správné parametry metody (self)!
* výstup metody
* správné odsazení
* nepřepisovat vnitřní proměnné nebo funkce Pythonu
====== Typické dvouhráčové hry ======
Další hry ala vězňovo dilema 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 seznam s prvky vektoru.
* Metoda ''get_vector(self)'' navrátí seznam obsahující prvky vektoru.
* Pomocí metody ''__mul__(self,other)'' implementujte [[https://en.wikipedia.org/wiki/Dot_product|skalární součin]] dvou objektů typu ''MyVector''. Výstupem je tedy skalár (jedno číslo). V metodě počítejte s libovolnou délkou vektorů, oba budou stejné, ale libovolné délky (ne jen 3-dimenzionální).
* Soubor ''vectors.py'' nesmí importovat jiné moduly.
* Soubor nahrajte do BRUTE do požadovaného termínu.
* BRUTE 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 v BRUTE. 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 skalarniho soucinu, pretizeny operator *, vola se __mul__
print(dot_product) # jen kontrolni vypis
===== Č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 Pythonu 2]] nebo [[https://www.codecademy.com/learn/learn-python-3|Pythonu 3]], pokud k němu máte přístup. 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í!**