3. Příklady a jednoduché algoritmy

Z minulého cvičení:

Podmínka:

if logický_výraz_1:
     <první blok příkazů>
elif logický_výraz_2:
    <druhý blok příkazů>
...
else:
    <třetí blok příkazů>

Cykly:

FOR

for <výraz> in <iterovatelný_objekt>:
    <blok_kódu_for>

Případně:

for <výraz> in <iterovatelný_objekt>:
    <blok_kódu_for>
else:
    <blok_kódu_else>

WHILE

while <logický_výraz>:
     <blok_kódu_while>

Případně:

while <logický_výraz>:
     <blok_kódu_while>
else:
    <blok_kódu_else>

Funkce

def <název_funkce>(<parametry>):
    <prikaz>
    <prikaz>
    <prikaz>

Případně s výstupní proměnnou:

def <název_funkce>(<parametry>):
    <prikaz>
    <prikaz>
    <prikaz>
    return <vystup>

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 math, který je jeden z vestavěných modulů Pythonu. Tento modul, stejně jako moduly ostatní, obsahují sady již připravených funkcí (viz odkaz).

Načtení modulu

Načtení modulu probíhá pomocí příkazu

import <název_modulu>

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)<název_funkce>(<parametry_funkce>)

# 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. Heronův vzorec.

def heron(a,b,c):
 
    # <Zde doplntě příslušný vzorec (či vzorce)>
 
    return obsah

Modul random

Na přednášce jste se setkali také s modulem 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 <název_modulu> import <název_funkce>

případně

from <název_modulu> import <název_první_funkce>, <název_druhé_funkce>, <název_třetí_funkce>, 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 <název_modulu> as <alias>

# 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 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):
 
    <vas kod> 
 
def rozklad_cisla(N):
 
    <vas kod>

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 <název_složky>.<název_modulu>

Funkce z daného modulu pak zavoláte pomocí:

<název_složky>.<název_modulu>.<název_funkce>(<argumenty_funkce>)

import moduly.prvni_modul

Případně můžete modul importovat s pomocí aliasu:

import <název_složky>.<název_modulu> as <alias_modulu>

Funkce z daného modulu pak zavoláte pomocí:

<alias_modulu>.<název_funkce>(<argumenty_funkce>)

import moduly.prvni_modul as prvni_modul

Případně můžete importovat jen určité funkce z daného modulu pomocí:

from <název_složky>.<název_modulu> import <název_funkce>

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. 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

courses/bab37zpr/tutorials/lab03.txt · Last modified: 2023/10/17 12:24 by vencovac