Přeskočit na obsah

Programování pro hračičky/Opičky/Lekce 6

Z Wikiverzity
Jak používat klasifikační nálepkuTato stránka je součástí kurzu:
středoškolská
Příslušnost: skupinová

Přehlednější zápis programů

[editovat]

Dokud jsme v programech pro svou opičku nepoužívali podmínky, byl zápis programu do jednoho řádku za sebe ještě poměrně přehledný, protože opička konala postupně všechny příkazy, jak byly v tomto řádku za sebou zapsány. Vzpomeňme si třeba na příkaz vyměň, kterému jsme opičku naučili ve 4. lekci:

'ájo pozor vyměň tohle tamto znamená polož tohle, vezmi tamto, prohlédni si tamto, tvař se jako opička mající tamto

Program tohoto příkazu si můžeme o něco přehledněji znázornit způsobem, jakým si ho přečteme na vodítku (i to jsme si ukazovali ve 4. lekci, jen o kapitolu dál):

vymen <1> <2>: polož <1>, vezmi <2>, prohlédni si <2>, tvař se jako opička mající <2>

anebo si můžeme jednotlivé příkazy představit třeba takhle pod sebou:

vymen <1> <2>:
  polož <1>
  vezmi <2>
  prohlédni si <2>
  tvař se jako opička mající <2>

Dokud ovšem celý program spočívá v postupném vykonávání souvislé posloupnosti příkazů, pak ani jeden z těchto zápisů nezvýší přehlednost příkazu nijak výrazně. Jakmile se však náš program začne větvit podle splněných či nesplněných podmínek, začne první i druhý zápis pro náš lidský pohled přehlednost ztrácet. Připomeňme si příklad s příkazem vemsu3 z minulé lekce, který jsme opičce zadali takto:

'ájo pozor vemsu3 znamená pokud vidíš sušenku, vem sušenku, očichej sušenku, jinak tvař se jako opička toužící po sušence, potom usměj se, vzdychni

Když si přečteme týž příkaz na obojku opičky, uvidíme:

vemsu3: pokud vidíš sušenku, vem sušenku, očichej sušenku, jinak, tvař se
        jako opička toužící po sušence, potom, usměj se, vzdychni

Když si ovšem nyní celý program příkazu zapíšeme po jednotlivých krocích pod sebe a odsazením odlišíme jednotlivé souvislé části, zjistíme, že se v celku můžeme najednou mnohem lépe orientovat:

vemsu3:
  pokud vidíš sušenku
    vem sušenku
    očichej sušenku
  jinak
    tvař se jako opička toužící po sušence
  potom
  usměj se
  vzdychni

A ještě o něco lepší to bude, když si očíslujeme jednotlivé řádky, abychom potom mohli bez složitého vysvětlování hovořit třeba o tom, co opička provádí zrovna na řádku 3:

vemsu3:
  pokud vidíš sušenku
    vem sušenku
    očichej sušenku
  jinak
    tvař se jako opička toužící po sušence
  potom
  usměj se
  vzdychni

Tento způsob zápisu programů budeme nadále používat pro své programátorské úvahy. Opičkám budeme samozřejmě programy zadávat stejně jako dříve (jinak to opička neumí), ale nám tento zápis usnadní přemýšlení. Nesmíme jen zapomenout, že při předávání programu opičce je potřeba mezi jednotlivé kroky doplnit ještě oddělující čárky:

'ájo pozor vemsu3 znamená pokud tu je sušenka, vem sušenku, očichej sušenku, jinak, tvař se jako opička toužící po sušence, potom, usměj se, vzdychni

A také bychom měli mít na paměti, že námi zapsaná struktura programu existuje v naší mysli, nikoli v paměti opičky. Opička pracuje s jednou nepřerušenou řadou příkazů, v níž se orientuje pomocí klíčových slov jako pokud, jinak, potom apod. Protože je sama naprogramovaná, o příkazech nijak nepřemýšlí, a nemusí si je tudíž uspořádávat do žádné přehledné struktury. Uspořádání je naše, a jen my sami si také ručíme za to, jak v něm například odsadíme jednotlivé řádky — když to uděláme chybně, budeme si možná funkci programu představovat jinak, než jak jej potom bude opička vykonávat.

Vnořené podmínky

[editovat]

Vyzbrojeni možností přehlednějšího zápisu programů si můžeme zkusit několik příkladů se složitějším použitím podmínek.[1] Nechme opičku například jednat různě podle toho, zda má hlad, ale rozlišme v obou případech ještě, zda má žízeň:

hladzizen:
  pokud nemáš hlad
    pokud máš žízeň
      tvař se žíznivě a nehladově
    jinak
      tvař se zcela nasyceně
  jinak
    pokud máš žízeň
      tvař se hladově a žíznivě
    jinak
      tvař se hladově a nežíznivě

V příkazu hladzizen jsme podmínku použili třikrát. Nejprve jsme rozlišili, zda opička má nebo nemá hlad, a do obou větví programu jsme pak vnořili ještě podrobnější rozlišení, zda opička má nebo nemá žízeň. Ve všech případech jsme přitom použili podmínku s oběma variantami, tedy popsali jsme, co má opička dělat pokud ... , i co má opička dělat jinak. Co kdybychom ale chtěli, aby se opička projevovala jen v případě, že má hlad nebo žízeň? Co kdybychom zkusili napsat:

hladzizen:
  pokud nemáš hlad
    pokud máš žízeň
      tvař se žíznivě
  jinak
    pokud máš žízeň
      tvař se hladově a žíznivě
    jinak
      tvař se hladově

Můžeme si vyzkoušet, že tento program by nefungoval kýženým způsobem. Projeví se tu totiž, že přehledná struktura programu je jen v naší mysli, zatímco opička prostě vykonává příkaz za příkazem, a slovo jinak přiřadí vždy poslední předcházející podmínce pokud, která ještě nebyla ukončena a k níž zatím nebylo přiřazeno žádné jinak. Když si to přeložíme opět do myšlenkového schématu, provede opička toto:

hladzizen:
  pokud nemáš hlad
    pokud máš žízeň
      tvař se žíznivě
    jinak
      pokud máš žízeň
        tvař se hladově a žíznivě
      jinak
        tvař se hladově

Aby opička vykonávala to, co chceme, musíme jí nějak sdělit, že ono první jinak nepatří ke druhému, nýbrž k prvnímu pokud. A to můžeme udělat buď pomocí slova jinak, jímž vytvoříme prázdnou druhou variantu druhého pokud, nebo pomocí slova potom, jímž opičce sdělíme, že část programu patřící ke druhému pokud skončila:

hladzizen:
  pokud nemáš hlad
    pokud máš žízeň
      tvař se žíznivě
    jinak
  jinak
    pokud máš žízeň
      tvař se hladově a žíznivě
    jinak
      tvař se hladově
hladzizen:
  pokud nemáš hlad
    pokud máš žízeň
      tvař se žíznivě
    potom
  jinak
    pokud máš žízeň
      tvař se hladově a žíznivě
    jinak
      tvař se hladově

Pokud nás toto použití slova jinak nebo potom na řádku 4 poněkud mate, představme si, jako by za tímto slovem byl ještě příkaz nedělej nic. Takový příkaz opička reálně nezná. Pokud nemá dělat nic, prostě jí nenapíšeme žádný příkaz — a přesně to je případ onoho řádku 4, po němž nenásleduje žádný příkaz, a pak už řádkem 5 začíná druhá větev podmínky z řádku 1.

Zřetězené podmínky

[editovat]

Vnořování podmínek, které jsme si vyzkoušeli v minulé kapitole této lekce, se nám hodí všude tam, kde chceme otestovat, zda bylo splněno několik podmínek naráz. Často však stojíme před potřebou v jistém smyslu opačnou — potřebujeme zjistit, zda z celé řady podmínek platí vůbec nějaká. Naše opička má třeba prověřit různé možnosti nasycení:[2]

  pokud vidíš sušenku
    vem sušenku
    jez sušenku
  jinak
    pokud vidíš mrkev
      vem mrkev
      jez mrkev
    jinak
      pokud vidíš citrón
        vem citrón
        jez citrón
      jinak
        tvař se naprosto nešťastně

Na tomto místě si opět můžeme uvědomit onen zásadní poznatek, že struktura programu jestvuje v naší mysli, a ono postupné prověření několika rovnocenných podmínek si zapsat přehledně pod sebe tak, že všechna další pokud pospojujeme s předcházejícími jinak:

  pokud vidíš sušenka
    vem sušenku
    jez sušenku
  jinak pokud vidíš mrkev
    vem mrkev
    jez mrkev
  jinak pokud vidíš citrón
    vem citrón
    jez citrón
  jinak
    tvař se naprosto nešťastně

A když už umíme základní strukturu těchto zřetězených podmínek napsat takhle přehledně pod sebe, nic nám nebrání začít do ní vnořovat další podmínky:

  pokud vidíš ledničku
    pokud vidíš kohoutek
      tvař se jako opička v kuchyni
    potom
  jinak pokud vidíš černou knihu
    tvař se jako opička v knihovně
  jinak pokud vidíš kohoutek
    pokud vidíš mísu
      tvař se jako opička na záchodě
    jinak
      tvař se jako opička v záchodové předsíni
    potom
  jinak pokud vidíš truhlu
    pokud vidíš východní okno
      pokud vidíš severní dveře
        tvař se jako opička ve snídárně
      potom
    potom
  jinak
    tvař se jako ztracená opička

Využití podprogramů

[editovat]

Je možné, že jsme už ve druhé kapitole této lekce narazili na problém popsaný v poznámce pod čarou. Je také možné, že jsme na něj narazili až u posledního příkladu vnořování podmínek do zřetězených podmínek, anebo že jsme na něj dosud nenarazili, protože opičku máme už opravdu dobře vycvičenu. Přesto však stále přemýšlíme jako lidé, a proto si snáze představíme několik jednoduchých struktur než jednu složitou. Co třeba takovéhle tři příkazy:

hladova:
  pokud máš hlad
    tvař se hladově
  jinak
    netvař se hladově
zizniva:
  pokud máš žízeň
    tvař se žíznivě
  jinak
    netvař se žíznivě
testhlz:
  hladova
  zizniva

Ano, podařilo se nám poskládat k sobě několik testů tak, že je nevnořujeme aní neřetězíme, ale každý obstaráváme pěkně přehledně, tedy každý zvlášť a oba krátce, a ještě kratší je pak jejich spojení. Tímto příjemným trikem se sice nedají vyřešit všechny situace — někde se skutečně neobejdeme bez vnořování nebo řetězení — ale mnoho složitých a nepřehledných programů můžeme učinit výrazně pochopitelnějšími, když si je rozdělíme na několik podprogramů. Například:

zhernykjosefovi:
  západ
zesnidarnykjosefovi:
  jih
  zhernykjosefovi
zkuchynekjosefovi:
  jih
  zesnidarnykjosefovi
jetokuchyne:
  pokud vidíš ledničku
    pokud vidíš kohoutek
      zkuchynekjosefovi
      konec
jetosnidarna:
  pokud vidíš truhlu
    zesnidarnykjosefovi
    konec
jetoherna:
  pokud vidíš pohovku
    pokud vidíš hračky
      zhernykjosefovi
      konec
kjosefovi:
  jetokuchyne
  jetosnidarna
  jetoherna
  tvař se bezradně

Všimněme si, že v příkazech jetokuchyne, jetosnidarna a jetoherna jsme využili slova konec, které jinak známe jako nouzové zastavovátko zvenčí. Použijeme-li je takto v programu, funguje úplně stejně — když na ně opička při vykonávání programu narazí, ukončí celý program.

Pokud víme, že složité programy můžeme rozkládat do jednoduchých podprogramů (anebo jinými slovy, jednoduché podprogramy můžeme skládat do složitých programů) a že v libovolném místě programu, kde jsme shledali, že opička už vykonala všechno potřebné, můžeme slovem konec program ukončit, víme toho dost k tomu, abychom splnili následující úkoly, resp. aby nám opička pomalu začala být opravdovou pomocnicí ve hře.

Úkoly

[editovat]
  • Naprogramujte příkaz, kterým Vám Vaše opička oznámí, zda má nebo nemá hlad a žízeň. Nekopírujte ovšem příklad z této lekce, nýbrž snažte se vymyslet si nějaký jiný způsob, jak opička hlad a žízeň nebo jejich absenci projeví — a případně i jinou (ideálně pro Vás jednodušší nebo logičtější) strukturu programu.
  • Vyberte si tři místnosti, v nichž s opičkou často nebo rádi pobýváte, a naprogramujte příkaz, kterým opička zjistí, zda se nachází v některé z těchto tří místností, a pokud ano, tak se přemístí do té z nich, kterou máte nejraději.
  • Naprogramujte příkaz, jímž Vaše opička nejprve ověří, zda se nachází ve Vaší nejoblíbenější místnosti, pak zjistí, zda má hlad nebo žízeň (nebo obojí), a pokud ano, tak se dojde najíst nebo napít (nebo obojí).

Pracovní odkazy

[editovat]

Poznámky

[editovat]
  1. Pokud jsme zatím neplnili pilně všechny úkoly v minulých lekcích a nestarali se dost dobře o svou opičku, může se nám stát, že některé rozsáhlejší příklady budou na naši opičku příliš dlouhé. Můžeme to vyřešit buď tím, že ponejprv budeme ještě nějakou dobu dělat se svou opičkou věci jednodušší a sem se vrátíme, až se tím schopnosti naší opičky vycvičí, anebo tím, že dlouhé programy rozložíme v několik krátkých, jak se to popisuje ve čtvrté kapitole této lekce.
  2. V příkladech, v nichž nezáleží na tom, jak pojmenujeme celý program, pro přehlednost vynecháváme v zápise řádku 0, na níž by jinak bylo jméno programu uvedeno. Klidně bychom i tu řádku 0 mohli uvést, ale jde o to, abychom si uvědomili, že záleží skutečně jen a jen na nás samotných, jak si budeme programy pro svůj výklad zapisovat.