Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion courses/pyladies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ plan:
materials:
- lesson: git/collaboration
- lesson: git/ignoring
- lesson: beginners/files
- title: Gitový tahák
url: https://pyvec.github.io/cheatsheets/basic-git/basic-git-cs.pdf
type: cheatsheet
Expand All @@ -105,6 +104,13 @@ plan:
url: https://pyvec.github.io/cheatsheets/lists/lists-cs.pdf
type: cheatsheet

- title: Sekvence a soubory
slug: seq
materials:
- lesson: beginners/range
- lesson: beginners/zip-enumerate
- lesson: beginners/files

- title: Grafika
slug: pyglet
materials:
Expand Down
131 changes: 131 additions & 0 deletions lessons/beginners/range/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Range – sekvence čísel

Funkce `range(10)` vrátí speciální hodnotu,
která v sobě obsahuje čísla od 0 do 9:

```pycon
>>> sekvence = range(10)
>>> sekvence
range(0, 10)
```

Je to hodnota typu `range`, podobně jako čísla jsou typu `int`, řetězce typu
`str`, nebo seznamy typu `list`.

Chceš-li se podívat, co v tomhle `range(0, 10)` vlastně je, máš dvě základní
možnosti – projít ho cyklem `for` nebo převést na seznam konkrétních čísel:

```pycon
>>> sekvence
range(0, 10)
>>> for i in sekvence:
... print(i)
0
1
2
3
4
5
6
7
8
9
>>> list(sekvence)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

Možná se ptáš – proč tak složitě?
Proč se místo `range(0, 10)` prostě ta čísla neukážou rovnou?

Je to proto, že `range` se dá použít na opravdu dlouhé řady čísel:

```pycon
>>> range(10000)
range(0, 10000)
>>> list(range(10000))
[0, 1, 2, 3, ..., 9999]
```

Kdybys zkusil{{a}} třeba `list(range(1000000000000000))`, počítači
dojde paměť.
Biliarda čísel se tam prostě nevejde.
Python vyhodí výjimku `MemoryError`.


> [warning]
> Pokud máš na počítači v jiném okně neuloženou práci, radši `list(range(...))`
> s hodně vysokými čísly nezkoušej.
>
> U absurdně vysokého čísla jako `1000000000000000` Python předem ví,
> že mu paměť dojde, a tak ohlásí chybu ještě než se bude snažit seznam vytvořit.
> U trochu menšího čísla (např. `1000000000`, ale na každém počítači je to
> jinak) se může stát, že se Python pokusí seznam začít tvořit, zaplní přitom
> většinu dostupné paměti a počítač „zamrzne“.
> V závislosti na systému se pak třeba může stát že reakce na
> <kbd>Ctrl</kbd>+<kbd>C</kbd> bude trvat hodně dlouho.

Se samotným `range(1000000000000000)` ale není problém.
S konceptem *všech čísel od 0 do biliardy* se počítač vypořádá, i když si je
neumí „zapamatovat“ všechny *najednou*.

Je spousta věcí, které Python umí s `range` udělat, aniž by potřeboval
„spočítat“ každé z čísel.
Spousta operací, které znáš od seznamů, bude fungovat i s `range`:

```pycon
>>> zajimava_cisla = range(8, 10000, 3) # Každé třetí číslo od 8 do 9999
>>> zajimava_cisla[80] # Osmdesáté "zajímavé číslo"
248
>>> zajimava_cisla[:5] # Prvních 5 "zajímavých čísel"
range(8, 23, 3)
>>> list(zajimava_cisla[:5]) # Vypsání prvních 5 "zajímavých čísel"
[8, 11, 14, 17, 20]
>>> len(zajimava_cisla) # Kolik tam je čísel?
3331
>>> 1337 in zajimava_cisla # Je v této sekvenci moje konkrétní číslo ?
True
>>> zajimava_cisla.index(1337) # Kolikáté je?
443
```

```pycon
>>> import random
>>> random.choice(zajimava_cisla)
1229
```

```pycon
>>> for i in zajimava_cisla:
... print(i)
... if i > 20:
... break # Stačilo!
8
11
14
17
20
23
```

Objekt `range` ale nejde měnit – mazání prvků nebo metody jako
`zajimava_cisla.sort()`, `zajimava_cisla.pop()` fungovat nebudou.

> [note] Proč ne?
> Když máš objekt jako `range(8, 10000, 3)`, osmdesátý prvek je jen trocha
> matematiky: spočítáš `8 + 3 * 80` a zkontroluješ že to nepřesáhlo `10000`.
> Podobně je to s ostatními sekvencemi „všech <var>X</var>-tých čísel od
> <var>A</var> do <var>B</var>“, tedy s ostatními `range`.
>
> Kdyby ale šlo udělat něco jako:
>
> ```python
> sekvence = range(8, 10000, 3)
> del sekvence[10]
> sekvence.insert(103, 'ježek')
> ```
>
> … jde najednou o mnohem složitější koncept, kde se N-tý prvek hledá mnohem
> hůř. Už to není jednoduchá sekvence čísel – už to není `range`, ale spíš
> seznam jakýchkoli hodnot.

Pokud budeš něco, co `range` neumí, potřebovat, převeď `range` na seznam.
4 changes: 4 additions & 0 deletions lessons/beginners/range/info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
title: Range - sekvence čísel
style: md
attribution: Pro PyLadies Brno napsal Petr Viktorin, 2019.
license: cc-by-sa-40
42 changes: 0 additions & 42 deletions lessons/beginners/tuple/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,48 +97,6 @@ podil, zbytek = podil_a_zbytek(12, 5)
> ```


## Funkce, které vracejí <var>n</var>-tice

`zip` je zajímavá funkce.
Používá se ve `for` cyklech, podobně jako funkce `range`, která „dává” čísla.

Když funkce `zip` dostane dva seznamy
(či jiné věci použitelné ve `for`),
„dává” dvojice, a to tak, že nejdřív spáruje
první prvek jednoho seznamu s prvním prvkem
druhého seznamu,
pak druhý s druhým, třetí s třetím a tak dál.

Hodí se to, když máš dva seznamy se stejnou
strukturou – příslušné prvky k sobě „patří”
a chceš je zpracovávat společně:

```python
osoby = 'máma', 'teta', 'babička', 'vrah'
vlastnosti = 'hodná', 'milá', 'laskavá', 'zákeřný'
for osoba, vlastnost in zip(osoby, vlastnosti):
print('{} je {}'.format(osoba, vlastnost))
```

Když `zip` dostane tři seznamy,
bude tvořit trojice, ze čtyř seznamů nadělá čtveřice a tak dále.

Další funkce, která vrací dvojice, je `enumerate`.
Jako argument bere seznam (či jinou věc použitelnou
ve `for`) a vždy spáruje index (pořadí v seznamu) s příslušným prvkem.
Jako první tedy dá
(0, *první prvek seznamu*), potom
(1, *druhý prvek seznamu*),
(2, *třetí prvek seznamu*)
a tak dále.

```python
prvocisla = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

for i, prvocislo in enumerate(prvocisla):
print('Prvočíslo č.{} je {}'.format(i, prvocislo))
```

## Malé <var>n</var>-tice

Jak vytvořit <var>n</var>-tici s žádným nebo jedním prvkem? Takhle:
Expand Down
Loading