Warning
This page is located in archive.

Cvičení 2: Cykly a reálná aritmetika

Opakování

Celočíselné operace - práce s časem

  • Napište program, který načte celé číslo udávající časový interval ve vteřinách a vypíše kolik je to dní, hodin, minut a vteřin.
  • Tedy pokud bude vstup 100000 pak vypíše: den 1 hodin 3 minut 46 vterin 40

Rozdíl dvou časových údajů

  • Napište program, který vypočítá rozdíl dvou časů zadaných ve formátu: HH:MM:SS

Cykly

Základní druhy cyklů

  • for cyklus - procházení seznamu hodnot
  • while cyklus - opakuj cyklus dokud platí podmínka

While cyklus

  • while cyklus je založen na podmínce, která se vždy na začátku cyklu testuje a pokud je splněna vykoná se zadaný blok instrukcí

while podmínka:
  blok instrukcí

  • Zajímavost
    • Lze dokázat, že nelze sestrojit program, který by rozhodl, zda jiný program skončí či nikoliv.
    • Člověk může dokázat, že daný while cyklus skončí
    • Pokud důkaz chybí, není jisté, zda program s while cyklem skončí

n = int(input())
while n > 1:
  if n % 2 == 0:
    n = n // 2
  else:
    n = 3 * n + 1

For cyklus

For cyklus

  • for cyklus standardně prochází zadaný seznam hodnot
  • for cyklus je založen na proměnné, která prochází seznam hodnot a pro každou hodnotu ze seznamu provede blok instrukcí

for proměnná in seznam:
  blok instrukcí

for i in "abcd":
  print(i)

for i in (1, 10, 2, 8):
  print(i)

  • Pro standardní procházení nějakého rozmezí:
    • range(start, cíl, krok),
    • range(cíl), kdy start je automaticky 0 a krok je nastaven na 1,
    • range(start, cíl), kdy krok je 1.
  • Lze vytvořit i for cyklus, který má dynamicky měnící se seznam hodnot, případně vrací nekonečně krát stejné/rozdílné hodnoty. V tomto případě se pak jedná spíše o while cyklus a vám doporučujeme vzhledem k přehlednosti implementovat takový program jako while cyklus.

Instrukce break a continue

  • Uvnitř bloku instrukcí mohou být příkazy break a continue.
  • Příkaz break znamená, že se okamžitě ukončí vykonávání bloku instrukcí a ukončí se i cyklus, který tento blok instrukcí obsahuje.
  • Příkaz continue znamená, že
    • se ukončí provádění bloku instrukcí a provede se vyhodnocení podmínky (u while cyklu)
    • se přejde na novou hodnotu (u for cyklu) a pokud je to možné pokračuje se v provádění bloku instrukcí.
  • POZOR u vnořených cyklů nemají příkazy break/continue vliv na vnější cyklus.

for i in "abcd":
  if i == "c":
    break
  print(i)

  • Výstup:

a
b

for i in "abcd":
  if i == "c":
    continue
  print(i)

  • Výstup:

a
b
d

While cykly

  • Napište program, který udělá to samé co opakování for cyklů pomocí while cyklu:
    • vytiskněte čísla 10 až 500 po deseti
    • vytiskněte čísla -20 až -600 po dvaceti

Break loop

  • Napište program, který načte číslo $n$ a najde jeho nejmenšího dělitele většího než 1.
  • Je vhodné použít konstrukci break, cyklus můžete použít while i for.
  • Otestujte svůj program na čísle 999962000357

Tisk šachovnice

  • Napište program, který vytiskne čtvercovou šachovnici ze znaků 'O' a '*' o velikosti zadané uživatelem, jako vstup Vašeho programu.
  • Pro tisk znaku bez konce řádky použijte následující konstrukci (end definuje zakončení řetězce a je standardně nastaveno na nový řádek):

print('.', end="")

Odlaďte syntaktické chyby v programu

  • Zkopírujte si následující kód do souboru
  • V programu odstraňte syntaktické chyby
  • Program spusťte a zjistěte co dělá

step = 0.1
sum = 0
for is in range(1, 11):
    sum += step
    if suma == is / 10:
        print("Plati", sum, "rovno", is / 10)
     else:
       print("Neplati", sum, "nerovno", is / 10)

Výpočet třetí odmocniny přičítáním

  • Vypočtěte třetí odmocninu kladného čísla $y$, zadaného jako vstup Vašeho programu následujícím postupem:
    • Přičítejte k proměnné $v$ číslo 1 dokud je třetí mocnina této proměnné menší než $y$
    • Přičítejte k proměnné $v$ číslo 0.1 dokud je třetí mocnina této proměnné menší než $y$
    • Přičítejte k proměnné $v$ číslo 0.01 dokud je třetí mocnina této proměnné menší než $y$
    • Proměnná $v$ obsahuje odmocninu čísla $y$ s přesností na dvě desetinná čísla

Výpočet třetí odmocniny přičítáním se zadanou přesností

  • Upravte předchozí program tak, aby pracoval se zadanou přesností
  • Program načte číslo $y$ a $n$ a nalezne třetí odmocninu z čísla $y$ na $n$ desetinných míst
  • Upravte algoritmus, aby uměl spočítat i třetí odmocniny ze záporných čísel

Půlení intervalu

  • Metoda půlení intervalu hledá řešení obecné rovnice $f(x)=0$, kdy známe dva body $x_1$ a $x_2$ takové, že $f(x_1)<0$ a $f(x_2)>0$.
    • Algoritmus rozpůlí interval mezi body $x_1$ a $x_2$, tedy nalezne bod $x' = \frac{x_1+x_2}{2}$ a pokud je $f(x')<0$ pak nahradí bod $x_1$ bodem $x'$, jinak nahradí bod $x_2$ bodem $x'$.
    • Výše uvedený krok se opakuje dokud není $|x_1-x_2|<\epsilon$, kde $\epsilon$ je požadovaná přesnost.
  • V případě hledání třetí odmocniny z čísla y:
    • $f(x)=x^3-y$
    • Pokud $f(x)=0$, tak $x^3-y=0$, což lze zapsat jako $x^3=y$ a tedy $x=\sqrt[3]{y}$
  • Napište program, který nalezne třetí odmocninu zadaného čísla $y$ na 8 desetinných míst
    • (výpočet ukončíte pokud $|x_1-x_2|<0.000000001$).
    • Na počátku zvolte $x_1=0$ a $x_2=y$ pro kladná $y>1$, $x_1=y$ a $x_2=0$ pro záporná $y< -1$, a $x_1=-1$ a $x_2=1$ v ostatních případech.

Výpočet třetí odmocniny - porovnání

  • Spusťte všechny úlohy 6 - 8 pro stejné hodnoty čísla $y$ a zjistěte, které řešení potřebuje nejmenší počet kroků (změna hodnoty $x$) k nalezení řešení s přesností na 8-desetinných míst $\epsilon=10^{-8}$.

Témata k procvičení

  • Výpočet třetí odmocniny Newtonovou metodou: Newtonova (Babylónská) metoda tečen $x_{i+1}= x_{i}-\frac{f(x_i)}{f'(x_i)}$ pro třetí odmocninu z čísla $y$ je opět $f(x)=x^3-y$ a tím $f'(x)=3x^2$, pak dostáváme $$x_{i+1}=\frac{1}{3}\left( 2x_i + \frac{y}{x_i^2} \right)$$
    • Řada $x_i$ konverguje k třetí odmocnině z čísla $y$
    • $x_0$ můžete nastavit na libovolnou hodnotu různou od 0, např $x_0=1$, případně na lepší odhad.
    • Čím lepší odhad nalezneme, tím rychleji řada konverguje.
    • Výpočet lze ukončit
      • např. podle rozdílu $|x_{i+1}-x_i| < \epsilon$
      • nebo lze testovat $|x_i^3 - y| < \epsilon$
  • Algoritmus pro výpis čísel -100,-99,-80,-79,-60,-59, $\ldots$ -20,-19,0,1,20,21, $\ldots$, 100.
  • Výpis hodnot sin(x) v intervalu $<0,2\pi)$ se zadaným krokem $\delta$. Např. pro $\delta=0.1$ program vypíše sin(0), sin(0.1), sin(0.2) atd.

Domácí úkol

Lehká varianta

* Napište program root.py který metodou půlení intervalu spočítá kořen polynomu 5-tého stupně $a_5\cdot x^5+a_4\cdot x^4+a_3\cdot x^3+a_2\cdot x^2+a_1\cdot x+a_0$

  • Vstup: šest řádek, obsahující postupně koeficienty $a_5$ až $a_0$. Koeficient $a_5$ je na první řádce, $a_0$ na poslední řádce.
  • Výstup: jedno reálné číslo, které je kořenem zadaného polynomu.
  • Pro výpočet použijte metodu půlení intervalu.
  • Výsledek nalezněte s přesností na 9 desetinných míst (výpočet ukončíte pokud $|x_1-x_2|<0.0000000001$).
  • Pro prvotní nastavení krajních mezí víte že:
    • kořen $x \in (-10,10 )$
  • Použití jakékoliv knihovní funkce (např. math.log) není dovoleno, program volající cizí funkce nebude hodnocen.
  • Příklady:

Vstup:
4
-12
1
-30
11
-14
Výstup:
3.5
Protože $4\cdot3.5^5-12\cdot3.5^4+3.5^3-30\cdot3.5^2+11\cdot3.5-14 = 4\cdot525.21875-12\cdot150.0625+42.875-30\cdot12.25+11\cdot3.5-14 = 0$

Těžká varianta

  • Napište program subtraction.py, který od sebe odečte dvě reálná čísla zadané v binární číselné soustavě
    • Vstup: dvě řádky standardního vstupu, každá řádka obsahuje desetinné číslo v binární číselné soustavě ve tvaru 1.0101e-101
    • Výstup: rozdíl čísel v binární soustavě nebo ERROR pokud nebyly vstupy zadané korektně.
  • Řešení spočtěte přesně, nepoužívejte převod na reálné číslo v Pythonu, které může provést zaokrouhlení.
  • Správný formát desetinného čísla:
    • nenulové číslo začíná znaky '1.' (nebo záporné číslo znaky '-1.'), po kterých může následovat desetinná část čísla složená ze znaků '0' a '1', dále může následovat znak 'e' po kterém může následovat znak '-' a dále musí následovat celé číslo v binární formě reprezentující exponent.
    • nulové číslo je reprezentováno pouze znakem '0'
  • Řešení vypište ve stejném tvaru, jake je vstupní tvar desetinného čísla. Navíc nevypisujte zbytečné 0 před znakem “e”, případně na konci čísla, kde se “e” nevyskytuje:

špatně   1.010e100
správně  1.01e100

  • Příklady:
    Vstup:
    1.01e11
    1.01e11
    Výstup:
    0
    Vstup:
    1.1101e-1011
    1.1
    Výstup:
    -1.011111111100011
    Vstup:
    1.1101
    1.101e-1
    Výstup:
    1.
    Vstup:
    -1.1101e11
    1.101e-1
    Výstup:
    -1.1110101e11
    Vstup:
    1.11011e1101
    1.001e-101
    Výstup:
    1.110101111111111110111e1101
    Vstup:
    1.11011e
    1.001e-101
    Výstup:
    ERROR
courses/b3b33alp/cviceni/t02.txt · Last modified: 2023/10/17 15:23 by petrapa6