Cvičení č. 4 rozšířené o poznámky ze cvičení a řešení některých příkladů (ZS 2025/26)¶
V minulém díle jste viděli...¶
- Způsob kódování dat v paměti počítače: znaky, celá čísla a "reálná" čísla.
- Použití funkcí
bool,int,floata konstantNone,True,False. - Importování modulu
matha použití matematických konstant a funkci:
import math
print("Číslo π je přibližně", math.pi)
print("Hodnota cos(π) je ", math.cos(math.pi))
Číslo π je přibližně 3.141592653589793 Hodnota cos(π) je -1.0
- Jak odevzdávat úkoly v rozhraní Nbgrader
Typ complex¶
Jazyk Python také umožňuje provádět výpočty s komplexními čísly, která jsou reprezentována pomocí typu complex.
Komplexní číslo má reálnou a imaginární část, přičemž imaginární jednotka se značí suffixem j:
c1 = complex(1, 2)
print("c1 =", c1)
c2 = 1 - 2j
print("c2 =", c2)
c1 = (1+2j) c2 = (1-2j)
x = float(3)
x
3.0
c = complex(3) # stačí jeden parametr
c
(3+0j)
1 - 2j
(1-2j)
1.1 - 2.5j
(1.1-2.5j)
2.5 - 0j
(2.5+0j)
# mezi číslem a znakem 'j' nesmí být mezera a číslo nesmíme vynechat
c1 = 1 + 2 j
Cell In[77], line 2 c1 = 1 + 2 j ^ SyntaxError: invalid syntax
c1 = 1 + j
# načítání komplexních čísel:
c = complex(input("zadej komplexni cislo:"))
c
Pozor na to, že imaginární jednotka j musí vždy následovat bezprostředně za nějakou číslicí, jinak je j syntakticky interpretován jako identifikátor proměnné, který ani nemusí být komplexní číslo.
j = 3
print(j)
print(1j)
j = 9
c = 2 + 1j
d = 2 + j
print(c, d)
print(type(c), type(d))
S hodnotami typu complex můžeme provádět téměř všechny aritmetické operace stejně jako pro typ int, s výjimkou operátoru % (zbytek po celočíselném dělení).
Viz tabulka v předchozím cvičení.
# s komplexními čísli mohu provádět většinu operací jako s celými čísli:
c = 1 - 2j
d = complex(3, 4)
print(c + d, c - d, c * d, c / d)
print(c + 5, c - 1, c * 3, c / 2, c ** 2)
# všechny aritmetické operátory s výjimkou // %
c // d
c % d
Typ complex představuje první složený datový typ, se kterým jsme se setkali.
Hodnoty typu complex jsou složené z reálné a imaginární části, které mají typ float a lze k nim přistoupit pomocí tzv. atributů .real a .imag.
Typ complex dále poskytuje tzv. metodu .conjugate(), která provádí komplexní sdružení.
c = 2 + 1j
c.real
# přímý převod z complex na int/float nejde:
int(c)
c.imag
d = c.conjugate()
d
x = (2-8j).conjugate()
print(x, type(x))
c = 1 + 2j
print("reálná část:", c.real)
print("imaginární část:", c.imag)
print("komplexně sdružené číslo:", c.conjugate())
# modul cmath .. obdoba modulu math pro komplexní čísla
import math
math.sqrt(-1) # chyba
cmath.sqrt(-1)
cmath.sqrt(-25)
cmath.sqrt(1-1j)
(-1) ** 0.5 # funguje, vrací typ complex
# pozorujeme zaokrouhlovací chybu
Příklady¶
- Napište program, který spočítá vzdálenost dvou komplexních čísel.
# vzdalenost = abs(c - d)
# abs(z=a+bi)= sqrt(a^2+b^2) = sqrt(z * komplexně sdružené číslo k z)
c = 1 + 2j
d = 3 - 1j
# input na nacteni
c = complex(input("zadej prvni cislo"))
d = complex(input("zadej druhe cislo"))
print(c, d)
# 1. výpočet pres pres násobení čísla s číslem komplexne sdruzenym, z.conjugate()
z = c - d
vysledek = (z * z.conjugate()) ** (1 / 2) # pozor na uzávorkování!
vysledek = (z * z.conjugate()) ** 0.5
vysledek = vysledek.real
print("Výsledek je", vysledek)
import cmath
z = c - d
vysledek = cmath.sqrt(z * z.conjugate())
vysledek = vysledek.real
print("Výsledek je", vysledek)
# 2. výpočet pomocí atributů z.imag, z.real
z = c - d
vysledek = (z.real ** 2 + z.imag ** 2) ** (1 / 2) # pozor na uzávorkování!
print("Výsledek je", vysledek)
import math
z = c - d
vysledek = math.sqrt(z.real ** 2 + z.imag ** 2)
print("Výsledek je", vysledek)
# 3. výpočet pomocí funkce abs()
vzdálenost = abs(c-d)
print("Vzdálenost", c, "a", d, "je", vzdálenost)
- Použijte jazyk Python pro vyřešení kvadratické rovnice $\pi x^2 + 2x + 1 = 0$. (Řešení tohoto příkladu nemusí být univerzální program, stačí posloupnost příkazů s výpočty, které byste prováděli "na papíře".)
# 1. spočteme diskriminant
import math
a = math.pi
b = 2
c = 1
diskriminant = b * b - 4 * a * c
print(diskriminant)
# 2. spočteme kořeny
# protože je diskriminant záporný, bude mít rovnice komplexní kořeny:
x1 = -b/(2*a) + 1j * math.sqrt(-diskriminant)/(2*a)
x2 = -b/(2*a) - 1j * (-diskriminant)**0.5/(2*a)
print("kořeny:", x1, x2)
x1 = -b/(2*a) + diskriminant**0.5/(2*a)
x2 = -b/(2*a) - diskriminant**0.5/(2*a)
print("kořeny:", x1, x2)
x1 = -b/(2*a) + diskriminant**0.5/(2*a)
x2 = x1.conjugate()
print("kořeny:", x1, x2)
Práce s proměnnými v Pythonu¶
Pojem proměnná (anglicky variable) představuje oblast v paměti počítače, která je vyhrazena pro uložení odkazu na nějakou hodnotu, kterou si chceme zapamatovat. Abychom mohli s proměnnými v programech pracovat, musíme je pojmenovat. Kdykoliv potom v kódu použijete název proměnné, interpret zařídí dosazení hodnoty, na kterou se daná proměnná odkazuje.
Pojem identifikátor představuje název proměnné, který vystupuje ve zdrojovém kódu. V Pythonu platí pro identifikátory následující pravidla:
- Smějí obsahovat písmena, číslice a podtržítka.
- Nesmějí začínat číslicí.
- Rozlišuje se v nich velikost písmen. Identifikátory
ahoj,AhojaAHOJtedy představují různé proměnné. - Nesmějí být shodné s některým klíčovým slovem, což jsou slova, která mají v jazyce speciální význam.
Zatím jsme potkali tato klíčová slova:
True,False,Nonea k dalším se dostaneme později. Jejich seznam není potřeba se učit nazpaměť – v nových verzích jazyka se postupně rozšiřuje a pokud byste náhodou porušili toto pravidlo, interpret vám oznámí syntaktickou chybu.
Nejdůležitější zásadou je volit názvy proměnných tak, aby co nejlépe naznačovaly jejich účel a aby se při čtení kódu člověkem nepletly s ostatními názvy používanými v programu.
Nejběžnější konvence pro pojmenování proměnných v Pythonu používá pouze malá písmena a znak _ pro spojení více slov: proměnná_s_dlouhým_názvem.
True = 7 # toto je chyba
abs = 7 # toto není chyba, ale ztratíme tak referenci k vestavěné funkci abs()
print(abs)
abs(8)
Inicializace a předefinování proměnných¶
Novou proměnnou vytvoříme pomocí přiřazovacího operátoru =, kde na levé straně vystupuje nový identifikátor a na pravé straně výraz, který po vyhodnocení inicializuje danou proměnnou:
# definice proměnné:
a = 1
b = a + 2
print(a, b)
a = 5
print(a, b)
Proměnná se však odkazuje výslednou hodnotu inicializačního výrazu, nikoliv na celý výraz.
Pokud bychom např. v předchozí buňce dále změnili hodnotu proměnné a, nemělo by to vliv na proměnnou b.
Pokud již inicializovaná proměnná existuje, tedy název se již odkazuje na nějakou hodnotu, dojde jednoduše ke změně odkazu na novou hodnotu. Při tom může dojít ke změně typu, tedy proměnná není vázána na typ hodnoty použitý při inicializaci.
# pokud do proměnné vložím novou hodnotu, může se změnit její typ:
a = 7
print(a, type(a))
a = "abc"
print(a, type(a))
Jazyk Python pracuje s odkazy na hodnoty, tj. s proměnnými, stejně jako s odkazy na jiné objekty, se kterými se postupně seznámíme. Umožňuje tedy např. vytvářet nové odkazy na funkce a dokonce "předefinovat" existující odkaz na funkci jiným objektem:
# můžeme vytvářet nová jména pro existující funkce, nebo je tzv. "předefinovat":
nahradni_print = print
nahradni_print("ahoj")
print = "nadpis"
nahradni_print(print)
print("ahoj") # chyba
print = nahradni_print
print("ahoj") # už opět funguje
a = print
print = "Hello, world!"
a(print)
print = a
Proměnné a buňky v Jupyter notebooku¶
Seznam aktuálně definovaných proměnných můžeme zobrazit kliknutím na tlačítko (Enable Debugger) v horním panelu a následným zobrazením debuggeru na pravé straně. V rozhraní JupyterLab je zde opět ikona brouka, v rozhraní Jupyter Notebook je tlačítko v menu View → Right Sidebar → Show Debugger.
V prostředí Jupyter se notebooky obsahující buňky s kódem mohou chovat na první pohled nečekaným způsobem. Proměnné definované v jedné buňce totiž po jejím spuštění zůstanou definované v interpretu zpracovávajícího daný notebook a můžou ovlivnit chování při vyhodnocování kódu dále spouštěných buněk. Zkuste například opakovaně spouštět následující dvě buňky v různém pořadí a sledujte stav proměnných v debuggeru:
import cmath
cmath.pi
from math import pi, cos
a = 0
a = a + 1
x = 7
y = 1 + 4j
K zamyšlení: co se stane po restartování kernelu pro tento notebook a spuštění pouze druhé z těchto buněk?
Příklady¶
Dokončete všechny příklady z minulého cvičení.
# viz poznámky ke 3. cvičení
Úvod do podmínek v Pythonu¶
x = 3
if x > 0:
print("x je vetsi nez 0")
print("x je opravdu vetsi nez 0")
print(x)
x je vetsi nez 0 x je opravdu vetsi nez 0 3
x = -1
if x > 0:
print("x je vetsi nez 0")
print("x je opravdu vetsi nez 0")
print(x)
-1
# chyba v odsazení:
x = 3
if x > 0:
print("x je vetsi nez 0")
print("x je opravdu vetsi nez 0")
print(x)
Cell In[82], line 5 print("x je opravdu vetsi nez 0") ^ IndentationError: unexpected indent
# chyba v odsazení:
x = 5
y = 3
print(x, y)
diskriminant = 0
if diskriminant > 0:
print("realne koreny")
print("ahoj")
elif diskriminant == 0:
print("dvojnasobny koren")
else:
print("komplexni koreny")
print(diskriminant)