2. For-cyklus

2.1. Priradenia

Najprv dokončíme základné prvky jazyka: typy hodnôt, premenné a hlavne priradenia a hneď potom sa zoznámime s prvým zloženým príkazom na opakovanie nejakej činnosti for-cyklom.

Začneme s takýmto jednoduchým príkladom programu (skriptu), ktorý zapíšeme v editovacom okne:

meno = input('ako sa volas? ')
print('ahoj', meno)

V tomto príklade sa využíva funkcia input(), ktorá zastaví bežiaci výpočet, vypýta si od používateľa zadať nejaký text a tento uloží do premennej meno. Na koniec toto zadané meno vypíše. Program spustíme klávesom F5. Beh programu v konzolovom okne (shell pythonu) môže vyzerať napr. takto

ako sa volas? Jozef
ahoj Jozef
>>>

Týmto program skončil a môžeme pokračovať aj v skúmaní premenných, napr. v programovom režime zistíme hodnotu premennej meno:

>>> meno
'Jozef'

V našich budúcich programoch bude bežné, že na začiatku sa vypýtajú hodnoty nejakých premenných a ďalej program pracuje s nimi.

Ďalší program ukazuje, ako to vyzerá, keď chceme načítať nejaké číslo:

cislo = input('zadaj cenu jedneho vyrobku: ')
spolu = cislo * 4
print('4 vyrobky stoja', spolu, 'euro')

Týmto programom sme chceli prečítať cenu jedného výrobku a z toho vypočítať, aká je cena 4 takýchto výrobkov. Po spustení programu dostávame:

zadaj cenu jedneho vyrobku: 1.2
4 vyrobky stoja 1.21.21.21.2 euro

Takýto výsledok je zrejme nesprávny: očakávali sme celkovú cenu 4.8 euro. Problémom tu bolo to, že funkcia input() zadanú hodnotu vráti nie ako číslo, ale ako znakový reťazec, teda '1.2'. Na tomto mieste potrebujeme takýto reťazec prekonvertovať na desatinné číslo. Využijeme jednu z troch konvertovacích (pretypovacích) funkcií:

pretypovanie hodnôt

Mená typov int, float a str zároveň súžia ako mená pretypovacích funkcií, ktoré dokážu z jedného typu vyrobiť hodnotu iného typu:

  • int(hodnota) z danej hodnoty vyrobí celé číslo, napr.
    • int(3.14) => 3
    • int('37') => 37
  • float(hodnota) z danej hodnoty vyrobí desatinné číslo, napr.
    • float(333) => 333.0
    • float('3.14') => 3.14
  • str(hodnota) z danej hodnoty vyrobí znakový reťazec, napr.
    • str(356) => '356'
    • str(3.14) => '3.14'

Zrejme pretypovanie reťazca na číslo bude fungovať len vtedy, keď je to správne zadaný reťazec, inak funkcia vyhlási chybu.

Program by mal vyzerať správne takto:

cislo_str = input('zadaj cenu jedneho vyrobku: ')
cislo = float(cislo_str)                            # pretypovanie
spolu = cislo * 4
print('4 vyrobky stoja', spolu, 'euro')

Prečítaný reťazec sa najprv prekonvertuje na desatinné číslo a až potom sa s týmto číslom pracuje ako so zadanou cenou jedného výrobku v eurách. Po spustení dostávame:

zadaj cenu jedneho vyrobku: 1.2
4 vyrobky stoja 4.8 euro

Kvôli čitateľnosti programu sme tu použili tri rôzne premenné: cislo_str, cislo a spolu. Neskôr budeme takto jednoduché programy zapisovať kompaktnejšie. Tu je príklad, ktorý by vám mal ukázať, že takto zatiaľ programy nezapisujte: sú len pre pokročilého čitateľa a hlavne sa v takomto zápise ťažšie hľadajú a opravujú chyby:

print('4 vyrobky stoja', 4*float(input('zadaj cenu jedneho vyrobku: ')), 'euro')

Tento program robí presne to isté, ako predchádzajúci zápis, len nevyužíva žiadne pomocné premenné.

Veľa našich programov bude začínať načítaním niekoľkých vstupných hodnôt. Podľa typu požadovanej hodnoty môžeme prečítaný reťazec hneď prekonvertovať na správny typ, napr. takto:

cele = int(input('zadaj celé číslo: '))               # konverovanie na celé číslo
desatinne = float(input('zadaj desatinné číslo: '))   # konverovanie na desatinné číslo
retazec = input('zadaj znakový reťazec: ')            # reťazec netreba konvertovať

Úprava pythonovského programu

Programátori majú medzi sebou dohodu, ako správne zapisovať pythonovský kód (oficiálny dokument je PEP 8). My zatiaľ píšeme len veľmi jednoduché zápisy, ale je dôležité si zvykať už od začiatku na správne zápisy. Takže niekoľko základných pravidiel:

  • mená premenných obsahujú len malé písmená
  • pre znak = v priraďovacom príkaze dávame medzeru pred aj za
  • operácie v aritmetických výrazoch sú väčšinou tiež oddelené od operandov medzerami
  • riadky programu by nemali byť dlhšie ako 79 znakov
  • za čiarky, napr. ktoré oddeľujú parametre v príkaze print() dávame vždy medzeru

Postupne sa budeme zoznamovať aj s ďalšími takýmito odporúčaniami.

V Pythone je zadefinovaných niekoľko štandardných funkcií, ktoré pracujú s číslami. Ukážeme si dve z nich: výpočet absolútnej hodnoty a zaokrúhľovaciu funkciu:

abs() absolútna hodnota

abs(cislo)
Parametre:cislo – celé alebo desatinné číslo

Funkcia abs(cislo) vráti absolútnu hodnotu zadaného čísla, napr.

  • abs(13) => 13
  • abs(-3.14) => 3.14

Funkcia nemení typ parametra, s ktorým bola zavolaná, t.j.

>>> type(abs(13))
<class 'int'>
>>> type(abs(-3.14))
<class 'float'>

Ak vyskúšame zistiť typ nie výsledku volania funkcie, ale samotnej funkcie, dostávame:

>>> type(abs)
<class 'builtin_function_or_method'>

Totiž aj každá funkcia (teda aj print aj input) je hodnotou, s ktorou sa dá pracovať podobne ako s číslami a reťazcami, teda ju môžeme napr. priradiť do premennej:

>>> a = abs
>>> print(a)
<built-in function abs>

Zatiaľ je nám toto úplne na nič, ale je dobre o tom vedieť už teraz. Keď už budeme dobre rozumieť mechanizmu priraďovania mien premenných rôznymi hodnotami, bude nám jasné, prečo funguje:

>>> vypis = print
>>> vypis
<built-in function print>
>>> vypis('ahoj', 3 * 4)
ahoj 12

Ale môže sa nám „prihodiť“ aj takýto nešťastný preklep:

>>> print=('ahoj')
>>> print('ahoj')
...
TypeError: 'str' object is not callable

Do premennej print, ktorá obsahovala referenciu na štandardnú funkciu, sme omylom priradili inú hodnotu (znakový reťazec 'ahoj') a tým sme znefunkčnili vypisovanie hodnôt pomocou pôvodného obsahu tejto premennej.

Ďalšia funkcia help() nám niekedy môže pomôcť v jednoduchej nápovedi k niektorým funkciám a tiež typom. Ako parameter pošleme buď meno funkcie, alebo hodnotu nejakého typu:

>>> help(abs)
Help on built-in function abs in module builtins:

abs(...)
    abs(number) -> number

    Return the absolute value of the argument.

>>> help(0)
Help on int object:

class int(object)
 |  int(x=0) -> integer
 |  int(x, base=10) -> integer
...

… ďalej pokračuje dlhý výpis informácií o celočíselnom type.

Druhou štandardnou číselnou funkciou je zaokrúhľovanie.

round() zaokrúhľovanie čísla

round(cislo)
round(cislo, pocet)
Parametre:
  • cislo – celé alebo desatinné číslo
  • pocet – celé číslo, ktoré vyjadruje na koľko desatinných miest sa bude zaokrúhľovať; ak je to záporné číslo, zaokrúhľuje sa na počet mocnín desiatky

Funkcia round(cislo) vráti zaokrúhlenú hodnotu zadaného čísla na celé číslo. Funkcia round(cislo, pocet) vráti zaokrúhlené číslo na príslušný počet desatinných miest, napr.

  • round(3.14) => 3
  • round(-0.74) => -1
  • round(3.14, 1) => 3.1
  • round(2563, -2) => 2600

Tiež si o tom môžete prečítať pomocou:

>>> help(round)
Help on built-in function round in module builtins:

round(...)
    round(number[, ndigits]) -> number

    Round a number to a given precision in decimal digits (default 0 digits).
    This returns an int when called with one argument, otherwise the
    same type as the number. ndigits may be negative.

2.1.1. Priraďovacie príkazy

Vráťme sa k priraďovaciemu príkazu z 1. prednášky v tvare:

meno_premennej = hodnota
  • najprv sa zistí hodnota na pravej strane priraďovacieho príkazu => táto hodnota sa vloží do pamäte hodnôt
  • ak sa toto meno_premennej ešte nenachádzalo v pamäti mien premenných, tak sa vytvorí toto nové meno
  • meno_premennej dostane referenciu na novú vytvorenú hodnotu

Pozrime sa na takéto priradenie:

>>> ab = ab + 5
...
NameError: name 'ab' is not defined

Ak premenná ab ešte neexistovala, Python nevie vypočítať hodnotu ab + 5 a hlási chybovú správu. Skúsme najprv do ab niečo priradiť:

>>> ab = 13
>>> ab = ab + 5
>>> ab
18

Tomuto hovoríme aktualizácia (update) premennej: hodnotu premennej ab sme zvýšili o 5 (najprv sa vypočítalo ab + 5, čo je 18) a potom sa toto priradilo opäť do premennej ab. Konkrétne takto sme zvýšili (inkrementovali) obsah premennej. Podobne by fungovali aj iné operácie, napr.

>>> ab = ab * 11
>>> ab
198
>>> ab = ab // 10
>>> ab
19

Python na tieto prípady aktualizácie nejakej premennej ponúka špeciálny zápis priraďovacieho príkazu:

meno_premennej += hodnota        # meno_premennej = meno_premennej + hodnota
meno_premennej -= hodnota        # meno_premennej = meno_premennej - hodnota
meno_premennej *= hodnota        # meno_premennej = meno_premennej * hodnota
meno_premennej /= hodnota        # meno_premennej = meno_premennej / hodnota
meno_premennej //= hodnota       # meno_premennej = meno_premennej // hodnota
meno_premennej %= hodnota        # meno_premennej = meno_premennej % hodnota
meno_premennej **= hodnota       # meno_premennej = meno_premennej ** hodnota

Každý z týchto zápisov je len skrátenou formou bežného priraďovacieho príkazu. Nemusíte ho používať, ale verím, že časom si naň zvyknete a bude pre vás veľmi prirodzený.

Všimnite si, že fungujú aj tieto zaujímavé prípady:

>>> x = 45
>>> x -= x          # to isté ako x = 0
>>> x += x          # to isté ako x *= 2
>>> z = 'abc'
>>> z += z
>>> z
'abcabc'

Ďalším užitočným tvarom priraďovacieho príkazu je možnosť naraz priradiť tej istej hodnoty do viacerých premenných. Napr.

x = 0
sucet = 0
pocet = 0
ab = 0

Môžeme to nahradiť jediným priradením:

x = sucet = pocet = ab = 0

V takomto hromadnom priradení dostávajú všetky premenné tú istú hodnotu, teda referencujú na tú istú hodnotu v pamäti hodnôt.

Posledným užitočným variantom priradenia je tzv. paralelné priradenie: naraz priraďujeme aj rôzne hodnoty do viacerých premenných. Napr.

x = 120
y = 255
meno = 'bod A'
pi = 3.14

Môžeme zapísať jedným paralelným priradením:

x, y, meno, pi = 120, 255, 'bod A', 3.14

Samozrejme, že na oboch stranách priraďovacieho príkazu musí byť rovnaký počet mien premenných a počet hodnôt. Veľmi užitočným využitím takéhoto paralelného priradenia je napr. výmena obsahov dvoch premenných:

>>> a = 3.14
>>> b = 'hello'
>>> a, b = b, a          # paralelné priradenie
>>> a
'hello'
>>> b
3.14

Paralelné priradenie totiž funguje takto:

  • najprv sa zistí postupnosť všetkých hodnôt na pravej strane priraďovacieho príkazu (bola to dvojica b, a, teda hodnoty 'ahoj' a 3.14)
  • tieto dve zapamätané hodnoty sa naraz priradia do dvoch premenných a a b, teda sa vymenia ich obsahy

Zamyslite sa, čo sa dostane do premenných po týchto príkazoch:

>>> p1, p2, p3 = 11, 22, 33
>>> p1, p2, p3 = p2, p3, p1

alebo

>>> x, y = 8, 13
>>> x, y = y, x+y

Paralelné priradenie funguje aj v prípade, že na pravej strane príkazu je jediný znakový reťazec nejakej dĺžky a na pravej strane je presne toľko premenných, ako je počet znakov, napr.

>>> a, b, c, d, e, f = 'Python'
>>> print(a, b, c, d, e, f)
P y t h o n

Keďže tento znakový reťazec je vlastne postupnosť 6 znakov, priradením sa táto postupnosť 6 znakov paralelne priradí do 6 premenných.

2.1.2. Znakové reťazce

Ak znakový reťazec obsahuje dvojicu znakov '\n', tieto označujú, že pri výpise funkciou print() sa namiesto nich prejde na nový riadok. Napr.

>>> a = 'prvý riadok\nstredný\ntretí riadok'
>>> a
'prvý riadok\nstredný\ntretí riadok'
>>> print(a)
prvý riadok
stredný
tretí riadok

Takáto dvojica znakov '\n' zaberá v reťazci len jeden znak.

Python umožňuje pohodlnejšie vytvárania takýchto „viacriadkových“ reťazcov. Ak reťazec začína tromi apostrofmi ''' (alebo úvodzovkami """), môže prechádzať aj cez viac riadkov, ale opäť musí byť ukončený rovnakou trojicou, ako začal. Prechody na nový riadok v takomto reťazci sa nahradia špeciálnym znakom '\n'. Napr.

>>> ab = '''prvý riadok
stredný
tretí riadok'''
>>> ab
'prvý riadok\nstredný\ntretí riadok'
>>> print(ab)
prvý riadok
stredný
tretí riadok

Takýto reťazec môže obsahovať aj apostrofy a úvodzovky.

Niekedy potrebujeme vytvárať znakový reťazec pomocou komplikovanejšieho zápisu, v ktorom ho budeme skladať (zreťaziť) z viacerých hodnôt, napr.

>>> meno, x, y = 'A', 180, 225
>>> r = 'bod ' + meno + ' na súradniciach (' + str(x) + ',' + str(y) + ')'
>>> r
'bod A na súradniciach (180,225)'

Python poskytuje špeciálny typ funkcie (tzv. metódu znakového reťazca), pomocou ktorej môžeme vytvárať aj takto komplikované výrazy. Základom je formátovacia šablóna, do ktorej budeme vkladať ľubovoľné aj číselné hodnoty. V našom prípade bude šablónou reťazec 'bod {} na súradniciach ({},{})'. V tejto šablóne sa každá dvojica znakov {} nahradí nejakou konkrétnou hodnotou, v našom prípade týmito hodnotami sú postupne meno, x, y. Zápis takejto formátovacej metódy bude:

>>> meno, x, y = 'A', 180, 225
>>> r = 'bod {} na súradniciach ({},{})'.format(meno, x, y)
>>> r
'bod A na súradniciach (180,225)'

To znamená, že za reťazec šablóny píšeme znak bodka a hneď za tým volanie funkcie format() s hodnotami, ktoré sa do šablóny dosadia (zrejme ich musí byť rovnaký počet ako dvojíc {}). Neskôr sa zoznámime aj s ďalšími veľmi užitočnými špecialitami takéhoto formátovania.

2.2. Cyklus

Ak potrebujeme 5-krát vypísať ten istý text, môžeme to zapísať napr. takto:

print('programujem v Pythone')
print('programujem v Pythone')
print('programujem v Pythone')
print('programujem v Pythone')
print('programujem v Pythone')

Namiesto toho použijeme novú konštrukciu for-cyklu:

for i in 1, 2, 3, 4, 5:
    print('programujem v Pythone')

Ako to funguje:

  • do premennej i sa bude postupne priraďovať nasledovná hodnota zo zoznamu hodnôt
  • začíname s prvou hodnotou, teda v tomto prípade 1
  • pre každú hodnotu so zoznamu sa vykonajú príkazy, ktoré sú v tele cyklu, t.j. tie príkazy, ktoré sú odsadené
  • v našom príklade sa päťkrát vypíše rovnaký text 'programujem v Pythone', hodnota premennej i nemá na tento výpis žiadny vplyv
  • všimnite si znak ‚:‘ na konci riadka s for - ten je tu povinne, bez neho by to nefungovalo

Telo cyklu:

  • tvoria príkazy, ktoré sa majú opakovať; definujú sa odsadením príslušných riadkov
  • odsadenie je povinné a musí byť minimálne 1 medzera, odporúča sa odsadzovať vždy o 4 medzery
  • ak telo cyklu obsahuje viac príkazov, všetky musia byť odsadené o rovnaký počet medzier
  • telo cyklu nesmie byť prázdne, musí obsahovať aspoň jeden príkaz
  • niekedy sa môže hodiť prázdny príkaz pass, ktorý nerobí nič, len oznámi čitateľovi, že sme na telo cyklu nezabudli, ale zatiaľ tam nechceme mať nič
  • prázdne riadky v tele cyklu nemajú žiaden význam, často slúžia na sprehľadnenie čitateľnosti kódu

Podobný výpis dostaneme aj takýmto zápisom for-cyklu:

for i in 1, 1, 1, 1, 1:
    print('programujem v Pythone')
    print('~~~~~~~~~~~~~~~~~~~~~')

Aj v tomto prípade sa telo cyklu bude opakovať 5-krát. Telo cyklu sa tu teraz skladá z dvoch príkazov print(), preto sa vypíše týchto 10 riadkov textu:

programujem v Pythone
~~~~~~~~~~~~~~~~~~~~~
programujem v Pythone
~~~~~~~~~~~~~~~~~~~~~
programujem v Pythone
~~~~~~~~~~~~~~~~~~~~~
programujem v Pythone
~~~~~~~~~~~~~~~~~~~~~
programujem v Pythone
~~~~~~~~~~~~~~~~~~~~~

Ak by sme ale druhý riadok tela cyklu neodsunuli:

for i in 1, 1, 1, 1, 1:
    print('programujem v Pythone')
print('~~~~~~~~~~~~~~~~~~~~~')

telo cyklu je teraz len jeden príkaz. Program najprv 5-krát vypíše text 'programujem v Pythone' a až potom jeden riadok s vlnkami:

programujem v Pythone
programujem v Pythone
programujem v Pythone
programujem v Pythone
programujem v Pythone
~~~~~~~~~~~~~~~~~~~~~

V tele cyklu môžeme použiť aj premennú cyklu, ktorej hodnota sa pri každom prechode cyklom automaticky mení. V nasledovnom príklade je premennou cyklu prem:

for prem in 1, 2, 3, 4, 5:
    print(prem)

Po spustení programu sa postupne vypíšu všetky nadobudnuté hodnoty:

1
2
3
4
5

Ďalší program počíta druhé mocniny niektorých zadaných prvočísel:

for x in 5, 7, 11, 13, 23:
    x2 = x ** 2
    print('druhá mocnina', x, 'je', x2)

Po spustení dostávame:

druhá mocnina 5 je 25
druhá mocnina 7 je 49
druhá mocnina 11 je 121
druhá mocnina 13 je 169
druhá mocnina 23 je 529

Premenná cyklu nemusí nadobúdať len celočíselné hodnoty, ale hodnoty úplne ľubovoľného typu, napr.

>>> for x in 22/7, 3, 14, 8., 1000-1e-3:
        print('druha odmocnina z', x, 'je', x ** .5)

druha odmocnina z 3.142857142857143 je 1.7728105208558367
druha odmocnina z 3 je 1.7320508075688772
druha odmocnina z 14 je 3.7416573867739413
druha odmocnina z 8.0 je 2.8284271247461903
druha odmocnina z 999.999 je 31.62276079029154

Niektoré hodnoty postupnosti hodnôt for-cyklu sú tu celočíselné, iné sú desatinné. V tomto príklade si všimnite, ako sme tu počítali druhú odmocninu čísla: číslo sme umocnili na 1/2, t.j. 0.5.

V ďalšom cykle sme namiesto zoznamu hodnôt použili znakový reťazec: už vieme, že znakový reťazec je vlastne postupnosť znakov, preto for-cyklus tento znakový reťazec „rozoberie“ na jednotlivé znaky a s každým znakom vykoná telo cyklu (znak vypíše 10-krát):

>>> for pismeno in 'Python':
        print(pismeno * 10)

PPPPPPPPPP
yyyyyyyyyy
tttttttttt
hhhhhhhhhh
oooooooooo
nnnnnnnnnn

Rovnaký výsledok by sme dosiahli aj týmto zápisom for-cyklu:

for pismeno in 'P', 'y', 't', 'h', 'o', 'n':
    print(pismeno * 10)

2.2.1. Generovanie postupnosti čísel

Využijeme ďalšiu štandardnú funkciu range(), pomocou ktorej budeme najmä vo for-cykloch generovať rôzne postupnosti hodnôt. Táto funkcia môže mať rôzny počet parametrov a podľa toho sa bude generovaná aj výsledná postupnosť. Všetky parametre musia byť celočíselné.

funkcia range()

range(stop)
range(start, stop)
range(start, stop, krok)
Parametre:
  • start – prvý prvok vygenerovanej postupnosti (ak chýba, predpokladá sa 0)
  • stop – hodnota, na ktorej sa už generovanie ďalšej hodnoty postupnosti zastaví - táto hodnota už v postupnosti nebude
  • krok – hodnota, o ktorú sa zvýši (resp. zníži pre záporný krok) každý nasledovný prvok postupnosti, ak tento parameter chýba, predpokladá sa 1

Väčšinou platí, že do parametra stop nastavíme o 1 väčšiu hodnotu, ako potrebujeme poslednú hodnotu vygenerovanej postupnosti.

Najlepšie si to ukážeme na príkladoch rôzne vygenerovaných postupností celých čísel. V tabuľke vidíme výsledky pre rôzne parametre:

range(10) 0,1,2,3,4,5,6,7,8,9
range(0, 10) 0,1,2,3,4,5,6,7,8,9
range(0, 10, 1) 0,1,2,3,4,5,6,7,8,9
range(3, 10) 3,4,5,6,7,8,9
range(3, 10, 2) 3,5,7,9
range(10, 100, 10) 10,20,30,40,50,60,70,90
range(10, 1, -1) 10,9,8,7,6,5,4,3,2
range(10, 1) prázdna postupnosť
range(1, 1) prázdna postupnosť

Niekoľko ukážok v priamom režime:

>>> for n in range(5):     # postupnosť čísel od 0 pre menšie ako 5
        print(n)

0
1
2
3
4
>>> for n in range(5, 9):  # postupnosť čísel od 5 pre menšie ako 9
        print(n)

5
6
7
8
>>> print(range(7, 100, 11))
range(7, 100, 11)

Všimnite si, že volaním print(range(7, 100, 11)) sa nedozvieme nič užitočné o vygenerovanej postupnosti. Pre kontrolu hodnôt vygenerovaných pomocou range() musíme zatiaľ použiť for-cyklus.

Ak potrebujeme vypisovať pomocou for-cyklu väčší počet čísel, je veľmi nepraktické, ak každý jeden print() vypisuje do ďalšieho riadka. Hodilo by sa nám, keby print() v niektorých situáciách nekončil prechodom na nový riadok. Využijeme nový typ parametra:

funkcia print()

print(..., end='reťazec')
Parametre:end='reťazec' – tento reťazec nahradí štandardný '\n' na ľubovoľný iný, najčastejšie je to jedna medzera ' ' alebo prázdny reťazec ''

Tento parameter musí byť v zozname parametrov funkcie print() uvedený ako posledný za všetkými vypisovanými hodnotami. Vďaka nemu po vypísaní týchto hodnôt sa namiesto prechodu na nový riadok vypíše zadaný reťazec.

Napr.

print('programujem', end='_')
print(10, end='...')
print('rokov')

Tieto 3 volania print() vypíšu len jeden riadok:

programujem_10...rokov

Tento špeciálny parameter v print() sa využije najmä vo for-cykloch. V nasledujúcom príklade vypíšeme 100 hodnôt do jedného dlhého riadka, čísla pritom oddeľujeme čiarkami s medzerou:

>>> for cislo in range(100,200):
        print(cislo, end=', ')

100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
196, 197, 198, 199,

Zrejme v programovom režime ostane pozícia výpisu funkciou print() na konci posledného riadka a ďalšie výpisy by pokračovali tu. Zvykne sa po skončení takéhoto cyklu zavolať print() bez parametrov.

Pri tlačení napr. tabuliek nejakých hodnôt často potrebujeme slušne naformátovať takýto výstup. Napr.

>>> for i in range(1,11):
        print(i, i * i, i ** 3, i ** 4)

1 1 1 1
2 4 8 16
3 9 27 81
4 16 64 256
5 25 125 625
6 36 216 1296
7 49 343 2401
8 64 512 4096
9 81 729 6561
10 100 1000 10000

Najčastejšie použijeme formátovanie znakového reťazca (metódou format()):

>>> for i in range(1,11):
        print('{:3} {:4} {:5} {:6}'.format(i, i * i, i ** 3, i ** 4))

  1    1     1      1
  2    4     8     16
  3    9    27     81
  4   16    64    256
  5   25   125    625
  6   36   216   1296
  7   49   343   2401
  8   64   512   4096
  9   81   729   6561
 10  100  1000  10000

V tomto príklade vidíte, že formátovacia dvojica znakov '{}' môže obsahovať šírku vypisovanej hodnoty - uvádzame ju za dvojbodkou, teda '{:3}' označuje, že hodnota sa vypisuje na šírku 3 a ak je kratšia (napr. jednociferné číslo), zľava sa doplní medzerami.

Ďalší príklad ilustruje for-cyklus, v ktorom počet prechodov určuje načítaná hodnota nejakej premennej:

n = int(input('zadaj pocet: '))
for i in range(1, n + 1):
    print('*' * i)

Program vypíše n riadkov, pričom v prvom je jedna hviezdička, v druhom 2, atď. Napr. takéto spustenie programu:

zadaj pocet: 5
*
**
***
****
*****

Túto ideu môžeme rôzne rozvíjať tak, že v každom riadku bude nejaký počet medzier a nejaký iný počet hviezdičiek, napr.

n = int(input('zadaj pocet: '))
for i in range(n):
    print(' '*(n-1-i) + '*'*(2*i+1))
for i in range(n):
    print(' '*i + '*'*(2*n-2*i-1))

A spustenie, napr.

zadaj pocet: 5
    *
   ***
  *****
 *******
*********
*********
 *******
  *****
   ***
    *

For-cyklus sa výborne využije v prípadoch, keď sa v tele cyklu vyskytuje príkaz, ktorý inkrementuje nejakú premennú (alebo ju mení inou operáciou). Zrejme toto inkremenovanie prejde toľkokrát, koľko je prechodov cyklu a často sa pritom využije premenná cyklu.

Ukážme túto ideu na príklade, v ktorom spočítame všetky hodnoty premennej cyklu. Použijeme na to ďalšiu premennú, do ktorej sa bude postupne pripočítavať premenná cyklu:

n = int(input('zadaj pocet: '))
sucet = 0
for i in range(1, n + 1):
    sucet = sucet + i                  # alebo  sucet += i
print('sucet cisel =', sucet)

V tomto programe sme použili premennú sucet, do ktorej postupne pripočítavame všetky hodnoty z intervalu (range) od 1 do n. Vďaka tomu sa po skončení cyklu v tejto premennej nachádza práve súčet všetkých celých čísel do n. Spustíme napr.

zadaj pocet: 10
sucet cisel = 55

Tento program nám môže slúžiť ako nejaká šablóna, pomocou ktorej riešime podobnú triedu úloh: v každom prechode cyklu niečo pripočítavame, násobíme, delíme, … Takáto pripočítavacia šablóna sa skladá z:

  • inicializácia pomocnej premennej (alebo viacerých premenných), do ktorej sa bude pripočítavať, najčastejšie je to vynulovanie;
  • v tele cyklu sa do tejto pomocnej premennej pripočíta nejaká hodnota, najčastejšie premenná cyklu;
  • po skončení cyklu sa v tejto pomocnej premennej nachádza očakávaný výsledok sčitovania.

Ukážeme to na niekoľkých príkladoch.

Výpočet faktoriálu, čo je vlastne súčin čísel 1 * 2 * 3 * … * n. Pomocná premenná musí byť inicializovaná 1, namiesto pripočítavania bude násobenie:

n = int(input('zadaj cislo: '))
sucin = 1
for i in range(1, n + 1):
    sucin = sucin * i                  # alebo  sucin *= i
print('{}! = {}'.format(n, sucin))

V záverečnom výpise sme použili formátovanie reťazca. Po spustení, napr.

zadaj cislo: 6
6! = 720

Úplne rovnaký princíp môžeme použiť aj keď premenná cyklu nebude obsahovať čísla nejakého intervalu, ale budú to znaky z rozoberaného znakového reťazca. Nasledovný príklad postupne prechádza znak za znakom daného reťazca a za každým k pomocnej premennej pripočíta 1:

retazec = input('zadaj retazec: ')
pocet = 0
for znak in retazec:
    pocet = pocet + 1                  # alebo  pocet += 1
print('dlzka retazca =', pocet)

Tento program spočíta počet znakov zadaného znakového reťazca, napr.

zadaj retazec: python
dlzka retazca = 6

Ďalší príklad ilustruje, ako môžeme využiť premennú cyklu, ktorá obsahuje znak zadaného reťazca. Pomocná premenná bude znakového typu a v tomto príklade ju budeme inicializovať prázdnym reťazcom:

retazec = input('zadaj retazec: ')
novy = ''
for znak in retazec:
    novy = novy + znak + znak
print('novy retazec =', novy)

V tele cyklu sa k pomocnej premennej prireťazujú dva rovnaké znaky. Vďaka tomuto sa vytvorí nový reťazec, v ktorom bude každý znak z pôvodného reťazca dvakrát, napr.

zadaj retazec: Python
novy retazec = PPyytthhoonn

2.2.2. Vnorené cykly

Napíšme najprv program, ktorý vypíše čísla od 0 do 99 do 10 riadkov tak, že v prvom stĺpci sú čísla od 0 do 9, v druhom od 10 do 19, … v poslednom desiatom sú čísla od 90 do 99:

for i in range(10):
    print(i, i+10, i+20, i+30, i+40, i+50, i+60, i+70, i+80, i+90)

Po spustení dostaneme:

0 10 20 30 40 50 60 70 80 90
1 11 21 31 41 51 61 71 81 91
2 12 22 32 42 52 62 72 82 92
3 13 23 33 43 53 63 73 83 93
4 14 24 34 44 54 64 74 84 94
5 15 25 35 45 55 65 75 85 95
6 16 26 36 46 56 66 76 86 96
7 17 27 37 47 57 67 77 87 97
8 18 28 38 48 58 68 78 88 98
9 19 29 39 49 59 69 79 89 99

Riešenie tohto príkladu využíva for-cyklus len na vypísanie 10 riadkov, pričom obsah každého riadka sa vyrába bez cyklu jedným príkazom print(). Toto je ale nepoužiteľný spôsob riešenia v prípadoch, ak by tabuľka mala mať premenlivý počet stĺpcov, napr. keď je počet zadaný zo vstupu. Vytvorenie jedného riadka by sme teda tiež mali urobiť for-cyklom, t.j. budeme definovať for-cyklus, ktorý je vo vnútri iného cyklu, tzv. vnorený cyklus. Všimnite si, že celý tento cyklus musí byť odsadený o ďalšie 4 medzery:

for i in range(10):
    for j in range(0, 100, 10):
        print(i + j, end=' ')
    print()

Vnútorný for-cyklus vypisuje 10 čísel, pričom premenná cyklu i postupne nadobúda hodnoty 0, 10, 20, … 90. K tejto hodnote sa pripočítava číslo riadka tabuľky, teda premennú j. Tým dostávame rovnakú tabuľku, ako predchádzajúci program. Rovnaký výsledok vytvorí aj nasledovné riešenie:

for i in range(10):
    for j in range(i, 100, 10):
        print(j, end=' ')
    print()

V tomto programe má vnútorný cyklus tiež premennú cyklu s hodnotami s krokom 10, ale v každom riadku sa začína s inou hodnotou.

Túto istú ideu využijeme, aj keď budeme vytvárať tabuľku čísel od 0 do 99, ale organizovanú inak: v prvom riadku sú čísla od 0 do 9, v druhom od 10 do 19, … v poslednom desiatom sú čísla od 90 do 99:

for i in range(0, 100, 10):
    for j in range(i, i + 10):
        print(j, end=' ')
    print()

Možných rôznych zápisov riešení tejto úlohy je samozrejme viac.

Ešte dve veľmi podobné úlohy:

  1. Prečítať celé číslo n a vypísať tabuľku čísel s n riadkami, pričom v prvom je len 1, v druhom sú čísla 1 2, v treťom 1 2 3, atď. až v poslednom sú čísla od 1 do n:
pocet = int(input('zadaj počet riadkov: '))
for riadok in range(1, pocet + 1):
    for cislo in range(1, riadok + 1):
        print(cislo, end=' ')
    print()

Všimnite si mená oboch premenných cyklov riadok a cislo, vďaka čomu môžeme lepšie pochopiť, čo sa v ktorom cykle deje. Spustíme, napr.

zadaj počet riadkov: 7
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
  1. Zadanie je podobné, len tabuľka v prvom riadku obsahuje 1, v druhom 2 3, v treťom 4 5 6, atď. každý ďalší riadok obsahuje o jedno číslo viac ako predchádzajúci a tieto čísla v každom ďalšom riadku pokračujú v číslovaní. Zapíšeme jedno z možných riešení:
pocet = int(input('zadaj počet riadkov: '))
cislo = 1
for riadok in range(1, pocet + 1):
    for stlpec in range(1, riadok + 1):
        print(cislo, end=' ')
        cislo += 1
    print()
zadaj počet riadkov: 7
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27 28

V tomto riešení využívame pomocnú premennú cislo, ktorú sme ešte pred cyklom nastavili na 1, vo vnútornom cykle vypisujeme jej hodnotu (a nie premennú cyklu) a zakaždým ju zvyšujeme o 1.

2.3. Zhrnutie

konverzie medzi typmi
pomocou funkcií: int(), float(), str()
paralelné (viacnásobné) priradenie
viac rôznych hodnôt sa naraz priradí do viacerých premenných
funkcia ‚reťazec‘.format()
slúži na formátovanie reťazca, ktorý môže obsahovať nejaké iné hodnoty (tieto sa automaticky prekonvertujú na reťazce)
for-cyklus
pomocou premennej cyklu vykoná zadaný počet-krát telo cyklu
funkcia range()
vytvorí postupnosť celočíselných hodnôt, najčastejšie pre for-cyklus

Správne použitie

Radšej nepoužívajte

2.4. Cvičenie

  1. Napíšte skript, ktorý prečíta rozmery bazénu v metroch a vypočíta množstvo vody v litroch, ktoré potrebujeme na zaplnenie tohto bazéna.
  • po spustení skriptu

    zadaj 1. rozmer bazena: 5
    zadaj 2. rozmer bazena: 1.5
    zadaj hĺbku bazena: 0.8
    
    pocet litrov = 6000
    
  1. Napíšte skript, ktorý prečíta celé číslo n a reťazec a vytvorí nový reťazec, ktorý po vypísaní vytvorí tabuľku n riadkov po n reťazcov. Využite znaky '\n' a ' '. Nepoužite cyklus.
  • po spustení skriptu

    zadaj pocet: 5
    zadaj slovo: ahoj
    
    ahoj ahoj ahoj ahoj ahoj
    ahoj ahoj ahoj ahoj ahoj
    ahoj ahoj ahoj ahoj ahoj
    ahoj ahoj ahoj ahoj ahoj
    ahoj ahoj ahoj ahoj ahoj
    
  1. Napíšte skript, ktorý prečíta znakový reťazec a potom postupne z tohto reťazca vypíše do každého riadka jedno písmeno a to toľkokrát, koľké je to písmeno.
  • napr.

    zadaj slovo: Python
    
    P
    yy
    ttt
    hhhh
    ooooo
    nnnnnn
    
  1. pre čísla od 11 do 20 vypísať ich druhé aj tretie mocniny v tvare (11,121,1331) = každé do jedného riadka. Použite metódu format().
  • po spustení skriptu

    (11,121,1331)
    (12,144,1728)
    ...
    
  1. Napíšte skript, ktorý prečíta jedno celé číslo n a dva rôzne znakové reťazce. Potom do n riadkov postupne strieda vypisovanie týchto dvoch reťazcov. Dajte pozor na nepárne n. Možno využijete priraďovací príkaz, ktorý vymieňa obsah dvoch premenných.
  • po spustení skriptu

    zadaj pocet: 5
    prvy text: programujem v Pythone
    druhy text: som na matfyze
    
    programujem v Pythone
    som na matfyze
    programujem v Pythone
    som na matfyze
    programujem v Pythone
    
  1. Napíšte skript, ktorý najprv prečíta jedno celé číslo n a potom prečíta n ďalších desatinných čísel. Na záver vypíše súčet týchto čísel aj ich priemer.
  • napr.

    zadaj pocet: 4
    zadaj cislo: 14.2
    zadaj cislo: 1
    zadaj cislo: 5.7
    zadaj cislo: 22
    
    sucet je 42.9
    priemer je 10.725
    
  1. Napíšte skript, ktorý prečíta dve celé čísla a zo znakov '+', '-' a '|' vypíše obdĺžnik veľkosti podľa zadaných čísel.
  • napr.

    zadaj 1. cislo: 5
    zadaj 2. cislo: 2
    
    +-----+
    |     |
    |     |
    +-----+
    
  1. Napíšte skript, ktorý prečíta celé číslo n a vypíše tabuľku n x n čísel od 1 do n**2, ktoré sú usporiadané do stĺpcov.
  • napr.

    zadaj n: 5
    
    1 6 11 16 21
    2 7 12 17 22
    3 8 13 18 23
    4 9 14 19 24
    5 10 15 20 25
    
  1. Napíšte skript, ktorý prečíta celé číslo n a vypíše tabuľku čísel s n riadkami, pričom v prvom sú čísla od 1 do n, každý ďalší riadok je o 1 kratší (bez posledného čísla), v poslednom je 1.
  • napr.

    zadaj pocet: 5
    
    1 2 3 4 5
    1 2 3 4
    1 2 3
    1 2
    1
    
  1. Upravte riešenie predchádzajúceho príkladu tak, že výpis každého riadku (okrem prvého) bude o 1 posunutý vpravo oproti predchádzajúcemu.
  • napr.

    zadaj pocet: 5
    
    1 2 3 4 5
     1 2 3 4
      1 2 3
       1 2
        1
    
  1. Napíšte skript, ktorý prečíta celé číslo n a vypíše výpočet faktoriálu tohto čísla v tvare n! = 1*2*...*n = číslo.
  • napr.

    zadaj n: 5
    
    5! = 1*2*3*4*5 = 120
    
  1. Napíšte skript, ktorý vypíše tabuľku výpočtu prvých 10 faktoriálov (vo formáte z predchádzajúceho príkladu). Použite vnorené cykly.
  • výpis by mal byť v tomto tvare

    1! = 1 = 1
    2! = 1*2 = 2
    3! = 1*2*3 = 6
    4! = 1*2*3*4 = 24
    ...