Cvičení č. 2 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...¶
- základní pojmy – počítač, program, algoritmus
- základní vlastnosti programovacích jazyků
- představení prostředí Python a Jupyter
První programátorské prvky, které jsme si ukázali:
Python jako kalkulačka¶
- matematické výrazy obsahující čísla, ( , ), operátory + , - , *, / , ** , // , % , proměnné
- pořadí vyhodnocení operátorů je celkem intuitivní (pokud nevím, mrknu se do dokumentace nebo použiji závorky)
- kód v buňce (nebo v konzoli) spustím např. pomocí
Shift enter
- interpret Pythonu pracuje ve smyčce:
- načti vstup - vyhodnoť výraz - vypiš výsledek
4 + (5 - 6) * -7.4
11.4
2 ** 0.5 # mocnina
1.4142135623730951
13 / 5 # dělení
2.6
13 // 5 # celočíselné dělení
2
13 % 5 # zbytek po celočíselném dělení
3
- v buňkách může být buď text (ve formátu Markdown) nebo zdojový kód (Python)
- pokud omylem nastavíme typ buňky jako Markdown, kód se po spuštění neprovede (ale bere se jako text ve formátu Markdown):
x = 8 x
- a teď správně:
x = 8
x
8
- Použití funkce
print
pro výpis textu, případně více hodnot:- může mít více parametrů, pak vypíše výsledky za sebe na jeden řádek oddělené mezerou, na konci odřádkuje
- Volání funkce:
název_funkce (parametry oddělené čárkou)
, např.print(x, y, z)
print("Hello, world!")
print("Výsledek je", 42)
print(67 + 6, 5/4, "a") # každý z výrazů se vyhodnotí, vypíší se výsledky
# pro pokročilé:
print(67 + 6, 5/4, "a", sep = "_") # oddělovač nebude mezera, ale "_"
Hello, world! Výsledek je 42 73 1.25 a 73_1.25_a
- Zápis jednoduchých matematických výrazů:
print(1 + 2 * 3 - 4 / 5)
6.2
- Používání proměnných:
# proměnná umožňuje uchovat hodnotu pro další použití
a = 1
b = 2
c = 2 * (a + b)
d = "ahoj"
print(a, b, c, d)
1 2 6 ahoj
# hodnotu proměnné můžeme měnit:
b = 6
b = b + 3
b = b // 2
b
4
# zkuste spustit opakovaně:
b = b * 2
b
120
# operátory můžeme psát zkráceně:
b = 6
# b = b - 3
b -= 3
print(b)
# b = b * (8 - 3)
b *= 8 - 3
b
3
15
b = 6
b -= 3
b *= 8 - 3
b
15
# příklad: zkuste si spočítat v hlavě:
a = 14
a += 1
a /= 3
a %= 3
a
2.0
# vícenásobné přiřazení:
x = y = z = 7
# x += 1
print(x, y, z)
x, y, z = 3, 3.5, "a"
print(x, y, z)
7 7 7 3 3.5 a
- názvy proměnných : písmena, číslice, '_' , prvním znakem nesmí být číslice, v názvech proměnných nesmí být mezery
8x = 7
Cell In[51], line 1 8x = 7 ^ SyntaxError: invalid decimal literal
a1 = 8
d_min = 89
# program je přehlednější, pokud proměnné mají smysluplné názvy
# pro psaní víceslovných názvů platí různé konvence:
žirafy = 8
hroši = 7
celkem_zvířat = žirafy + hroši
#celkemZvířat
#print("V Zoo máme", celkem_zvířat, "zvířat.", sep = "_")
print("V Zoo máme", celkem_zvířat, "zvířat.")
# je pohodlnější používat angličtinu :-)
V Zoo máme 15 zvířat.
- Použití funkce
input
pro přečtení uživatelského vstupu ve formě textu:
x = input()
print(x)
ahoj
# pozor, funkce input vrací textový řetězec (str), pokud chci číslo, musím hodnotu tzv. přetypovat
text = input("Zadej text:")
print("Zadal jsi", text)
text
Zadal jsi 67
'67'
text + 7
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[3], line 1 ----> 1 text + 7 TypeError: can only concatenate str (not "int") to str
int(text) + 7
74
x = input("Zadej číslo:")
x1 = int(x)
x2 = float(x)
y = x1 + 7
print(x, x1, x2)
print(y)
# Každá proměnná má nějaký datový typ
# Typ proměnné zjistím pomocí funkce type()
print(type(x), type(x1), type(x2))
78 78 78.0 85 <class 'str'> <class 'int'> <class 'float'>
# Zkrácený zápis:
x = input("1.Zadej číslo:")
x = int(x)
print(x)
x = int(input("2. Zadej číslo:"))
print(x)
# teoreticky by šlo i toto (ale není to pěkné):
print(int(input("3. Zadej číslo:")))
1
2
3
# operátory dělají různé věci pro různé datové typy:
x = "45" # str
print(x + x, 3 * x)
x = 45 # int
print(x + x, 3 * x)
4545 454545 90 135
Příklady na procvičení¶
- Napište program, který spočítá a vypíše počet sekund v roce.
vteřin = 365 * 24 * 60 * 60
print("V roce je",vteřin, "vteřin.")
V roce je 31536000 vteřin.
- Napište program, který spočítá cenu nafty potřebné na cestu osobním autem z Prahy do Ostravy a zpět. Vzdálenost po dálnici D1 je $380~km$, auto má průměrnou spotřebu $5.1~l/100~km$ a aktuální cena nafty je $35.90~Kč/l$. Pro jaký minimální počet cestujících je cesta autem výhodnější než cesta vlakem?
# druhý příklad
vzdalenost = 380
spotřeba_l_za_100_km = 5.1
cena_za_litr = 35.9
# celkova cena = celkova spotreba (v litrech) * cena (za litr)
# celkova spotreba = celkova vzdalenost v km * spotřeba za km
celková_spotřeba = (vzdalenost * 2) * (spotřeba_l_za_100_km / 100)
celková_cena = celková_spotřeba * cena_za_litr
print("Cena nafty je", celková_cena, ".")
Cena nafty je 1391.484 .
# druhy podpriklad
cena_jízdenky = 500
# cena_jízdenky = input("Jaka je cena zpáteční jizdenky z Prahy do Ostravy?")
print(celková_cena / cena_jízdenky)
autem_lépe = celková_cena // cena_jízdenky + 1
autem_lépe = int(autem_lépe)
print("Jízda autem se vyplatí", autem_lépe, "lidem.")
2.782968 Jízda autem se vyplatí 3 lidem.
Efektivní používání klávesnice¶
Ačkoliv programátoři tráví více času čtením existujícího kódu než psaním nového kódu, je potřeba naučit se používat klávesnici efektivním způsobem. Není totiž nic trapnějšího, než když přijdete za kolegou diskutovat svůj kód a při první úpravě nemůžete na klávesnici najít středník, složenou závorku nebo libovolný jiný znak... Proto zde uvádíme přehled užitečných klávesových zkratek a dalších triků.
Také velmi doporučujeme procvičit si psaní všemi deseti, bude se vám to hodit nejen při programování.
Používání klávesnice závisí na rozložení kláves. V ČR jsou populární rozložení CZ QWERTZ, US a Česká programátorská klávesnice. Každé rozložení kláves navíc umožňuje psát speciální znaky pomocí různých kombinací kláves – tyto kombinace se ale liší v závislosti na operačním systému a samozřejmě na zvoleném rozložení kláves.
V případě používání české klávesnice (rozložení CZ) doporučujeme pro usnadnění programování a zrychlení psaní používat následující klávesové zkratky využívající klávesu AltGr:
AltGr
+x
→#
AltGr
+v
→@
AltGr
+b
→{
AltGr
+n
→}
AltGr
+,
→<
AltGr
+.
→>
AltGr
+f
→[
AltGr
+g
→]
V systému Linux navíc fungují následující zkratky využívající horní řadu znaků s diakritikou (speciální znaky jsou na těchto klávesách spolu s číslicemi nakresleny pro snazší zapamatování):
AltGr
+ě
→@
AltGr
+š
→#
AltGr
+č
→$
AltGr
+ř
→%
AltGr
+ž
→^
AltGr
+ý
→&
AltGr
+á
→*
AltGr
+í
→{
AltGr
+é
→}
Pod ostatními klávesami se skrývají další, i když méně užitečné speciální znaky.
Data v paměti počítače¶
Každý program pracuje s daty: čte vstupní data, produkuje výstupní data a v průběhu zpracování používá paměť počítače pro uchování přechodných dat. Ačkoliv uživateli jsou data většinou zobrazena v takovém formátu, se kterým dokáže člověk snadno pracovat, počítač pracuje pouze s daty zakódovanými ve dvojkové (binární) soustavě. Dále je nutné si uvědomit, že záleží na tom, které kódování je pro danou hodnotu použito, protože různé hodnoty s použitím různých kódování můžou mít stejnou binární reprezentaci (viz příklady níže).
Bez ohledu na způsob kódování je binární kód charakterizován tím, že v něm vystupují pouze číslice 0 a 1. Nejmenší jednotka informace je bit (zkratka z anglického binary digit) a skupina 8 bitů představuje 1 bajt (anglicky byte).
Paměť počítače je fyzicky uzpůsobena tak, že umožňuje adresovat jednotlivé bajty a procesor počítače používá instrukce, které zpracovávají celé skupiny bajtů. V dnešní době jsou nejčastější procesory, které využívají 64-bitové instrukce.
Kódování celých čísel¶
Přirozená čísla zapisujeme ve dvojkové soustavě, která funguje podobně jako desítková soustava – je to poziční číselná soustava o základu 2 s číslicemi 0 a 1. Pro převod ze dvojkové soustavy do desítkové se používá substituční metoda) a převod z desítkové soustavy do dvojkové se používá metoda dělení základem. Pro kódování záporných čísel se nejčastěji používá dvojkový doplněk.
Kódování znaků¶
Základní metoda pro binární reprezentaci textu jakožto posloupnosti znaků využívá tzv. ASCII tabulku, která každému znaku vystupujícímu v tabulce přiřazuje unikátní binární kód. Je to původně 7-bitový kód obsahující 128 platných znaků, ale pro praktické účely se každý zakódovaný znak doplňuje jedním nevyužitým bitem, aby v posloupnosti každému znaku odpovídal jeden bajt.
V současné době je nejčastější kódování UTF-8, které je zpětně kompatibilní (každý ASCII kód je platný UTF-8 kód) a umožňuje kódovat $2^{31}$ znaků, čili pokrývá celou znakovou sadu Unicode.
Kódování "reálných" čísel¶
Výše uvedené způsoby kódování celých čísel a znaků jsou bezeztrátové, čili opakovaným převodem hodnoty do binární soustavy a zpět dostaneme přesně původní hodnotu. Je ale problém najít prakticky užitečné kódování reálných čísel do binární soustavy, které by bylo bezeztrátové. Problém spočívá v tom, že např. číslo 0.3 má konečný rozvoj v desítkové soustavě, ale nekonečný rozvoj ve dvojkové soustavě. Při převodu se tedy musíme uchýlit k aproximaci – musíme provést zaokrouhlení tak, aby výsledná hodnota obsahovala daný počet bitů.
K dalším problémům dochází při vyhodnocování aritmetických operací. Pokud např. při součtu dvou "reálných" čísel ve dvojkové soustavě obsahuje správný výsledek větší počet bitů než je povoleno pro dané kódování, musíme opět provést zaokrouhlení a výsledek je špatně. Lze tedy říci, že většina výpočtů s "reálnými" čísly v počítači probíhá nepřesně. Problémům s přesností počítačové aritmetiky se nebudeme dále věnovat, podrobnosti můžete najít např. na stránce Floating Point Arithmetic: Issues and Limitations.
Příklady¶
- desítková reprezentace binárního čísla 11:
3
- binární reprezentace čísla 11:
1011
- binární reprezentace textového řetězce "11" podle ASCII kódování:
0011000100110001
- desítková reprezentace binárního čísla 0011000100110001:
12593
- 64-bitová binární reprezentace hodnoty
1.0
podle standardu IEEE 754:11111111110000000000000000000000000000000000000000000000000000
Datové typy a zadávání hodnot v Pythonu¶
1/3 * 3
1.0
1/6 + 1/6 + 1/6 + 1/6+ 1/6 + 1/6
0.9999999999999999
Zatím jsme viděli tyto typy objektů v Pythonu:
- text (např.
"Hello, world!"
) - číslo
- celé číslo (např.
0
,1
, atd.) - "reálné" číslo (např.
1.5
)
- celé číslo (např.
Pokud použijeme funkci input
, výsledek je vždy textový objekt, i když uživatel zadá číslo.
Pokud chceme získat číselný objekt, musíme použít příslušnou funkci, která získá číselnou hodnotu z textu:
- funkce
int
vrátí celé číslo:a = int(input("Zadej číslo:")) print(a * 2)
- funkce
float
vrátí "reálné" číslo:a = float(input("Zadej číslo:")) print(a * 2)
K zamyšlení a vyzkoušení: Co se stane, když uživatel nezadá číslo, ale něco jiného? Co se stane, když zadá několik čísel oddělených mezerou nebo čárkou?
x = input("zadej číslo: ")
x = int(x)
x = float(input("zadej číslo: "))
x
78.0
y = int(x)
z = float(x)
print(x, y, z)
print(type(x), type(y), type(z))
6 6 6.0 <class 'str'> <class 'int'> <class 'float'>
Nyní si procvičíme programování na několika příkladech. K datovým hodnotám a zadávání čísel se vrátíme ještě podrobněji na příštím cvičení...
Příklady¶
- Napište program, který se zeptá uživatele na kladné číslo a spočítá obvod a obsah čtverce, který má délku strany rovnou zadané hodnotě.
# je dobré si to rozdělit na 3 části: načst zadání, spočítat výsledek, vypsat výsledek
a = input("Zadej délku strany:")
a = float(a)
# mohu zkratit na jeden řádek:
# a = float(input("Zadej délku strany:"))
o = 4 * a
s = a * a
print("Obvod čtverce o délce strany", a, "je", o,"a jeho obsah je", s,".")
# pro pokročilé:
print(f"Obvod čtverce o délce strany {a} je {o} a jeho obsah je {s}.")
Obvod čtverce o délce strany 4.0 je 16.0 a jeho obsah je 16.0 . Obvod čtverce o délce strany 4.0 je 16.0 a jeho obsah je 16.0.
- Napište program, který se zeptá uživatele na kladné číslo a spočítá obvod a obsah pravidelného pětiúhelníku, který má délku strany rovnou zadané hodnotě.
Nápověda: odmocnina se dá spočítat pomocí obecné mocniny.
# Obvod pětiúhelníku o délce strany 4.0 je 20.0 a jeho obsah je 27.53.
3a. Napište program, který se zeptá uživatele na jeho výšku a hmotnost. Následně spočítá a vypíše příslušnou hodnotu BMI indexu.
# pozor na správné jednotky, zkontrolujte si výsledek
3b. Rozšiřte předchozí program tak, aby vypsal, jaké je rozmezí optimální (normální) hmotnosti uživatele při jeho výšce.
# jde to i bez podmínek (ty ještě neumíme)