Ülesanne 1: Sõnastiku loomine (võti-väärtus paarid) ||| Tere tulemast AT7 nädalasse! Siiamaani oleme hoidnud andmeid listides, kus elementidele pääseb ligi järjekorranumbri (indeksi) alusel. Kuid mis oleks, kui tahaksime andmetele viidata tähenduslike nimede ehk **võtmete** (keys) kaudu? Pythonis on selleks **sõnastik** (dictionary), mis salvestab andmeid paaridena võti: väärtus. See on asendamatu seadmete, konfiguratsioonide ja andurite parameetrite haldamisel! Loo sõnastik konfiguratsioon, kus võtmeks on 'kiirus' ja väärtuseks 100. ||| # Loo sõnastik konfiguratsioon võtmega 'kiirus' ja väärtusega 100 # Sinu kood siia pass ||| print ||| Põhitest => => {'kiirus': 100} ==== Ülesanne 2: Väärtuse lugemine sõnastikust võtme järgi ||| Sõnastikust väärtuse kättesaamiseks kasutame kandilisi sulgusid ja võtme nime (nt andmed['temperatuur']). See on palju kiirem ja loetavam kui indeksi otsimine! Trüki välja sõnastikust andur võtme 'asukoht' väärtus. ||| andur = {"tüüp": "ultrasonic", "asukoht": "ladu"} # Prindi välja anduri asukoht sõnastikust # Sinu kood siia pass ||| print ||| Lugemise test => => ladu ==== Ülesanne 3: Meetodi .get() kasutamine väärtuse küsimiseks ||| Mis juhtub, kui küsime sõnastikust võtit, mida seal pole? Python annab vea (KeyError). Turvalisem on kasutada meetodit .get(), mis tagastab vea asemel None või meie poolt määratud vaikeväärtuse. Kasuta meetodit .get(), et küsida sõnastikust võtit 'rõhk'. ||| andmed = {"temp": 22} # Küsi meetodiga .get() võtit 'rõhk' ja prindi tulemus # Sinu kood siia pass ||| print ||| Get test => => None ==== Ülesanne 4: Uue võti-väärtus paari lisamine sõnastikku ||| Sõnastikud on dünaamilised – saame programmi töö käigus hõlpsasti lisada uusi parameetreid ilma eelneva struktuuri muutmiseta. Lisa olemasolevale sõnastikule seade uus võti 'staatus' väärtusega 'valmis' ja prindi kogu sõnastik. ||| seade = {"nimi": "Robot-1"} # Lisa võti 'staatus' väärtusega 'valmis' ja prindi seade # Sinu kood siia pass ||| print ||| Lisamise test => => {'nimi': 'Robot-1', 'staatus': 'valmis'} ==== Ülesanne 5: Olemasoleva väärtuse muutmine sõnastikus ||| Kui seadme parameeter muutub (näiteks kiirus tõuseb või režiim vahetub), saame sõnastiku väärtust lihtsalt ümber kirjutada omistamismärgiga (=). Muuda sõnastikus mootor kiiruse väärtuseks 250. ||| mootor = {"kiirus": 100, "suund": "edasi"} # Muuda kiiruse väärtuseks 250 ja prindi mootor # Sinu kood siia pass ||| print ||| Muutmise test => => {'kiirus': 250, 'suund': 'edasi'} ==== Ülesanne 6: Elemendi eemaldamine sõnastikust pop() abil ||| Kui mõni parameeter pole enam vajalik, saame selle eemaldada. Meetod .pop() eemaldab määratud võtme ja tagastab selle väärtuse. Eemalda sõnastikust võti 'viga' meetodiga .pop() ja prindi tulemus. ||| logi = {"kood": 200, "viga": False} # Eemalda võti 'viga' meetodiga .pop() ja prindi logi # Sinu kood siia pass ||| print ||| Pop test => => {'kood': 200} ==== Ülesanne 7: Võtme olemasolu kontrollimine operaatoriga in ||| Enne väärtuse lugemist on nutikas kontrollida, kas võti üldse eksisteerib, et vältida tõrkeid. Operaator in teeb seda silmapilkselt. Kontrolli, kas võti 'IP' eksisteerib sõnastikus verk, ja prindi tulemus (True/False). ||| verk = {"gateway": "192.168.1.1"} # Kontrolli kas 'IP' on verk võtmetes ja prindi True/False # Sinu kood siia pass ||| print ||| In test => => False ==== Ülesanne 8: Sõnastiku pikkuse leidmine len() abil ||| Nagu listide puhul, näitab funktsioon len() sõnastikus olevate võti-väärtus paaride koguarvu. See on kasulik seadme parameetrite loendamisel. Prindi sõnastiku andurid pikkus. ||| andurid = {"temp": 20, "niiskus": 50, "valgus": 300} # Prindi andurid sõnastiku pikkus len() abil # Sinu kood siia pass ||| print ||| Len test => => 3 ==== Ülesanne 9: Kõikide võtmete toomine .keys() abil ||| Kui vajame ülevaadet kõigist sõnastiku võtmetest (näiteks menüü või parameetrite nimede kuvamiseks), on abiks meetod .keys(). Prindi sõnastiku konf võtmed. ||| konf = {"port": 8080, "protokoll": "HTTP"} # Prindi konf võtmed meetodi .keys() abil # Sinu kood siia pass ||| print ||| Keys test => => dict_keys(['port', 'protokoll']) ==== Ülesanne 10: Kõikide väärtuste toomine .values() abil ||| Analoogiliselt võtmetega saame meetodiga .values() kätte kõik sõnastikus salvestatud väärtused (näiteks andurite toorandmed). Prindi sõnastiku nadal väärtused. ||| nadal = {"E": 8, "T": 8, "K": 6} # Prindi nadal väärtused meetodi .values() abil # Sinu kood siia pass ||| print ||| Values test => => dict_values([8, 8, 6]) ==== Ülesanne 11: Võtmete ja väärtuste paari toomine .items() abil ||| Meetod .items() tagastab sõnastiku elemendid paaridena, mida on äärmiselt mugav tsüklites kasutada. Prindi sõnastiku info items-kogum. ||| info = { "versioon": 1.2, "autor": "Admin" } # Prindi info items meetodi abil # Sinu kood siia pass ||| print ||| Items test => => dict_items([('versioon', 1.2), ('autor', 'Admin')]) ==== Ülesanne 12: For-tsükkel sõnastiku võtmetel ||| Käime for-tsükliga läbi sõnastiku võtmed ja prindime need ükshaaval. See on tüüpiline seadme konfiguratsioonifaili logimisel. Koosta for-tsükkel sõnastiku pult võtmete kuvamiseks. ||| pult = {"kanal": 3, "aku": 90} # Kasuta for-tsüklit pult võtmete printimiseks # Sinu kood siia pass ||| print ||| For keys test => => kanal, aku ==== Ülesanne 13: For-tsükkel sõnastiku väärtustel ||| Saame for-tsükliga otse läbi käia ka väärtused, et näiteks arvutada nende summat või keskmist. Arvuta sõnastiku mõõdud väärtuste summa for-tsüklis ja prindi see. ||| mõõdud = {"pikkus": 10, "laius": 20, "kõrgus": 30} summa = 0 # For-tsükkel, mis liidab väärtused summasse ja prindib selle # Sinu kood siia pass ||| print ||| For values test => => 60 ==== Ülesanne 14: For-tsükkel .items() abil (võti ja väärtus) ||| Kõige võimsam viis sõnastiku läbikäimiseks on meetod .items(), mis annab meile korraga kätte nii võtme kui ka väärtuse! Prindi for-tsüklis iga võti ja väärtus kujul võti: väärtus. ||| andur = {"id": 101, "arv": 25.5} # Kasuta for võti, väärtus in andur.items() ja prindi need # Sinu kood siia pass ||| print ||| For items test => => id: 101\narv: 25.5 ==== Ülesanne 15: Sõnastiku täiendamine meetodiga .update() ||| Meetod .update() võimaldab liita ühte sõnastikusse teise sõnastiku andmed korraga. See on suurepärane vaikesätete ülekirjutamisel! Uuenda sõnastikku baas teise sõnastikuga lisa ja prindi baas. ||| baas = {"kiirus": 50} lisa = {"kiirus": 120, "režiim": "turbo"} # Uuenda baas sõnastikku lisa andmetega ja prindi baas # Sinu kood siia pass ||| print ||| Update test => => {'kiirus': 120, 'režiim': 'turbo'} ==== Ülesanne 16: Pesastatud sõnastik (nested dictionary) ||| Tööstusautomaatikas on andmed sageli hierarhilised: ühel seadmel on mitu alammoodulit. Selleks kasutatakse pesastatud sõnastikke (sõnastik sõnastiku sees). Prindi pesastatud sõnastikust süsteem sisemine väärtus 'temp'. ||| süsteem = { "cpu": {"temp": 45, "koormus": 12} } # Prindi cpu temperatuur pesastatud sõnastikust # Sinu kood siia pass ||| print ||| Nested test => => 45 ==== Ülesanne 17: Enniku (tuple) loomine ja selle muutumatus ||| Oleme jõudnud teise suure teemani: **ennik** (tuple). Ennik sarnaneb listiga, kuid ta on **muutumatu** (immutable) – pärast loomist ei saa selle elemente lisada, eemaldada ega muuta! See tagab andmete turvalisuse. Loo ennik koordinaadid väärtustega 10 ja 20 ning prindi see. ||| # Loo ennik koordinaadid väärtustega (10, 20) ja prindi see # Sinu kood siia pass ||| print ||| Tuple loomine test => => (10, 20) ==== Ülesanne 18: Enniku elementide indekseerimine ||| Kuna ennik on järjend, saame selle elementidele ligi indeksite abil (täpselt nagu listidel). Prindi ennikust andmed teine element (indeks 1). ||| andmed = (400, 500, 600) # Prindi enniku teine element indeksi abil # Sinu kood siia pass ||| print ||| Tuple indeks test => => 500 ==== Ülesanne 19: Enniku viilutamine (slicing) ||| Ennikutele kehtivad samuti viilutamise (slicing) reeglid, mis võimaldavad eraldada ennikust alamosi. Viiluta ennikust paun kaks viimast elementi ja prindi tulemus. ||| paun = (1, 2, 3, 4, 5) # Viiluta paun viimased kolm elementi (indeksist 2 kuni lõpuni) ja prindi # Sinu kood siia pass ||| print ||| Tuple slicing test => => (3, 4, 5) ==== Ülesanne 20: Enniku meetodid .count() ja .len() ||| Kuigi ennik on muutumatu, on sellel kasulikke sisseehitatud meetodeid, näiteks .count() elementide esinemissageduse loendamiseks. Leia ennikust arvulise väärtuse 1 esinemiste arv .count() abil. ||| vead = (0, 1, 0, 1, 1, 0) # Leia mitu korda esineb ennikus väärtus 1 ja prindi tulemus # Sinu kood siia pass ||| print ||| Tuple count test => => 3 ==== Ülesanne 21: Enniku lahtipakkimine (tuple unpacking) ||| Pythonis saab enniku väärtused omistada mitmele muutujale korraga ühel real! Seda nimetatakse lahtipakkimiseks (unpacking). Paki ennik tp lahti muutujatesse x ja y ning prindi need. ||| tp = (15, 30) # Paku tp lahti muutujatesse x ja y ning prindi mõlemad # Sinu kood siia pass ||| print ||| Unpacking test => => 15 30 ==== Ülesanne 22: Funktsioon, mis tagastab enniku (mitu väärtust) ||| Funktsioonid saavad Pythonis tagastada korraga mitu väärtust – tegelikult pakib Python need automaatselt ennikuks! Loo funktsioon arvuta(x), mis tagastab ennikuna arvu ruudu ja kuubi, ning kutsu seda. ||| def arvuta(x): return (x ** 2, x ** 3) # Kutsu funktsiooni argumendiga 3 ja prindi tulemus # Sinu kood siia pass ||| print ||| Func tuple test => => (9, 27) ==== Ülesanne 23: Enniku kasutamine sõnastiku võtmena ||| Kuna ennik on muutumatu (immutable), saab teda kasutada sõnastiku **võtmena**! Listi selleks kasutada ei saa (list annab TypeErrori). Loo sõnastik, kus võtmeks on ennik (kaardikoordinaadid) ja väärtuseks asukoha nimi. ||| # Loo sõnastik, kus võtmeks on ennik (59.4, 24.7) ja väärtuseks 'Tallinn', ning prindi see # Sinu kood siia pass ||| print ||| Tuple key test => => {(59.4, 24.7): 'Tallinn'} ==== Ülesanne 24: Listi teisendamine ennikuks ja vastupidi ||| Andmetüüpide teisendamine käib lihtsalt funktsioonidega tuple() ja list(). See on kasulik, kui vajame vahepeal andmete muutmist. Teisenda list [1, 2, 3] ennikuks ja prindi selle tüüp. ||| lst = [1, 2, 3] # Teisenda lst ennikuks ja prindi tulemuse tüüp type() # Sinu kood siia pass ||| print ||| Type cast test => => ==== Ülesanne 25: Hulga (set) loomine ja kordumatud väärtused ||| Jõuame kolmanda uue struktuurini: **hulk** (set). Hulk on koodis määratud loogeliste sulgudega, kuid erinevalt sõnastikust pole seal võti-väärtus paare, vaid ainult unikaalsed väärtused. Kõik korduvad elemendid visatakse automaatselt välja! Loo hulk andmed korduvate arvudega ja prindi see. ||| # Loo hulk väärtustega {1, 2, 2, 3, 3, 3} ja prindi see # Sinu kood siia pass ||| print ||| Set loomine test => => {1, 2, 3} ==== Ülesanne 26: Elemendi lisamine hulka meetodiga .add() ||| Kuna hulk on dünaamiline, saame sinna elemente lisada meetodiga .add(). Kui lisatav element on juba hulgas, ei juhtu midagi (unikaalsus säilib). Lisa hulka id_hulk uus element 10. ||| id_hulk = {1, 2, 3} # Lisa hulka element 10 meetodiga .add() ja prindi hulk # Sinu kood siia pass ||| print ||| Set add test => => {1, 2, 3, 10} ==== Ülesanne 27: Elemendi eemaldamine hulgast .remove() abil ||| Hulgast elementide kustutamiseks kasutame meetodit .remove(). Eemalda hulgast väärtused element 5 ja prindi hulk. ||| väärtused = {5, 10, 15} # Eemalda element 5 ja prindi väärtused # Sinu kood siia pass ||| print ||| Set remove test => => {10, 15} ==== Ülesanne 28: Hulkade ühisosa (intersection) ||| Matemaatilised hulgatehted on Pythonis ülimalt võimsad. Ühisosa (elemendid, mis on **mõlemas** hulgas) leitakse meetodiga .intersection() või sümboliga &. Leia kahe andurite grupi ühisosa. ||| grupp1 = {1, 2, 3, 4} grupp2 = {3, 4, 5, 6} # Leia grupp1 ja grupp2 ühisosa ning prindi see # Sinu kood siia pass ||| print ||| Intersection test => => {3, 4} ==== Ülesanne 29: Hulkade ühend (union) ||| Hulkade ühend (kõik elemendid kokku ilma duplikaatideta) leitakse meetodiga .union() või sümboliga |. Leia kahe seadmete loendi ühend. ||| seadmed_a = {"ESP32", "Arduino"} seadmed_b = {"Arduino", "Raspberry"} # Leia mõlema seadmekogumi ühend ja prindi see # Sinu kood siia pass ||| print ||| Union test => => {'ESP32', 'Arduino', 'Raspberry'} ==== Ülesanne 30: Hulkade vahe (difference) ||| Hulkade vahe leiab elemendid, mis on esimeses hulgas, aga mitte teises (funktsioon .difference() või miinusmärk -). Leia hulga A ja hulga B vahe. ||| a = {1, 2, 3, 4} b = {3, 4} # Leia a ja b vahe (a - b) ning prindi tulemus # Sinu kood siia pass ||| print ||| Difference test => => {1, 2} ==== Ülesanne 31: Duplikaatide eemaldamine listist hulga abil ||| Üks levinumaid trikke Pythonis: kui viskad listi ümber hulka (set(list)) ja siis tagasi listiks (list(set)), kaovad kõik korduvad väärtused sekundiga! Eemalda duplikaadid listist [1, 2, 2, 3, 1] ja prindi puhastatud list. ||| toored = [1, 2, 2, 3, 1] # Eemalda duplikaadid hulga abil ja prindi tulemus listina # Sinu kood siia pass ||| print ||| Duplikaadi eemaldus test => => [1, 2, 3] ==== Ülesanne 32: Sõnastiku ja hulga kombineerimine seadmete halduses ||| Loome reaalsema süsteemi: meil on sõnastik aktiivsetest kontrolleritest ja hulk lubatud IP-aadressidest. Kontrolli, kas kontrolleri IP on lubatud hulgas. Kontrolli IP olemasolu ja prindi True/False. ||| lubatud = {"192.168.1.5", "192.168.1.10"} kontroller_ip = "192.168.1.5" # Kontrolli kas kontroller_ip on lubatud hulgas ja prindi tulemus # Sinu kood siia pass ||| print ||| Set check test => => True ==== Ülesanne 33: Pesastatud andmestruktuur (list sõnastikest andurite logis) ||| Tööstuslikes andmebaasides hoitakse sageli listi sees sõnastikke (JSON-formaadi standardne esitus). Prindi listis logid asuva teise sõnastiku väärtus võtmega 'väärtus'. ||| logid = [ {"andur": "A1", "väärtus": 20}, {"andur": "A2", "väärtus": 35} ] # Prindi teise sõnastiku väärtus võtmega 'väärtus' # Sinu kood siia pass ||| print ||| Nested list-dict test => => 35 ==== Ülesanne 34: AT7 Meistriklass: Nutika labori andmebaasi haldur ||| Suurepärane töö! Selles AT7 meistriklassi ülesandes paneme kokku sõnastikud, ennikud ja hulgad. Loo programm, mis haldab labori seadmeid: sõnastik seadme nimest ja selle olekust, ennik püsikatsetuse koordinaatidest ning hulk unikaalsetest veakoodidest. Prindi kokkuvõte! Koosta koondraport. ||| seade_info = {"nimi": "Kamber-1", "staatus": "Aktiivne"} koordinaadid = (60.1, 24.9) vead = {404, 500, 404} # Prindi seadme nimi, koordinaadid ja vigade hulk ühes vormindatud vastuses # Sinu kood siia pass ||| print ||| Meistritesti test => => Kamber-1 (60.1, 24.9) {404, 500}