Cvičení č. 4 rozšířené o poznámky ze cvičení a řešení některých příkladů (ZS 2024/25)¶
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
,float
a konstantNone
,True
,False
. - Importování modulu
math
a 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)
c = complex(input("zadej komplexni cislo:"))
c
(1+3j)
j = 9
c = 2 + 1j
d = 2 + j
print(c, type(c), d)
(2+1j) <class 'complex'> 11
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)
3 1j
c1 = 1 - 2j
c2 = complex(3,4)
print(c1 + c2, c1 - c2, c1 * c2, c1 / c2, c1 ** 0.5)
# c1 % c2
(4+2j) (-2-6j) (11-2j) (-0.2-0.4j) (1.272019649514069-0.7861513777574233j)
c1.real
1.0
c1.imag
-2.0
d = c1.conjugate()
d
(1+2j)
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í.
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 = 1 + 2j
print("reálná část:", c.real)
print("imaginární část:", c.imag)
print("komplexně sdružené číslo:", c.conjugate())
reálná část: 1.0 imaginární část: 2.0 komplexně sdružené číslo: (1-2j)
Příklady¶
- Napište program, který spočítá vzdálenost dvou komplexních čísel.
import math
c1 = 1 - 3j
c2 = 2 + 4j
c = c1 - c2
print(c)
# varianta c
vzdálenost = math.sqrt(c.real ** 2 + c.imag ** 2)
print("Vzdlenost", c1, "a", c2, "je", vzdálenost)
vzdálenost = (c.real ** 2 + c.imag ** 2) ** (1/2)
print("Vzdlenost", c1, "a", c2, "je", vzdálenost)
(-1-7j) Vzdlenost (1-3j) a (2+4j) je 7.0710678118654755 Vzdlenost (1-3j) a (2+4j) je 7.0710678118654755
# varianta b
vzdálenost = math.sqrt((c * c.conjugate()).real)
print("Vzdlenost", c1, "a", c2, "je", vzdálenost)
vzdálenost = (c * c.conjugate()) ** (1/2)
vzdálenost = vzdálenost.real
print("Vzdlenost", c1, "a", c2, "je", vzdálenost)
vzdálenost = ((c * c.conjugate()) ** (1/2)).real
print("Vzdlenost", c1, "a", c2, "je", vzdálenost)
import cmath
vzdálenost = cmath.sqrt((c * c.conjugate())).real
print("Vzdlenost", c1, "a", c2, "je", vzdálenost)
Vzdlenost (1-3j) a (2+4j) je 7.0710678118654755 Vzdlenost (1-3j) a (2+4j) je 7.0710678118654755 Vzdlenost (1-3j) a (2+4j) je 7.0710678118654755 Vzdlenost (1-3j) a (2+4j) je 7.0710678118654755
# varianta a
vzdálenost = abs(c1-c2)
print("Vzdálenost", c1, "a", c2, "je", vzdálenost)
Vzdálenost (1-3j) a (2+4j) je 7.0710678118654755
- 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".)
import math
a = math.pi
b = 2
c = 1
diskriminant = b * b - 4 * a * c
print(diskriminant)
-8.566370614359172
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)
kořeny: (-0.3183098861837907+0.4658204617032757j) (-0.3183098861837907-0.4658204617032757j) kořeny: (-0.31830988618379064+0.4658204617032757j) (-0.31830988618379075-0.4658204617032757j)
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
,Ahoj
aAHOJ
tedy 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
,None
a 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
.
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:
a = 1
b = a + 2
a = 7
a = "abc"
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.
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:
a = print
a("ahoj")
ahoj
print = ("ahoj")
print("a")
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[14], line 1 ----> 1 print("a") TypeError: 'str' object is not callable
print = a
print("a")
a
a = print
print = "Hello, world!"
a(print)
print = a
Hello, world!
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:
a = 0
a = a + 1
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í.