Tlačítka

Zatiaľ sme vytvorili kód, ktorý hovorí zariadeniu, čo má robiť. Tomu hovoríme výstup (output). Niekedy ale potrebujeme, aby naše zariadenie reagovalo na podnety. Tomu hovoríme vstupy (input).

Zapamätáš si to ľahko: výstup je niečo, čo ide zo zariadenia von do sveta a vstup je niečo, čo vchádza do zariadenia, ktoré to spracuje.

Asi najviac viditeľný spôsob vstupu na micro:bite sú jeho dve tlačítka, označené ako A a B. Potrebovali by sme, aby MicroPython nejako reagoval, keď tlačítka stlačíme.

Toto je obzvlášť jednoduché:

from microbit import *

sleep(10000)
display.scroll(str(button_a.get_presses()))

Tento skript najskôr spí desať tisíc milisekúnd (teda 10 sekúnd) a potom posúvaním zobrazí počet, koľko krát si stlačil(a) tlačítko A. To je všetko!

Uznávam, trochu zbytočný skript, ale zoznamuje nás s niekoľkými zaujímavými novými myšlienkami:

  1. Funkcia sleep („spať“) povie micro:bit, že má spať určité množstvo milisekúnd. Ak chceš mať vo svojom programe pauzu, urobíš to presne takto. Funkcia je presne ako metóda, akurát nie je spojená bodkou s objektom.
  2. Ďalej máme objekt s názvom button_a („tlačítko A“), ktorý nám umožňuje zistiť, koľko krát bolo stlačené pomocou metódy get_presses.

Keďže get_presses dáva číselnú hodnotu a display.scroll vie zobrazovať iba znaky, musíme numerickú hodnotu konvertovať (premeniť) na reťazec znakov. To urobíme pomocou funkcie str (skratka pre „string“ = reťazec) ~ mení veci na reťazce znakov).

Tretí riadok je trochu ako cibuľa. Ak by boli zátvorky šupky cibule, videli by sme, že display.scroll obsahuje str, ktoré obsahuje button_a.get_presses. Python sa snaží spracovať to od najhlbšie vnorenej odpovede smerom k vonkajším vrstvám. Hovoríme tomu nesting („hniezdovanie“) - programovací ekvivalent ruských matriošiek.

../_images/matrioshka.jpg

Predstavme si, že si stlačil(a) tlačítko 10-krát. Takto Python spracuje to, čo sa deje na riadku tri:

Python vidí celý riadok a získa hodnotu z``get_presses``:

display.scroll(str(button_a.get_presses()))

Teraz, keď už Python vie, koľkokrát bolo tlačítko stlačené, premení číslo na reťazec znakov:

display.scroll(str(10))

Nakoniec Python vie, čo má zobraziť a posúvať po obrazovke:

display.scroll("10")

Hoci to vyzerá ako kopec práce, MicroPython to zvládne neobyčajne rýchlo.

Cykly

Často potrebujeme, aby program len tak čakal na nejakú zaujímavú udalosť. Na to môžeš využiť slučku = opakovanie kúska kódu, ktorý hovorí o tom, akomá program reagovať v prípade špeciálnych udalostí, napríklad stlačenie tlačítka.

Na takéto cykly v Pythone používame slovo while („kým“), ktoré kontroluje, či je niečo pravdivé (True). Ak je, spustí blok kódu, ktoému hovorím telo slučky. Ak podmienka nie je pravdivá, vyskočí zo slučky (preskočí telo) a pokračuje vo vykonávaní zvyšku programu.

V Pythone je jednoduché písať blok kódu. Povedzme, že mám zoznam úloh napísaný na papieri. Bude to vyzerať asi takto nejako:

Shopping
Fix broken gutter
Mow the lawn

Ak by som chcel posunúť môj zoznam úloh trochu ďalej, mohol by som napísať niečo takéto:

Shopping:
    Eggs
    Bacon
    Tomatoes
Fix broken gutter:
    Borrow ladder from next door
    Find hammer and nails
    Return ladder
Mow the lawn:
    Check lawn around pond for frogs
    Check mower fuel level

Je zrejmé, že hlavné úlohy sú rozdelené do pod-úloh, ktoré sú odsadené pod hlavnou úlohou, ku ktorej patria. Takže Vajíčka, Slanina a Rajčiny samozrejme patria ku Nákupu. Odsadením vecí docielime, že je na prvý pohľad jasné, ktoré úlohy patria k sebe.

To sa volá nesting („hniezdovanie“). Používame ho na definovanie blokov kódu, ako napríklad tento:

from microbit import *

while running_time() < 10000:
    display.show(Image.ASLEEP)

display.show(Image.SURPRISED)

Funkcia running_time (čas behu) vracia počet milisekúnd od spustenia zariadenia.

Riadok while running_time() < 10000: kontroluje či čas behu (running time) je menej ako 10000 milisekúnd (teda 10 sekúnd). Ak je, a toto je presne miesto, kde prichádza do akcie scoping, potom zobrazí ospalý obrázok Image.ASLEEP. Všimni si, ako je odsadný pod výrazom while presne ako v našom zozname úloh.

Je jasné, že ak je čas behu rovný alebo väčší ako 10000 milisekúnd, displej zobrazí Image.SURPRISED (obrázok Prekvapený). Prečo? Lebo podmienka pre while bude nepravdivá (False), pretože running_time (čas behu) už nie je < 10000. V tom prípade cyklus skončí a program bude pokračovať tam, kde končí blok kódu v cykle while. Bude to vyzerať, ako keby tvoj micro:bit 10 sekúnd spal a potom sa zobudil s prekvapeným výrazom na tvári.

Vyskúšaj to!

Spracovanie udalosti

Ak chceme, aby MicroPython reagoval na stlačenia tlačítka, musíme dať kód do nekonečného cyklu (slučky) a kontrolovať, či je tlačítko stlačené (is_pressed).

Urobiť nekonečný cyklus je jednoduché:

while True:
    # Do stuff

(Nezabudni, while kontroluje či je niečo pravdivé (True), aby určil, či má spustiť blok kódu. Keďže Pravda (True) je jednoznačne vždy pravdivá, dostaneš tak nekonečný cyklus!)

Urobme si veľmi jednoduché kyber zvieratko. Ak nestlačíš tlačítko A, tak je stále smutné. Ak stlačíš tlačítko B, umrie. (Uznávam, že tot nie je veľmi pekná hra, ale aspoň máš priestor na zlepšenie.):

from microbit import *

while True:
    if button_a.is_pressed():
        display.show(Image.HAPPY)
    elif button_b.is_pressed():
        break
    else:
        display.show(Image.SAD)

display.clear()

Vidíš, ako kontrolujeme, ktoré tlačítka sú stlačené? Použili sme if („ak“), elif (skratka pre „else if“ = „inak ak“) a else („inak“). Hovoríme im podmienky a fungujú takto:

if something is True:
    # do one thing
elif some other thing is True:
    # do another thing
else:
    # do yet another thing.

Toto sa vážne podobá na angličtinu!

Metóda is_pressed dáva iba dva výsledky: True („pravda“) alebo False („nepravda“). Ak práve stláčaš tlačítko, vráti True, inak vráti False. Vyššie uvedený kód hovorí, po slovensky, „na večné veky, ak je stlačené tlačítko A, ukáž veselú tvár, inak ak je stlačené tlačítko B, vyskoč z cyklu, inak zobraz smutnú tvár.“ Z cyklu vyskočíme pomocou príkazu break (inak by program bežal na večné veky).

Na úplnom konci, keď kyber zvieratko umrie, vyčístíme (clear) displej.

Vieš vymyslieť nejaký spôsob, aby táto hra nekončila tak tragicky? Ako by si skontroloval(a), či sú stlačené obidve tlačítka? (Hint: Python má logické operátory and („a“), or („alebo“) a not („nie“), pomocou ktorých môžeš skontrolovať rôzne výrazy (veci, čo vracajú ako výsledky buď pravda alebo nepravda - True alebo False).