C2184 Úvod do programování v Pythonu Nepovinné úkoly V úkolech v této sadě je potřeba (narozdíl od předchozích sad) vždy zadefinovat nejakou funkci. Není třeba načítat vstup pomocí funkce input, testy budou volat Vaši funkci tak, jak uvádí vzorové volání. Pokud je uvedené vzorové volání a vzorový výsledek, chce se od Vás, aby návratovou hodnotou vzorového volání byl vzorový výsledek (return). Pokud je uvedené vzorové volání a vzorový výstup, nemá funkce vracet žádnou návratovou hodnotou, ale má vypisovat vzorový výstup (print). Cvičení 6.1: Objem kužele Úkol: Napište funkci cone_volume, která bere jako parametry poloměr podstavy kužele (radius) a jeho výšku (height) a vrací objem kužele. Objem kužele lze spočítat podle vzorce: 𝑉 = 1 3 𝜋𝑟2 ℎ Vzorové volání 1:   Vzorové volání 2:   cone_volume(10, 5) cone_volume(1.5, 3.2) Vzorový výsledek 1:   Vzorový výsledek 2:   523.5987755982989 7.5398223686155035 [ ]: import math def cone_volume(radius: float, height: float) -> float: return 1/3 * math.pi * radius**2 * height 1 Cvičení 6.2: Dělitelé Úkol: Napište funkci divisors, která bere jako parametr přirozené číslo n a vrací seznam všech dělitelů čísla n (v pořadí od nejmenšího). Funkce navíc bere nepovinný parametr proper: • Pokud je proper nastaveno na False (default), pak funkce vrací všechny dělitele, včetně samotného n. • Pokud je proper nastaveno na True, pak funkce vrací pouze vlastní dělitele, tj. všechny dělitele kromě samotného n. Poznámka: na hledání dělitelů existují efektivnější algoritmy, ale v této úloze úplně postačí naivní řešení, tj. zkusit všechna čísla od 1 až po n. Vzorové volání 1:   Vzorové volání 2:   divisors(12) divisors(30, proper=True) Vzorový výsledek 1:   Vzorový výsledek 2:   [1, 2, 3, 4, 6, 12] [1, 2, 3, 5, 6, 10, 15] [ ]: def divisors(n: int, proper: bool = False) -> list[int]: result = [] for i in range(1, n+1): if n % i == 0: result.append(i) if proper: result.pop() return result Cvičení 6.3: Společná písmena Úkol: Napište definici funkce common_letters, která přijímá seznam řetězců. Funkce vrátí množinu znaků, které se vyskytují v každém z těchto řetězců. Pokud bude funkce volána na prázdném seznamu, vrátí prázdnou množinu. Nápověda: při řešení lze využít množinové operace (průnik intersection (&), sjednocení union (|)…). Vzorové volání 1:   Vzorové volání 2:   common_letters(['mrkev', 'krkavec', 'krabice']) common_letters([]) Vzorový výsledek 1:   Vzorový výsledek 2:   {'e', 'k', 'r'} set() 2 [ ]: def common_letters(words: list[str]) -> set[str]: if len(words) == 0: return set() result = set(words[0]) for word in words: result = result & set(word) # OR result.intersection_update(word) return result Cvičení 6.4: Úhel Mějme dva vektory v rovině: ⃗𝑢 = (𝑢 𝑥, 𝑢 𝑦), ⃗𝑣 = (𝑣 𝑥, 𝑣 𝑦). Pak velikost úhlu 𝛼 mezi těmito vektory umíme spočítat podle vzorce cos(𝛼) = ⃗𝑢 ⋅ ⃗𝑣 | ⃗𝑢| | ⃗𝑣| V tomto vzorci ⃗𝑢 ⋅ ⃗𝑣 značí skalární součin vektorů a | ⃗𝑢| značí velikost vektoru. ⃗𝑢 ⋅ ⃗𝑣 = 𝑢 𝑥 𝑣 𝑥 + 𝑢 𝑦 𝑣 𝑦 | ⃗𝑢| = √ ⃗𝑢 ⋅ ⃗𝑢 Úkol: Napište funkci angle, která spočítá velikost úhlu (v radiánech) mezi dvěma zadanými vektory. Vektory budou reprezentovány dvojicemi reálných čísel. Řešení je vhodné rozdělit na jednodušší podúkoly, například definovat nejdřív funkce dot (skalární součin) a size (velikost) a ty pak vhodně volat ve funkci angle. Vzorové volání 1:   Vzorové volání 2:   angle((1, 1), (2, -2)) angle((1.5, 2.2), (5.2, 4.8)) Vzorový výsledek 1:   Vzorový výsledek 2:   1.5707963267948966 0.22695795704220176 Pro kontrolu: velikost vektorů ve vzorovém volání 1 má vyjít zhruba 1.414 a 2.828, skalární součin 0.0. [ ]: import math def angle(u: tuple[float, float], v: tuple[float, float]) -> float: """Return the angle between two 2D vectors in radians""" cos_alpha = dot(u, v) / (size(u) * size(v)) alpha = math.acos(cos_alpha) 3 return alpha def dot(u: tuple[float, float], v: tuple[float, float]) -> float: """Return the dot product of two 2D vectors""" return u[0]*v[0] + u[1]*v[1] def size(u: tuple[float, float]) -> float: """Return the size (magnitude) of a 2D vector""" return math.sqrt(dot(u, u)) 4