15. praktikumi harjutused
Lahendused esita Moodle’is. Kui teed koos paarilisega, kirjuta juurde ka kummagi paarilise nimi.
1. Kuld
Seifi pannakse üks kuldmünt ja seif ise omakorda pannakse teise, suuremasse seifi, kuhu lisatakse veel ka üks kuldmünt. Teine seif pannakse omakorda kolmandasse, veel suuremasse seifi, lisades sinna veel kaks kuldmünti jne. (Koos esimese seifiga pannakse 1 münt, teisega 2, kolmandaga 3 münti jne.) Koosta rekursiivne funktsioon, mis saab argumendiks seifi järjekorranumbri ja tagastab selles seifis olevate kuldmüntide koguarvu.
Muutmised
- Muuda funktsiooni nii, et see tagastab seifis olevate kuldmüntide koguarvu, kui koos esimese seifiga pannakse järgmisse seifi 1 kuldmünt, teisega 4, kolmandaga 9 jne.
- Muuda funktsiooni nii, et see tagastab seifis olevate kuldmüntide koguarvu, kui
- esimesel sammul pannakse seifi 1 kuldmünt,
- teisel sammul pannakse suuremasse seifi kaks eelmises punktis kirjeldatud seifi ja lisaks 1 kuldmünt,
- kolmandal sammul pannakse omakorda suuremasse seifi kaks eelmises punktis kirjeldatud seifi ja lisaks 1 kuldmünt jne.
Argumendiks on sammude arv.
2. Lennuplaan
Koosta rekursiivne funktsioon lennuplaan, mis võtab argumentideks lähtelinna nime, sihtlinna nime ja lendude andmebaasi ning tagastab linnade järjendi, mis tuleb läbida, et jõuda lähtelinnast sihtlinna. Kui lennata ei ole võimalik, siis tagastab tühja järjendi.
Lendude andmebaas on esitatud sõnastikuna, kus igas kirjes on võtmeks linna nimi ja sellele vastavaks väärtuseks hulk, mille elementideks on kõigi sellest linnast lähtuvate otselendude sihtkohad.
>>> lennuplaan('Tallinn', 'Nice', {'Berliin': {'Tallinn'}, 'Tallinn': {'Berliin'}}) [] >>> lennuplaan('Tallinn', 'Berliin', {'Berliin': {'London'}, 'Tallinn': {'Berliin'}}) ['Tallinn', 'Berliin'] >>> lennuplaan('Tallinn', 'Nice', {'Pariis': {'London', 'Berliin', 'Nice'}, 'London': {'Berliin', 'Pariis'}, 'Berliin': {'London', 'Pariis', 'Tallinn'}, 'Tallinn': {'Berliin'}}) ['Tallinn', 'Berliin', 'Pariis', 'Nice']
Vihjed
- Mis on rekursiooni baas?
- Teekond lähtelinnast sihtlinna peab minema läbi mingi linna, kuhu on võimalik lähtelinnast otse lennata.
- Tsükliliste ringkäikude vältimiseks tuleb vaatlemata jätta need naaberlinnad, mis juba sisalduvad külastatud linnade järjendis.
3. Käsureaargumendid
Oleme kursuse jooksul kasutajalt sisendi hankimiseks kasutanud funktsiooni input(), mis küsib sisendit programmi käivitamise jooksul. Kui on vaja programmi automatiseerida, on käsuga input() küsitavaid sisendeid keeruline väärtustega täita. Sellepärast on võimalik anda sisend enne programmi käivitamist argumentidena programmile kaasa.
Kui käivitada Pythoni programmi terminaliaknas, saab argumendid lisada käivituskäsu lõppu:
$ python3 failinimi.py esimenearg teinearg
Siin esimene argument on „esimenearg” ning teine argument on „teinearg”.
Thonnys võib kirjutada alla aknasse käsu %Run failinimi.py, mis käivitab programmi failinimi.py. Seda teeb automaatselt F5 või nupu „Run current script” vajutamine. Kuid sinna saab ka argumente juurde kirjutada:
>>> %Run failinimi.py esimenearg teinearg
Niisama ei tee need argumendid midagi, aga neid saab kätte muutujast argv, mis asub moodulis sys. See muutuja on järjend, mille esimene element on programmifaili nimi ning järgnevad elemendid programmile kaasaantud argumendid.
from sys import argv print(argv) print("Esimene argument on", argv[1])
>>> %Run failinimi.py esimenearg teinearg ["failinimi.py", "esimenearg", "teinearg"] Esimene argument on esimenearg
Ülesanne
Koosta programm, mis võtab kasutajalt argumendina sisse arvu ning väljastab ekraanile:
- teksti "Fizz", kui see arv jagub kolmega;
- teksti "Buzz", kui see arv jagub viiega;
- teksti "Fizzbuzz", kui see arv jagub nii kolme kui viiega;
- kasutaja sisestatud arvu, kui see arv ei jagu ei kolme ega viiega.
4. Rakendusliides ehk API
Võib juhtuda, et programmiks vajalikke andmeid ei ole võimalik saada kasutajalt ega kuskilt dokumendist ning peab pöörduma Interneti poole. Järgmine koodijupp näitab, kuidas Pythoniga lugeda Tartu Ülikooli veebilehekülge:
>>> import urllib.request >>> aadress = "https://www.ut.ee/et" >>> lehekülg = urllib.request.urlopen(aadress).read() >>> lehekülg b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML+RDFa 1.1//EN">\n<html lang="et"...
Suvaliste lehtedega proovides võib tulla palju HTML-koodi, millest midagi välja lugeda on küll võimalik, kuid ebapraktiline ning jääb selle praktikumi materjalidest väljapoole. (Huvitatutel soovitame uurida teeki Beautiful Soup või otsida võtmesõna HTML parsing.)
Et teha andmed programmile kergesti loetavaks, kasutatakse tihti JSON-vormingut. See vorming lubab sõnedes hoida JavaScripti objekte, mis on sarnased Pythoni sõnastikele. Koodijupp JSON-vormingus sõne teisendamisest Pythoni sõnastikuks:
>>> import json >>> sõne = '{"ping": "pong", "töötab": true}' >>> andmed = json.loads(sõne) >>> andmed["ping"] ‘pong’ >>> andmed["töötab"] True
Internetis leidub palju rakendusliideseid, mis väljastavadki JSON-vormingus mitmesuguseid andmeid. Mõned näited:
- https://pokeapi.co/ - andmed erinevate Pokémonide kohta, eelkõige hariduslikel eesmärkidel, et rakendusliideseid õppida
- https://api.chucknorris.io/ - Chuck Norrise naljad
- https://www.metaweather.com/api/ - Ilmaennustus (kahjuks ei ole Eesti asukohti)
- https://yesno.wtf/api - väljastab juhuslikult “yes” või “no” ja vastava gifi
- https://exchangeratesapi.io/ - valuutad
- https://dog.ceo/dog-api/ - koerad
Suur nimekiri sarnastest rakendusliidestest: https://github.com/toddmotto/public-apis
Veel üks: https://any-api.com/
Paljud rakendusliidesed ei ole niisama kättesaadavad ning nõuavad autentimist, et saaks vajadusel päringuid piirata. Nende kasutamiseks peab registreeruma kasutajaks ning iga päringuga kaasa saatma võtme, mille kasutajaks registreerumisel saab genereerida. Mõned huvitavad rakendusliidesed, mis nõuavad autentimist:
- https://developer.wordnik.com/ - sõnastik
- https://openweathermap.org/api - ilmaennustus
- https://developer.spotify.com/documentation/web-api/ - muusika
- https://cloud.google.com/translate/docs/ - tõlkimine
Ülesanne
Kirjuta lihtne programm, mis küsib kasutajalt millegi kohta sisendit, kasutab mõnda huvitavat rakendusliidest ning väljastab sisendile vastava Internetist saadud info.
Märkus
Kui Python annab veateate 403 (Forbidden), võib vaikimisi määratud kasutajaagent olla keelatud. Õnneks saab selle muuta ükskõik milleks:
import urllib.request aadress = "https://pokeapi.co/api/v2/pokemon/pikachu/" päring = urllib.request.Request(aadress) päring.add_header("User-Agent", "Mozilla/5.0") lehekülg = urllib.request.urlopen(päring).read()