====== Den 3 ====== ===== Úkoly na opakování for-cyklu ===== ==== Úkol 1 ==== Aritmetická posloupnost je posloupnost čísel, která má stálý rozdíl sousední členů. Tomuto rozdílu říkáme diference. Například posloupnost 0 5 10 15 20 25 30 ... má diferenci 5. * Napište program, který vypíše prvních dvacet členů této posloupnosti. * Rozšiřte program tak, aby nejprve načetl požadovanou diferenci a následně vypsal dvacet členů odpovídající posloupnosti. Příklad: Zadejte diferenci: 7 0 7 14 21 28 35 42 49 56 63 70 77 84 91 98 105 112 119 126 133 * Rozšiřte program tak, aby nejprve načetl první člen posloupnosti a diferenci a následně vypsal prvních dvacet členů odpovídající posloupnosti. Příklad: Zadejte prvni clen posloupnosti: 14 Zadejte diferenci: 7 14 21 28 35 42 49 56 63 70 77 84 91 98 105 112 119 126 133 140 147 [[courses:pri-bootcamp:solutions:day3#ukol_1|Řešení]] Připomeňme, že pokud chceme pokračovat ve výpisu na stejném řádku musíme přidat parametr: ''end=""'', který Pythonu říká, jak ukončit výpis (v tomto případě s ''" "'', tj. mezerou). print("abc",end=" ") ---- ==== Úkol 2 ==== Napište program, který načtěte hodnotu ''N'' a vypíše jednotkovou matici. Vzorový výstup pro ''N=3'': 1, 0, 0 0, 1, 0 0, 0, 1 Jednotková matice je matice, která má diagonále (úhlopříčce) jedničky a všude jinde nuly ([[https://cs.wikipedia.org/wiki/Jednotkov%C3%A1_matice|Rigorózní definice ]]). [[courses:pri-bootcamp:solutions:day3#ukol_2|Řešení]] ---- ==== Úkol 3 ==== Napište program, který načte hodnotu ''N'' a vypíše následující obrazce (pro ''N=5''): 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 [[courses:pri-bootcamp:solutions:day3#ukol_3|Řešení]] ---- ==== Úkol 4 ==== Napište program, který načte hodnotu ''N'' a vypíše následující obrazce (pro ''N=5''): 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 [[courses:pri-bootcamp:solutions:day3#ukol_4|Řešení]] ---- ==== Úkol 5 ==== Napište program, který vykreslí tabulku malé násobilky, tj. tabulku všech vzájemných násobků čísel 1 až 10 (dodržte zarovnání v jednotlivých sloupcích): 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 K naformátování výpisu celého čísla uloženého v proměnné ''a'' na ''5'' míst je možné použít následující kód: print("{:5d}".format(a)) Dojde k nahrazení složených závorek (''{}'') hodnotou ''a'', která bude naformátována podle sekvence '':5d''. \\ Význam sekcence je: * znak formátování '':''\\ * počet míst ''5''\\ * číselná soustava (desítková) ''d''ecadical\\ Formátovaný výpis je možné kombinovat i s vlastním koncem řádků, takže desetinné číslo ''x'' vypíšeme s přesností na ''2'' desetinná místa bez zalomení konce řádku takto: print("{:.2f}".format(x),end="") [[courses:pri-bootcamp:solutions:day3#ukol_5|Řešení]] ===== While cyklus - teorie ===== V některých případech dopředu nevíme, kolikrát budeme muset nějaký příkaz nebo nějaké příkazy vykonat, a nemůžeme proto použít for-cyklus, který má pevně daný počet opakování. Pro tyto případy můžeme použít //while// cyklus, který opakuje příkazy ve svém těle dokud je splněna nějaká podmínka. Použití while cyklu si ukážeme na jednoduchém příkladu, kde od uživatele čteme čísla, které následně vypisujeme, ale jen do té doby, než uživatel zadá nulu, kdy cyklus skončí: x = -1 while x != 0: x = int(input("Zadej cislo: ")) print("Zadane cislo je: " + str(x)) V následujících úlohách se může stát, že while cyklus nepůjde opustit, ale pamatujte, že v Linuxu můžete vždycky přerušit vykonávaný program pomocí klávesové zkratky **ctrl + c**. Všechny programy zapsané pomocí for cyklu je možné přepsat i pomocí while cyklu, ne obráceně. ===== While cyklus - úkoly ===== ==== Úkol 1 ==== Napište program, který bude číst čísla ze vstupu, dokud uživatel nezadá nulu. Poté vypíše jejich součet. Upravete tento program tak, aby také vypsal: - délku posloupnosti - počet lichých a sudých čísel v posloupnosti - největší a nejmenší číslo - průměrnou hodnotu zadaných čísel [[courses:pri-bootcamp:solutions:day3#ukol_11|Řešení]] ---- ==== Úkol 2 ==== Přečtěte čísla A a B. Vypište nejmenší číslo, které je dělitelné B a je větší než A. [[courses:pri-bootcamp:solutions:day3#ukol_21|Řešení]] ---- ==== Úkol 3 ==== Přečtěte na vstupu jedno celé číslo a vypište jeho binární zápis. Hodnotu posledního bitu můžete určit podle toho, zda-li je zadaté číslo liché. | Ukázkové vstupy | Ukázkové výstupy | | 20 | 10100 | | 52 | 110100 | Binární zápis z předchozího řádku lze číst takto: $1 \cdot 2^4 + 0 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 0 \cdot 2^0 = 16 + 4 = 20$ Další rozsáhlejší vodítka k pochopení [[https://algoritmy.net/article/80/Prevod-cisla-mezi-soustavami|zde (cz)]]. [[courses:pri-bootcamp:solutions:day3#ukol_31|Řešení]] ---- ==== Úkol 4 ==== Načtěte celé číslo ze standardního vstupu a vypište nejmenší prvočíslo, které je větší než zadané číslo. [[courses:pri-bootcamp:solutions:day3#ukol_41|Řešení]] ---- ==== Úkol 5 ==== Člověk si myslí číslo od 1 do 100 a počítač se jej snaží uhádnout. Může se ovšem zeptat pouze, jestli je hádané čílo větší než nějaká hodnota. Napiště program, který co nejrychleji uhádne toto číslo. Vzorový průběh: Myslete si cislo mezi 1 a 100 Je tvoje cislo vetsi nez 50 ? (y/n) n Je tvoje cislo vetsi nez 25 ? (y/n) y Je tvoje cislo vetsi nez 38 ? (y/n) y Je tvoje cislo vetsi nez 44 ? (y/n) n Je tvoje cislo vetsi nez 41 ? (y/n) y Je tvoje cislo vetsi nez 43 ? (y/n) n Je tvoje cislo vetsi nez 42 ? (y/n) n Vase cislo je 42 [[courses:pri-bootcamp:solutions:day3#ukol_51|Řešení]] ---- ===== Seznam (pole) - teorie ===== Někdy se nám může stát, že nevíme, kolik dat bude náš program pokračovat (například, kolik čísel uživatel zadá) a tudíž nemůžeme mít pro každé načítané číslo vlastní proměnnou. Pro podobné případy, kdy potřebujeme mít mnoho porměnných stejného druhu, používáme //seznam// (anglicky //list//), který je uspořádanou skupinou více hodnot, kterým říkáme //prvky seznamu//. ==== Vytvoření seznamu ==== Seznam obsahující prvních 5 prvočísel (''2, 3, 5, 7, 11'') uložený v proměnné ''primes'' zapíšeme takto: primes = [2, 3, 5, 7, 11] Seznam může mít libovolný počet prvků a může tedy být i prázdný. Prázdný seznam můžeme vytvořit pomocí hranatých závorek nebo pomocí ''list()'': l1 = [] l2 = list() ==== Přístup k prvkům seznamu ==== Pro zjištění prvku na ''i''-té pozici (''i''-tém //indexu//) lze použít indexování. primes[i] Seznam je indexovaný **od nuly** (tedy první prvek má index 0). Pokud prvek seznamu neexistuje, program skončí s chybou, je tedy důležité vědět, jak dlouhý seznam je. Pro zjištěný délky seznamu můžeme použít funkci ''len()'', která vrátí počet prvků seznamu. velikost = len(seznam) Všimněte si nápadné podobnosti mezi textovými řetězci a seznamy. Není to náhoda, textové řetězce nejsou nic jiného než seznamy jednotlivých znaků ;) === Indexování v Pythonu === Specialitou Pythonu (a hrstky dalších programovacích jazyků) je možnost indexovat nejen od začátku seznamu, ale i od konce a to pomocí znaménka ''-'': primes[-1] # Posledni prvek primes[-2] # Predposledni prvek === Slicing === Specialitou Pythonu (a hrstky dalších programovacích jazyků) je takzvaný //slicing//, tedy přístup k celému intervalu indexů. Chceme-li získat seznam obsahující dvou prvcích s indexy 2 a 3 ze seznamu ''primes'' použijeme následující příkaz indexaci ve tvaru ''[a:b]'', která bere prvky s indexy v intervalu $ primes = [2, 3, 5, 7, 11] some_primes = primes[2:4] print(some_primes) vypíše ''[5, 7]''. Slicing funguje podobně jako range, tedy seznam a tedy podobon jako u range funguje i zde takzvanný //step// (krok), tedy kód: primes = [2, 3, 5, 7, 11] arr = primes[2:6:2] print(arr) vypíše ''[5, 11]'' prvky s indexy 2 a 4. ==== Vložení do seznamu ==== Chceme-li na konec seznamu ''arr'' vložit prvek ''x'', použijeme ''arr.append(x)''. Kupříkladu: arr = [1,2,4,8] x = 16 arr.append(x) print(arr) vypíše ''[1,2,4,8,16]''. Chceme-li přepsat hodnotu prvku v seznamu ''arr'' na ''i''-tém místě na hodnotu ''x'', použijeme ''arr[i]=x''. Kupříkladu: arr = [1,2,4,8] x = 3 arr[2] = x print(x) vypíše ''[1,2,3,8]''. Pomocí ''[ ]'' je tedy možné, jak číst obsah seznamu na konkrétné pozici, tak i měnit její hodnotu. Cheme-li přidat hodnotu ''x'' na pozici ''i'' a zbytek seznamu ''arr'' na obou stranách zachovat, použijeme ''arr.insert(i, x)''. Kupříkadu: arr = [1,2,3] x = 4 arr.insert(1,4) print(arr) vypíše ''[1, 4, 2, 3]''. \\ === Spojování seznamů v Pyhonu === Python umožňuje spojování seznamů dvěma způsoby. Chceme-li přidat na konec seznamu (''arr1'') postupně všechny prvky druhého seznamu (''arr2'') použijeme funkce ''extend'' (''arr1.extend(arr2)''). Například: arr1 = [1,2,3] arr2 = [4,5,6] arr1.extend(arr2) print(arr1, arr2) vypíše ''[1,2,3,4,5,6] [4,5,6]''. Chceme-li spojit stejné seznamy do nového seznamu ''arr3'', použijeme operátor ''+''. Například: arr1 = [1,2,3] arr2 = [4,5,6] arr3 = arr1 + arr2 print(arr1, arr2, arr3) vypíše ''[1, 2, 3] [4, 5, 6] [1, 2, 3, 4, 5, 6]''. \\ === Odstranění prvku z konce seznamu === Cheme-li odstranit poslední prvek ze seznamu ''arr'' a jeho hodnotu uložit do proměnné ''x'', použijeme ''x = arr.pop()''. Například: arr = [1,2,3] x = arr.pop() print(x) print(arr) vypíše nejprve ''x'' a pak ''[1,2]''. Chceme-li odstranit prvek ze seznamu ''arr'' na konkrétním indexu ''i'' a uložit ho do proměnné ''x'', použijeme ''x = arr.pop(i)''. \\ === Zjistění počtu výskytů prvku v seznamu === Cheme-li uložit počet prvků hodnoty ''x'' v seznamu ''arr'' do proměnné ''cnt'', použijeme ''cnt=arr.count(x)''. Například: arr = [1,2,3,2,2] cnt = arr.count(4) print(cnt) cnt = arr.count(2) print(cnt) vypíše nejprve ''0'' a pak ''3''. \\ === Seřazení seznamu === Cheme-li seřadit hodnoty v seznamu ''arr'' od největší po nejmenší, použijeme ''arr.sort()''. Obdobně můžeme použít ''srt = sorted(arr)'', která uloží seřazený seznam ''arr'' do proměnné ''srt'', aniž by měnila pořadí původního seznamu ''arr''. Například: arr = [2,2,6,0,9,11] arr.sort() print(arr) vypíše ''[0, 2, 2, 6, 9, 11]''. \\ === Otočení pořadí seznamu === Chceme-li obrátit pořadí prvků v seznamu ''arr'', použijeme ''arr.reverse()''. Například: arr = [1,2,3,4] arr.reverse() print(arr) vypíše ''[4, 3, 2, 1]''. Obdobně můžeme použít ''rev = reversed(arr)'', která uloží seznam ''arr'' v opačném pořadí do proměnné ''rev'', aniž by měnila pořadí původního seznamu ''arr''. ===== N-tice - teorie ===== //N-tice// (anglicky tuple) je datová struktura podobná seznamu. N-tice se od seznamů liší tím, že ji nelze měnit (nelze přepisovat její hodnoty, ani volat ''append()'', ''insert()'', apod). N-tices se používají v případech, kdy data nepotřebujeme a nechceme měnit. N-tici vytvoříte pomocí kulatých závorek: dny = ("pondeli", "utery", "streda", "ctvrtek", "patek", "sobota", "nedele") Ze seznam můžeme vytvořit novou n-tici použitím funkce ''tuple()''. Z n-tice můžeme vytvořit nový seznam použitím funkce ''list()''. ===== Seznamy a N-tice - úkoly ===== ==== Úkol 0 ==== Napište program, který načte pevně daný počet čísel (třeba 5), uloží je do seznanu a následně je vypíše. [[courses:pri-bootcamp:solutions:day3#ukol_0|Řešení]] ---- ==== Úkol 1 ==== Napište program, který načte pevně daný počet čísel (třeba 5), uloží je do seznamu, setřídí vzestupně a následně je vypíše. [[courses:pri-bootcamp:solutions:day3#ukol_12|Řešení]] ---- ==== Úkol 2 ==== Napište program, který načte pevně daný počet čísel (třeba 5), uloží je do seznamu, setřídí sestupně a následně je vypíše. [[courses:pri-bootcamp:solutions:day3#ukol_22|Řešení]] ---- ==== Úkol 3 ==== Napište program, který načte pevně daný počet čísel (třeba 5), uloží je do seznamu a najde minimum a maximum, které následně vypíše. [[courses:pri-bootcamp:solutions:day3#ukol_32|Řešení]] ---- ==== Úkol 4 ==== Napište program, který načte pevně daný počet čísel (třeba 5), najde mezi nimi dvě čísla taková, že jejich rozdíl je největší možný, tato čísla i jejich rozdíl vypíše. [[courses:pri-bootcamp:solutions:day3#ukol_42|Řešení]] ---- ==== Úkol 5 ==== Napište program, který načte pevně daný počet čísel (třeba 5), najde mezi nimi dvě čísla taková, že jejich rozdíl (ve smyslu abs. hodnoty) je nejmenší možný, tato čísla i jejich rozdíl vypíše. [[courses:pri-bootcamp:solutions:day3#ukol_52|Řešení]] ---- ==== Úkol 6 ==== Napište program, který načte pevně daný počet čísel (třeba 5) a najde medián [[https://cs.wikipedia.org/wiki/Medi%C3%A1n|wikipedie (cz)]], který následě vypíše. Případně upravte program tak, aby zvládal počítat medián i pro sekvence sudé délky. [[courses:pri-bootcamp:solutions:day3#ukol_6|Řešení]] ---- ==== Úkol 7 ==== Napište program, který načte pevně daný počet čísel (třeba 5), uloží je do seznamu, obrátí jejich pořadí a čísla vypíše. Nepoužívejte funkci ''reverse()''. Případně upravte program tak, aby zvládal obracet i sekvence sudé délky. [[courses:pri-bootcamp:solutions:day3#ukol_7|Řešení]] ---- ==== Úkol 8 ==== Napište program, který načte pevně daný počet čísel (třeba 5), seřadí je podle velikosti a následně vypíše. Nepoužívejte funkci ''sort()''. Případně upravte program tak, aby zvládal obrace i sekvence sudé délky. [[courses:pri-bootcamp:solutions:day3#ukol_8|Řešení]] ---- ==== Úkol 9 ==== Vraťte se k [[courses:pri-bootcamp:02#opakovani - Úkol 1|tomuto úkolu]] a zkuste využít nově získanou znalost. [[courses:pri-bootcamp:solutions:day3#ukol_9|Řešení]] ---- ===== Knihovny (a python moduly) - teorie ===== V programování se často setkávání s tím, že náš program musí dělat nějakou specifickou věc (například číst ze souboru, práci s časem, načítat obrázky, vykreslovat průběhy funkcí), kterou už až určitě někdo před námi řešil, můžeme si usnadnit práci tím, že využijeme knihoven, které tuto činnost implementují. V pythonu se namísto označení knihovna, používá označení //modul//. S moduly jsme se již setkali, například jsme využili modul ''math''. Chceme-li modul využívat, musíme o tom python informovat tím, že na začátek našeho skriptu napíšeme ''import jmeno_modulu''. Například: import math Chceme-li následně využívat funkce nebo proměnné (konstanty) modulu, používá se ''.'', tedy ''jmeno_modulu.jmeno_funkce()'' a ''jmeno_modulu.jmeno_promenne''. Například pro $\pi$ z modulu ''math'': math.pi ===== Modul random - teorie ===== Někdy v programu potřebujeme generovat náhodná čísla (například simulace nějakého náhodného jevu). Právě k tomuto účelu slouží modul ''random'', z nějž si ukážeme dvě funkce na následujících příkladech. Jako v případě libovolného modulu, musíme nejdříve modul importovat: ''import random'', pak můžeme používat jeho funkce jako ''random.funkce_kterou_chceme()''. Cheme-li vygenerovat celá čísla v danném intervalu $$ použijeme funkci ''randint(a, b)'', jako ku příkladu k simulaci hodu kostkou: # Program hraci kostka import random x = random.randint(1, 6) print(x) Chceme-li vygenerovat desetinné číslo, použijte funkci ''random()''. Ta vygeneruje číslo z intervalu <0, 1). import random x = random.random() print(x) Modul ''random'' obsahuje i další funkce, viz [[https://docs.python.org/3/library/random.html|dokumentaci modulu (en)]]. /* is it really necessary information? Takto vygenerovaná čísla ve skutečnosti nejsou náhodná, ale //pseudonáhodná//. To znamená, že jsou počítána jasně definovaným algoritmem, který vytváří takovou posloupnost čísel, že se její prvky zdají být náhodné. */ ===== Moduly random anebo math - úkoly ===== ==== Úkol 0 ==== Napište program, který vygeneruje 10 náhodných čísel v rozsahu 1 až 100. Program spočítá počet sudých, lichých čísel, spočítá průměrnou hodnotu všech čísel. Nakonec program nalezne největší a druhé největší číslo. Všechna tato čísla vypíše do příkazové řádky Zvládnete tuto úlou i bez použití seznamů? ;) [[courses:pri-bootcamp:solutions:day3#ukol_01|Řešení]] ---- ==== Úkol 1 ==== Jednou z možností, jak můžeme odhadnout hodnotu čísla $\pi$, je následující rovnice: $ \pi = 4 \left( 1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \frac{1}{9} - \frac{1}{11} + \frac{1}{13} - \frac{1}{15} + \dots \right)$ Napište program, který podle této rovnice odhadne hodnotu $\pi$ (třeba na 4 desetinná místa) a na závěr vypíše počet iteracích nutných k dosažení této přesnosti. Jako referenční hodnotu $\pi$ můžete použít modul ''math'': import math ref_pi = math.pi [[courses:pri-bootcamp:solutions:day3#ukol_13|Řešení]] ---- ==== Úkol 2 ==== Naprogramujte výpočet hodnoty čísla $\pi$ pomocí metody [[https://en.wikipedia.org/wiki/Monte_Carlo_method#Overview|Monte Carlo]]. Na vstupu uživatel zadá, na kolik desetinných míst by chtěl $\pi$ spočítat. Navíc po každých sto iteracích uložte současný mezivýsledek (hodnotu $\pi$) do seznamu. Seznam po doběhnutí výpočtu vytiskněte, abyste demonstrovali postupné zpřesňování výsledku. Pokud bude mít seznam více než sto prvků, vytiskněte pouze prvních sto. Pro kontrolu dosavadní přesnosti můžete váš výsledek porovnat s konstantou pi, která je již v Pythonu k dispozici. import math error = abs(moje_pi - math.pi) [[courses:pri-bootcamp:solutions:day3#ukol_23|Řešení]] ---- ==== Úkol 3 ==== Počítač vygeneruje náhodné číslo od 1 do 100 a vy ho musíte uhádnout. Když odpovíte špatně, počítač vám prozradí, jestli je vygenerované čílo větší nebo menší. Když uhádnete, program končí a pogratuluje vám. Vygenerovat náhodné číslo je možné pomocí následujícího kódu s použitím balíčku random: import random to_be_guessed = random.randint(0,100) Vzorový průběh: Zkus uhadnout moje cislo: 50 Moje cislo je mensi. Zkus uhadnout moje cislo: 20 Moje cislo je vetsi. Zkus uhadnout moje cislo: 30 Moje cislo je vetsi. Zkus uhadnout moje cislo: 40 Moje cislo je vetsi. Zkus uhadnout moje cislo: 45 Uhadl jsi :-) 45 [[courses:pri-bootcamp:solutions:day3#ukol_33|Řešení]] ---- ==== Úkol 4 ==== Napište program, který simuluje ''N'' hodů dvojicí kostek a vypište četnosti pro součet čísel na obou kostkách. Pro ''N=100'' může výpis vypadat například takto: 2: ** 3: **** 4: ************ 5: *********** 6: ***************** 7: ************************ 8: ******** 9: ******** 10: ***** 11: ******* 12: ** Hody kostkou je nutné simulovat pro každou kostku zvlášť. [[courses:pri-bootcamp:solutions:day3#ukol_43|Řešení]] /* HIC SUNT OLD VERSION TODO: */