Cvičení 3: Funkce

Opakování cyklů

Ramanujan Taxi

  • Ramanujan (1887-1920) byl velmi zajímavý geniální indický matematik. Byl objeven prof. Hardym a pozván do Anglie. Zde onemocněl a když ho prof. Hardy navštívil v nemocnici, řekl mu, že za ním přijel taxíkem číslo XXXX. Ramanujan mu okamžitě odpověděl, že je to velmi zajímavé číslo, protože je to nejmenší číslo, které lze zapsat dvěma různými způsoby jako součet dvou krychlí (třetích mocnin přirozených čísel).
  • Najděte čtyřciferné číslo taxíku XXXX.

Funkce

Při programování často potřebujeme vykonat určité operace opakovaně. K tomu se hodí tzv. funkce.

  • Funkce je seskupení příkazů
  • Vstupem funkce jsou argumenty (jsou nepovinné)
  • Složitý problém se typicky rozdělí na jednodušší úkony, které se naprogramují do funkcí
  • Takový kód je snáze udržovatelný/čitelný
  • Funkce mohou obsahovat lokální proměnné, které “nejsou vidět” ve zbytku programu
  • V Pythonu se funkce definují klíčovým slovem def a tělo funkce (vnitřní příkazy) jsou odsazeny

def jmenoFunkce( parametry ):
   telo_funkce

Maximum ze dvou čísel:

def maximum(x,y):
    if x>y:
        return x
    else:
        return y  

  • klíčové slovo return vrací výsledek funkce. Příklad volání této funkce:

max = maximum(2,0.5)
print(max)
 
# nebo rovnou muzeme predat jiné funkci
a = 6
b = 7
print("Maximum z ",a," a ", b, " je ", maximum(a,b))

  • Parametry jsou nepovinné. Funkci bez parametrů definmujeme s prázdnými závorkami

def hello():
    print("Hello World!")

  • V tomto případě funkce ani nevrací žádnou hodnotu (pouze vypíše řetězec), není tedy třeba volat return
  • Volání funkce bez parametrů

hello()

  • Funkce v Pythonu mohou vracet více parametrů
  • Příklad: funkce vracející maximum ze dvou čísel, s informací o tom, jestli maximem je 1. nebo 2. argument

def maximum2(x,y):
    if (x > y):
        return x, True
    else:
        return y, False  
 

  • Volání

maxValue, info = maximum2(5,6)
 
#zkusime predat printu:
print("Maximum z 5,6 je ", maximum2(5,6))

Funkce quit()

  • Pokud není uvedeno jinak, program končí po vykonání posledního příkazu
  • Někdy se hodní ukončit program dříve, např. při špatně zadaném vstupu.
  • K tomu slouží funkce quit()

if (spatny_vstup):
    quit()

Dosud jsme se setkali s několika funkcemi:

  • input() - načte řetězec ze standardního vstupu
  • print( argumenty ) - tiskne řetězec na standardní výstup
  • int( argument ) - převod na celé číslo
  • float( argument ) - převod na reálné číslo
  • str( argument ) - převod na řetězec
  • quit() - ukončí běh programu

Úkol 1: absolutní hodnota

  • Napište funkci s jedním argumentem, která vrací absolutní hodnotu tohoto argumentu

Úkol 2: Sexy prvočísla

  • Sexy prime jsou takové dvojice prvočísel, jejichž (kladný) rozdíl je 6. Například 5 a 11 jsou prvočísla a zároveň se liší o 6, tedy dvojice (5,11) jsou tzv. sexy-primes.
  • Napište program, který vypíše všechny takové dvojice menší než 1000.

Úkol 3: Dokonalá čísla

  • Dokonalé číslo je takové číslo, které je součtem všech svých dělitelů (kromě sebe samotného samozřejmě).
  • Například číslo 6 je dokonalé, neboť 6 = 1 + 2 + 3, kde 1,2,3 jsou dělitelé čísla 6.
  • Napište program, který vypíše všechna dokonalá čísla od 1 do 10000.

Úkol 4: Super-dokonalá čísla čísla

  • Super-dokonalá čísla jsou zobecněním dokonalých čísel.
  • Číslo $n$ je super-dokonalé, pokud platí $f(f(n)) = 2n$, kde $f(n)$ je součet dělitelů čísla $n$ od 1 do $n$ (včetně $n$).
  • Například pro číslo 4: dělitelé jsou $1,2$ a $4$, tedy $f(4)=1+2+4=7$. Dělitelé 7 jsou 1 a 7, tedy $f(7)=1+7=8$, což je $2\times4$. Číslo 4 je tedy super-dokonalé.
  • Napište funkci soucet_delitelu, která spočte součet dělitelů čísla $n$, tedy funkci $f(n)$.
  • Funkci soucet_delitelu použijte v programu, který vypíše seznam super-dokonalých čísel od 1 do 10000.

Úkol 5: Největší společný dělitel

  • Napište funkce gcd1(a,b) a gcd2(a,b), které vrátí největšího společného dělitele čísel $a$ a $b$.
  • Funkce gcd1 bude počítat největšího společného dělitele čísel $a$ a $b$ takto:
    • Dokud a není rovno b
      • Je-li a větší než b
        • a = a-b
      • jinak
        • b = b-a
    • a i b jsou největší společný dělitel původních čísel
  • Funkce gcd2 bude počítat největšího společného dělitele čísel následovně:
    • Dokud b není rovno nule
      • t = b
      • b = a mod b
      • a = t
    • a je největší společný dělitel původních čísel
  • Zjistěte kolik kroků potřebuje gcd1 a gcd2 pro spočtení největšího společného dělitele 6997193,18992381 a dvojice 361,18992381

Úkol 6 Césarova šifra

  • Napište program pro realizaci tzv. Césarovy šifry
  • Vstup: dvě řádky
    • 1. řádka: textový řetězec (pouze písmena a mezery)
    • 2. řádka: číslo definující posunutí písmen v Césarově šifře
  • Program na výstup vypíše vstupní řetězec zašifrovaný posunutím písmen o zadanou hodnotu
  • Ascii hodnota znaku se získá funkcí ord('A'), opačně znak z celého čísla získáte funkcí chr(65)
  • Je nutné posouvat velká písmena na velká písmena, malá písmena na malá písmena a mezeru ponechat jako mezeru

Úkol 7 Převod měsíců

  • Napište funkci convert_num_to_month, která dostane jako parametr pořadové číslo měsíce v roku a vrátí jeho jméno.
  • Napište funkci convert_month_to_num, která dostane jako parametr jméno měsíce v roku a vrátí jeho pořadové číslo v roce.
  • Předpoklad: leden má číslo 1, prosinec 12
  • Tuto funkci použijte v programu, který načte řetězec
    • Pokud je první znak písmeno, vytiskne se na obrazovku číslo měsíce
    • Pokud je první znak číslo vytiskne se název měsíce
  • Pomůcka: V programu můžete využít následující proměnnou:

month=['leden','unor','brezen','duben','kveten','cerven','cervenec','srpen','zari','rijen','listopad','prosinec']

Témata k procvičení

  • Napište funkci, která vypisuje 1,-1,1,-1 …
  • Napište funkci, která vypisuje výsledek operace $(-1)^k$ pro $k=0,\ldots,100$. Zamyslete se nad rychlostem výpočtu, navrhněte alternativní postupy
  • Napište funkci min(a,b), která vrací minimum z těchto dvou prvků (proměnné jsou čísla).
  • Napište funkci max(a,b)
  • Napište funkci area(radius), která vypočítá obsah kruhu o zadaném poloměru
  • Napište funkci d2r(angle), která převede stupně na radiány “degrees to radians = d2r”
  • Napište funkci r2d(angle), která převede radiány na stupně
  • Napište funkci normalize(angle), která převede zadaný úhel (v radiánech) do intervalu $<0, 2\pi)$
  • Napište funkci pro výpis pole:
    • s využitím cyklu for
    • s využitím cyklu while
  • Rozšiřte program na výpočet Sexy-prvočísel tak, aby vypisoval trojice prvočísel, které se od sebe liší o 6 - taková trojice je např. (5,11,17).
  • Dále rozšiřte tento program pro výpočet čtveřic (např. (61,67,73,79) ).

Domácí úkol

Lehká varianta

  • Čísla jsou soudělná, jestliže je jejich největší společný dělitel větší než 1
  • Vstup:
    • celé číslo $a$ a $b$ ze dvou řádek standardního vstupu, číslo $a$ na první řádce, číslo $b$ na druhé řádce
  • Výstup:
    • pokud je $a < 2$ nebo $b < 2$ nebo $a=b$, pak program vytiskne 'ERROR'
    • Jinak program vytiskne čtvercovou tabulku, jejíž řádky indexujeme $n$ a sloupce $m$, kde $ min(a,b) \leq m, n \leq max(a, b)$
    • Pokud jsou čísla $m,n$ soudělná, vypíše se na $n$-tém řádku a $m$-tém sloupci 'x' , pokud čísla nejsou soudělná a jedno z čísel $m$, nebo $n$ je prvočíslo, vytiskne 'p' jinak se vytiskne mezera ' '
    • Mezi sloupce tabulky vložte znak '|' , řádky oddělte znaky '-' , viz. příklady níže.
  • Program pro úlohu HW03 pojmenujte commensurable.py

Např. pro vstup

2
10
vypadá výsledek takto:
x|p|x|p|x|p|x|p|x
-----------------
p|x|p|p|x|p|p|x|p
-----------------
x|p|x|p|x|p|x| |x
-----------------
p|p|p|x|p|p|p|p|x
-----------------
x|x|x|p|x|p|x|x|x
-----------------
p|p|p|p|p|x|p|p|p
-----------------
x|p|x|p|x|p|x| |x
-----------------
p|x| |p|x|p| |x| 
-----------------
x|p|x|x|x|p|x| |x
pro vstup
11
10
vypadá výsledek takto:
x|p
---
p|x
pro vstup
2
1
vypadá výsledek takto:
ERROR

Těžká varianta

  • Vytvořte program translate.py pro úlohu HW03,
  • Vstup: řetězec ze standardního vstupu
    • Tento řetězec buď obsahuje desetinné číslo v desítkové soustavě nebo číslo zapsané slovy bez diakritiky
      • např. nulacelapettisicin
    • Všechna čísla jsou v rozsahu od 0 do 1000 (bez tisíce), desetinná část má nejvýše 6 cifer, tedy maximálně miliontiny.
    • Všechna čísla obsahují číslo pro celek a nenulové číslo pro desetinnou část.
  • Výstup: řetězec na standardní výstup
    • tento řetězec obsahuje vstup převedený do opačného zápisu, tj. text na číslo, a číslo na text.
    • Pokud vstup neodpovídá ani jedné z těchto možností, tedy zápisu desetinného čísla textem nebo ciframi, vytiskněte 'ERROR'
  • Příklady (všechny uvedené příklady můžete využít i tak, že výstup bude vstupem):
    • Příklad 1
      • Vstup: 1.00256
      • Výstup: jednaceladvestepadesatseststotisicin
    • Příklad 2:
      • Vstup: dvacetpetcelychsestsetin
      • Výstup: 25.06
    • Příklad 3:
      • Vstup: 123.00200
      • Výstup: stodvacettricelychdvestestotisicin
    • Příklad 4:
      • Vstup: ctyriceledvanacttisictristactyricetpetmiliontin
      • Výstup: 4.012345
    • Příklad 5:
      • Vstup: 2.01010
      • Výstup: dvaceletisicdesetstotisicin
  • Pro textovou reprezentaci čísel použijte pouze následující spojení:
    • nula, jedna, dva, tri, ctyri, pet, sest, sedm, osm, devet, deset, jedenact, dvanact, trinact, ctrnact, patnact, sestnact, sedmnact, osmnact, devatenact, dvacet, tricet, ctyricet, padesat, sedesat, sedmdesat, osmdesat, devadesat, sto, dveste, trista, ctyrista, petset, sestset, sedmset, osmset, devetset, tisic, tisice, desetin, setin, tisicin, desetitisicin, stotisicin, miliontin.
  • Pozn.:
    • V češtině je správně “dvatisice”, ale lze napsat “stodvatisic” a “stodvatisice”. Po Vás požadujeme řešení ve tvaru “ctyritisice”, “stodvatisic” (tedy tisice, pouze pokud bude jejich počet přesně 2,3, nebo 4).
    • Pokud se v čísle vyskytuje “jedentisíc…” pak jedničku neuvádějte, na výstupu bude jen “tisic…”
    • Obdobně pro skloňování celá, celé, celých. Pro 0 a 1 použijte “celá”, pro 2,3,4 “celé” a pro ostatní čísla “celých”
    • Název části (tedy desetin, setin, tisícin, desetitisícin, stotisícin, milióntin) neskloňujte, tedy chceme po Vás převést “1.1” jako “jednacelájednadesetin” a “2.2” jako “dvacelédvadesetin”.
    • Čísla jsou sice v rozsahu 0-999, ale v desetinné části se mohou vyskytovat i tisícemiliontin.
  • Hodnocení
    1. Program umí převádět validní vstupy v obou směrech [1.0b]
      • Vstup:
        999.999999
        Výstup:
        devetsetdevadesatdevetcelychdevetsetdevadesatdevettisicdevetsetdevadesatdevetmiliontin
      • Vstup:
        petsetcelychdvacetjednamiliontin
        Výstup:
        500.000021
    2. Program navíc umí detekovat chybné vstupy [1.0b]
      • Vstup:
        desetcelychstodesetin
        Výstup:
        ERROR
      • Vstup:
        desetdvacetcelychpetseststo
        Výstup:
        ERROR
courses/b3b33alp/cviceni/t03.txt · Last modified: 2021/10/05 12:45 by barucden