V případě, že máme dvě instance třídy datetime, můžeme provádět jejich rozdíl. Výsledkem je instance datetime.timedelta.
1
2
3
4
fromdatetimeimportdatetime# čas do Nového roku
datetime(year=2022,month=1,day=1)-datetime.now()
Případně můžeme vytvořit datetime.timedelta ručně a provádět aritmetické operace.
1
2
3
4
5
6
7
8
9
fromdatetimeimportdatetime,timedelta# vrátí datetime posunutý o jeden den dopředu
datetime.now()+timedelta(days=1)# vrátí datetime posunutý o jeden den dozadu
datetime.now()-timedelta(days=1)# ekvivalentní
datetime.now()+timedelta(days=-1)
Měření doby běhu
V praxi často chceme změřit dobu běhu našeho programu/funkce. V modulu time nalezneme perf_counter což je nejpřesnější způsob měření času. Více informací naleznete zde.
Na začátku je nutné upozornit na fakt, že většina náhodně generovaných dat nejsou náhodná ve vědeckém slova smyslu, jedná se o pseudonáhodná data.
Náhodná čísla je možné generovat pomoci true random number generator (TRNG), tím je například opakovaný hod hrací kostkou. Za předpokladu že nemáme “cinklou” kostku nedokážeme odhadnout jaké číslo na hrací kostce padne.
Pseudonáhodná čísla je narozdíl od náhodných čísel možné generovat za pomoci softwaru. Proces generování začne náhodným číslem (seed) a následně použitím algoritmu, který na základě seedu vygeneruje pseudonáhodné číslo.
Dále je nutné upozornit, že pseudonáhodné generátory z modulu random není vhodné používat pro bezpečnostní aplikace.
1
2
3
4
5
6
7
importrandom# náhodné číslo z rozsahu [0.0, 1.0]
random.random()# 0.6974581966212106
random.random()# 0.3773080227020298
Generovaná čísla vypadají náhodně, problém však nastane v následující demonstraci.
1
2
3
4
5
6
7
8
9
10
importrandomrandom.seed(123)# náhodné číslo z rozsahu [0.0, 1.0]
random.random()# 0.052363598850944326
random.seed(123)random.random()# 0.052363598850944326
Nastavením stejného seedu jsme schopni zopakovat stejné “náhodné” číslo! Celý popis problematiky a mnoho dalšího naleznete zde.
Dále se podívejme jak generovat náhodný int z rozsahu.
1
2
3
4
5
6
importrandom# náhodný integer z intervalu [0, 10]
random.randint(0,10)# náhodný integer z intervalu [0, 10)
random.randrange(0,10)
Rovněž je možné generovat náhodné float z rozsahu.
1
2
3
4
importrandom# náhodný float z intervalu [0, 10]
random.uniform(0,10)
Použití random u sekvencí
Výběr náhodného prvku.
1
2
3
4
5
6
7
8
9
10
11
12
importrandomvalues=[2,5,1,6,7]# náhodná hodnota ze seznamu values
random.choice(values)# náhodné 3 hodnoty (s opakováním) ze seznamu values
random.choice(values,k=3)# náhodný podseznam délky 3 (bez opakování) ze seznamu values
random.sample(items,3)
Náhodné zamíchání sekvence.
1
2
3
4
5
6
7
8
importrandomvalues=[2,5,1,6,7]# náhodné zamíchání, pozor je inplace
random.shuffle(values)values
Pokročilejší matematika - modul math
Modul math obsahuje množství užitečných high-level funkcí pro matematické operace. Obsáhlejší článek je možné najít zde.
Konstanty
Modul math obsahuje několik matematicky významných konstant.
1
2
3
4
5
6
7
8
9
10
11
12
importmath# Pi
math.pi# Tau - 2*pi
math.tau# Eulerovo číslo
math.e# Nekonečno
math.inf# Not a Number
math.nan
importmath# faktoriál 7!
math.factorial(7)# nejbližší celé číslo, které je větší nebo rovno zadanému číslu
math.ceil(4.2)# 5
math.ceil(-4.2)# -4
# nejbližší celé číslo, které je menší nebo rovno zadanému číslu
math.floor(4.2)# 4
math.floor(-4.2)# -5
# odebrání desetíné části čísla
math.trunc(4.2)# 4
math.trunc(-4.2)# -4
assertmath.trunc(12.32)==math.floor(12.32)assertmath.trunc(-43.24)==math.ceil(-43.24)
Dále můžeme zjistit zda jsou dvě čísla blízko (se zadanou přesností).
importmath# na první pohled zbytečné ale..
math.pow(2,3)==2**3importtimeittimeit.timeit("math.pow(10, 300)",setup="import math")# 0.1181572710047476
timeit.timeit("10 ** 300")# 0.8508502449840307
Druhá odmocnina
1
2
3
importmathmath.sqrt(9)
Výpočet logaritmu
1
2
3
4
5
6
7
8
9
10
11
importmath# přirozený, tedy ln
math.log(4)# o základu 2
math.log(3,2)# existují zkrácené verze
math.log2(3)math.log10(3)
Největší společný dělitel
1
2
3
importmathmath.gcd(15,25)
Suma čísel v iterable (přesněji)
Doteď jsme používali sum() pro součet čísel v iterable, existuje však přesnější verze.