Základy_Python

Základy Pythonu

Čísla

Celá čísla

  • vytvoříme proměnnou a, do které zapíšeme hodnotu 5
  • python automaticky přiřadí typ int
  • typ si můžeme věřit pomocí funkce type()
In [1]:
a = 5
print('a =', a)
print('type(a) =', type(a))
a = 5
type(a) = 

Desetinné číslo (floating point numbers)

$$ x \in \mathcal{R} $$ \begin{equation} x \in \mathcal{R} \end{equation}

In [2]:
# vytvořte proměnnou, uložte do ní desetinné číslo a ověřte typ
a = 5.87687
print('a =', a)
print('type(a) =', type(a))
a = 5.87687
type(a) = 
In [3]:
# zde je vidět, že všechna čísla nelze pomocí tohoto formátu uložit absolutně přesně
b = 1.4 + 1.2
print(b)
2.5999999999999996
In [4]:
# informace o formátu float
import sys
sys.float_info
Out[4]:
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

Decimal fixed point

In [5]:
from decimal import Decimal
a = Decimal(1.4)
b = Decimal(1.2)
a + b
Out[5]:
Decimal('2.599999999999999866773237045')
In [6]:
a = Decimal('1.4')
b = Decimal('1.2')
a + b
Out[6]:
Decimal('2.6')

Fraction - zlomky

In [7]:
from fractions import Fraction
a = Fraction(1, 5)
b = Fraction(4, 8)
a + b
Out[7]:
Fraction(7, 10)

Komplexní čísla

In [8]:
c = 2 + 4j
print('c =', c)
print('type(c) =', type(c))
c.real
c = (2+4j)
type(c) = 
Out[8]:
2.0
In [9]:
c.imag
Out[9]:
4.0
In [10]:
print('real part =', c.real, 'a imag part =', c.imag)
real part = 2.0 a imag part = 4.0
In [11]:
# komplexně sdružené číslo - konjugace
c.conjugate()
Out[11]:
(2-4j)

Aritmetické operace

  • můžeme používat všechny běžné aritmetické operace
    • +-*/
    • % modulo - zbytek po dělení
    • // celočíselné dělení
    • ** mocnina
In [12]:
2e2 + 5 * 6 - (13 / 3)**2 + 11%4
Out[12]:
214.22222222222223
In [13]:
print("5/3 =", 5 // 3, "a zbytek", 5 % 3)
5/3 = 1 a zbytek 2
In [14]:
# absolutní hodnota
abs(-5)
Out[14]:
5
In [15]:
# zaokrouhlování
# celé číslo,   na stovky,         na setiny
round(3.4895), round(245.876, -2), round(245.876, 2)
Out[15]:
(3, 200.0, 245.88)
In [16]:
#### Pozor na přejmenovávání pythonovských proměnných a funkcí!!
In [17]:
# předefinujeme funkci abs a vložíme do ní celé číslo 5
abs = 5
# nyní se pokusím zavolat funkci abs, ale dostaneme chybu, protože abs už není funkce, ale celé číslo, které nelze volat jako dunkci
abs(-4)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/2136882445.py in ()
      2 abs = 5
      3 # nyní se pokusím zavolat funkci abs, ale dostaneme chybu, protože abs už není funkce, ale celé číslo, které nelze volat jako dunkci
----> 4 abs(-4)

TypeError: 'int' object is not callable

Konverze typů

In [18]:
# konverze desetinného čísla na celé
print(int(1.765))
# konverze řetězce obsahujícího číslo, abychom k němu mohli přičíst číslo 2
print(int('12') + 2)
1
14
In [19]:
# konverze celého čísla na desetinné
print(float(6))
# konverze řetězce
print(float('3.1322'))
6.0
3.1322
In [20]:
# octal, binary, hex
0o23, 0b1111, 0xFF
Out[20]:
(19, 15, 255)
In [21]:
# nelze sčítat řetězec a číslo
'12' + 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/2734961184.py in ()
      1 # nelze sčítat řetězec a číslo
----> 2 '12' + 2

TypeError: can only concatenate str (not "int") to str
In [22]:
# ani naopak to nejde - číslo a řetězec
2 + '12'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/2286538187.py in ()
      1 # ani naopak to nejde - číslo a řetězec
----> 2 2 + '12'

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Inplace operace

In [23]:
a = 5
a += 4
a **= 2
a
Out[23]:
81

Logické datové typy (Boolean)

  • může nabývat dvou hodnot True a False
  • typ je bool
In [24]:
q = True
print('q =', q)
print('type(q) =', type(q))
q = True
type(q) = 
In [25]:
q = (5 == 100)
q
Out[25]:
False
  • logické podmínky můžeme řetězit pomocí logických operátorů and (&), or(|), xor
  • negace not
In [26]:
x = 1
(x > 0) and (x < 3), (x > 0) & (x < 3)
Out[26]:
(True, True)
In [27]:
(x > 0) or (x < 3), (x > 0) | (x < 3)
Out[27]:
(True, True)
In [28]:
a = 5
4 < a <6
Out[28]:
True
In [29]:
not (x < 20)
Out[29]:
False

Řetězce (Strings)

In [30]:
# dvojité uvozovky
s = "hello world"
print('s =', s)
print('type(s) =', type(s))
s = hello world
type(s) = 
In [31]:
# jednoduché uvozovky
s = 'hello world'
print('s =', s)
print('type(s) =', type(s))
s = hello world
type(s) = 
In [32]:
# tisk řetězce s uvozovkami - s výhodou využijeme oba typy uvozovek
text = 'text "text v uvozovkách"'
print(text)
text "text v uvozovkách"
In [33]:
# jinak bysme museli před vnitřní uvozovky \, což z nich udělá obyčejné uvozovky
text = "text \"text v uvozovkách\""
print(text)
text "text v uvozovkách"
In [34]:
# \ v řetězci, který vytvoří speciální znak
text = 'v latexu se řecké písmeno beta sází jako \beta'
print(text)
# buď přidáme lomítko
text = 'v latexu se řecké písmeno beta sází jako \\beta'
print(text)
# nebo z řetězce uděláme raw string (přidáním **r** před začátek řetězce), který se vysází tak jak je napsán - bez provedení zpeciálních znaků
text = r'v latexu se řecké písmeno beta sází jako \beta'
print(text)
v latexu se řecké písmeno beta sází jakoeta
v latexu se řecké písmeno beta sází jako \beta
v latexu se řecké písmeno beta sází jako \beta
  • řetězec nelze měnit změnou znaku na nějaké pozici - dostaneme chybu
In [35]:
s[2] = 'O'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/3510758706.py in ()
----> 1 s[2] = 'O'

TypeError: 'str' object does not support item assignment
  • můžeme to provést např. následovně
In [36]:
s = s[:2] + 'O' + s[2:]
print(s)
heOllo world

Operace s řetězci

  • spojování řetězců pomocí +
  • opakování řetězce *n
In [37]:
'hello' + ' ' + 'world'
Out[37]:
'hello world'
In [38]:
print('ok ok' * 5)
print('_' * 40)
ok okok okok okok okok ok
________________________________________
  • určení délky řetězce pomocí funkce len
In [39]:
w = 'hello world'
print('délka řetězce =', len(w))
délka řetězce = 11

Dělení a spojování řetězců

In [40]:
s = 'slova  oddělená \t mezerou'
s.split() # bez parametru rozdělí řetězec podle všech bílých znaků " \t\n" a vrátí list slov
Out[40]:
['slova', 'oddělená', 'mezerou']
In [41]:
s = 'slova-oddělená-pomlčkou'
word_list = s.split('-') # rozdělí řetězec v místě pomlček
word_list
Out[41]:
['slova', 'oddělená', 'pomlčkou']
In [42]:
# spojit seznam slov s oddělovačem "; "
'; '.join(word_list)
Out[42]:
'slova; oddělená; pomlčkou'

Další funkce

In [43]:
# seznam možných funkcí a parametrů, které lze získat z řetězce
print([i for i in dir(s) if not i.startswith('_')])
['capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
In [44]:
# nahraď znaků za jiný/é
s = 'slova-oddělená-pomlčkou'
s.replace('-', '--')
Out[44]:
'slova--oddělená--pomlčkou'
In [45]:
# všechny znaky převeď na velká písmena
s.upper()
Out[45]:
'SLOVA-ODDĚLENÁ-POMLČKOU'
In [46]:
# ořízni bíle znaky z obou stran řetězce
s = '    \t   slovo xxx    \n'
s.strip()
Out[46]:
'slovo xxx'
In [47]:
# víceřádkový řetězec včetně konců řádků (''' také fungují, ale doporučené jsou dvojité)
a = """více
řádků"""
print(a)
repr(a) # řetězec, který reprezentuje objekt
více
řádků
Out[47]:
"'více\\nřádků'"
In [48]:
# zalomení v kódu
a = ('více '
     'řádků')
a
Out[48]:
'více řádků'
In [49]:
a = 'více ' \
    'řádků'
a
Out[49]:
'více řádků'
In [50]:
import time
for i in range(5):
    print(i + 1, end='\r', flush=True)
    time.sleep(.5)
5
In [51]:
# objekty mají definovanou metory __str__(), která vrátí řetězec pro tisk
# při použití print se toto provede automaticky a není nutné volat "str()"
print(str(3.2))
print(3.2)
3.2
3.2
In [52]:
# konverze řetězce na číslo int/float
int('3'), float('3.33')
Out[52]:
(3, 3.33)
In [53]:
int('FF', 16) # převeď čísla z šesnáctkové soustavy do desítkové
Out[53]:
255
In [54]:
int('1111', 2) # převeď čísla z binární soustavy do desítkové
Out[54]:
15
In [55]:
s = 'hello world'
# první znak, pátý znak, poslení znak
s[0], s[4], s[-1]
Out[55]:
('h', 'o', 'd')
  • slicing [od (včetně) : do (bez) : krok]
In [56]:
# druhý až čtvrtý znak
s[1:4]
Out[56]:
'ell'
In [57]:
# 1. - 5. znak
s[0:5], s[:5] # 0 můžeme vynechat
Out[57]:
('hello', 'hello')
In [58]:
# od začátku po 5. znak vypiš každý druhý
s[:5:2]
Out[58]:
'hlo'
In [59]:
# na pozici složených uvozovek se postupně doplní objekty ze seznamu
print('{} {} {}'.format('a', 'b', 'c'))
a b c
In [60]:
# do závorek lze umístit index objektu ze seznamu, který lze umístit i vícekrát
print('{2} {1} {0} {1}'.format('a', 'b', 'c'))
c b a b
In [61]:
# seznam může obsahovat jakékoliv objekty
# můžou být zadány i pomocí klíčových proměnných - pomocí názvu klíče se lze v {} na tento objekt odkazovat
print('{color} {0} {x} {1}'.format(10, 'cosi', x=1.5, color='zelená'))
zelená 10 1.5 cosi
In [62]:
# uvnitř {} lze za : umístit informace o formátování objektu
# {0:10} - vysázej objekt na pozici 0 na šířku 10 znaků (chybějící znaky jsou doplněny mezerami)
# {1:^10d} - ^ zarovnej na střed, "d" celé číslo, do oblasti široké 10 znaků
# {c:10.3f} - do oblasti široké 10 znaků umísti desetinné číslo "f" zaokrouhlené za desetinnou čárkou na 3 místa ".3"
print('{0:10} {1:^10d} {c:10.3f}'.format('text', 50, c=3.7659876))
text           50          3.766
In [63]:
# jak by to dopadlo bez 10
print('{0} {1:d} {c:.3f}'.format('text', 50, c=3.7659876))
text 50 3.766
In [64]:
x = 5.876e-6
s = 'hello'
f'{s} {x:.6g}' # g - general format
Out[64]:
'hello 5.876e-06'
  • alternativní způsob formátování pomocí %
In [65]:
'%s %.3f a %03d' % ('text', 4.8475, 6)
Out[65]:
'text 4.848 a 006'

Seznamy (Lists)

  • seznam se vytváří zadáním hodnot do hranatých závorek
  • typ je list
In [66]:
a = [1, 2, 3, 4]
a, type(a)
Out[66]:
([1, 2, 3, 4], list)
In [67]:
# pomocí operátoru sčítání lze listy spojovat
[1, 2] + [3, 4]
Out[67]:
[1, 2, 3, 4]
In [68]:
# pomocí operátoru * lze hodnoty opakovat
[1, 2] * 3
Out[68]:
[1, 2, 1, 2, 1, 2]
  • funkce range(od (včetně), do (bez), krok) vrací generátor sekvence celých čísel
In [69]:
range(5)
Out[69]:
range(0, 5)
In [70]:
# pomocí funkce **list()** získáme seznam hodnot
# seznam hodnot od 0 do 4 po 1
list(range(5))
Out[70]:
[0, 1, 2, 3, 4]
In [71]:
# seznam hodnot od 2 do 10 po 2
list(range(2, 11, 2))
Out[71]:
[2, 4, 6, 8, 10]
  • indexování a slicing funguje stejně jako u řetězců
In [72]:
a = [1, 2, 3, 4]
# nahraď 2. až 3. hodnotu
a[1:3] = [20, 30]
a
Out[72]:
[1, 20, 30, 4]
In [73]:
# hodnoty na pozici 2. až 3. nahraď čtyřmi novými
a[1:3] = [20, 30, 40 ,50]
a
Out[73]:
[1, 20, 30, 40, 50, 4]
In [74]:
# odstraň 2. až 3. hodnotu
a[1:3] = []
a
Out[74]:
[1, 40, 50, 4]
  • další funkce jsou také obdobné
In [75]:
# vrať počet hodnot v seznamu
len(a)
Out[75]:
4
In [76]:
# odstraň hodnotu na indexu 2
del a[2]
a
Out[76]:
[1, 40, 4]
In [77]:
# zjisti jestli seznam obsahuje hodnotu 40
40 in a
Out[77]:
True
In [78]:
# ověř, že hodnota 20 není v seznamu
20 not in a
Out[78]:
True
In [79]:
# seznam může obsahovat různé typy objektů
a = ['text', 30, [1,2,3]]
a[0], a[2][1]
Out[79]:
('text', 2)
In [80]:
[i for i in dir(a) if not i.startswith('_')]
Out[80]:
['append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']
In [81]:
a = []
a.append(4) # přidej do seznamu číslo 4
a
Out[81]:
[4]
In [82]:
a.append(40) # přidej do seznamu číslo 40
a
Out[82]:
[4, 40]
In [83]:
# rozšiř seznam o více hodnot najednou
a.extend([3,4,5])
a
Out[83]:
[4, 40, 3, 4, 5]
In [84]:
a.append([400, 500]) # append vloží do seznamu čísla v listu
a
Out[84]:
[4, 40, 3, 4, 5, [400, 500]]
In [85]:
# počet hodnot 4
a.count(4)
Out[85]:
2
In [86]:
# vrátí první index, na kterém se nachází číslo 4
a.index(4)
Out[86]:
0
In [87]:
# na index 3 vlož hodnotu 50
a.insert(3, 50)
a
Out[87]:
[4, 40, 3, 50, 4, 5, [400, 500]]
In [88]:
# odstraň číslo z listu, pokud není v seznamu vrátí error
a.remove(44)
a
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_636311/1730150053.py in ()
      1 # odstraň číslo z listu, pokud není v seznamu vrátí error
----> 2 a.remove(44)
      3 a

ValueError: list.remove(x): x not in list
In [89]:
# vyjmy poslední hodnotu z listu
val = a.pop()
print(val)
[400, 500]
In [90]:
# vyjmy číslo na indexu 2
val = a.pop(2)
print(val)
a
3
Out[90]:
[4, 40, 50, 4, 5]
In [91]:
# setřiď seznam
a = [3,5,1,2,1]
b = sorted(a) # funkce sorted() vrátí setřízený seznam a uložíme ho do proměnné "b"
a, b
Out[91]:
([3, 5, 1, 2, 1], [1, 1, 2, 3, 5])
In [92]:
print(a)
a.sort() # na seznamu můžeme zavolat metodu sort(), která setřídí seznam uvnitř proměnné "a" (o nesetříděný seznam přijdeme)
print(a)
[3, 5, 1, 2, 1]
[1, 1, 2, 3, 5]
In [93]:
# seznam v proměnné "a" zapíše v opačném pořadí
a.reverse()
a
Out[93]:
[5, 3, 2, 1, 1]
In [94]:
# pokud si chceme otočený seznam uložit do proměnné, můžeme využít slicing
print(a)
b = a[::-1]
print(a)
print(b)
[5, 3, 2, 1, 1]
[5, 3, 2, 1, 1]
[1, 1, 2, 3, 5]
In [95]:
# mutable and immutable
# pokud lze objekt měnit "mutable" např. list
a = [1,2,3,4]
b = a
b[0] = 100
a, b, id(a), id(b) # což můžeme vidět když si vypíšeme adresu objektu (hodnoty jsou stejné)
Out[95]:
([100, 2, 3, 4], [100, 2, 3, 4], 140350073113408, 140350073113408)
In [96]:
# pokud tomu chceme zabránit musíme provést kopii objektu
a = [1,2,3,4]
b = a[:] # provede kopii listu
# b = a.copy() # nebo pomocí metody copy
b[0] = 100
a, b, id(a), id(b) # nyní jsou adresy různé
Out[96]:
([1, 2, 3, 4], [100, 2, 3, 4], 140350130202304, 140350072945600)
In [97]:
# příklad "immutable"
a = 'text'
b = a
b[0] = 'T'
a, b
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/2380997346.py in ()
      2 a = 'text'
      3 b = a
----> 4 b[0] = 'T'
      5 a, b

TypeError: 'str' object does not support item assignment

N-tice (tuples)

In [98]:
# n-tici vytvoříme vložením seznamu objektů do kulatých závorek
a = (1, 2, 3, 4)
a, type(a)
Out[98]:
((1, 2, 3, 4), tuple)
In [99]:
# funguje to i bez závorek
a = 1, 2, 3, 4
a, type(a)
Out[99]:
((1, 2, 3, 4), tuple)
In [100]:
# pro vytvožení n-tice s jednou hodnotou je nutné vložit za číslo čárku
a = (10, )
b = (10)
a, type(a), b, type(b)
Out[100]:
((10,), tuple, 10, int)
In [101]:
# přetypovat list na tuple lze pomocí funkce "tuple()"
a = [1, 2, 3]
a = tuple(a)
a, type(a)
Out[101]:
((1, 2, 3), tuple)
In [102]:
# jedná se o immutable objekt a hodnoty nelze měnit - je nutné vytvořit nový objekt
a[0] = 5
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/660467208.py in ()
      1 # jedná se o immutable objekt a hodnoty nelze měnit - je nutné vytvořit nový objekt
----> 2 a[0] = 5

TypeError: 'tuple' object does not support item assignment
In [103]:
# pojmenované ntice
from collections import namedtuple
Person = namedtuple('Person', ['first', 'last', 'age'])
person = Person('Václav', 'Sadílek', 6)
print(person)
print('věk =', person[-1])
print('věk =', person.age)
# přidejte výšku
Person(first='Václav', last='Sadílek', age=6)
věk = 6
věk = 6

Slovníky (Dictionaries)

In [104]:
# vytvoření {key: value}
# key musí být neměnitelný objekt (immutable)
# value může být cokoliv
d = {'škoda': 10, 55: 100}
d['seat'] = 2
d, type(d)
Out[104]:
({'škoda': 10, 55: 100, 'seat': 2}, dict)
In [105]:
# slovník lze vytvořit pomocí funkce "dict" a klíčových parametrů
# klíče jsou omezeny názvy, které lze použít pro názvy proměnných v klíčových parametrech
d = dict(a=5, text='pokus')
d
Out[105]:
{'a': 5, 'text': 'pokus'}
In [106]:
# také můžeme funkci dát seznam obsahující dvojice "key, hodnota"
d = dict([('rohlíky', 10), ('mléko', [1,2])])
d
Out[106]:
{'rohlíky': 10, 'mléko': [1, 2]}
In [107]:
dist = {}
dist[('Praha', 'Ostrava')] = 20
dist[('Praha', 'Brno')] = 30
dist[('Ostrava', 'Brno')] = 50
dist
Out[107]:
{('Praha', 'Ostrava'): 20, ('Praha', 'Brno'): 30, ('Ostrava', 'Brno'): 50}
In [108]:
dist[('Praha', 'Brno')]
Out[108]:
30
In [109]:
dist[('Brno', 'Praha')]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/tmp/ipykernel_636311/5023062.py in ()
----> 1 dist[('Brno', 'Praha')]

KeyError: ('Brno', 'Praha')
In [110]:
res = dist.get(('Brno', 'Praha'))
print(res, res is None)
None True
In [111]:
print(dist.get(('Brno', 'Praha'), 'unknown'))
unknown
In [112]:
#del pop update keys, values, items
In [113]:
dist.keys() # klíče
Out[113]:
dict_keys([('Praha', 'Ostrava'), ('Praha', 'Brno'), ('Ostrava', 'Brno')])
In [114]:
dist.values() # hodnoty
Out[114]:
dict_values([20, 30, 50])
In [115]:
dist.items() # položky jako seznam dvojit "key, value"
Out[115]:
dict_items([(('Praha', 'Ostrava'), 20), (('Praha', 'Brno'), 30), (('Ostrava', 'Brno'), 50)])

Množiny (sets)

In [116]:
# množinu lze vytvořit pomocí složených závorek a seznamu hodnot
s = {1, 2, 5}
s, type(s)
Out[116]:
({1, 2, 5}, set)
In [117]:
# pomocí funkce "set()" lze vytvořit množinu z tuplu nebo listu
s = set((1,2))
s, type(s)
Out[117]:
({1, 2}, set)
In [118]:
# do setu se ukládají pouze unikátní hodnotu
s = set([1,2,3,1,4,2,1])
s
Out[118]:
{1, 2, 3, 4}
In [119]:
# může obsahovat různé datové typy
s = {1, 2, 30., 'd', 2, 'd'}
s, type(s)
Out[119]:
({1, 2, 30.0, 'd'}, set)
In [120]:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
In [121]:
# sjednocení
c = a.union(b)
c
Out[121]:
{1, 2, 3, 4, 5, 6}
In [122]:
c = a | b
c
Out[122]:
{1, 2, 3, 4, 5, 6}
In [123]:
# průnik
c = a.intersection(b)
c
Out[123]:
{3, 4}
In [124]:
a & c
Out[124]:
{3, 4}
In [125]:
# rozdíl
c = a.difference(b)
c
Out[125]:
{1, 2}
In [126]:
a - b
Out[126]:
{1, 2}
In [127]:
c = a.symmetric_difference(b)
c
Out[127]:
{1, 2, 5, 6}
In [128]:
a ^ b # xor
Out[128]:
{1, 2, 5, 6}
In [129]:
# zjištění jestli je podmnožinou
b.issubset(a), b <= a
Out[129]:
(False, False)
In [130]:
a.issuperset(b), a >= b
Out[130]:
(False, False)
In [131]:
# přidávání prvků do množiny
t = {1, 2, 3}
t.add(5)
t
Out[131]:
{1, 2, 3, 5}
In [132]:
# rozšíření množiny o více prvků
t.update([2, 6, 3])
t
Out[132]:
{1, 2, 3, 5, 6}
In [133]:
# remove, pop, discard

Frozenset

In [134]:
# set() nelze použít jako key ve slovníku, protože je mutable
# můžeme použit frozenset
dist = {}
dist[frozenset(('Praha', 'Ostrava'))] = 20
dist[frozenset(('Praha', 'Brno'))] = 30
dist[frozenset(('Ostrava', 'Brno'))] = 50
dist
Out[134]:
{frozenset({'Ostrava', 'Praha'}): 20,
 frozenset({'Brno', 'Praha'}): 30,
 frozenset({'Brno', 'Ostrava'}): 50}
In [135]:
# v frozenset nezáleží na pořadí
dist[frozenset(('Praha', 'Brno'))], dist[frozenset(('Brno', 'Praha'))]
Out[135]:
(30, 30)

Podmínky

  • řízení běhu programu pomocí podmínek
if podmínka/y:
    # odsazení 4 mezery
    co se  provést
elif podmínka/y:
    co se  provést
else:
    pokud není splněna žádná podmínka proveď tento blok
In [136]:
x = -10
if x > 0:
    print('x > 0')
elif x == 0:
    print('x == 0')
else:
    print('x < 0')
x < 0
In [137]:
# prázdné objekty list, set, tuple vrací False
x = []
if x:
    print('jsem plný')
else:
    print('jsem prázdný')
jsem prázdný

list vs set

In [138]:
val_list = list(range(1000)) 
val_set = set(val_list)
In [139]:
%timeit 1 in val_list
46.2 ns ± 4.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [140]:
%timeit 1 in val_set
39.9 ns ± 5.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [141]:
# zkuste zjistit zda se tam nachází 100 (je) a 1000 (není)

Cykly (While, for)

  • cyklus while
while podmínka/y:
    # odsazení 4 mezery
    blok pro vykonání v rámci cyklu
    
zrušením odsazení končí blok cyklu while a pokračuje se předchozí úrovní
  • cyklus for
for (proměnná, seznam proměnných) in (list, tuple, iterátor, seznam, ...):
    blok příkazu uvnitř cyklu
In [142]:
lst = list(range(3))
print(lst)
while lst: # dokud není list prázdný, while len(lst) != 0
    print(lst)
    lst = lst[1:] # v každém cyklu odstraň z listu 1. hodnotu
[0, 1, 2]
[0, 1, 2]
[1, 2]
[2]
In [143]:
lst = list(range(3))
while lst:
    val = lst.pop() # vyjmi poslední hodnotu
    print(val) # konec bloku zyklu while
    
print('konec') # zrušeno odsazení - provede se až po dokončení cyklu
2
1
0
konec
In [144]:
i = 0
while True: # nekonečný cyklus
    if i < 3:
        print(i, end=' ')
    else:
        break # přerušení cyklu po splnění podmínky
    i += 1
0 1 2 
In [145]:
# stejný cyklu, pouze podmínka se přesunula k "while"
i = 0
while i<3:
    print(i, end=' ')
    i += 1
0 1 2 
In [146]:
# vytiskni každou položku v iterátoru range(3)
for item in range(3):
    print(item, end=' ')
0 1 2 
In [147]:
# vytiskni každý znak v řetězci a za každý vlož mezeru
for item in 'abcdef':
    print(item, end=' ')
print('\nkonec')
a b c d e f 
konec
In [148]:
# spojení seznamu slov v jeden řetězec pomocí cyklu
animals = ['pes', 'kočka', 'slepice']
accum = ''
for animal in animals:
    accum += animal + ' '
accum
Out[148]:
'pes kočka slepice '
In [149]:
while animals:
    animal = animals.pop()
    print('animal =', animal)
animal = slepice
animal = kočka
animal = pes
In [150]:
a = 'abc'
for i in range(len(a)): # iterátor přes délku řetězce, který generuje indexy jednotlivých znaků
    print(i, a[i]) # vytiskne index a přes index vytáhne znak z proměnné "a"
0 a
1 b
2 c
In [151]:
# stejného výsledku dosáhneme zabalením řetězce do "enumerate", který oindexuje jednotlivé položky a vrací dvojice (index, hodnota), které si uložíme do proměnné "i" a "item"
for i, item in enumerate(a):
    print(i, item)
0 a
1 b
2 c
In [152]:
values = [1, 2, 3, 4, 5, 6, 7, 8]
for val in values:
    if val % 2 == 0: # pokud je číslo sudé, tak ho vytiskni
        print(val, end=' ')
    elif val>5: # pokud je číslo větší jak 5, tak přeruš cyklus
        break
    else: # jinak pokračuj
        continue
2 4 6 

List comprehension

In [153]:
# do listu squares ulož druhé mocniny hodnot z listu values pomocí cyklu for
values = [1, 2, 3, 4, 5, 6, 7, 8]
squares = []
for x in values:
    squares.append(x**2)
squares
Out[153]:
[1, 4, 9, 16, 25, 36, 49, 64]
In [154]:
# pomocí comprihension
squares = [x**2 for x in values]
squares
Out[154]:
[1, 4, 9, 16, 25, 36, 49, 64]
In [155]:
# comprehension s podmínkou
squares = [x**2 for x in values if x<=4]
squares
Out[155]:
[1, 4, 9, 16]
In [156]:
# funguje stejně se set, dict
# vytvoř slovní, kde key je hodnota a value je hodnota**2
d = {x: x**2 for x in values}
d
Out[156]:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64}
In [157]:
def power_comprehension(x):
    return [i**2 for i in x]

def power_cycle(x):
    res = []
    for i in x:
        res.append(i**2)
    return res
data = list(range(100))
In [158]:
%timeit power_comprehension(data)
23.9 µs ± 3.14 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [159]:
%timeit power_cycle(data)
27.9 µs ± 2.35 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Funkce

  • pro často opakující se fukcionalitu je vhodné si vytvořit funkci
def funkce(poziční parametry, klíčové parametry):
    """dokumentační řetězec"""
    blok funkce,
    return výsledek/ky
  • pokud chceme výsledek dále používat, uložit si ho do proměnné, tak funkce musí obsahovat return
  • funkce nemusí nic vracet, může např. pouze něco tisknout "print", ukládat do souboru, ...
In [160]:
# jednoduchá funkce, která bere 2 povinné parametry a vrací jejich součet
def func(a, b):
    """Add two values"""
    return a + b
In [161]:
# zavoláme funkci s dvěma parametry a výsledek uložíme do res
res = func(3, 5)
print(res)
8
In [162]:
# v ipythonu, jupyter lab, jupyter notebook můžeme vytisknout nápovědu pomocí "?"
func?
Signature: func(a, b)
Docstring: Add two values
File:      /tmp/ipykernel_636311/4064473358.py
Type:      function
In [163]:
# v souboru .py můžeme vytisknout nápovědu
print(help(func))
Help on function func in module __main__:

func(a, b)
    Add two values

None
In [164]:
# zavoláním funkce s jedním parametrem dostaneme error
func(3)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/306815971.py in ()
      1 # zavoláním funkce s jedním parametrem dostaneme error
----> 2 func(3)

TypeError: func() missing 1 required positional argument: 'b'
In [ ]:
# i obyčejné parametry lze volat jako klíčové
# za parametr "b" pošleme 5 a opět dostaneme error
func(b=5)
In [165]:
# funkci lze poslat jakékoli 2 parametry, které lze sčítat/spojovat pomocí operátoru +
# např. řetězce
func('abc', 'def')
Out[165]:
'abcdef'
In [166]:
# pokud zadáme objekty, které to neumí, tak dostaneme opět error
func('abc', 5)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_636311/2652999683.py in ()
      1 # pokud zadáme objekty, které to neumí, tak dostaneme opět error
----> 2 func('abc', 5)

/tmp/ipykernel_636311/4064473358.py in func(a, b)
      2 def func(a, b):
      3     """Add two values"""
----> 4     return a + b

TypeError: can only concatenate str (not "int") to str
In [167]:
# funkce pro kvadratickou rovnici
# 1 povinný parametr "x"
# ostatní parametry klíčové parametry mají výchozí hodnoty
def quad(x, a=1, b=0, c=0):
    return a * x**2 + b*x + c
In [168]:
# zavoláním funkce s jedním parametrem dostaneme 1 * x **2 + 0 * x + 0
quad(2)
Out[168]:
4
In [169]:
# první 2 se dosadí za "x"
# 4.2 se dosadí za "a"
# b zůstane výchozí 0
# a c=3
quad(2, 4.2, c=3)
Out[169]:
19.8
In [170]:
# pro vytvoření funkce, která přijímá libovolný počet parametrů můžeme použít "*args" (běžně používaný název)
def add(x, *args):
    total = x
    for arg in args:
        total += arg
    return total
add(1, 2, 3, 4)
Out[170]:
10
In [171]:
# pro vytvoření funkce, která přijímá libovolný počet klíčových parametrů můžeme použít "**kwargs" (běžně používaný název)
def add(x, **kwargs):
    total = x
    for key, value in kwargs.items():
        print('adding', key)
        total += value
    return total
add(1, g=2, b=3, w=4)
adding g
adding b
adding w
Out[171]:
10
In [172]:
def func(*args, **kwargs):
    print(args, kwargs)
func(1, 2, x=5, b=6)
(1, 2) {'x': 5, 'b': 6}
In [173]:
l = [4, 5]
d = {'a': 10, 'k': 8}
# pokud chceme použít všechny hodnoty z listu/slovníku, tak abychom je nemuseli postupně vypisovat
# func(l[0], l[1], a=d['a'], k=d['k'])
# můžeme je rozbalit - * rozbalí list, a ** rozbalí slovník
func(*l, **d)
(4, 5) {'a': 10, 'k': 8}
In [174]:
def func(a, b):
    """Add two values"""
    return a + b
func(l[0], l[1]), func(*l)
Out[174]:
(9, 9)
In [175]:
# funkce, která převání souřadnice do polárních
from math import atan2
def to_polar(x, y):
    r = (x**2 + y**2)**0.5
    theta = atan2(y, x)
    return r, theta
r, theta = to_polar(1, 1)
r, theta
Out[175]:
(1.4142135623730951, 0.7853981633974483)

Práce se soubory (File IO)

In [176]:
# příprava testovacího souboru
# otevři textový soubor pro zápis a zapiš do něj hodnoty
with open('text.txt', 'w') as f:
    f.write('''x\ty
1\t2
3\t4.5
4\t10.2''')
In [177]:
f = open('text.txt', 'r') # otevři soubor pro čtení "r"
text = f.read() # načti obsah soboru do proměnné text
f.close() # pokud už soubor nebudu potřebovat, je dobré ho zavřít (pokud dojde k chybě přičtení, tak k zavření nedojde)
print(text)
x	y
1	2
3	4.5
4	10.2
In [178]:
# použití "with" zajistí automatické zavření soboru i pokud dojde k chybě uvnitř bloku
with open('text.txt', 'r') as f:
    text = f.read()
print(text)
x	y
1	2
3	4.5
4	10.2
In [179]:
f = open('text.txt', 'r')
lines = f.readlines() # načti řádky, vrátí list řádků
f.close()

print(lines)
['x\ty\n', '1\t2\n', '3\t4.5\n', '4\t10.2']
In [180]:
# zápis do soubotu "w"
# pokud soubor neexistuje, tak se vytvoří
# pokud soubor existuje, tak smaže jeho obsah
with open('output.txt', 'w') as f:
    f.write('První řádek\n')
In [181]:
# zápis do souboru v režimu append "a"
# nová data přidává na konec souboru
with open('output.txt', 'a') as f:
    f.write('Druhý řádek\n')
In [182]:
!cat output.txt # linux terminal vypiš obsah souboru
První řádek
Druhý řádek
In [183]:
!type output.txt # windows cmd vypiš obsah souboru
/bin/bash: line 0: type: output.txt: not found
In [184]:
# další režimy
# w+ read-write
# rU - universal newline mode
# wb, rb - write/read binary

Třídy (Classes)

speciální metody:

  • __new__()
  • __init__()
  • __repr__()
  • __str__()
  • __call__()
  • __iter__()
  • __add__()
  • __sub__()
  • __mul__()
  • __rmul__()
  • __class__()
  • __name__()
  • __delete__()

pojmenování parametrů a metod:

  • public
  • private - _name, _method()
  • special - __name, __method()
In [185]:
class Rectangle():
    """Dokumentační řetězec
    Parameters:
        width
        height
        
    Example:
        >>> rectangle = Rectange(2, 5)
        >>> rectangle.get_area()
            10
    """
    
    def __init__(self, w, h):
        """init doc"""
        self.width = w
        self.height = h
    
    def get_area(self):
        """Return rectangle area"""
        return self.width * self.height
    
    def __str__(self):
        return f'{self.__class__.__name__}({self.width}, {self.height})'
In [186]:
x = Rectangle(4, 3.5)
x, x.get_area()
Out[186]:
(<__main__.Rectangle at 0x7fa5cc3223a0>, 14.0)
In [187]:
Rectangle?
Init signature: Rectangle(w, h)
Docstring:     
Dokumentační řetězec
Parameters:
    width
    height
    
Example:
    >>> rectangle = Rectange(2, 5)
    >>> rectangle.get_area()
        10
Init docstring: init doc
Type:           type
Subclasses:     
In [188]:
print(help(Rectangle))
Help on class Rectangle in module __main__:

class Rectangle(builtins.object)
 |  Rectangle(w, h)
 |  
 |  Dokumentační řetězec
 |  Parameters:
 |      width
 |      height
 |      
 |  Example:
 |      >>> rectangle = Rectange(2, 5)
 |      >>> rectangle.get_area()
 |          10
 |  
 |  Methods defined here:
 |  
 |  __init__(self, w, h)
 |      init doc
 |  
 |  __str__(self)
 |      Return str(self).
 |  
 |  get_area(self)
 |      Return rectangle area
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

None
In [189]:
print(x) # volá naši upravenou funkci __str__
Rectangle(4, 3.5)
In [190]:
class Person():
    """height: meters
    """
    counter = 0 # parametr třídy
    
    def __init__(self, name, surname, height):
        # self.name jsou parametry, které se liší v každé instanci
        self.name = name
        self.surname = surname
        self._height = height
        print('jsem tu')
        Person.counter += 1 # při vytvoření nové instance se zvýší počítadlo
        
    def __del__(self):
        Person.counter -= 1 # zániku třídy se počítadlo sníží
        
    def return_fullname(self):
        return f'{self.name} {self.surname}'
    
    @property # dekorátor
    def fullname(self):
        return self.return_fullname()
    
    @property
    def height(self):
        return self._height
    
    @property
    def height_in_cm(self):
        return self._height * 100
    
    @height_in_cm.setter
    def height_in_cm(self, height):
        self._height = height / 100
        
    def get_height_in_mm(self):
        return self._height * 1000
    
    def set_height_in_mm(self, height):
        self._height = height / 1000

    height_in_mm = property(get_height_in_mm, set_height_in_mm) # alternativní způsob vytvoření bez dekorátoru
In [191]:
person1 = Person('Václav', 'Sadílek', 1.8)
print(person1.return_fullname()) # metoda, která vrací fullname
print(person1.fullname) # použitím property se funkce chová jako parametr a volá se bez ()
print(person1.height)
print(person1.height_in_cm)
person1.height_in_cm = 168
print(person1.height)
print(person1.height_in_mm)
jsem tu
Václav Sadílek
Václav Sadílek
1.8
180.0
1.68
1680.0
In [192]:
person1.fullname = "Nové jméno" # property nelze upravovat bez vytvoření property.setter
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_636311/2127129488.py in ()
----> 1 person1.fullname = "Nové jméno" # property nelze upravovat bez vytvoření property.setter

AttributeError: can't set attribute
In [193]:
print('Počet osob', Person.counter)
Počet osob 1
In [194]:
person2 = Person('Karel', 'Novák', 2)
person3 = Person('Pavel', 'Novák', 1.65)
print('Počet osob', Person.counter)
jsem tu
jsem tu
Počet osob 3
In [195]:
del person1 # smaž person1
print('Počet osob', Person.counter)
Počet osob 2

Cesty (Paths)

In [196]:
import os
In [197]:
fname = 'obrazek.jpg'
# spojování cest pomocí os.path zajistí správná lomítka podle operačního systému
os.path.join('figures', fname)
Out[197]:
'figures/obrazek.jpg'
In [198]:
fname = 'text.txt'
os.path.abspath(fname) # vypíše absolutní cestu
Out[198]:
'/media/data/Rozdeleni/VUT/vyuka/kurz_king_2022/Python/text.txt'
In [199]:
os.path.splitext(fname) # oddělení přípony z názvu souboru
Out[199]:
('text', '.txt')
In [200]:
os.path.abspath(os.path.curdir) # absolutní cesta k aktuální složce
Out[200]:
'/media/data/Rozdeleni/VUT/vyuka/kurz_king_2022/Python'
In [201]:
os.path.exists(fname) # test zda soubor existuje
Out[201]:
True
In [202]:
# novější způsob práce s cestami pomocí knihovny pathlib\
import pathlib
In [203]:
path = pathlib.Path('.') # nastavení cesty na aktuální složku - current dir = "."
path
Out[203]:
PosixPath('.')
In [204]:
path.absolute() # absolutní cesta
Out[204]:
PosixPath('/media/data/Rozdeleni/VUT/vyuka/kurz_king_2022/Python')
In [205]:
# řetězit názvy složek a souborů lze přes operátor děleno "/"
fname = 'text.txt'
text_file_path = path / fname
text_file_path, text_file_path.absolute()
Out[205]:
(PosixPath('text.txt'),
 PosixPath('/media/data/Rozdeleni/VUT/vyuka/kurz_king_2022/Python/text.txt'))
In [206]:
text_file_path.exists() # kontrola zda soubor existuje
Out[206]:
True
In [207]:
text_file_path.suffix # vrátí příponu
Out[207]:
'.txt'
In [208]:
text_file_path.name # název souboru
Out[208]:
'text.txt'
In [209]:
text_file_path.stem # jméno bez přípony
Out[209]:
'text'
In [210]:
text_file_path.parent # složka, ve které se soubor nachází
Out[210]:
PosixPath('.')

Vyjímky a varování

In [211]:
a = 5
a / 0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
/tmp/ipykernel_636311/3173116488.py in ()
      1 a = 5
----> 2 a / 0

ZeroDivisionError: division by zero
In [212]:
try:
    b = a / 0
except ZeroDivisionError:
    print('pokoušíš se dělit 0')
pokoušíš se dělit 0
In [213]:
try:
    b = a / 0
except ZeroDivisionError as exc:
    print('Exception message:', exc)
Exception message: division by zero
In [214]:
try:
    b = a / 0
except ZeroDivisionError as exc:
    print('Exception message:', exc)
finally:
    print('finally')
Exception message: division by zero
finally
In [215]:
class MojeVyjimka(ValueError):
    """Moje důležitá vyjímka"""
    pass
raise MojeVyjimka('zpráva vyjímky')
---------------------------------------------------------------------------
MojeVyjimka                               Traceback (most recent call last)
/tmp/ipykernel_636311/2089367117.py in ()
      2     """Moje důležitá vyjímka"""
      3     pass
----> 4 raise MojeVyjimka('zpráva vyjímky')

MojeVyjimka: zpráva vyjímky
In [216]:
import warnings
In [217]:
warnings.warn('text varování', RuntimeWarning)
/tmp/ipykernel_636311/1901632287.py:1: RuntimeWarning: text varování
  warnings.warn('text varování', RuntimeWarning)

Import balíčků

  • import balíčků se provádí nejčastěji na začátku zdrojového kódu
In [218]:
import math
# použití funkcí a proměnných se pak provádí
math.sin(3), math.pi # zde je hned jasné odkud se ta funkce bere
Out[218]:
(0.1411200080598672, 3.141592653589793)
In [219]:
from math import sin, pi # můžu si naimportovat pouze vybrané objekty
sin(3), pi
Out[219]:
(0.1411200080598672, 3.141592653589793)
In [220]:
# NEPOUŽÍVAT !!!
from math import * # naimportruje vše
# pokud se v nějakém balíčku vyskytují stejně pojmenované funkce/proměnné, tak dojde ke konfliktu
# potom se může použít funkce z jiného balíčku než očekáváme
In [221]:
# pokud je název dlouhý nebo by došlo ke konfliktu, tak ho při importu můžeme přejmenovat
import numpy as np
np.sin(3) # zde je také snadno identifikovatelné, ze kterého balíku sin pochází
Out[221]:
0.1411200080598672
In [ ]:
 
In [222]:
# sin už mám naimportovaný z math
from numpy import sin as np_sin
sin, np_sin
Out[222]:
(, )
In [ ]: