Prednáška 1: Úvod do Pythonu a Jupyter Notebookov¶
Obsah¶
- Úvod do JupyterLab a Pythonu
- Základné operácie s odstavcami
- Jazyk Python
- Prvý program
- Premenné
- Dátové typy
- Vetvenia
- Cykly
Úvod do JupyterLab a Pythonu¶
JupyterLab je interaktívne vývojové prostredie, ktoré umožňuje písanie, testovanie a vizualizovanie kódu v reálnom čase. V JupyterLab používame Jupyter Notebooks, ktoré sú kombináciou textu, kódu a výstupov. Tento nástroj je ideálny na učenie sa programovania, analýzu dát, vizualizáciu a experimentovanie s rôznymi algoritmami.
Jupyter Notebooky obsahujú tri typy odstavcov:
Textový popis
– Formátovaný v Markdown.Kód
– Zdrojový kód v jazyku Python.Výstup
– Výsledky kódu po jeho spustení.
Python je interpretovaný jazyk, čo znamená, že kód je vykonávaný priamo počas jeho spustenia. Na pozadí sa používa Python Interpreter, ktorý číta a vykonáva príkazy z vášho kódu.
1 + 1
2
Základné operácie s odstavcami¶
- Nový odstavec môžete vytvoriť kliknutím na tlačidlo
+
. Štandardne sa vytvorí odstavec s Python kódom, ktorý sa pridá za aktuálny odstavec. Ak chcete zmeniť typ odstavca napr. na textový popis, kliknite na menu s typom odstavcaCode
a zvoľte typMarkdown
. - Zmeny môžete uložiť cez menu
File > Save Notebook
, alebo stlačenímCtrl+S
. - Pri editovaní môžete zrušiť zmeny v texte alebo kóde, alebo ich opakovať v menu
Edit > Undo
, aleboEdit > Redo
. - Poradie odstavcov môžete jednoducho zmeniť drag-and-drop presúvaním.
- Ak chcete editovať textový odstavec, kliknite naň dvakrát myšou a zobrazí sa Vám Markdown formát. Pre zrušenie editovania, stlačte
Escape
. Ak chcete sformátovať a zobraziť text odstavca v Markdowne, alebo spustiť Python kód, stlačteShift+Enter
. - Ak chcete zmazať výstup po spustení, kliknite na odstavec pravým tlačidlom a v menu zvoľte
Clear Outputs
, aleboClear All Outputs
ak chcete zmazať výstupy v celom zápisníku. - Ak chcete zmazať niektorý odstavec, zrušte editovanie stlačením
Escape
a potom dva krát stlačteD
.
Jazyk Python¶
Váš program v jazyku Python zapísaný v zdrojovom texte (zdrojovom kóde) viete priamo spustiť pomocou Interpretera. Interpret je program, ktorý načíta váš zdrojový kód a priamo vykoná príkazy, ktoré ste v ňom zapísali (tzn. interpretuje zdrojový kód, preto sa jazyk Python označuje ako tzv. interpretovaný jazyk). Prostredie JupyterLab spustí Interpreter na pozadí vždy keď pracujete s dokumentom zápisníka, vykoná v ňom kód jednotlivých odstavcov ktoré spustíte, a zobrazí vám výsledky.
Prvý program¶
Tradične, keď sa začínate učiť nový programovací jazyk, mali by ste sa v ňom pokúsiť vypísať jednoduchú správu na obrazovku. V Pythone na to môžete použiť nasledujúci príkaz:
print("Hello world...")
Hello world...
Príkaz print("Hello world...")
predstavuje volanie funkcie. Slovo print
je názov funkcie za ktorým nasleduje zoznam parametrov (argumentov) funkcie ohraničený zátvorkami. V tomto prípade sme funkciu zavolali iba s jedným parametrom - reťazcom, ktorý obsahuje textovú správu "Hello world..."
. Text je v reťazcoch ohraničený úvodzovkami "
. Funkcia print
je priamo zabudovaná v jazyku Python, ale neskôr sa naučíme ako si môžete naprogramovať vlastné funkcie.
Premenné¶
Premenné slúžia na uchovávanie medzivýsledkov pri výpočte a môžete ich definovať zápisom [meno premennej] = [hodnota]
. Meno premennej si môžete zvoliť, ale malo by dostatočne popisovať účel premennej. Pre pomenovanie premenných by ste mali ďalej dodržiavať tieto pravidlá:
- Premenné označujte názvami s malými písmenami a nepoužívajte znaky s diakritikou. Viacslovné názvy oddeľujte
_
(napr.process_data
). - Premenné, ktoré budú slúžiť v programe ako konštanty a ktoré sa nebudú pri spustení meniť pomenujte veľkými písmenami oddelenými
_
(napr.DEFAULT_VALUE
).
# komentáre v Pythone začínajú znakom # a pokračujú do konca riadka.
# komentáre používajte na pridávanie krátkych vysvetľujúcich poznámok o kóde, dlhšie dokumentačné texty zapíšte do textového odstavca a sformátujte Markdownom
s = "Hello world..."
print(s) # = s (komentáre nemusia začínať na začiatku riadka.)
Ak sa pokúsite pristupovať k premennej ktorej ste nepriradili žiadnu hodnotu, Interpreterer skončí chybou NameError: name 'názov premennej' is not defined
. Ak chcete definovať premennú s prázdnou hodnotou, môžete ako hodnotu zadať konštantu None
. Napr. nasledujúci kód skončí chybou, pretože sme nedefinovali premennú s názvom unknown_variable
.
print(unknown_variable)
Ak chceme vypísať hodnotu niektorej premennej, nemusíme používať funkciu print
, stačí jej meno uviesť ako posledný výraz v odstavci, napr.:
x = 1
x
Po vytvorení premennej v jednom odstavci je premenná dostupná aj v ďalších odstavcoch, ktoré sa na ňu odkazujú, tzn. môžeme napr. ďalej pristupovať k premennej x
, alebo s
definovanej vyššie. Môžeme aj zmeniť ich hodnotu, čo sa prejaví vo všekých odstavcoch, ktoré sa na ňu odkazujú. Python neohraničuje typy premenných, tzn. do jednej premennej môžete zapísať napr. číslo a neskôr reťazec, alebo iný objekt.
Funkcie môžete volať aj s viacerými parametrami, pričom ako parameter môžete zadať priamo dátovú hodnotu, alebo sa odkazovať na nejakú premennu. Funkcia print
vypíše na obrazovku hodnoty všetkých parametrov v uvedenom poradí na jednom riadku a oddelí ich medzerou. Neskôr sa naučíme lepší spôsob formátovania vypisovaných správ.
s = "one" # zmenili sme hodnotu premennej s a priradili sme jej reťazec "one"
# viacero parametrov je pri volaní funkcie oddelených čiarkou
print("Python is number", s, "!!!") # = Python is number one !!!
Odstavce môžete spustiť viac krát, napr. nasledujúci kód vždy po spustení pripočíta k premennej x
, ktorú sme predtým inicializovali na 1, hodnotu 1.
x = x + 1
x
Dávajte si pozor aj na to, že odstavce môžete spustiť v inom poradí než ako sú zapísané v zápisníku, čo môže zmeniť výsledky výpočtov. Preto v návodoch vždy postupujte za sebou v poradí a spustite aspoň raz každý odstavec, ktorý inicializuje premenné.
Dátové typy¶
Python rozlišuje ako základné typy Boolovské hodnoty, čísla (celé a desatinné) a reťazce. Ak chcete definovať premennú s prázdnou hodnotou, môžete ako hodnotu zadať konštantu None
.
empty = None
Boolean hodnoty v Pythone¶
Boolean hodnoty True
a False
sú základné typy v Pythone, ktoré sa používajú hlavne na testovanie podmienok. Tieto hodnoty sa môžu kombinovať pomocou logických operátorov ako or
, and
, a not
.
not
sa používa na negáciu výrazu, tzn. zmení hodnotu True na False a naopak.and
je operátor, ktorý vrátiTrue
iba v prípade, že obidve podmienky sú pravdivé.or
vrátiTrue
, ak je aspoň jedna z podmienok pravdivá.
not (10 < 20 and 30 > 20) # False
Porovnávacie operátory:
==
(rovná sa)!=
(nerovná sa)<
,>
,<=
,>=
(menšie, väčšie alebo rovné)is
ais not
sú používané na porovnávanie identít objektov (nie hodnoty), čo je dôležité pri práci s prázdnymi hodnotami, akoNone
.
answer = False
answer is not None # True
Čísla v Pythone¶
V Pythone môžete používať bežné aritmetické operácie ako +
, -
, *
, /
, //
(celé delenie), %
(zvyšok po delení), a **
(mocnina).
V Pythone 3.x je delenie dvoch čísel (aj celých) vždy desatinné. Ak chcete zachovať desatinné číslo ako výsledok, nie je potrebné špeciálne pridať .0
pred čísla. Pokiaľ však vykonávate celočíselné delenie, používajte operátor //
na získanie iba celočíselného výsledku.
result = 50 / 4 # 12.5
result
Tento výpočet vráti 12.5, pretože Python automaticky poskytuje desatinný výsledok.
Ak chcete dostať celočíselný výsledok (tzn. bez desatinnej časti), použite operátor //
:
result_int = 50 // 4 # 12 (celé delenie)
result_int
# Delenie a celočíselné delenie
result = 17 / 3 # Výsledok: 5.666666666666667 (desatinné delenie)
result_int = 17 // 3 # Výsledok: 5 (celé delenie)
result_mod = 17 % 3 # Výsledok: 2 (zvyšok po delení)
# Mocnina
result_pow = 3 ** 2 # Výsledok: 9 (mocnina)
result_sqrt = 9 ** 0.5 # Výsledok: 3.0 (mocnina s desatinným exponentom, odmocnina)
# Záporné exponenty
result_inv = 3 ** -1 # Výsledok: 0.3333333333333333 (inverzné číslo)
Pre prácu s nekonečnými hodnotami môžete použiť špeciálnu hodnotu float("inf")
alebo float("-inf")
.
float("-inf") < -999999 # = True
Reťazce¶
Reťazce môžete zadávať do jednoduchých apostrofov alebo úvodzoviek. Ohraničujúce znaky ' a " môžete do reťazca vložiť cez postupnosť \'
resp. \"
ak je reťazec ohraničený úvodzovkami. Podobne môžete do reťazca vložiť znak pre nový riadok \n
, tabulátor \t
alebo samotný znak \ ako \\
. V Interpretereri sa reťazce zobrazia tak ako ich zapíšete aj s úvodnými apostrofmi, na výpis hodnôt preto používajte funkciu print([reťazec])
.
s = '"Isn\'t," she said.'
print(s)
# môžete definovať aj prázdny reťazec
s = ""
print(s)
Použitie trojitých úvodzoviek¶
Trojité úvodzovky sa bežne používajú na:
- Viacriadkové reťazce: Ak potrebujete definovať reťazec, ktorý má viacero riadkov, môžete ho jednoducho obklopiť trojitými úvodzovkami.
- Dokumentačné reťazce (docstrings): V Pythone sa trojité úvodzovky používajú na písanie dokumentácie funkcií, tried a modulov. Tento štýl je rozpoznávaný nástrojmi na generovanie dokumentácie (napr. Sphinx) a je súčasťou Python PEP 257 štandardu.
Viacriadkový reťazec¶
s = """first line
second line"""
print(s)
Dokumentačný reťazec (docstring)¶
def greet(name):
"""
This function takes a name as an argument and prints a greeting.
The greeting is returned in the form: "Hello, {name}!"
"""
print(f"Hello, {name}!")
# Zobrazenie docstringu cez help()
help(greet)
Help on function greet in module __main__: greet(name) This function takes a name as an argument and prints a greeting. The greeting is returned in the form: "Hello, {name}!"
# Zobrazenie docstringu a implementácie funkcie
greet??
Signature: greet(name) Source: def greet(name): """ This function takes a name as an argument and prints a greeting. The greeting is returned in the form: "Hello, {name}!" """ print(f"Hello, {name}!") File: /tmp/ipykernel_84/3527432504.py Type: function
Trojité úvodzovky umožňujú aj pridanie nových riadkov do kódu, čím sa zlepšuje čitateľnosť, najmä v prípade dlhších reťazcov alebo dokumentačných reťazcov, ktoré poskytujú informácie o funkcii alebo triede.
# reťazce môžete spájať cez + alebo opakovať cez *
s = "Py"
print(s + "thon is c" + 3*"oo" + "l") # = Python is cooooool
Takmer všetky objekty a hodnoty viete previesť na reťazec funkciou str([hodnota])
.
print("Py" + str(123) + str(True)) # = Py123True
Reťazec môžete previesť na celé číslo funkciou int([reťazec])
a na desatinné float([reťazec])
. Ak sa reťazec nedá previesť na číslo, príkaz skončí chybou ValueError
.
(1 + int("1")) / float("2.0") # = 1.0
float("123,45") # Tento reťazec obsahuje čiarku, čo je neplatné pre Python (v Python sa používa bodka ako desatinný oddeľovač).
K jednotlivým znakom reťazca môžete pristupovať cez zápis reťazec[index]
.
s = "Python"
print(s[1]) # = y - indexovanie je od 0
print(s[-3]) # = h - záporné indexy počítajú znaky od posledného, t.j, -1, posledný znak, -2 predposledný atď.
Podreťazce môžete zadať ako rozsah znakov [od:do]
(vyberú sa znaky vrátane indexu od, bez do).
s[2:5] # vypíše ‘tho’ - podreťazec od 3 znaku do 5 (vrátane, indexovanie je od 0)
s[:5] # vypíše ‘Pytho’ – podreťazec od začiatku po 5 znak (vrátane, indexovanie je od 0)
s[-2:] # vypíše ‘on’ – podreťazec od predposledného znaku do konca
Ak sa pokúsite pristupovať ku znakom mimo rozsahu, príkaz skončí chybou IndexError: string index out of range
. Reťazce sú v Pythone nemenné, takže napr. nemôžete zmeniť 2 znak zápisom s[1] = 'i'
. Dĺžku reťazca vráti funkcia len(s)
.
s[1] = 'i'
len(s) # = 6 (s = 'Python')
Samotné reťazce sú objekty, ktoré majú definované rôzne metódy slúžiace na transformáciu znakov, vyhľadávanie podreťazcov, rozdeľovanie a pod. Všetky metódy vracajú nový reťazec a pôvodný reťazec zostane nezmenený. Nasledujúca tabuľka uvádza prehľad niektorých metód.
Príkaz | Popis |
---|---|
s.lower() |
Prevedie všetky písmená reťazca na malé. |
s.upper() |
Prevedie všetky písmená reťazca na veľké. |
s.strip() |
Odstráni zo začiatku a konca reťazca prázdne znaky (medzery, tabulátory a znaky konca riadka). |
s.find(sub) |
Vráti index prvého výskytu podreťazca sub , alebo -1 ak sa sub v reťazci nevyskytuje. Voliteľne môžete zadať počiatočný index od ktorého sa začne reťazec prehľadávať s.find(sub, start) , alebo rozsah indexov v ktorom sa musí nachádzať celý podreťazec s.find(sub, start, end) . |
s.replace(old, new) |
Nahradí v reťazci všetky výskyty reťazca old za new . |
s.startswith(preffix) |
Vráti True ak reťazec začína zadaným prefixom, inak vráti False . |
s.endswith(suffix) |
Vráti True ak reťazec končí zadaným sufixom, inak vráti False . |
s.split(sep) |
Rozdelí reťazec podľa zadaného oddeľovača sep a vráti zoznam rozdelených podreťazcov (pozri ďalšiu kapitolu o zoznamoch). Ak sa parameter sep vynechá, s.split() rozdelí reťazec podľa prázdnych znakov. |
s.join(args) |
Prevedie prvky zoznamu alebo n-tice args na reťazec a spojí ich oddeľovačom s (pozri ďalšiu kapitolu o zoznamoch). |
# volanie viacerých metód môžete zreťaziť
print(" Python \t".strip().upper().replace("PY", "py")) # = pyTHON
# pri vyhľadávaní podreťazcov môžete zadať aj rozsah s negatívnymi indexami
"one two one".find("one", -5) # = 8 - index druhého výskytu, vyhľadávaný text musí byť medzi poslednými 5 znakmi
Formátovanie správ¶
Pre formátovanie správ, ktoré zobrazujú rôzne typy hodnôt je výhodné použiť metódu s.format(arg0, arg1, arg2, ...)
ktorá prevedie hodnoty argumentov na reťazce a nahradí nimi v reťazci s
formátovacie polia ohraničené {}
. V nasledujúcom príklade sa v reťazci "Hello {0}..."
nahradí formátovacie pole {0}
za reťazec "world"
, ktorý sme predali priamo pri volaní metódy format
ako prvý parameter.
print("Hello {0}...".format("world")) #= Hello world...
Viac informácií o formátovaní nájdete v nasledujúcom príklade, alebo tu (v angličtine).
# polia môžete použiť na odsadzovanie textu medzerami nasledujúcim zápisom:
print("{0:>20}".format("right text")) # pridané nastavenie :>20 odsadí text medzerami doprava tak aby mal celkovo 20 znakov
# podobne zápis :<n doplní medzery za text tak aby mal celkovo n znakov (odsadenie doľava)
print("{0:<20}{1}".format("left", "text")) # vo formátovacom reťazci sme definovali dve polia, do prvého sa sformátuje hodnota "left" a do druhého "text"
# text môžete aj vycentrovať
print("{0:^30}".format("center")) # riadok je celkovo široký 30 znakov
# na miesto medzery môžete definovať vlastný znak pre doplnenie za : (to platí aj pre zarovnávanie doprava a doľava)
print("{0:*^30}".format("center")) # doplníme text znakom * namiesto medzery
# celé čísla môžete zapísať v desiatkovej, hexadecimálnej, osmičkovej alebo binárnej reprezentácii
print("{0:d}, hex: {0:x}, oct: {0:o}, bin: {0:b}".format(42)) # = ‘42, hex: 2a, oct: 52, bin: 101010’
# pri desatinných číslach môžete definovať koľko desatinných miest za čiarkou sa má vypísať
print("{0:.3f}".format(3.141592654)) # vypíše iba ‘3.142’ (5 sa zaokrúhľuje smerom hore)
Podrobnejší popis ďalších metód pre reťazce nájdete tu (v angličtine).
Vetvenia¶
Vetvenia slúžia na vykonávanie postupnosti (bloku) príkazov iba pri splnení určitej podmienky.
number = 42
# podmienkou príkazu if môže byť ľubovoľný výraz, ktorý sa vyhodnotí ako Boolovská hodnota
# môžete napr. používať operátory <, >, <=, >=, ==, !=, ‘in’ (testovanie či objekt obsahuje daný prvok) a
# kombinovať ich logickými spojkami and, or, not
if number < 0:
print("negative")
number = 0 # podmienený blok môže obsahovať viacero príkazov, ktoré musia byť správne odsadené
else: # vetva ‘else’ je nepovinná
print("zero or positive")
# = zero or positive
Viacero podmienok môžete zreťaziť klauzulou elif
(zreťazenie cez elif
nahradzuje v Pythone príkaz switch/case
z jazyka C)
if number < 0:
number = 0
print("negative number, reset to 0")
elif number == 0:
print("zero")
elif number == 1:
print("single")
else:
print("more")
# = more
Pre jednoduché podmienené priradenie môžete použiť skrátený zápis podobný ternárnemu príkazu z C ?:
Hodnota1 if podmienka else hodnota2
- výraz sa rovná hodnota1
ak je podmienka splnená, alebo hodnota2
ak je nesplnená.
result = "negative" if number < 0 else "positive or zero"
result # = positive or zero
Odsadzovanie kódu¶
Odsadzovanie kódu medzerami, alebo tabulátorom na začiatku riadku je v Pythone veľmi dôležité, pretože definuje ako sú príkazy do seba vnorené a spojené do blokov. Napr. nasledujúci kód skončí chybou IndentationError: expected an indented block:
number = 42
if number < 0:
print("negative value") # chyba! vnorené príkazy musia byť odsadené na novom riadku aspoň jednou medzerou alebo tabulátorom
Interpreter očakáva za podmienkou príkazu if
aspoň jeden ďalší príkaz, ktorý sa vykoná ak je podmienka splnená. Keďže príkaz print('negative value')
nie je na začiatku riadku odsadený žiadnou medzerou alebo tabulátorom, Interpreter ho považuje za príkaz, ktorý by mal nasledovať za if
, a príkaz if
bude považovať za neukončený. Podobne, nasledujúci kód je logicky chybný keďže sa správa negative number, reset to 0
vypíše aj pre nezáporné čísla. Aby bol príkaz print
vykonaný iba pri splnení podmienky, musí byť odsadený do rovnakého bloku ako number = 0
.
number = 42
if number < 0:
number = 0
print("negative number, reset to 0") # logická chyba! ak sa má správa vypísať iba pre záporné čísla,
# musí byť príkaz rovnako odsadený ako number = 0
if number < 0:
number = 0
print("negative number, reset to 0") # chyba! odsadenie musí byť rovnaké pre všetky príkazy v jednom bloku
Cykly¶
Cykly slúžia na opakované vykonávanie bloku príkazov. Python podporuje cyklus while
, ktorý vykonáva vnorený blok príkazov, pokiaľ je splnená zadaná podmienka; a cyklus for
, ktorý slúži na postupné spracovanie prvkov (iterovanie) v kolekcii objektov (napr. zoznamov).
i = 0
while i < 10: # cyklus `while` vykonáva vnorený blok príkazov pokiaľ je podmienka splnená.
print(i)
i += 1 # skrátený zápis i = i + 1 (Python nepodporuje operátor ++/-- z jazyka C)
# ‘for‘ cyklus sa používa na postupné prechádzanie prvkov
numbers = [1, 2, 3]
# napr. pre zoznam, za ‘for’ definujete názov premennej, do ktorej budú postupne dosadené všetky prvky zoznamu
for x in numbers:
print(x)
print("x={0}".format(x)) # po iterovaní je premenná definovaná aj mimo bloku cyklu a má nastavenú poslednú hodnotu
# ak chcete naraz vypísať index a hodnotu, môžete použiť funkciu enumerate()
for i, v in enumerate(["tic", "tac", "toe"]):
print(i, v) # do i je priradený index (od 0) a do v hodnota
# ak budete počas iterovania pridávať alebo odoberať nejaké hodnoty zo zoznamu, je bezpečnejšie pre iterovanie urobiť jeho kópiu
for x in numbers[:]: # vytvoríme kópiu cez rozsah [:]
numbers.append(x * x) # pridáme na koniec zoznamu druhé mocniny
print(numbers) # = [1, 2, 3, 1, 4, 9]
Pre jednoduché iterovanie si môžete vygenerovať postupnosť čísel pomocou funkcie range()
, napr.:
for x in range(10): # vygeneruje sa postupnosť [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(x)
# ako argument funkcie range() môžete voliteľne zadať aj počiatočnú hodnotu a krok
range(3, 7) # = [3, 4, 5, 6]
range(10, 4, -2) # = [10, 8, 6] - v obrátenom poradí bez poslednej hodnoty
Pre prerušenie cyklu, alebo pre preskočenie kódu a pokračovanie ďalšou iteráciou sa používajú príkazy break
a continue
, ktoré fungujú podobne ako v jazyku C (môžete ich použiť aj v cykloch while
).
for x in range(1, 10):
if x % 2 == 0:
print("continue for even number")
continue # pre párne čísla sa pokračuje nasledujúcou iteráciou a ďalšie príkazy v cykle sa preskočia
if x == 5:
break # cyklus sa preruší pri x == 5 (pri vnorených cykloch ‘break’ preruší iba najbližší cyklus)
print(x)
# vypíše sa:
# 1
# continue for even number
# 3
# continue for even number