====== Cvičení 12: Náhodná čísla, grafický výstup ====== ===== Quick Testy ===== V průběhu týdne se zde objeví zadání pro Quick Test Q1 a Q2. Tyto testy nejsou povinné, slouží hlavně jako trénink ke zkoušce. Doporučujeme všem si quick test vyzkoušet, necháváme na Vás, kdy si test zkusíte. Vyčleňte si na test alespoň 1 hodinu a změřte si, jak dlouho Vám bude trvat odevzdat funkční program. Optimálně byste měli quick test vyřešit do 30 minut. Ten kdo nevyřeší quick test ani do 1.5 hodiny tak by zkouškou z ALP neprošel a měl by si zkusit vyřešit před zkouškou ještě více příkladů. ==== Quick test QT2 ==== {{ :courses:b3b33alp:cviceni:slovnik.txt |slovnik.txt}} ===== Generování (pseudo)náhodných čísel ===== * Co je to "náhodné" číslo? * Lze generovat náhodná čísla na deterministickém stroji? * Pro generování opravdu náhodný čísel je nutné použít vnější zdroj, např. šum diody, což je ne vždy možné. * Jiné řešení spočívá ve výpočtu takové řady čísel, která se na 'dostatečně krátkém' úseku jeví jako náhodná * Nejčastěji používané: [[https://en.wikipedia.org/wiki/Linear_congruential_generator | LCG ]] === Princip LCG === * Generujeme posloupnost čísel $x_{n+1} = (ax_n + c)\,\, \mathrm{mod}\,\, m $ * kde $x_n$ je předchozí číslo, $x_{n+1}$ je následující číslo * $a,c,m$ jsou konstanty. * $m$ určuje periodu posloupnosti. * Naprogramujte toto LCG s parametry $a=1$, $c=1$, $m=5$. * Pozorujte, co se stane při $m=6$. * Prvnímu číslu posloupnosti říkáme **seed** === Generování náhodných čísel v Pythonu === * Modul **random** * funkce 'random()': generuje náhodné číslo z rovnoměrného rozdělení v rozsahu $<0,1)$. * funkce 'randint(a,b)': náhodné int číslo z rovnoměrného rozdělení v rozsahu $$. * Uvědomte si, že horní mez u 'random()' narozdíl od 'randint()' není zahrnuta! import random for i in range(10): print(random.random()) import random for i in range(10): print(random.randint(-10,10)) * Python defaultně nastavuje **seed** tohoto generátoru na aktuální čas. * Seed lze nastavit ručně: ''random.seed( cislo )'' ===== Vytváření jednoduché grafiky ===== * Existuje mnoho knihoven realizujících grafiku. * Knihovna Matplotlib: {{http://matplotlib.org/}} * podobné ovládání jako příkaz ''plot'' v Matlabu Hlavním objektem je ''plt'' z modulu ''matplotlib.pyplot'', který poskytuje spoustu metod ke kreslení různých funkcí. import numpy as np import matplotlib.pyplot as plt x = np.arange(0.,10.,0.1) y = np.sin(x) plt.plot(y) plt.show() {{courses:b3b33alp:cviceni:graf1.png?300|}} Všimněte si, ze výsledný graf je na ose 'x' číslován od 0 do 100, neboť to je velikost pole 'y'. Další možností je na zobrazit funkci sinus společně s osou 'x' definovanou dle pole 'x': plt.plot(x,y) {{courses:b3b33alp:cviceni:graf2.png?300|}} A pomocí volání funkcí 'x/ylabel' nastavíme popisky jednotlivých os plt.xlabel('osa x') plt.ylabel('osa y') **Samostatné úsečky:** je třeba zadat pole počátečních x-ových a y-ových souřadnic. plt.plot([x1,x2],[y1,y2],'k-'); **Uložení obrázků** do souboru: příkaz: [[ http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.savefig | savefig ]]. Pro současné ulozeni obrázků do souboru a zobrazení je třeba volat ''savefig'' před příkazem ''show''. plt.savefig('jmeno.png') **Kreslení histogramu** - příkaz [[ http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.hist | hist ]] import numpy as np import matplotlib.pyplot as plt size = 10000 y = np.random.randn(size) n, bins, patches = plt.hist(y, 50, normed=0, alpha=0.74) plt.savefig('histogram1.png', dpi=600) plt.show() {{courses:b3b33alp:cviceni:histogram1.png?300|}} Poznámka: meze grafu lze určit i ručně příkazem [[ http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.axis | axis ]] plt.axis([-5,5, 0, 0.5]) zobrazí graf na ose 'x' v rozsahu -5,5 a na ose 'y' v rozsahu 0 až 0.5. ==== Zobrazení histogramu ==== * Vygenerujte náhodná čísla z Gaussova rozdělení se střední hodnotou 5 a $\sigma=15$. * Vygenerujte náhodná čísla z Gaussova rozdělení se střední hodnotou 0 a $\sigma=5$. * Zobrazte příslušné histogramy do jednoho grafu ==== Kreslení fraktálů ==== {{courses:b3b33alp:cviceni:fractal_example.png?300}} import numpy as np import matplotlib.pyplot as plt def drawBranch(x, y, length, angle): # Konec rekurze if (length < 0.3): return a1 = 0.15 a2 = -0.15 s = 0.7 l2 = s*length x1 = x + l2 * np.cos(angle) y1 = y + l2 * np.sin(angle) plt.plot([x,x1],[y,y1], 'k-') drawBranch(x1, y1, l2, angle+a1) drawBranch(x1, y1, l2, angle+a2) if __name__ == '__main__': drawBranch(5,0,6,1.57) plt.show() {{courses:b3b33alp:cviceni:fractal_example.png?300}}