NPRG030
)ssh
ssh [cas jmeno]@u-pl[1-25].ms.mff.cuni.cz
dir
vs. ls
atd.)sftp
sftp [cas jmeno]@u-pl[1-25].ms.mff.cuni.cz
put [umístění souboru v lokalním pc] [cílové umístění na vzdáleném pc]
get [umístění souboru na vzdaleném pc] [cílové umístění na lokálním pc]
sftp
; pro umístění přímo do adresáře, ze kterého se příkaz volal, stačí místo cesty zadat tečku)zadání v ReCodExu
zadání v ReCodExu
pyqt
[web] [ukázka/dokumentace]tkinter
[dokumentace] a [ukázka]tkinter
. Vytvořme jednoduchý formulář.
import tkinter as tk
window = tk.Tk()
window.option_add('*Font', 'Arial 9')
jmeno_label = tk.Label(window, text='Jméno:').pack()
jmeno_entry = tk.Entry(window)
jmeno_entry.pack()
prijmeni_label = tk.Label(window, text='Příjmení:').pack()
prijmeni_entry = tk.Entry(window)
prijmeni_entry.pack()
telefon_label = tk.Label(window, text='Telefon:').pack()
telefon_entry = tk.Entry(window)
telefon_entry.insert(0, '+420')
telefon_entry.pack()
def odesli():
print(jmeno_entry.get())
print(prijmeni_entry.get())
print(telefon_entry.get())
tk.Button(window, text=u"Odešli", width=10, command=odesli).pack()
tk.mainloop()
import tkinter as tk
window = tk.Tk()
window.option_add('*Font', 'Arial 9')
window.columnconfigure([0, 1, 2, 3], minsize=100)
jmeno_label = tk.Label(window, text='Jméno:').grid(row=0)
jmeno_entry = tk.Entry(window)
jmeno_entry.grid(row=0, column=1)
prijmeni_label = tk.Label(window, text='Příjmení:').grid(row=0, column=2)
prijmeni_entry = tk.Entry(window)
prijmeni_entry.grid(row=0, column=3)
telefon_label = tk.Label(window, text='Telefon:').grid(row=1)
telefon_entry = tk.Entry(window)
telefon_entry.insert(0, '+420')
telefon_entry.grid(row=1, column=1)
def odesli():
print(jmeno_entry.get())
print(prijmeni_entry.get())
print(telefon_entry.get())
tk.Button(window, text=u"Odešli", width=10, command=odesli).grid(row=3, column=3)
tk.mainloop()
.json
formátu.pygame
pro tvorbu jednoduchých her (viz [ukázka] a [dokumentace])numpy
- pro zpracování číselných dat [web] [ukázka/dokumentace]regex
- pro zpracování textu (modernější než původní knihovna re
) [web] [ukázka/dokumentace]networkx
- pro zpracování grafů [web] [ukázka/dokumentace]pandas
- pro zpracování libovolných datových zdrojů, převážně tabulkového/csv/xlsx formátu [web] [ukázka/dokumentace]matplotlib
a seaborn
- pro vizualizaci dat v podobě grafů a diagramů [web] [ukázka/dokumentace] a [web] [ukázka/dokumentace]request
- pro zpracování webu [web] [ukázka/dokumentace]flask
a django
- pro vytváření webu [web] [ukázka/dokumentace] a [web] [ukázka/dokumentace]sklearn
- pro zpracování strojového učení [web] [ukázka/dokumentace]tensorflow
- pro zpracování neuronových sítí [web] [ukázka/dokumentace]pandas
nebo cheat sheet pro tkinter
. Existují jich spousty, a to v různých verzích.try-except
k ošetření chyby. Jaká výjimka by se měla zachytit u proměnné c
?
try:
a = int('pokus')
except ValueError:
print('Toto není číslo.')
try:
b = 7 / 0
except ZeroDivisionError:
print('Dělíte nulou.')
try:
c = len(9)
except:
print('??')
try-except
k ošetření chyby a dalšímu běhu programu.
a = 7
b = 0
try:
c = a / b
print(c)
except ZeroDivisionError:
print('Dělí se nulou!')
else:
print('Tohle se provede, pokud chyba nenastane.')
finally:
print('Tohle se provede vždycky.')
raise
místo
def obsah_ctverce(strana):
if strana > 0:
return strana ** 2
else:
raise ValueError(f'Strana musí být kladná, číslo {strana} kladné není!')
# dlouhá notace
python3 -m pip install __jmeno_knihovny__
python3 -m pip install regex
# kratší notace
pip3 install __jmeno_knihovny__
pip3 install networkx==2.4
Správce: Když je knihovna instalována přímo do systému, je potřeba k instalaci externí knihovny povolení správce. Ve Windows by mělo stačit spustit příkazový řádek jako správce; v Unix by mělo stačit použít před výše uvedený příkaz klíčové slůvko sudo
.
Verze: Pokud chcete nainstalovat konkrétní verzi nějaké knihovny, stačí bezprostředně za název připojit ==číslo_verze
# jedna možnost - Unix i Windows
python3 -m venv __nazev_adresare__
python3 -m venv py3env
# druhá možnost - Unix
virtualenv -p python3 __nazev_adresare__
virtualenv -p python3 py3env
# aktivace - Unix
source py3env/bin/activate
# aktivace - Windows
.\py3env\Scripts\activate
# deaktivace
deactivate
# instalace knihoven bez aktivace
py3env/bin/python3 -m pip install __jmeno_knihovny__
unittest
, díky níž lze vytvářet testy, ale na ovládání je mnohem snazší knihovna pytest
, která se však musí doinstalovat
python3 -m pip install pytest
test_
, k vyhodnocení se používá klíčové slovo assert
, testy se většinou udržují ve speciálním samostatném souborutest_secteni.py
.
def secti(a, b):
return a + b
def test_secti():
assert secti(1, 2) == 3
Příkaz assert
ve výjimkách funguje v podstatě jako:
if not (a == b):
raise AssertionError('Test selhal!')
Test se spouští z příkazového řádku pomocí:
python3 -m pytest -v test_secteni.py
Vytvořený test je tzv. pozitivní test, lze ale vytvořit i negativní testy:
def test_secti2():
assert secti(1, 2) != 4
test_secteni.py
na dva soubory tak, aby byly testy a kód programu zvlášť, a přitom šlo kód programu testovat.
import pytest
@pytest.mark.parametrize(
['a', 'b'], [(10, 1), (11, 2), (12, 3), (13, 4), (14, 5)]
)
def test_secti(a, b):
assert secti(a, b) == a + b
os
[dokumentace]os
.
import os
os.getcwd() # vrátí aktuální pracovní adresář
os.chdir('...') # změna aktuálního pracovního adresáře
os.mkdir() # vytvoří adresář
os.rmdir('...') # smaže zadaný adresář
os.listdir() # vrátí seznam adresářů a souborů
os.path.exists('...') # zjistí, zda adresář/soubor existuje
os.path.getsize('...') # vrátí velikost souboru v Bytech
os.remove('...') # smaže zadaný soubor
sys
[dokumentace]: sys.exit()
, sys.argv
, sys.path
, sys.stdin
argparse
[dokumentace]argparse
k načtení parametrů.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--input')
parser.add_argument('--output', dest='out', help='popisek...')
parser.add_argument('--parameter1', type=float, help='popisek...')
parser.add_argument('--parameter2', type=float, required=False, help='popisek...')
parser.add_argument('--load_google', choices=['Ano', 'Ne'], default='No', help='popisek...')
parser.add_argument('--seznam', nargs='+', help='popisek...')
args = parser.parse_args()
print(args.input, args.out, args.load_google, args.seznam)
with
?
# starší způsob čtení
file = open('soubor.txt', 'r')
obsah = file.read()
file.close()
# modernější způsob čtení
with open('soubor.txt', mode='r', encoding='U8') as file:
obsah = file.read()
Čtení ze souboru lze také následovně:
file.read()
(příp. file.read(5)
),file.readline()
,for line in file: print(line)
# starší způsob zápisu
file = open('soubor.txt', 'w')
file.write('text...')
file.close()
# modernější způsob zápisu
with open('soubor.txt', mode='w', encoding='U8') as file:
file.write('text...') # nebo: print('text...', file=file)
* Parametr mode
může nabývat několika hodnot, např. w
(write), r
(read), b
(binary mode), a
(append). Stejně tak encoding
.
with
: zajišťuje, že nezůstane soubor otevřený a že čtení i zápis proběhnou hladce [popis z dokumentace]
csv
[dokumentace]: csv.reader()
, csv.writer()
csv
/tsv
.
# .csv
kočka,5,3,2
pes,3,2,1
želva,5,3,2
krkavec,7,5,2
myš,3,2,1
# .tsv
kočka 5 3 2
pes 3 2 1
želva 5 3 2
krkavec 7 5 2
myš 3 2 1
import csv
with open('soubor.csv', mode='r', encoding='U8') as csv_file:
obsah_souboru = csv.reader(csv_file, delimiter=',')
for radek in obsah_souboru:
print(' '.join(radek))
json
[dokumentace]: json.load()
, json.loads()
, json.dump()
, json.dumps()
(param. ensure_ascii=False
)json
.
{
'kočka': {'pismena': 5, 'souhlasky': 3, 'samohlasky': 2},
'pes': {'pismena': 3, 'souhlasky': 2, 'samohlasky': 1},
'želva': {'pismena': 5, 'souhlasky': 3, 'samohlasky': 2},
'krkavec': {'pismena': 7, 'souhlasky': 5, 'samohlasky': 2},
'myš': {'pismena': 3, 'souhlasky': 2, 'samohlasky': 1},
}
import json
with open('soubor.json', mode='r', encoding='U8') as json_file:
obsah_souboru = json.load(json_file)
print(obsah_souboru)
xlrd
[dokumentace] a xlwt
[dokumentace] pro čtení a zápis do .xls(x)
souborového formátuxml
[dokumentace]pickle
[dokumentace]: pickle.load()
, pickle.dump()
zipfile
[dokumentace]: zipfile.ZipFile().open()
, zipfile.ZipFile().open()
import zipfile
with zipfile.ZipFile('soubor.zip', 'w') as zip_file:
zip_file.write('zazipovany_soubor.txt')
with zipfile.ZipFile('soubor.zip') as zip_file:
with zip_file.open('zazipovany_soubor.txt') as muj_soubor:
obsah_souboru = muj_soubor.read().decode('utf-8')
print(obsah_souboru)
gzip
a shutil
[dokumentace a dokumentace]: gzip.open()
, shutil.copyfileobj()
import gzip, shutils
with open('soubor.txt', 'rb') as in_file:
with gzip.open(soubor.txt.gz', 'wb') as out_file:
shutil.copyfileobj(in_file, out_file)
with gzip.open('soubor.gz', 'rb') as gz_file:
obsah_souboru = gz_file.read().decode('utf-8')
print(obsah_souboru)
mašina
a vagon
Masina
a Vagon
podle popisu výše.U každé třídy stačí když vyrobíte metodu __init__()
která nastaví příslušné datové položky (ale pokud chcete, udělejte si i další metody). Níže je nástin. (Speciální funkce typu .__init__(self)
a .__str__(self)
naleznete vypsané zde.)
class Masina:
def __init__(self, vagon_za_mnou=None):
self.dalsi = vagon_za_mnou
class Vagon:
def __init__(self, naklad="brambory", mnozstvi=0, za_mnou=None):
...
Nepoužívejte žádné listy, v nějaké proměnné si udržujte pouze mašinu, a přes tu pak budete přistupovat k vagonům (můžete samozřejmě použít nějaké dočasné proměnné při vytváření vlaku, ale ty berme skutečně jako dočasné).
masina = Masina()
masina.dalsi = Vagon()
masina.dalsi.dalsi = Vagon('uhlí')
masina.dalsi.dalsi.dalsi = Vagon('koťátka', 3)
...
obecný komentář: pro každý bod níže vytvořte na mašině novou metodu, pokud možno parametrizovatelnou, tj. výchozí hodnota metody pridej_na_zacatek
může být přidat vagon vezoucí 30 ptakopysků, ale mělo by být možné pomocí parametrů přidat i vagon vezoucí něco jiného; metoda teoreticky buď vytvořit vagon dle zadání, ale lepší asi je, pokud ta metoda dostane už vytvořený vagon jako parametr, to se vám bude hodit v některých cvičeních (rada: pro přehlednost je vhodné, pokud každá metoda bude vypisovat, co dělá)
print(vagon)
a Python by místo něčeho jako __main__.Vagon object at 0x7fab3d588358
vypsal třeba něco jako Vagon vezouci drevo v mnozstvi 30
; (toho lze snadno dosáhnout předefinováním metody class.__str__(self)
kterou Python používá pro přetypování objektu daného typu na string (takže ta metoda musí vracet string))random
, vlastní vytvořené třídy Masina
a funkce pricti_sedm
.
import random
import Masina
from nazev_skriptu import pricti_sedm
Import vlastních tříd a funkcí předpokládá, že je soubor s implementovanou třídou v témže adresáři jako spouštěný skript. Pokud není, je potřeba přidat cestu k souboru do sys.path
, a teprve pak importovat. Lze zadat jak jako relativní, tak absolutní cestu.
# (a) import z adresáře, který je ve stejné složce jako spouštěný skript
from nazev_slozky.nazev_skriptu_se_tridou_Masina import Masina
# (b) import po přidání cesty do sys.paths
import sys
sys.path.append('cesta_do_adresare_se_souborem_se_tridou_Masina')
from nazev_skriptu_se_tridou_Masina import Masina
Varianta (a) nelze použít, pokud by byl skript s importovanou třídou Masina
v nějakém nadřazeném adresáři (cesta by k němu vedla relativně ../
). při importu v Pythonu totiž nelze použít from ../.nazev_skriptu_se_tridou_Masina import Masina
(ani jinou alternativu); musí se použít varianta (b). Varianta (b) lze použít jak v případě, kdy je skript s importovanou třídou v nadřazeném, tak podřazeném adresáři. Nejprve je však nutné přidat cestu do daného adresáře do sys.path
a teprve potom importovat potřebnou třídu.
Důležité upozornění : nazev_skriptu_se_tridou_Masina se zadává bez koncovky .py
a smí obsahovat jen písmena, čísla, podtržítka; mezery, spojovníky/pomlčky ani diakritiku při importu Python nezpracuje.
class Clovek:
def __init__(self, jmeno):
self.jmeno = jmeno
def rekni(self, text):
reknu = self.jmeno + ': ' + text
return reknu
def pozdrav(self):
return self.rekni('Ahoj, jsem ' + self.jmeno)
frantisek = Clovek('František')
frantisek.rekni('ptakopysk')
frantisek.pozdrav()
class Rvoun(Clovek):
def rekni(self, text):
reknu = self.jmeno + ': ' + text.upper()
return reknu
petr = Rvoun('Petr')
petr.pozdrav()
zprava = 'Klíče leží zapomenuté na stole...'
seznam = {'Anička': 'normální', 'Petr': 'tichošlápek', 'Marie': 'normální', 'Boženka': 'řvoun', 'Tereza': 'řvoun', 'Marek': 'tichošlápek', 'Josef': 'tichošlápek', 'Damián': 'řvoun', 'Magdaléna': 'řvoun', 'Běla': 'normální', 'Bohumír': 'řvoun', 'Martin': 'tichošlápek', 'Benedikt': 'normální', 'Bohouš': 'řvoun'}
dict()
: dict.get()
, dict.keys()
, dict.values()
, dict.items()
, dict.pop()
dict()
a jak lze pracovat s jejími metodami.
auto_1 = dict()
auto_1['znacka'] = 'Ford'
auto_1['model'] = 'Mustang'
auto_1['rok'] = 1964
auto_2 = {'znacka': 'Audi', 'model': 'Q5', 'rok': 2019}
print(auto_1.keys())
print(auto_1.values())
for klic, hodnota in auto_2.items():
print(klic, hodnota, sep='\t')
auto_2.pop('znacka')
print(auto_1.keys())
dict()
. V klíčích bude vždy zvíře, zatímco v hodnotě jeho jméno. Výsledný slovník se celý vypíše na výstupu pomocí metody dict.items()
; kolik se vypíše řádků? Na závěr nechte vypsat pomocí metody dict.get()
hodnoty klíčů 'kočka', 'rak' a 'želva'; pokud neexistuje, ať se místo jména vypíše 'není'.
seznam = [('kočka', 'Anička'), ('pes', 'Petr'), ('želva', 'Marie'), ('andulka', 'Boženka'), ('veverka', 'Tereza'), ('datel', 'Marek'), ('orel', 'Josef'), ('noserožec', 'Damián'), ('beruška', 'Magdaléna'), ('ropucha', 'Běla'), ('kačer', 'Bohumír'), ('kůň', 'Martin'), ('kohout', 'Benedikt'), ('hroch', 'Bohouš'), ('želva', 'Apolena')]
06_trideni
def
; na vstupu přijímají libovolný počet argumentů/parametrů, které mohou být i předvyplněnéa
, b
a c
?
def pricti_sedm(cislo, nasobek=1):
if cislo % 2 == 0:
return (cislo + 7) * nasobek
return cislo + (7 * nasobek)
a = pricti_sedm(5)
b = pricti_sedm(5, 2)
c = pricti_sedm(cislo=6, nasobek=3)
global
uvnitř funkcí
cislo = 5
def pricti_hodnotu(hodnota):
global cislo
cislo = cislo + hodnota # samostatně bez global by vrátilo chybu
return cislo # "cislo + hodnota" by v return prošlo!
print(cislo)
print(pricti_hodnotu(hodnota=3))
print(cislo)
# print(hodnota)
yield
, přičemž postupné generování hodnot se obsluhuje funkcí next()
def generator():
print('A')
yield 0
print('B')
yield 1
print('C')
it = generator()
next(it)
next(it)
next(it)
Generátory/iterátory lze vytvořit z iterovatelných objektů (jako jsou např. pole) pomocí iter(pole)
.
*Pro pokročilé: S generátory lze pracovat i obousměrně, tzn. v průběhu iterování do nich posílat nové vstupy, a to pomocí funkce send()
. Více o této a dalších možnostech lze nalézt [zde].
def faktorial(cislo):
if cislo > 0:
return faktorial(cislo - 1) * cislo
else:
return 1
print(faktorial(10))
Pro procvičení rekurze vypracujme cvičení josefuv_problem
.
math
: math.ceil()
, math.floor()
, math.pow()
, math.sqrt()
, math.exp()
, math.log()
, math.log2()
, math.comb()
, math.perm()
, math.factorial()
, math.pi
random
: random.seed()
, random.random()
, random.randint()
, random.shuffle()
, random.choice()
, random.choices()
, random.sample()
random
.
import random
random.seed(123)
print(random.random())
print(random.randint(2, 6))
pismena = ['a', 'b', 'c', 'd']
random.shuffle(pismena)
print(pismena)
print(random.choice(pismena))
print(random.choices(pismena, k=2)) # s opakováním
print(random.sample(pismena, k=2)) # bez opakování
tuple()
: indexování a funkce jsou stejné jako u list()
, nelze však přidávat/mazat položkyset()
: set.add()
, set.pop()
, set.remove()
, set.union()
, set.issubset()
, set.isdisjoint()
mnozina = set()
mnozina.add(5)
mnozina.add(3)
mnozina.add(5)
mnozina.add(7)
mnozina.pop()
mnozina.add(6)
mnozina.remove(7)
mnozina = mnozina.union({5,8,9})
print(mnozina)
for
a list comprehension [... for ...]
plus užitečné funkce range()
, enumerate()
, zip()
a příkazy pass
, break
, continue
dopravni_prostredky = (
'auto', 'kolo', 'loď', 'letadlo', 'motorka',
'brusle', 'koloběžka', 'surf', 'lanovka', 'kůň'
)
# klasický for cyklus
for i in range(0, len(dopravni_prostredky)):
if dopravni_prostredky[i] == 'letadlo':
print('To bude rychlost! Použiješ totiž letadlo!')
elif i == 4:
continue
elif i == 6:
break
else:
print('Použiješ {}?'.format(dopravni_prostredky[i]))
# list comprehension a funkce enumerate()
vysledek = [prostredek for i, prostredek in enumerate(dopravni_prostredky) if i % 2 == 0]
# funkce zip()
vysledek = [
prostredek
for i, prostredek in zip(range(0, len(dopravni_prostredky)), dopravni_prostredky)
if i % 2 == 0
]
sort()
.)inventura_v_zoo
round()
round()
jako v příkladu níže.
cislo = 1.5762357
print(round(cislo, 2))
str.split()
, str.strip()
, str.lstrip()
, str.rstrip()
, str.startswith()
, str.endswith()
, str.replace()
, str.join()
, str.format()
, str.lower()
, str.upper()
print('Cena limonády {} je {} {}.'.format('35', 'Sprite', 'KCZ'))
print('Cena limonády {limca} je {cena} {mena}.'.format(cena='35', mena='KCZ', limca='Sprite'))
print('Číslo je {:.2f}'.format(1.56789)) # všimněte si (ne)zaokrouhlení
print('kočka'.startswith('ko'))
print('kočka'.startswith('pe'))
print('pes'.endswith('e'))
print('pes'.endswith('es'))
print('Programování je lopota'.replace('o', ''))
print('Programování je lopota'.replace('je', 'přeci není'))
print('\n\tZnak "\\n" je zalomení řádků. Znak "\\t" reprezentuje tabulátor.\n'.lstrip())
print('\n\tZnak "\\n" je zalomení řádků. Znak "\\t" reprezentuje tabulátor.\n'.rstrip())
print('\n\tZnak "\\n" je zalomení řádků. Znak "\\t" reprezentuje tabulátor.\n'.strip())
print('kočka,pes,želva,papoušek,jelen'.split(','))
print(','.join(['kočka', 'pes', 'želva', 'papoušek', 'jelen'])) # zkuste do pole dát čísla
list()
: list[:]
, list.index()
, list.append()
, list.insert()
, list.pop()
, list.count()
, list.reverse()
, list.remove()
pole = list()
pole.append(5)
pole.append(3)
pole.append(7)
pole.append(1)
pole.insert(2, 6)
pole.insert(21, 6)
pole[1] = 8
pole.remove(6)
pole.pop()
pole.reverse()
print(pole[:2])
list
: len()
, sorted()
, min()
, max()
, range()
==
, !=
, <
, >
, <=
, >=
, not
, and
, or
, in
, all()
, any()
all()
a any()
.
print(all([True, True, False])
print(all([True, True, True])
print(all([False, False, False])
print(any([True, True, False])
print(any([True, True, True])
print(any([False, False, False])
if - elif - else
cislo = 1.78
if round(cislo, 0) < cislo:
print('A')
elif round(cislo, 0) > cislo:
print('B')
else:
print('C')
while
cislo = 0
while cislo < 5:
print('číslo se zvětšilo')
if cislo == 3:
print('číslo je 3')
cislo += 1
print('číslo je {}'.format(cislo))
while
, který bude na vstupu požadovat zadávání čísel od 1-20, a to dokud bude zadané číslo sudé. Jakmile dostane program na vstup liché číslo, vypíše: (i) že se jedná o číslo liché, (ii) minimální a (iii) maximální zadaná čísla, (iv) počty zadaných čísel z intervalů 1-5, 6-10, 11-15, 16-20..py
, .ipynb
)python3 jmeno_programu.py
/ py jmeno_programu.py
) vs. dvojklikemint
, float
, str
, bool
, None
str(5)
vrátí '5'
a
-g
? Ověřte pomocí funkce type()
.
a = 1
b = 1.5
c = 'ahoj'
d = True
e = None
f = '20'
g = "pozdravení"
+
, -
, *
, /
, **
, //
, %
a = 1 + 1
b = 1.5 - 1
c = 3 * 5
d = 4 ** 2
e = 10 / 2
f = 10 // 3
g = 5 % 4
h = 'černo' + 'bílý'
i = 2 * 'po' + 'skočit'
j = 3 * 4 + 2
k = 3 * (4 + 2)
l = True + 5
m = a + b
n = h * b
o = g + i
print()
, input()
, str.format()
, type()
a = 'ahoj'
b = input('Zadejte své jméno v 5. pádě: ')
c = a + ' ' + b + '!'
print(c)
# jiné způsoby, jak vytisknout tentýž výstup:
print(a + ' ' + b + '!')
print('ahoj {}!'.format(b))