3. Jednoduché výpočty¶
Návratová hodnota – return
V předchozích kapitolách funkce přímo něco prováděly – pohybovaly želvou nebo něco vypisovaly. Mnohokrát však nepotřebujeme aby funkce přímo něco provedla, ale jen aby něco vypočítala a vypočtenou hodnotu (případně nějaké jiné informace) vrátila, abychom s ní mohli dále pracovat. K tomuto účelu je v Pythonu klíčové slovo return. Příkaz return vrátí hodnotu, která za ním následuje, a okamžitě ukončí výpočet funkce. Tato vrácená hodnota je následně dostupná v místě volání funkce a lze s ní dále pracovat. Naprostá většina funkcí vestavěných v Pythonu něco vrací, například funkce round vrací zaokrouhlené číslo, funkce abs vrací absolutní hodnotu zadaného čísla, atd…
Důležitá a často zapomenutá vlastnost return je okamžité ukončení provádění funkce – typicky v případech kdy už funkce odvedla svoji práci a něco vrátila, takže není potřeba nic dále počítat.
Využití zastavení výpočtu funkce pomocí return
Cyklus while
V minulé kapitole byl představen cyklus for, který se hodí, když dopředu víme kolikrát cyklus chceme provést, nebo pokud chceme něco provést pro každou položku v seznamu (více v kapitole Řetězce a seznamy). V některých případech však nevíme, kolikrát cyklus chceme provést na začátku cyklení, ale zjistíme to až v jeho průběhu. Pro tyto případy Python má cyklus while, který jen definuje podmínku a dokud tato podmínka platí, tak se tělo cyklu opakovaně provádí.
Výpis mocnin trojky, menší než 10 000
3.1. Pokročilé počítání¶
Součet čísel od 1 do n
Napište funkci series_sum(n)
, která vrátí součet čísel od 1
do n
.
3.1.1. Faktoriál pomocí for¶
Napište funkci factorial(n)
, která vrací faktoriál čísla n
a využívá cyklus for. Připomeňme, že n! = 1·2·3· ... ·n
a že 0! = 1
.
def factorial(n):
pass
def test_factorial():
assert factorial(0) == 1
assert factorial(1) == 1
assert factorial(10) == 3628800
assert factorial(50) == 30414093201713378043612608166064768844377641568960512000000000000
3.1.2. Faktoriál pomocí while¶
Napište funkci factorial(n)
, která vrací faktoriál čísla n
a využívá cyklus while.
def factorial(n):
pass
def test_factorial():
assert factorial(0) == 1
assert factorial(1) == 1
assert factorial(10) == 3628800
assert factorial(50) == 30414093201713378043612608166064768844377641568960512000000000000
3.1.3. Ciferný součet¶
Napište funkci digit_sum(n)
, která vrátí
ciferný součet čísla n
.
def digit_sum(n):
pass
def test_digit_sum():
assert digit_sum(0) == 0
assert digit_sum(274) == 13
assert digit_sum(123456789) == 45
3.1.4. Opakovaný ciferný součet¶
Napište funkci repeated_digit_sum(n)
, která vypočítá ciferný součet čísla n
.
Ze získaného ciferného součtu opět vypočítá ciferný součet a tento postup opakuje dokud nezbude jednociferné číslo,
které vrátí. Zkuste své řešení rozložit do dvou funkcí.
def repeated_digit_sum(n):
pass
def test_repeated_digit_sum():
assert repeated_digit_sum(123) == 6
assert repeated_digit_sum(123456789) == 9
assert repeated_digit_sum(99989788879879) == 7
3.2. Dělitelnost a prvočísla¶
Připomeňme pár informací. Celé číslo (int) a
je dělitelem b
pokud existuje celé číslo c
tak, že a · c = b
–
jednoduše řečeno: zbytek po dělení b / a
je 0
. Zbytek po dělení v Pythonu získáme pomocí operace b % a
.
Prvočísla jsou pak přirozená čísla n
, která mají právě dva dělitele (1
a n
) – tedy 1
není prvočíslo.
Snažte se využívat funkce, které jste již dříve implementovali. Ušetříte tak čas a kód bude více srozumitelný. Obecně také lze říci, že pokud máte někde v programu dvakrát ten stejný nebo velmi podobný kód, něco je špatně. Zkuste společný kód abstrahovat do zvláštní funkce a tu pak jen volat s různými parametry.
Následující funkce shoping_list
pouze vypíše nákupní seznam ve speciálním formátu.
Přestože výsledek je netriviální, samotná funkce zůstává jednoduchá díky volání funkce frame
,
která se stará o formátování.
3.2.1. Dělitelé¶
Napište funkci divisors(n)
, která vypíše všechny dělitele čísla n
.
def divisors(n):
pass
divisors(1) # 1
divisors(5) # 1 5
divisors(42) # 1 2 3 6 7 14 21 42
divisors(127) # 1 127
divisors(1024) # 1 2 4 8 16 32 64 128 256 512 1024
3.2.2. Počet dělitelů¶
Napište funkci divisors_count(n)
, která vrátí počet dělitelů čísla n
.
def divisors_count(n):
pass
def test_divisors_count():
assert divisors_count(1) == 1
assert divisors_count(5) == 2
assert divisors_count(42) == 8
assert divisors_count(127) == 2
assert divisors_count(1024) == 11
3.2.3. Je prvočíslo¶
Napište funkci is_prime(n)
, která vrátí True
pokud je číslo n
prvočíslo, jinak False
.
def is_prime(n):
pass
def test_is_prime():
assert is_prime(1) == False
assert is_prime(2) == True
assert is_prime(3) == True
assert is_prime(42) == False
assert is_prime(127) == True
3.2.4. Prvočísla menší než n¶
Napište funkci primes_less_than(limit)
, která vypíše všechna prvočísla menší než limit
.
def primes_less_than(limit):
pass
primes_less_than(5) # 2 3
primes_less_than(15) # 2 3 5 7 11 13
primes_less_than(100)
# 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
3.2.5. k-té prvočíslo¶
Napište funkci kth_prime(k)
, která vrátí k
-té prvočíslo.
def kth_prime(k):
pass
def test_kth_prime():
assert kth_prime(1) == 2
assert kth_prime(2) == 3
assert kth_prime(10) == 29
assert kth_prime(100) == 541
3.2.6. Prvních k prvočísel¶
Napište funkci primes(count)
, která vypíše prvních count
prvočísel.
def primes(count):
pass
primes(2) # 2 3
primes(5) # 2 3 5 7 11
primes(10) # 2 3 5 7 11 13 17 19 23 29
3.2.7. Prvních k prvočíselných dvojčat¶
Napište funkci twin_primes(count)
, která vypíše prvních count
prvočíselných dvojčat.
def twin_primes(count):
pass
twin_primes(2) # 3-5, 5-7,
twin_primes(5) # 3-5, 5-7, 11-13, 17-19, 29-31,
twin_primes(10)
# 3-5, 5-7, 11-13, 17-19, 29-31, 41-43, 59-61, 71-73, 101-103, 107-109,
3.2.8. Rozklad na prvočísla¶
Napište funkci factorization(n)
, která vypíše
rozklad čísla n
na prvočísla (jen jako součin).
def factorization(n):
pass
factorization(2) # 2
factorization(7) # 7
factorization(25) # 5 5
factorization(42) # 2 3 7
factorization(360) # 2 2 2 3 3 5
factorization(1024) # 2 2 2 2 2 2 2 2 2 2
3.2.9. Rozklad na prvočísla s mocninami¶
Napište funkci power_factorization(n)
, která vypíše
rozklad čísla n
na prvočísla v mocninném tvaru.
def power_factorization(n):
pass
power_factorization(2) # 2^1
power_factorization(7) # 7^1
power_factorization(25) # 5^2
power_factorization(42) # 2^1 3^1 7^1
power_factorization(360) # 2^3 3^2 5^1
power_factorization(1024) # 2^10
3.2.10. Největší společný dělitel - naivně¶
Napište funkci gcd(a, b)
, která vrátí
největší společný dělitel
čísel a
a b
. Funkce může pracovat naivně, tj. zkoušet všechny možnosti a podobně.
def gcd(a, b):
pass
def test_gcd():
assert gcd(5, 7) == 1
assert gcd(8, 8) == 8
assert gcd(10, 5) == 5
assert gcd(5, 10) == 5
assert gcd(42, 36) == 6
assert gcd(0, 7) == 7
3.2.11. Nejmenší společný násobek¶
Napište funkci lcm(a, b)
, která vrátí
nejmenší společný násobek
čísel a
a b
.
def lcm(a, b):
pass
def test_lcm():
assert lcm(6, 9) == 18
assert lcm(6, 7) == 42
assert lcm(3, 9) == 9
assert lcm(9, 3) == 9
assert lcm(360, 42) == 2520
3.2.12. Euklidův algoritmus¶
Implementujte Euklidův algoritmus.
def euclid(a, b):
pass
def test_euclid():
assert euclid(5, 7) == 1
assert euclid(8, 8) == 8
assert euclid(10, 5) == 5
assert euclid(5, 10) == 5
assert euclid(42, 36) == 6
3.3. Aproximace¶
3.3.1. Eulerovo číslo¶
Napište funkci e()
pro přibližný výpočet
Eulerova čísla
pomocí nekonečného součtu s přesností na miliontiny.
def e():
pass
print(e()) # 2.718282
3.3.2. Pi¶
Napište funkci pi()
pro přibližný výpočet
čísla pi
pomocí Leibnizovy řady s přesností na tisíciny.
def pi():
pass
print(pi()) # 3.141
3.3.3. Aproximace sinu¶
Napište funkci sinus(x)
pro výpočet sinu úhlu x
(v radiánech) pomocí
Taylorovy řady
(sekce Příklady Taylorova rozvoje: sin x) s přesností na tisíciny.
from math import pi
def sinus(x):
pass
print(sinus(1.2)) # 0.932
print(sinus(0)) # 0.0
print(sinus(pi/4)) # 0.707
print(sinus(pi/2)) # 1.0
3.3.4. Aproximace cosinu¶
Napište funkci cosinus(x)
pro výpočet cosinu úhlu x
(v radiánech) pomocí
Taylorovy řady
(sekce Příklady Taylorova rozvoje: cosin x) s přesností na tisíciny.
from math import pi
def cosinus(x):
pass
print(cosinus(1.2)) # 0.362
print(cosinus(0)) # 1.0
print(cosinus(pi/4)) # 0.707
print(cosinus(pi/2)) # 0.0
3.4. Převody mezi číselnými soustavami¶
Motivační vtip:
Q: Why do programmers always mix up Halloween and Christmas?
A: Because Oct 31 == Dec 25!
3.4.1. Převod z desítkové soustavy do dvojkové¶
Napište funkci convert_10_to_2(n)
, která vrátí zadané číslo n
ve dvojkové soustavě jako řetězec.
def convert_10_to_2(x):
pass
def test_convert_10_to_2():
assert convert_10_to_2(2) == "10"
assert convert_10_to_2(8) == "1000"
assert convert_10_to_2(10) == "1010"
assert convert_10_to_2(31) == "11111"
assert convert_10_to_2(42) == "101010"
3.4.2. Převod z dvojkové soustavy do desítkové¶
Napište funkci convert_2_to_10(n)
, která vrátí zadaný řetězec n
reprezentující binární číslo v desítkové soustavě jako int.
def convert_2_to_10(n):
for b in n[::-1]:
b # jednotlive bity od zadu
def test_convert_2_to_10():
assert convert_2_to_10("10") == 2
assert convert_2_to_10("1000") == 8
assert convert_2_to_10("1010") == 10
assert convert_2_to_10("11111") == 31
assert convert_2_to_10("101010") == 42
3.4.3. Převod z desítkové soustavy do jiné¶
Napište funkci convert_10_to_x(n, symbols)
, která vrátí zadané číslo n
v jiné soustavě
– soustava, do které převádíme, bude zadána řetězcem znaků symbols
, které používá.
def convert_10_to_x(n, symbols):
pass
def test_convert_10_to_x():
assert convert_10_to_x(42, "01") == "101010"
assert convert_10_to_x(42, "0123") == "222"
assert convert_10_to_x(42, "0123456789") == "42"
assert convert_10_to_x(42, "0123456789ABCDEF") == "2A"