This shows you the differences between two versions of the page.
sde2:laboratoare:02_microbit_ro [2021/03/17 10:21] ioana_maria.culic [Variabile] |
sde2:laboratoare:02_microbit_ro [2021/03/22 11:05] (current) alexandra.state2607 [Exerciții] |
||
---|---|---|---|
Line 16: | Line 16: | ||
* Conectarea micro:bit-ului la PC | * Conectarea micro:bit-ului la PC | ||
* Încărcarea programelor pe micro:bit | * Încărcarea programelor pe micro:bit | ||
+ | * Definirea variabilelor folosind limbajul Python | ||
+ | * Familiarizarea cu structurile de date folosind limbajul Python | ||
+ | * Utilizarea structurilor repetitive și utilizarea funcțiilor folosind limbajul Python | ||
+ | * Crearea claselor și a obiectelor folosind limbajul Python | ||
Line 56: | Line 60: | ||
</code> | </code> | ||
- | Pentru a accesa simulatorul daca folosiți Linux sau MacOS scrieți comanda: | + | Pentru a accesa simulatorul deschideti un browser si accesati pagina ''http://localhost:8000/editor.html''. |
- | <code> | + | |
- | $ firefox editor.html | + | |
- | </code> | + | |
- | + | ||
- | Dacă folosiți Windows fie puteți folosi comanda anterioară, fie intrați in folder-ul "PythonEditor" și faceți click pe "editor.html". | + | |
Pentru a simula codul faceți click pe "Sim". Testați pentru **Exemplul 1** din secțiunea următoare. | Pentru a simula codul faceți click pe "Sim". Testați pentru **Exemplul 1** din secțiunea următoare. | ||
Line 125: | Line 124: | ||
{{ :sde2:laboratoare:flash.png?250 | }} | {{ :sde2:laboratoare:flash.png?250 | }} | ||
+ | <note info> | ||
+ | Pentru a vizualiza mesajele printate în consolă, trebuie să selectăm opțiunea ''Open Serial'' care va deschide terminalul cu un interpretorul de Python. | ||
+ | </note> | ||
===== Programarea Python ===== | ===== Programarea Python ===== | ||
<note warning> | <note warning> | ||
Line 206: | Line 207: | ||
- | ===== Excepții în Python ====== | ||
- | Există 2 tipuri de execpții: erori de sintaxă și de excepții. | + | =====Structuri de date==== |
- | **Erorile de sintaxă**, cunoscute sub numele de erori de analiză (parsing error) sunt cele mai cunoscute: | + | === Liste === |
+ | Listele sunt similare cu array-urile. Pot conține nenumărate tipuri de variabile și de de elemente. | ||
+ | <note warning> Desi Python permite adaugarea de elemente de tipuri diferite in aceeasi lista, este recomandat sa nu faceti acest lucru care poate duce la aparitia a multe erori in program.</note> | ||
+ | |||
+ | Pentru a crea o listă care contine elemente de tip intreg vom rula următoarea linie de cod: | ||
<code python> | <code python> | ||
- | >>> while True print('Hello world') | + | myList = [1,2,3,4,5] |
- | File "<stdin>", line 1 | + | |
- | while True print('Hello world') | + | |
- | ^ | + | |
- | SyntaxError: invalid syntax | + | |
</code> | </code> | ||
- | **Excepțiile** apar la momentul execuției: | + | Putem de asemeanea să creăm o listă goală, la care vom adăuga elemente ulterior: |
+ | <code python> | ||
+ | # Declararea unei liste | ||
+ | |||
+ | mylist = [] | ||
+ | |||
+ | # Inserarea elementelor | ||
+ | |||
+ | mylist.append(1) | ||
+ | mylist.append(2) | ||
+ | mylist.append(3) | ||
+ | </code> | ||
+ | |||
+ | Pentru a extrage un element din listă folosim o construcție de tipul ''lista[indice]'': | ||
<code python> | <code python> | ||
- | >>> 10 * (1/0) | + | |
- | Traceback (most recent call last): | + | mylist = [1,2,3] |
- | File "<stdin>", line 1, in <module> | + | |
- | ZeroDivisionError: division by zero | + | # Afișarea fiecărui element |
+ | |||
+ | print( mylist[0] ) | ||
+ | print( mylist[1] ) | ||
+ | print( mylist[2] ) | ||
+ | |||
+ | # Output | ||
+ | 1 | ||
+ | 2 | ||
+ | 3 | ||
</code> | </code> | ||
- | === Gestionarea excepțiilor ==== | + | <note> |
+ | În toate limbajele de programare numerotarea elementelor dintr-o listă începe de la indicele 0. | ||
+ | </note> | ||
+ | |||
+ | ==Funcția range== | ||
+ | <note warning> | ||
+ | Informațiile din această secțiune se aplică doar pentru folosirea limbajului Python pentru micro:bit. | ||
+ | </note> | ||
+ | Pentru a crea o listă cu elemente numere întregi, putem folosi funcția ''range'' care întoarce o listă cu toate numerele întregi dintr-un anumit interval. Funcția are urmăatarea definiție: ''range(start, stop, pas)'', unde ''start'' este prima valoare din listă, ''stop'' este valoarea de oprire (valoarea nu este inclusă), ''pas'' este pasul de incrementare și este un parametru opțional (valoarea default e 1). | ||
+ | |||
+ | **Exemplu** | ||
+ | |||
+ | Pentru a crea o listă cu valori pare de la 2 la 12, vom rula următoarea linie de cod: | ||
- | Pentru a rezolva execpțiile în Python, se utilizează bloc-ul **try-except**, ca în exemplul următor: | ||
- | |||
<code python> | <code python> | ||
- | while True: | + | mylist = range (2, 13, 2) |
- | try: | + | |
- | x = int(input("Please enter a number: ")) | + | |
- | break | + | |
- | except ValueError: | + | |
- | print("Oops! That was no valid number. Try again...") | + | |
</code> | </code> | ||
+ | ==Funcții predefinite pentru gestionarea listelor == | ||
+ | * [[https://www.tutorialspoint.com/python/list_cmp.htm|cmp( listName1, listName2)]] -> compararea elementelor din 2 liste | ||
+ | * [[https://www.tutorialspoint.com/python/list_len.htm|len( listName ) ]] -> numărul de elemente din listă | ||
+ | * [[https://www.tutorialspoint.com/python/list_max.htm|max( listName )]] -> elemntul cu valoarea maximă | ||
+ | * [[https://www.tutorialspoint.com/python/list_min.htm|min( listName )]] -> elementul cu valoarea minimă | ||
- | ===== Input devices sau butoane ===== | + | == Metode predefinite pentru gestionarea listelor == |
+ | * [[https://www.tutorialspoint.com/python/list_append.htm|listName.append( element )]] -> inserarea unui element la finalul listei | ||
+ | * [[https://www.tutorialspoint.com/python/list_count.htm|listName.count( element )]] -> numarul de apariții al unui elemnt într-o listă | ||
+ | * [[https://www.tutorialspoint.com/python/list_index.htm|listName.index( element )]] -> indicele de la prima apariție a elementului în listă | ||
+ | * [[https://www.tutorialspoint.com/python/list_insert.htm|listName.insert( index, element )]] -> inserearea elementului în listă la indicele indicat | ||
+ | * [[https://www.tutorialspoint.com/python/list_pop.htm|listName.pop()]] -> șterge și returnează ultimul element al listei | ||
+ | * [[https://www.tutorialspoint.com/python/list_remove.htm|listName.remove( element )]] -> șterge ultimul element din listă | ||
+ | * [[https://www.tutorialspoint.com/python/list_reverse.htm|listName.reverse()]] -> inversează oridnea elementelor din listă | ||
+ | * [[https://www.tutorialspoint.com/python/list_sort.htm|listName.sort( [function] )]] -> sortează elemnetele în funcție de parametru | ||
- | În schema microcontroller-ului prezentată anterior, se poate observa faptul că [[https://ocw.cs.pub.ro/courses/sde/laboratoare/02_microbit_ro?&#prezentare_bbc_microbit|micro:bit-ul]] are trei butoane. | + | === Dicționar === |
- | Cel de pe spate este pentru **reset**. Dacă acest buton este apăsat timp de cinci secunde microcontroller-ul va opri rularea programului care este încarcat. Totodată, dacă butonul de reset este apăsat scurt programul care este flash-uit pe placuță se va reseta. | + | Un dicționar este o structură de date similară cu vectorii sau cu listele, dar funcționează cu cheie și valoare în loc de indice. Fiecare valoare stocată într-un dicționar poate fi accesată cu ajutorul unei chei, care poate fi reprezentată de orice tip de obiect(un șir, un număr, o listă etc.). |
- | Pe partea din față se pot observa două butoane A și B, care pot fi accesate în cod astfel //button_a// și //button_b//. Acestea au o metoda //is_pressed()//, care va returna //True// dacă butonul este apăsat, în caz contrar metoda va returna //False//. | + | De exemplu, dicționarele pot fi utilizate pentru a implementa baze de date, Presupunând că avem o bază de date de studenți trebuie să reținem specializarea pentru care fiecare a optat. |
- | În acest exemplu vom folosi condiționalul “if” sau “if statement”. | + | == Declararea unui dicționar == |
<code python> | <code python> | ||
- | # Simple decision | + | specialisation = {} |
+ | |||
+ | specialisation["Ana"] = "Informatique" | ||
+ | specialisation["Radu"] = "Electronique" | ||
+ | </code> | ||
+ | |||
+ | Sau | ||
+ | |||
+ | <code python> | ||
+ | specialisation = { | ||
+ | "Ana": "Informatique", | ||
+ | "Radu": "Electronique" | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | == Parcurgerea elementelor dintr-un dicționar == | ||
+ | |||
+ | <code python> | ||
+ | for nom, spec in specialisation.iteritems(): | ||
+ | print ("Le nom de l'optionel ou {} a été répartisé est: {}".format(nom, spec)) | ||
+ | </code> | ||
+ | |||
+ | == Eliminarea valorilor dintr-un dicționar == | ||
+ | |||
+ | <code python> | ||
+ | del optionalRepartizare["Ana"] | ||
+ | |||
+ | # sau | ||
+ | |||
+ | optionalRepartizare.pop("Ana") | ||
+ | </code> | ||
+ | |||
+ | == Proprietățile cheilor într-un dicționar == | ||
+ | |||
+ | Într-un dicționar nu există restricționări pentru valori, doar pentru chei, acestea trebuie să fie unice. În cazul în care nu se respectă această proprietate și există aceeași cheie de 2 ori, doar ultima înregsitrată va fi validă. | ||
+ | De exemplu, pentru următoarea secvență de cod: | ||
+ | |||
+ | <code python> | ||
+ | age = { | ||
+ | "Ana" : 14, | ||
+ | "Ioana" : 13, | ||
+ | "Ana" : 16, | ||
+ | "Ioana" : 22, | ||
+ | "Ana" : 11 | ||
+ | } | ||
+ | |||
+ | print ("Ana a {} années et Ioana a {} années.".format(age["Ana"], age["Ioana"])) | ||
+ | |||
+ | </code> | ||
+ | |||
+ | Se va afișa mesajul urmator: "Ana a 11 années et Ioana a 22 années.". | ||
+ | |||
+ | == Funcții utile pentru dicționare == | ||
+ | |||
+ | * [[https://www.tutorialspoint.com/python/dictionary_cmp.htm|cmp(dictionarUnu, dictionarDoi)]] -> compararea elementelor a 2 dicționare | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_len.htm|len(numeDictionar)]] -> numărul de elemente dintr-un dicționar | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_str.htm|str(numeDictionar)]] -> generarea unei versiuni mai simple de a afișa un dicționar | ||
+ | |||
+ | == Metode utile pentru dicționare == | ||
+ | |||
+ | [[https://www.tutorialspoint.com/python/dictionary_clear.htm|numeDictionar.clear()]] -> eliminarea tututot elemetelor dintr-un dicționar | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_copy.htm|numeDictionar.copy()]] -> returnează copia unui dicționar | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_has_key.htm|numeDictionar.has_key(key)]] -> returneză "true" dacă există un element cu cheia "key", altfel returnează "false" sinon | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_items.htm|numeDictionar.items()]] -> o listă cu toate perechile de tipul (cheie, valoare) care se găsesc în dicționar | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_keys.htm|numeDictionar.keys()]] -> lista de chei | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_update.htm|dictionar1.update(dictionar2)]] -> daugă conținutul dicționurului //dictionar2// în dicționarul //dictionar1// | ||
+ | * [[https://www.tutorialspoint.com/python/dictionary_values.htm|numeDictionar.values()]] -> listă cu toate valorile stocate în dicționar | ||
+ | |||
+ | |||
+ | ===== Structura de decizie "if" ===== | ||
+ | |||
+ | <code python> | ||
+ | # Decizie simplă | ||
a = 33 | a = 33 | ||
b = 200 | b = 200 | ||
Line 262: | Line 375: | ||
<code python> | <code python> | ||
- | # Use "elif" to add an additional condition | + | # Utilizare elif pentru a adăuga condiție suplimentară |
a = 33 | a = 33 | ||
b = 33 | b = 33 | ||
Line 272: | Line 386: | ||
<code python> | <code python> | ||
- | # The "else" keyword takes anything that has not been included before | + | # Cuvantul cheie else care cuprinde tot ce nu a fost inclus anterior |
a = 200 | a = 200 | ||
b = 33 | b = 33 | ||
Line 284: | Line 399: | ||
<code python> | <code python> | ||
- | # Else without elif | + | # else fară elif |
a = 200 | a = 200 | ||
b = 33 | b = 33 | ||
Line 291: | Line 407: | ||
else: | else: | ||
print("b is not greater than a") | print("b is not greater than a") | ||
- | </code> | + | </code> |
- | ==== Exemplul 2 ==== | + | ===== Structurile repetitive ===== |
- | Programul urmator va afișa pe display litera ”A” daca butonul A este apăsat, respectiv litera “B” daca butonul B este apăsat. Dacă niciun buton nu este apăsat va afișa pe dislapay o imagine, care reprezintă un emoticon confuz. | + | === Bucla "for" === |
+ | |||
+ | Contrar altor limbaje, care au forma strandard **for(..) { code } ** pentru bucla //for//, Python a eliminat parantezele care arata iterarea unei liste si utilizează **:** pentru a indica începutul uni bloc de cos care va fi executat în interiorul buclei, ca în exemplul următor: | ||
<code python> | <code python> | ||
- | from microbit import display, button_a, button_b, Image | + | listaDeNume = ["Ana", "Maria", "Ioana", "Irina", "Andreea", "Cristina"] |
+ | |||
+ | for nume in listaDeNume: | ||
+ | print (nume) | ||
+ | </code> | ||
- | while True: #infinite looop | + | În Python, indicele pasului la care ne aflăm în timpul parcurgerii, nu este vizibil, iar pentru asta exista o metodă care numără pașii, numită **enumerate**: |
- | if button_a.is_pressed(): #check if the button A is pressed | + | |
- | display.scroll("A") | + | <code python> |
- | elif button_b.is_pressed(): #check if the button B is pressed | + | cours= [ "Analyse", "SdE", "ALF"] |
- | display.scroll("B") | + | |
+ | |||
+ | for index, hobby in enumerate(cours): | ||
+ | print (index, hobby) | ||
+ | |||
+ | # Output: | ||
+ | 0 Analyse | ||
+ | 1 SdE | ||
+ | 2 ALF | ||
+ | </code> | ||
+ | |||
+ | O altă funcție este ultilitarul **zip**, care permite oarcurgerea a două liste simultan. | ||
+ | |||
+ | <code python> | ||
+ | lista1 = [ 3, 9, 17, 15, 19] | ||
+ | lista2 = [ 2, 4, 30, 24, 3] | ||
+ | |||
+ | for a, b in zip( lista1, lista2 ): | ||
+ | if a > b: | ||
+ | print (a) | ||
else: | else: | ||
- | display.show(Image.CONFUSED) | + | print (b) |
+ | |||
+ | # Output: | ||
+ | |||
+ | 3 | ||
+ | 9 | ||
+ | 30 | ||
+ | 24 | ||
+ | 19 | ||
</code> | </code> | ||
+ | O altă particularitate a limbajului Python este faptul că se poate aplica conditioa //else// si pentru bucla //for//. În acest caz, ramura //else// va fi executată după bucla //for//, dacă și numai dacă în interiorul buclei //for// nu există p declarație de tip //break//. | ||
+ | De exemplu: | ||
+ | <code python> | ||
+ | listeAnimaux = [ "loup", "lapin", "lion", "ours" ] | ||
- | ===== Accelerometru. Gesturi ===== | + | for i in listeAnimaux: |
+ | print (i) | ||
+ | if i == "lapin" | ||
+ | print ("Le lapin n'est pas sauvage") | ||
+ | break | ||
+ | else: | ||
+ | print ("Tous les animaux!") | ||
+ | |||
+ | # Output | ||
+ | loup | ||
+ | lapin | ||
+ | Le lapin n est pas sauvage | ||
- | Micro:bit poate să recunoască gesturi precum înclinare sau scuturare. | + | #Si on execute la sequence suivante: |
- | Pe spatele microntroler-ului, în partea de jos, se poate vedea un chip mic, care reprezintă un **accelerometru**, numit [[https://ocw.cs.pub.ro/courses/sde/laboratoare/02_microbit_ro?&#prezentare_bbc_microbit|"Compass and Accelerometer”]]. Acesta poate măsura acclerarea în toate cele trei dimensiuni, anume accelerarea stânga-dreapta, accelerarea față-spate și accelerarea sus-jos. | + | for i in listeAnimaux: |
+ | print (i) | ||
+ | if i == "lapin" | ||
+ | print ("Le lapin n'est pas sauvage") | ||
+ | else: | ||
+ | print ("Tous les animaux!") | ||
+ | |||
+ | # Output | ||
+ | loup | ||
+ | lapin | ||
+ | Le lapin n est pas sauvage | ||
+ | lion | ||
+ | ours | ||
+ | Tous les animaux! | ||
+ | </code> | ||
- | Ce este un accelreometru? Un accelerometru are rolul de a măsura și a analiza accelerațiile liniare și unghiulare, de exemplu, masinile moderne folosesc un accelerometru care detectează un accident pentru a declansa airbag-urile. | + | === Bucla "while" === |
- | ==== Exemplul 3 ==== | + | <code python> |
- | În acest exemplu vom explora acclerometrul afișând pe display-ul micr:obit-ului un pătrat dacă acesta este înclinat către stânga, un tringhi dacă acesta este înclinat către dreapta și un diamant dacă este pus cu fața în sus. | + | #Afficher les chiffres de 0 a 9 |
+ | |||
+ | count = 0 | ||
+ | |||
+ | while count < 10: | ||
+ | print (count) | ||
+ | count = count + 1 | ||
+ | </code> | ||
+ | |||
+ | Ca și pentru bucla //for// există, de asemnea, posibilitatea de a aplica condița //else// pentru bucla //while//. Diferența este că blocul //else// va fi executat de fiecare dată când condiția de la structura repetitivă va fi evaluată ca și falsă: | ||
<code python> | <code python> | ||
- | from microbit import display, accelerometer, Image | + | print ("Dévinez de numéro de l'intervalle [ 1, 10 ]") |
+ | |||
+ | monNr = 7 | ||
+ | votreNr = 0 | ||
+ | |||
+ | while votreNr!= monNr: | ||
+ | votreNr = int( input("Choisissez. ") ) | ||
+ | else: | ||
+ | print ("Félicitations!") | ||
+ | </code> | ||
+ | === Break și Continue === | ||
+ | |||
+ | Instrucțiunea //break// este utilizată pentru a ieși dintr-o structură repetitivă. De exemplu, se pot afișa numerele de la 0 la 9 în felul următor: | ||
+ | |||
+ | <code python> | ||
+ | count = 0 | ||
+ | |||
while True: | while True: | ||
- | if accelerometer.current_gesture() == "left": | + | print (count) |
- | display.show(Image.SQUARE) | + | count = count + 1 |
- | elif accelerometer.current_gesture() == "right": | + | if count > 10: |
- | display.show(Image.TRIANGLE) | + | break |
- | elif accelerometer.current_gesture() == "face up": | + | |
- | display.show(Image.DIAMOND) | + | |
- | else: | + | |
- | display.clear() | + | |
</code> | </code> | ||
- | ===== Direcții. Busolă ===== | + | //Continue// este utilizat pentru a ignora un bloc de instrucțiuni. De exemplu, il putem utiliza pentru a afișa numerele pare de la 0 la 20 astfel: |
- | Senzorul pentru [[https://www.youtube.com/watch?v=a3P6LWwPBqM&feature=emb_logo|busolă]] deceteaza câmpuri magnetice ale Pământului și este amplasat tot pe spatele micro:bit-ului, precum acclerometrul. Acesta este folosit pentru a decta dacă un magnet se afla prin preajma micro:bit-ului sau pentru navigare, poate arata direcțiile Nord, Sud, Est și Vest. | + | <code python> |
+ | number = 0 | ||
+ | |||
+ | while number < 21: | ||
+ | if number % 2 == 1 | ||
+ | continue | ||
+ | print (number) | ||
+ | </code> | ||
- | ==== Exemplul 4 ==== | + | ===== Funcții ===== |
- | + | ||
- | În acest exemplu vom vedea cum micr:obit-ul poate fi folosit ca o busolă. __Atenție__: Imediat după ce ați rulat codul trebuie să așteptați puțin pană se afisează textul care spune “TITLING FILL”, iar apoi pe rând se va afișa căte un LED; trebuie să înclinați micro:bit-ul până display-ul se va lumina complet. | + | === Declarație === |
<code python> | <code python> | ||
- | from microbit import display, compass | + | def myFunction(): |
- | compass.calibrate() | + | print ("Welcome") |
+ | |||
+ | # sau | ||
- | while True: | + | def simpleSum( a, b ): |
- | degrees = compass.heading() | + | return a + b |
- | if degrees < 45 or degrees > 315: | + | |
- | display.show('N') | + | |
- | elif degrees < 135: | + | |
- | display.show("E") | + | |
- | elif degrees < 225: | + | |
- | display.show("S") | + | |
- | elif degrees < 315: | + | |
- | display.show("W") | + | |
- | else: | + | |
- | display.show(' ') | + | |
</code> | </code> | ||
- | ===== Microfonul și Speaker-ul ===== | + | === Apel === |
- | BBC micro:bit V2 are fixat pe spate microfonul, iar pe partea din față se observa indicatorul, care lumineaza atunci cand acesta aste accesat. Acesta poate măsura nivelul de sunet din jurul plăcuței și poate reacționa la sunete înalte sau mai joase. | + | <code python> |
+ | myFunction() | ||
- | Tot in partea din spate exista pe [[https://www.allaboutcircuits.com/technical-articles/what-is-a-printed-circuit-board-pcb/|PCB]] un difuzor(speaker) magnetic din care rezultă ca output sunetul. | + | # sau |
+ | first = 1 | ||
+ | second = 1 | ||
+ | sum = simpleSum( first, second ) | ||
+ | print (sum) | ||
- | ==== Exemplul 5 ==== | + | print (simpleSum( first, second )) |
- | Acest exemplu simulează o lumânare. După importarea bibliotecilor se declară un contor numit //lit//, care inițial are valoarea True. Apoi se verifica dacă a fost înregistrat un sunet puternic folosind funcția //was_event()//, care totodată șterge istoricul evenimentelor sonore înainte de a returna. Dacă cea din urma returnează True se schimba valoare contorului, anume valoarea lui //lit//. În cazul în care lumânarea este aprinsă se va afișa pe display o imagine care o simuleaza o lumânare și care va face flacăra să licarească la o poziție random de la 1 la 3. | + | </code> |
- | Pentru a crea **imaginea** este necesar să dăm valori fiecarui pixel de pe display. Valoarea 0 însemna ca led-ul respectiv este oprit, nu luminează. Valorile între 1 și 9(valoarea maximă) arată nivelul de luminozitate al pixelului. Pentru a reprezenta o linie valorile sunt închise în //""// și se termină cu //:// . În acest exemplu, se observă faptul că fiecare linie din //Image()// reprezintă poziționarea led-urilor de pe display-ul fizic al mico:bit-ului. Prin urmare, analizând prima linie, care sugerează flacăra, toate led-urile sunt oprite cu exceptia celui de pe pozitia 3, care are pixel-ul setat la luminozitate maximă. Restul liniilor sunt asemenea pentru a forma restul lumânării, pozițiile 1 și 5, au pixel-ul setat la valoarea 0, iar restul la valoarea 9. | + | ===== Clase și obiecte ===== |
- | Pentru a crea **efectul de licărire** se folosește funcția //set_pixel()//, caruia i se dau ca parametrii linia, coloana și valoarea pixelului. | + | Un **obiect** este o încapsulare de variabile și de funcții într-o singură entitate, în timp ce o **clasă** reprezintă un model pentru a crea obiecte. În concluzie, un obiect își ia datele dintr-o clasă. |
<code python> | <code python> | ||
- | from microbit import display, microphone, SoundEvent, Image, sleep | + | # Classe simple |
- | import random | + | |
- | lit = True | + | class MaClasse: |
+ | variable = "Bonjour" | ||
+ | |||
+ | def maFonction(self): | ||
+ | print ("Bonjour de l'autre part!") | ||
- | while True: | ||
- | if microphone.was_event(SoundEvent.LOUD): #check if a loud sound was | ||
- | lit = not lit | ||
- | sleep(500) | ||
- | if lit: | ||
- | display.show(Image( #candle image | ||
- | "00900:" | ||
- | "09990:" | ||
- | "09990:" | ||
- | "09990:" | ||
- | "09990")) | ||
- | sleep(150) | ||
- | flicker = random.randint(1, 3) | ||
- | if flicker != 2: | ||
- | display.set_pixel(2,0,0) | ||
- | display.set_pixel(flicker,0,9) | ||
- | sleep(150) | ||
- | else: | ||
- | display.clear() | ||
- | </code> | ||
+ | # Association classe objet | ||
+ | monObjet = MaClasse() | ||
- | ===== Senzorul de atingere ===== | ||
- | Micro:bit-ul are senzorul de atingere amplasat pe [[https://www.youtube.com/watch?v=spFD3SxxxHQ&feature=emb_logo|logo]], care poate fi folosit ca și input. Acesta poate interacționa cu user-ul precum un buton. | + | # Afficher le contenu de la variable de MaClasse |
+ | print (monObjet.variable) | ||
- | + | # Appeler la fonction maFonction, qui va afficher sur l'écran le message "Bonjour de l'autre part!" | |
+ | monObjet.maFonction() | ||
+ | </code> | ||
- | ==== Exemplul 6 ==== | + | <note important> |
- | În acest exemplu se verifică dacă senzorul este atins atunci, se va afișa mesajul “Hello” altfel, display-ul va fi neluminat. | + | În Python **self** reprezintă instanța unei clase, fiind identică cu **this** din Java. Utilizând cuvantul-cheie **self**, se pot accesa atributele și metodele definite în clasă. |
+ | </note> | ||
- | <code python> | + | Numărul de obiecte care pot fi create dintr-o clasă nu este limitat, acestea moștenesc toate caracteristicle clasei(variabile și funcții). Cu toate acestea, fiecare obiect conține copii independente ale variabilelor definite în interiorul clasei. Prin urmare, dacă se creaza un obiect nou din clasa mamă, se poate modifica conținutul făra a afecta clasa ințială. |
- | from microbit import display, pin_logo | + | |
- | while True: | + | <code python> |
- | if pin_logo.is_touched(): | + | class MaClasse: |
- | display.scroll("Hello") | + | variable = "Bonjour" |
- | else: | + | |
- | display.clear() #display stays empty | + | def maFonction(self): |
+ | print ("Bonjour de l'autre part!") | ||
+ | |||
+ | monObjet1 = MaClasse() | ||
+ | monObjet2 = MaClasse() | ||
+ | |||
+ | monObjet2.variable = "au revoir" | ||
+ | |||
+ | print (monObjet1.variable) | ||
+ | print (monObjet2.variable) | ||
+ | |||
+ | #Output | ||
+ | bonjour | ||
+ | au revoir | ||
</code> | </code> | ||
- | ===== Senzorul de temperatura și de lumină ===== | + | ===== Funcții matematice ===== |
- | Senzorul de [[https://youtu.be/mrHn8eZ9eqg|temperatură]] înregistrează cu aproximație temperatura din jurul micr:obit-ului, iar senzorul de [[https://youtu.be/ii0U_FMr-Z4|lumină]] poate înregistra nivelul de lumină prin intermediul LED-urilor. | + | Pentru a putea utiliza funcții care execută operații matematice în Python, trebuie ca modulul **math** să fie importat. |
- | ==== Exemplul 7 ==== | + | <code python> |
+ | import math | ||
+ | </code> | ||
- | Exemplul urmator afisează temepratura dacă butonul A este apăsat, iar dacă deasupra LED-urilor micro:bit-ul înregistrează o lumină puternică va afișa pe display un soare. Pentru a testa senzorul de lumină, în acest exemplu puteți îndrepta lumina de la lanterna telefonului către plăcuță. | + | |
+ | <note tip> | ||
+ | Fiecare funcție a bibliotecii **math** se apelează astfel: | ||
<code python> | <code python> | ||
- | from microbit import display, button_a, Image, temperature | + | math.functionName( params ) |
+ | </code> | ||
- | while True: | + | Câteva funcții elementare: **floor**, **ceil**, **pow**, **sqrt**. |
- | if button_a.was_pressed(): | + | </note> |
- | display.scroll(temperature()) #displat the temperature | + | |
- | elif display.read_light_level() > 100: #check the light level | + | <note tip> |
- | display.show(Image( #sun image | + | Există funcții predefinite care nu necesită să fie importate dintr-un modul auxiliar. Sunt apelate astfel: |
- | "90909:" | + | |
- | "09990:" | + | <code python> |
- | "99999:" | + | functionName( params ) |
- | "09990:" | + | |
- | "90909")) | + | |
- | else: | + | |
- | display.clear() | + | |
</code> | </code> | ||
- | ===== Exerciții ===== | + | Exemple de funcții din acestă categorie: **abs**, **round**, **sum**. |
+ | </note> | ||
- | - Scrieți un program care la apăsarea simultană a butoanelor A și B va afișa o imagine care reprezintă "DA", iar dacă niciun buton nu este apăsat va apărea o imagine care reprezintă "NU". Pentru imagini vezi [[https://microbit-micropython.readthedocs.io/en/v2-docs/tutorials/images.html|documentația]]. | + | <note important> |
- | - Modificați exercițiul anterior astfel încât la apăsarea butonului A se va afișa litera "A", iar la apăsarea butonului B se va afișa litera "B". | + | O listă completă de funcții matematice din Python poate fi găsită |
- | - Scrieți un program care afișeaza pe display numărul curent de scuturări. Când micro bit-ul înregistrează 9 scuturări pe display va apărea o imagine. | + | [[https://docs.python.org/2/library/math.html|aici]]. |
- | - Creați un program care înregistrează numarul de înclinări către stanga și către dreapta. De fiecare data când micro:bit-ul este îndreptat în una dintre cele două părți să se afișeze numărul curent de înclinări către partea respectivă. //Hint//: folosiți metoda [[https://microbit-micropython.readthedocs.io/en/v1.0.1/microbit.html#microbit.sleep|sleep]] | + | </note> |
- | - Scrieți un program care la atingerea logo-ului(senzorul de atingere) să faca toggle între o imagine cu diamant și imagine cu diamant mic. | + | ===== Citirea de la tastatură ====== |
- | - Să se scrie un program, care la înregistrarea unui sunet va afișa pe display o imagine și va rosti cu ajutorul speech-ului "ON". Dacă nu este înregistrat niciun sunet display-ul rămâne gol. Afișati nivelul de sunet la o acțiune la alegere(apăsare unui buton, atingerea logo-ului, înclinare etc.) | + | |
- | - Modificați codul de la [[https://ocw.cs.pub.ro/courses/sde/laboratoare/02_microbit_ro?&#senzorul_de_temperatura_si_de_lumina|exemplul 7]] astfel încât micro:bit-ul detectează lumină să folosească speaker-ul pentru a reda muzica JUMP_UP, iar când lumina este oprită să redea muzica JUMP_DOWN. Pentru acesarea bibliotecii "music" vezi [[https://microbit-micropython.readthedocs.io/en/v2-docs/tutorials/music.html|documentația]]. | + | |
+ | Datele de intrare pot fi citite de la tastaura, pentru asta există funcția **input()**. Aceasta poate avea și parametrii suplimentari, string-ul care va fi afoșsat în linia de comanda la momentul citirii datelorȘ | ||
- | + | <code python> | |
+ | name = input("Quel est votre nom? ") | ||
+ | print("Bienvenue, " + name + "!") | ||
+ | </code> | ||
+ | <code bash> | ||
+ | # Output dans la ligne de commande | ||
+ | Quel est votre nom? "Ana" | ||
+ | Bienvenue, Ana! | ||
+ | </code> | ||
+ | <note important> | ||
+ | Rulați exemplul de mai sus pe BBC micro:bit. Conectați placuta și deschideți editorul de cod. Conectați plăcuța iar apoi apăsați //Flash//. După cateva secunde deschideți faceți click pe //Open Serial//. Veți avea un output similar cu cel de jos, ce rămâne de făcut este să introduceți de la tastatură input-ul. Pentru a reveni apăsați pe //Close Serial//. | ||
+ | {{ :sde2:laboratoare:open_serial.png?450 |}} | ||
+ | </note> | ||
+ | ===== Excepții în Python ====== | ||
+ | Există 2 tipuri de execpții: erori de sintaxă și de excepții. | ||
+ | **Erorile de sintaxă**, cunoscute sub numele de erori de analiză (parsing error) sunt cele mai cunoscute: | ||
+ | <code python> | ||
+ | >>> while True print('Hello world') | ||
+ | File "<stdin>", line 1 | ||
+ | while True print('Hello world') | ||
+ | ^ | ||
+ | SyntaxError: invalid syntax | ||
+ | </code> | ||
+ | **Excepțiile** apar la momentul execuției: | ||
+ | <code python> | ||
+ | >>> 10 * (1/0) | ||
+ | Traceback (most recent call last): | ||
+ | File "<stdin>", line 1, in <module> | ||
+ | ZeroDivisionError: division by zero | ||
+ | </code> | ||
+ | === Gestionarea excepțiilor ==== | ||
+ | Pentru a rezolva execpțiile în Python, se utilizează bloc-ul **try-except**, ca în exemplul următor: | ||
+ | <code python> | ||
+ | while True: | ||
+ | try: | ||
+ | x = int(input("Please enter a number: ")) | ||
+ | break | ||
+ | except ValueError: | ||
+ | print("Oops! That was no valid number. Try again...") | ||
+ | </code> | ||
+ | ===== Exerciții ====== | ||
+ | - Creați 3 variabile de tipuri diferite, ca mai jos, și afișați-le în consolă: **(0.5p)** | ||
+ | - o variabilă //int// cu valoarea 80 | ||
+ | - o variabilă //float// având valoarea 20.2 | ||
+ | - o variabilă "string", care va reține șirul "python" | ||
+ | - Utilizând funcția [[https://docs.python.org/2/library/functions.html#type|type]] determinați tipul variabilelor următoare. Pentru afișare puteți folosi [[https://www.w3schools.com/python/ref_func_print.asp|print]], iar pentru a vedea output-ul deschideți serialul //Open Serial//. **(0.5p)** | ||
+ | - var1 = 80 | ||
+ | - var2 = 20.2 | ||
+ | - var3 = "microbit" | ||
+ | - Scrieți un program care primește ca parametrii de la linia de comandă 4 numere și afișați rezultatul calculuilui a+b*c-d. **(1p)** | ||
+ | - Creați o listă cu prenumele colegilor de clasa, acestea se pot repeta. Adăugați cel puțin un element folosind metoda //append()//. Rezolvați următoarele cerințe: **(2p)** | ||
+ | - Copiați lista inițială într-o altă listă numită copyList și sortați-o în ordine alfabetică | ||
+ | - Determinați numarul de apariții al fiecarui nume folosind o listă auxiliară care conține elemente distincte | ||
+ | - Determinați numele care are numarul maxim de apariții în listă și numele cu numărul minim de apariții (dacă exista mai multe elemente care respectă condiția se vor afișa toate) | ||
+ | - Inversați lista copyList și ștergeți ultimul element din lista inițială. | ||
+ | - Întocmiți o bază de date al unui magazin de electrocasnice cu ajutorul dicționarului. Adăugati funcționalitatea ca atunci cand se citește de la tastatură un produs să se afișeze prețul acestuia. Se va afișa o eroare dacă produsul nu există "Error" și se caută produse până cand se introduce textul "stop". **(2p)** | ||
+ | - Scrieți un program, care va afișa rezultatul returnat de funcția //digitize(n)//. Această funcție va primi ca si parametru un int și va returna o lista cu cifrele numărului în ordine inversă. **(1p)** Exemplu: 348597 => [7,9,5,8,4,3] | ||
+ | - Creați o clasă Senzori folosită pentru a stoca valori provenind de la următorii senzori: temperatură, lumină, umiditate. Pentru fiecare senzor se pot citi și modifica valorile prin apeluri de funcții. **(1p)** | ||
+ | - Creați un program care folosind clasa definită mai sus reține valori provenind de la seturi diferite de senzori pentru următoarele încăperi a unei locuințe si le afișează pe ecran: bucătărie, hol, dormitor, sufragerie. Programul realizează operațiile prin primirea de comenzi din consolă astfel: **(2p)** | ||
+ | * ''insert <încăpere> <sensor> <value>'' - unde ''<incapere>'', ''<sensor>'' si ''<value>'' vor fi înlocuiți cu unul din cei 3 senzori și o valoare - inserează o valoarea nouă pentru senzorul respectiv | ||
+ | * ''delete <încăpere> <sensor> <value>'' - șterge valoarea pentru senzorul respectiv, valoarea după ștergere va fi 0 | ||
+ | * ''print <incapere><sensor>'' - afișează valoarea pentru senzorul din încăperea precizată | ||
+ | * ''print <incapere>'' - afișează toți senzorii și valorile aferente pentru încăperea precizată | ||
+ | * ''add_room <incapere>'' - adaugă un nou set de senzori pentru o nouă încăpere | ||
+ | * ''del_room <incapere>'' - șterge setul de senzori pentru o încăpere | ||
+ | Dacă se introduce o altă comandă, programul va arunca o excepție. | ||
+ | == Bonus == | ||
+ | - Modificați programele anterioare pentru a afișa valorile pe micro:bit, nu în consolă. | ||
+ | - Creați un program care aprinde pe rând fiecare LED de pe micro:bit. | ||
+ | - Creați un program care citește temperatura ambientală folosind senzorul de pe micro:bit și o afișează folosind LED-urile. | ||
+ | ==== ==== | ||
+ | [[https://github.com/UPB-FILS-SdE2/Solutions/tree/main/TP3|Soluții]] | ||