====== 3. Příklady a jednoduché algoritmy ====== ===== Z minulého cvičení: ===== ==== Podmínka: ==== if logický_výraz_1: elif logický_výraz_2: ... else: ==== Cykly: ==== === FOR === for in : Případně: for in : else: === WHILE === while : Případně: while : else: ==== Funkce ==== def (): Případně s výstupní proměnnou: def (): return ===== Moduly (knihovny) ===== Výchozí instalace Pythonu obsahuje tzv. moduly (knihovny) funkcí. Další, velmi užitečné, moduly lze do Pythonu doinstalovat. Co si ale pod pojmem modul představit a jak s ním zacházet? ==== Modul math ==== Na přednášce jste se již setkali s modulem [[https://docs.python.org/3/library/math.html|math]], který je jeden z [[https://docs.python.org/3/library/index.html|vestavěných]] modulů Pythonu. Tento modul, stejně jako moduly ostatní, obsahují sady již připravených funkcí (viz [[https://github.com/python/cpython/blob/3.10/Lib/random.py|odkaz]]). === Načtení modulu === Načtení modulu probíhá pomocí příkazu import import math # nápověda k funkci math je dostupná skrze příkaz help help(math) Po načtení modulu můžete volat funkce v ní obsažené. random(tečka)() # VS Code Vám napoví jaké funkce modul obsahuje math. # případně lze použít funkci dir print(dir(math)) # nápověda dostupná i pro parametry funkce # případně pomocí help(math.cos) # Mocnina math.pow(5,2) # Zamyslete se nebo najděte jaký je rozdíl mezi math.pow() a operátorem ** ==== Úloha 1. - obsah trojúhelníka z délek stran ==== Napište funkci na výpočet obsahu trolúhelníka pomocí délek jeho stran. Využijte modul math. K výpočtu použijte tzv. [[https://cs.wikipedia.org/wiki/Heron%C5%AFv_vzorec|Heronův vzorec]]. def heron(a,b,c): # return obsah ==== Modul random ==== Na přednášce jste se setkali také s modulem [[https://docs.python.org/3/library/random.html|random]], který slouží k práci s (pseudo-)náhodnými čísly. === Import funkce z modulu random === Výše jsme si ukázali, že pomocí funkce import můžeme naimportovat všechny funkce z vybraného modulu. Když ale chceme naimportovat pouze některé funkce, použijeme syntaxi from import případně from import , , , atd. # Import funkce randint z modulu random from random import randint # Funkci randint pak voláme randint(10,20) # Nelze tedy volat random.randint(10,20) ==== Úloha 2. - hod mincí ==== Napište funkci na hod mincí s pomocí funkce randint. Funkce by měla vypsat zda padla Panna nebo Orel. def hod_minci(): # Zde doplně kód pro hod mincí. ==== Import modulu jako ==== Modul můžete také importovat pod jiným jménem (aliasem) from as # import modulu random s aliasem rand import random as rand ==== Výpočet pi metodou Monte Carlo (pomocí funkce random) ==== pocet_bodu = 100 v_kruznici = 0 # počet bodů v jednotkové kružnici for i in range(pocet_bodu): x = 2*rand.random() - 1 # ziska nahodne cislo od -1 do 1 (rovnomerne rozdeleni) y = 2*rand.random() - 1 if (x**2 + y**2)<=1: # zjistuji, jestli jsou nahodna cisla uvnitr plochy kruhu v_kruznici += 1 pi_MC = 4*v_kruznici/pocet_bodu # odhad pi -- vychazi se z pomeru ploch kruhu a ctverce # prumer kruhu je roven delce strany ctverce. # odhad ploch je proveden poctem bodu, ktere padnou do ploch print(pi_MC) ==== Úloha 3. - Počet bodů ==== Kolik bodů musíte použít, abyste dostali $\pi$ o hodnotě 3.14? Upravte výše zmíněný kód tak, abyste automaticky našli takový počet bodů, při kterém Vám $\pi$ vyjde 3.14. Pro výpočet použijte cyklus while. ==== Úloha 4. - Jablka a hrušky ==== V krabici jsou jablka a hrušky. Víte, že by hrušek v krabici mělo být asi 7% z celkového počtu ovoce, ale nejste si zcela jistí. Začnete proto přendávat ovoce z jedné krabice do druhé a u toho jednotlivé kusy ovoce počítáte. Kolik hrušek jste napočítali, když jsem přendali 1000 kus ovoce? Využijte funkci random() z modulu random, společně s cyklem a vhodně navrženou podmínkou. Vypište kolik jste napočítali hrušek. # implicitně deklarujeme tzv. výchozí hodnotu pro počet kusů ovoce # tento parametr při volání funkce můžeme změnit # v případě, že funkci zavoláme bez vstupního parametru, nastaví se pro danou proměnnou výchozí hodnota def pocet_hrusek(kusu_ovoce=1000): ===== Tvorba vlastního modulu ===== Prozatím jsme využívali výchozí moduly obsažené v instalaci Pythonu. Modul je ale jen [[https://docs.python.org/3/tutorial/modules.html|souhr funkcí]], a tak si každý kdo v Pythonu programuje může vytvoři moduly vlastní. Pro vytvoření modulu tedy potřebujeme nějaké funkce. Dejme tomu, že máme funkci **isprime** (viz minulé cvičení): def isprime(n): ''' isprime(n) vraci True pokud je n prvocislo, jinak vrati False funkce nekontroluje, jestli je n cele cislo funkce postupne prochazi vsechny cisla od 2 az do hodnoty argumentu a zjistuje, jestli je zbytek po deleni roven nule ''' if n<2: return False for i in range(2,n): if n%i==0: return False return True Z jedné funkce také můžete udělat modul, ale v tomto případě to není úplně vhodné. Pojďme vytvořit alespoň ještě jednu funkci. ==== Úloha 5. - Rozložení celého kladného čísla na součin prvočísel ==== Celé kladné číslo vetší než 1 je možné rozložit jako součin prvočísel (základní teorém aritmetiky).
Napište program, který provede rozklad a vypíše jednotlivá provočísla na standardní výstup.
Pro rozložení implementujte tento algoritmus:
* Nejprve vydělte zadané číslo číslem 2 * Pokud je zbytek po dělení 0 a dělitel je prvočíslo, pak je dělitel jedním z nalezených faktorů * Vydělte zadané číslo dělitelem, pokud se výsledek rovna 1, pak algoritmus končí * Pokud se výsledek nerovná 1, pak inkrementujte dělitel (přičtěte k děliteli 1) a pokračujte v algoritmu Při výpisu oddělte jednotlivá provočísla symboly pro násobení na standardní výstup.
Pro řešení využije funkci isprime() vytvořenou v rámci domácích úloh z minulého cvičení (nebo viz výše) def rozklad_cisla(N): === Modul jako souhrn funkcí === * Funkce, **isprime** a **rozklad_cisla**, je potřeba přidat do stejného .py skriptu. * Daný skript si pak uložíme na stejné místo jako je tento notebook. * Název skriptu = název modulu. Název skriptu je tedy potřeba zvolit takový, aby se Vám nepletl, ale také tak, aby nebyl stejný jako název jiného modulu či funkce. Dejme tomu, že vytvoříme skript s názvem **prvni_modul.py**, do kterého dáme def isprime(n): def rozklad_cisla(N): Samotný modul načteme stejně jako moduly výchozí: import prvni_modul ## pro volání funkce isprime použíjeme prvni_modul.isprime(249) === Import modulů ze složky === Dejme tomu, že máte více funkcí, které nechcete mít všechny jen v jednom skriptu, a tak je rozdělíte do více souborů. Nechcete ale také, aby jste ve výchozí složce měli příliš mnoho souborů (chcete oddělit funkce od samotného programu). Co můžete v takovém případě udělat, je dát všechny skripty/moduly do jedné složky ve výchozím adresáři (např. **moduly**). Jednotlivé moduly pak naimportujete pomocí příkazů: import . //Funkce z daného modulu pak zavoláte pomocí:// ..() import moduly.prvni_modul Případně můžete modul importovat s pomocí aliasu: import . as //Funkce z daného modulu pak zavoláte pomocí:// .() import moduly.prvni_modul as prvni_modul Případně můžete importovat jen určité funkce z daného modulu pomocí: from . import from moduly.prvni_modul import isprime ===== Příklady na procvičení ve zbytku cvičení nebo doma ===== ==== Úloha 6. - Házení mincí o peníze ==== Cílem této úlohy vytvoření jednoduché hry, ve které hráč hází mincí a podle výsledku hodu buď peníze vyhraje nebo prohraje. Před každým hodem nechte uživatele hádat, jestli padne panna nebo orel (volba panna může být například písmeno 'p', orel písmeno 'o'). Pokud hráč zvolí něco jiného, opakujte volbu. Pokud uživatel uhodne výsledek hodu, vyhraje 1$\$$, pokud neuhodne, ztratí 2$\$$. Na začátku hry má uživatel 10$\$$. Hra končí, jakmile uživatel přijde o všechny peníze. Každý hod mincí vypište na standardní výstup. Vypište volbu hráče, jaký byl výsledek hodu (panna či orel) a stav hráčova konta po daném hodu. Příklad: Volis panna. //Na minci je panna, uhodl jsi! Bank: 11$\$$// //Pro hod mincí využijte modul random, viz úloha 2// ==== Úloha 7. - Největší společný dělitel ==== Přidejte do svého modulu tzv. [[https://cs.wikipedia.org/wiki/Eukleid%C5%AFv_algoritmus|Euklidův algoritmus]] pro nalezení největšího společného dělitele celých kladných čísel. * Algoritmus implementujte do funkce ''%%gcd(m,n)%%'', která bude mít dva parametry: $m$ a $n$
* Ve funkci nejprve odečtěte menší argument od většího a porovnejte, jestli výsledek odečtu a hodnota menšího argumentu si nejsou rovny.
* **Pokud ano**, rozdíl je největší společený dělitel. * **Pokud ne**, odečtěte od rozdílu čísel menší z argumentů a opakujte porovnání výsledku odečtu s odečítanou hodnotou (viz první krok).
* Takto algoritmus opakujte, dokud si nejsou čísla rovna, výsledek je pak největší společný dělitel. Na příkladu pro $m=9$ a $n=6$: * $m - n = 9 - 6 = 3$ * 3 není rovno 6, takže opakujeme odečítaní * Odečteme nyní $6 - 3 = 3$ * 3 == 3 a 3 je tudíž největší spolčený dělitel čísla 9 a 6 ==== Úloha 8. - Brownův pohyb (ve VS Code nemusí fungovat úplně skvěle) ==== Vytvořte simulaci Brownova pohybu pomocí standardního výstupu, na který budete vypisovat znak hvězdičky, který bude představovat zrnko pilu náhodně se pohybujícího na řádku.
* V prvním kroku bude poloha hvězdičky 100 znaků od začátku řádku
* V následujcích krocích generujte náhodná čísla od 0 do 1
* Pokud bude číslo v intervalu $<0,0.5)$ zobrazte hvězdičku na stejném řádku o jeden znak vlevo
* Pokud bude číslo v intervalu $<0.5,1>$ zobrazte hvězdičku na stejném řádku o jeden znak vpravo
* Pro zpomalení pohybu hvězdičky použijte funkci sleep z modulu time: ''%%time.sleep(cas)%%'', kde argument ''%%cas%%'' je doba pauzy v sekundach
import time, random ===== Domácí úkol ===== viz: cw k předmětu