2.3 MicroPython: Základné konštrukcie jazyka
MicroPython je jednoduchou a efektívnou implementáciou programovacieho jazyka Python 3.4. Zahŕňa len časť štandardných knižníc Python, má však knižnice pre prácu s hardvérom a je optimalizovaný pre mikrokontroléry s obmedzenými zdrojmi. Snaží sa byť kompatibilný s plnohodnotným jazykom Python.
Základné konštrukcie jazyka MicroPython sú totožné s Python a môžeme teda využívať dokumentáciu jazyka Python. Oplatí sa však oboznámiť so špecifikami MicroPython - či už po stránke optimalizácie zápisov alebo špeciálnych knižníc určených pre ovládanie hardvéru.
Syntax MicroPython
Pre komentár v jazyku Python slúži znak „#“ a pre viacriadkový komentár je možné využiť viacriadkový text, ktorý začína i končí trojicou apostrofov: '''
Operátory
Matematické operátory sú podobné C++:
- +, -, *, /, %: sčítanie, odčítanie, násobenie, delenie, zvyšok po delení
- na rozdiel od C++ delenie celých čísel vráti desatinné číslo;
- //, **: celočíselné delenie, mocnina - navyše oproti C++.
Operátory porovnávania sú rovnaké ako v C++:
- ==, !=, <, >, <=, >=: rovný, nerovný, menší, väčší, …
Logické operátory sa píšu slovne:
- not, or, and: negácia, logický súčet, logický súčin.
Ďalšie informácie: W3Schools - Python Operators
Premenné a dátové typy
V názvoch premenných sa rozlišujú malé a veľké písmená, môžeme používať aj diakritiku. Premenné nie je potrebné deklarovať, priamo môžeme definovať hodnotu:
- {názov premennej} = {hodnota}
počet = 10
pi = 3.14
Logické hodnoty (boolean) sú označované True a False:
je_horúco = False
Textové reťazce môžu byť v úvodzovkách i apostrofoch - môžeme si vybrať:
meno = "Dušan"
priezvisko = 'Zervan'
Typ premennej je možné zistiť funkciou type({premenná}) - tá vracia objekt, no pre získanie názvu typu vo forme textového reťazca môžeme využiť jeho vlastnosť .__name__:
type(meno).__name__
Je možné priraďovať naraz do viacerých premenných:
meno, vek = "Anna", 15
Vstup a výstup
Výpis z MicroPython na štandardný výstup sa nerealizuje „na obrazovku“, ale na konzolu / sériový port.
Príkaz print({výraz 1}, {výraz 2}, …) vypíše zadané výrazy oddelené medzerou, na konci bude ENTER:
print(meno, "získal z testu", počet, "bodov.")
Ukončenie riadku určuje parameter end, oddeľovanie sep, napríklad:
print("údaje v CSV:", end=" ")
print(počet, poradie, meno, sep=";")
Premennú môžeme načítať z konzoly: {premenná} = input({text výzvy})
vek = input("Zadaj vek: ")
Používanie funkcií z modulov
...
Užitočné funkcie
Funkcie pre prácu s časom z modulu time: - umožňuju nielen získať systémový čas, ale aj pozastaviť vykonávanie programu a šetriť energiu, či merať trvanie úseku programu:
- sleep({čas}) / sleep_ms({čas}): vykoná úspornú pauzu trvajúcu zadaný počet sekúnd / milisekúnd;
- time() / time_ns(): vráti aktuálny čas v sekundách / nanosekundách;
- ticks_ms() / ticks_us(): vráti počet milisekúnd / mikrosekúnd od spustenia;
- ticks_diff({čas2}, {čas1}): vráti rozdiel časov z funkcií ticks_ms() a ticks_us().
V module machine nájdeme v MicroPython funkcie týkajúce sa hardvéru, pre nás bude potrebných len zopár:
- unique_id(): vráti identifikátor zariadenia;
- freq(): vráti frekvenciu procesora (v Hz) alebo ju nastaví na zadaný parameter;
- reset(): vykoná reštart.
Funkcie z modulu random:random umožňujú pohodlnú prácu s náhodnými číslami:
- random({čas}): vráti náhodné reálne číslo v intervale [0.0, 1.0]
;
- uniform({a}, {b}): vráti náhodné reálne číslo v intervale [a, b]
;
- randint({a}, {b}): vráti náhodné celé číslo v intervale [a, b]
;
- randrange({a}, {b}, {n}): vráti náhodný násobok celého čísla n z intervalu [a, b]
;
- choice({zoznam}): vráti náhodný prvok zo zoznamu alebo
tuplyFunkcie z modulu machine:unique_id(): vráti identifikátor zariadeniafreq(): vráti frekvenciu procesora (v Hz) alebo i nastaví
tuply.reset(): vykoná reštart
Funkcie textového reťazca
Textový reťazec je objekt, jedná sa teda o objektové funkcie. Tieto funkcie vracajúcevracajú nový objektobjekt, (nemenia pôvodný):pôvodný:
- .upper() / .lower(): prevod na malé / veľké
písmenápísmená;
- .strip(): odstráni „biele znaky“ zo začiatku a konca (trim)
;
- .replace({čo}, {čím}): nahradí reťazec iným
reťazcomreťazcom;
- .split({oddeľovač}): rozdelí reťazec do poľa (zoznamu reťazcov)
;
- .join({pole}): spojí prvky poľa (zoznam / tupla) do textového reťazca, oddeľovačom je textový
reťazecreťazec;
- .format({parametre}): mocná funkcia na spájanie textov s premennými, viď
https://pyformat.info.
ďalšieĎalšie funkcie:funkcie https://www.w3schools.com/python/python_ref_string.asppre prácu s textovým reťazcom: W3Schools - Python String Method
Kolekcie údajov
Python rozlišuje 3 typy „polí“:
list (zoznam), zátvorky [] - ako pole v C++, teda prvky majú svoje poradie, môžu sa opakovať a môžu sa meniť ich hodnoty
tuple, zátvorky () - ako list, ale prvky sa nemôžu meniť, ide teda o pevne daný nemenný zoznam, rýchlejšie spracovávaný
set (množina), zátvorky {} - prvky nemajú svoje poradie, nie je ich možné indexovať, nemôžu sa opakovať (žiadne duplikáty)
Najbohatšiu ponuku funkcií majú zoznamy, niektoré funkcie sú dostupné aj pre tuple a množiny.
Zoznam (list): zátvorky []
správa sa podobne ako pole v C++, prvky sa číslujú od 0
indexovať prvky je možné aj od konca (záporným číslom) a prvky nemusia byť rovnakého dátového typu, napr.:
⁘ čísla = ["dvanásť", 15, "štyri"]
⁘ print(čísla[-1])
počet prvkov: len({pole}), súčet prvkov: sum({pole})
prvky je možné uložiť do premenných:
⁘ {premenná 1}, {premenná 2}, … = {zoznam}
zoznamy je možné spojiť operátorom + a opakovať operátorom *
vloženie prvku do zoznamu:
⁘ .append({prvok}) - na koniec zoznamu
⁘ .insert({pozícia}, {prvok}) - na uvedenú pozíciu
odobratie prvku zo zoznamu:
⁘ .pop({pozícia}) - z uvedenej pozície (ak neuvedieme, z konca)
⁘ .remove({hodnota}) - prvý prvok obsahujúci uvedenú hodnotu
⁘ .clear() - vyprázdni celý zoznam (zostane prázdny)
ďalšie zaujímavé funkcie zoznamu:
⁘ .reverse() - v zozname otočí poradie prvkov
⁘ .sort() - abecedne zoradí zoznam, voliteľný parameter reverse
⁘ .count({hodnota}) - vráti počet prvkov s uvedenou hodnotou
viac funkcií: https://www.w3schools.com/python/python_lists_methods.asp
zistenie výskytu prvku v poli: {hľadaný prvok} in {pole} - vráti bool
delenie poľa: {pole}[{začiatok}:{koniec}] - od uvedeného začiatočného prvku (vrátane) po konečný prvok (bez neho)
- môžu byť aj záporné hodnoty (od konca)
- ak neuvedieme {začiatok}, začne prvým prvkom (č. 0)
- ak neuvedieme {koniec}, skončí posledným prvkom
rovnakým spôsobom môžeme aj prepisovať prvky na uvedenej pozícii:
- ak uvedieme prvky v rovnakom počte, prepíšu sa
- ak ich bude viac, nadbytočné sa vložia za prepísané
Tuple: zátvorky ()
ako zoznam, ale prvky sa nemôžu meniť, ide teda o pevne daný - nemenný zoznam, rýchlejšie spracovávaný
môže sa jednať aj o jediný prvok, vtedy musí končiť čiarkou:
⁘ {tuple} = ({prvok},)
poskytuje tie isté operácie a funkcie, ako majú zoznamy - s výnimkou tých, ktoré menia hodnoty
viac: https://www.w3schools.com/python/python_tuples_methods.asp
Množina (set): zátvorky {}
prvky nemajú svoje poradie, nie je ich možné indexovať, nemôžu sa opakovať (žiadne duplikáty)
pridanie prvku do množiny:
⁘ .add({prvok}) - pridá jeden prvok
⁘ .update({pole}) - pridá celú množinu / zoznam / tuple
odobratie prvku z množiny:
⁘ .remove({hodnota}) - ak neexistuje, spôsobí chybu
⁘ .discard({hodnota}) - ak neexistuje, ignoruje
viac: https://www.w3schools.com/python/python_sets_methods.asp
Slovník (dictionary)
údaje organizuje v pároch kľúč:hodnota rovnako ako JSON:
{slovník} = { {kľúč}: {hodnota}, … }
podobná forma ako množina (set) - neumožňuje duplikáty, čiže dva údaje nemôžu mať rovnaký kľúč
prístup ku jednotlivým prvkom je podobný ako pri zozname, no namiesto indexu uvádzame kľúč
viac: https://www.w3schools.com/python/python_dictionaries_methods.asp
Podmienený príkaz: if - elif - else
veľmi podobný C++, mierne odlišná syntax, nutné správne predsadiť!
⁘ if {podmienka 1}:
⁘ {príkazy pri splnení podmienky 1}
⁘ elif {podmienka 2}:
⁘ {príkazy pri splnení podmienky 2}
⁘ else:
⁘ {príkazy pri nesplnení žiadnej podmienky}
časť elif sa môže opakovať viackrát
nie je povinná ani časť elif, ani časť else
môžeme využívať aj vnorené podmienky, opäť treba správne predsadiť
Cyklus podľa podmienky: while
funguje rovnako ako v C++, mierne odlišná syntax:
⁘ while {podmienka}:
⁘ {príkazy tela cyklu}
tiež je možné použiť break (predčasné ukončenie cyklu) a continue (predčasný prechod na ďalšiu iteráciu) - rovnako ako v C++
cyklus môže obsahovať aj časť else: - vykoná sa po poslednej iterácii (teda nie po ukončení cez break)
Cyklus pre zoznam a interval hodnôt: for
odlišuje sa od C++, používa sa na prechod sekvenciou (zoznam, reťazec):
⁘ for {premenná} in {zoznam}:
⁘ {príkazy tela cyklu}
⁘ for x in [1, 2, 4, 8]:
⁘ print(x)
vytvorí lokálnu premennú, bude v nej iterovať hodnoty zo zoznamu
výrazy break, continue a else je možné používať rovnako ako v cykle while
pre vytvorenie zoznamu čísel môžeme využiť funkciu range():
⁘ range({počet}) - od čísla 0 po {počet} - 1
⁘ range({začiatok}, {koniec}) - od začiatku (vrátane) po koniec (bez)
⁘ range({začiatok}, {koniec}, {krok}) - s uvedeným krokom
príklad:
⁘ for x in range(10, 30, 5):
⁘ print(x) # 10 15 20 25
Definícia funkcie
pri definícii funkcie neuvádzame ani návratovú hodnotu, ani typ parametrov, inak je podobná C++
⁘ def {názov} ({parametre}):
⁘ {príkazy tela funkcie}
funkcia nemusí mať parametre, zátvorky musia byť uvedené
parametre môžu byť nepovinné (mať predvolenú hodnotu)
výsledok (jedinú návratovú hodnotu) je možné odovzdať a funkciu ukončiť cez return
viac výsledkov je možné odovzdať cez yield - ide o generátor, funkcia sa neukončí
funkcia môže používať globálne premenné, deklaruje ich výraz global
volanie (použitie) funkcie je podobné C++
Parametre funkcie
parametre je možné volať s menom v ľubovoľnom poradí, napr.:
⁘ def Priemer(sucet, pocet):
⁘ return sucet / pocet
⁘ print(Priemer(pocet=10, sucet=45)) # 4.5
funkcia môže mať aj viacnásobný parameter:
- ak názov začína znakom *, používa sa ako tuple
- ak názov začína znakmi **, používa sa ako slovník s názvom parametra pri volaní
Lambda
lambda je jednoduchá anonymná funkcia, ktorú formálne môžeme priradiť do premennej:
⁘ lambda {parametre} : {výraz s parametrami}
príklad:
⁘ SúčetČísel = lambda x : (1 + x) * x / 2
⁘ print(SúčetČísel(10))
viac: https://www.w3schools.com/python/python_lambda.asp
Zachytávanie výnimiek (chýb)
princíp rovnaký ako v C++, mierne odlišná syntax:
⁘ try:
⁘ {príkazy}
⁘ except:
⁘ {príkazy, ak nastala chyba}
⁘ else:
⁘ {príkazy, ak nenastala chyba}
⁘ finally:
⁘ {príkazy spustené vždy na záver}
časti else a finally nie sú povinné
príkazy finally sa vykonajú vždy, a to aj v prípade predčasného ukončenia cez break a return
za výrazom except môže byť uvedený typ zachytávanej chyby
viac: https://www.w3schools.com/python/python_try_except.asp
Inštalácia rozširujúcich modulov
rozširujúce moduly môžeme nahrať ručne do priečinku /lib alebo do aktuálneho / koreňového priečinku
ak je modul prítomný na viacerých miestach, uplatní sa priorita definovaná v sys.path
predvolená priorita v MicroPython je: 1. aktuálny priečinok, 2. zabudovaný modul (frozen), 3. priečinok /lib
v školskej inštalácii je priorita zmenená nasledovne: 1. aktuálny priečinok, 2. priečinok /lib, 3. zabudovaný
pokiaľ je aktívne pripojenie do internetu (na Wi-Fi), je možné automatizovane stiahnuť modul do /lib, stačí poznať jeho názov:
⁘ import mip
⁘ mip.install("{názov modulu}")
Trieda (class)
...