Materjalid koostas ja kursuse viib läbi
Tartu Ülikooli arvutiteaduse instituudi programmeerimise õpetamise töörühm
< eelmine | 8. OSA sisukord | järgmine > |
8.1 Andmevahetus. Lugemine veebist. Failid
Seni oleme programmides vajalikud andmed kirjutanud programmi sisse või küsinud neid kasutajalt. Reaktsiooni oleme väljastanud ekraanile. Tegelikult võib ette tulla ka olukordi, kui algandmed tuleb hankida näiteks internetist ja tulemuse peaks salvestama hoopis faili. Käesolevas osas vaatleme andmevahetuse mõningaid võimalusi.
LUGEMINE VEEBIST
Võimalik, et meid huvitavad andmed on veebis kättesaadavad. Püüame sellise teksti kätte saada. Veebist lugemine pole eriti raske – tuleb kasutada käsku urlopen, mis on vaja eelnevalt importida moodulist urllib.request.
Olgu meid huvitav tekst järgneval aadressil
https://kodu.ut.ee/~eno/mooc/maa.txt
.
Püüame teksti sealt siis otse kätte saada.
from urllib.request import urlopen vastus = urlopen("https://kodu.ut.ee/~eno/mooc/maa.txt") baidid = vastus.read() # veebist lugemisel annab käsk read() meile tavalise sõne asemel hunniku baite, # mis on vaja veel sõneks "dekodeerida" tekst = baidid.decode() vastus.close() print(tekst)
Tekstides võib peituda salajasi teateid. Näiteks võime teada saada, mis tuleb täita lastega.
Ülesanne
Arutame nüüd, mida tekst[10].upper() + tekst[2] + tekst[-2]
täpsemalt tähendab. Muutuja tekst väärtus on sõnetüüpi. Sõne koosneb sümbolitest (märkidest), seejuures loetakse eraldi sümboliks ka näiteks tühikut, reavahetust jms.
Sõnest saab sümboleid ühekaupa kätte indeksite abil. Erinevalt tavaelust on sümbolid sõnes nummerdatud nii, et tavamõttes esimene on indeksiga 0, teine indeksiga 1 jne. Negatiivse indeksi korral võetakse sümboleid alates sõne lõpust, nii on viimane sümbol indeksiga -1, eelviimane -2 jne.
Nii annab tekst[10]
meile 11. sümboli ja funktsioon upper()
muudab selle suurtäheks. Sümbol tekst[2]
on tavamõttes kolmas sümbol ja tekst[-2]
eelviimane.
Meenutame ülesannet, kus isikukoodi järgi tuli teada saada sünnikuupäev. Isikukoodi 4. ja 5. sümbol näitavad kuud, 6. ja 7. sümbol näitavad kuupäeva. Arvestades, et Python (ja paljud teised keeled) alustavad indeksite loendamist nullist, saame näiteks sellise programmi.
isikukood = input("Teie isikukood: ") print("Teie sünnipäev on " + isikukood[5] + isikukood[6] + "." + isikukood[3] + isikukood[4])
Selliseid andmestruktuure, mida saab käsitada elementide kaupa, on Pythonis mitmeid. Üheks selliseks on list, mida märgitakse nurksulgudega ja kus elemendid eraldatakse komadega. Omistame muutujale a väärtuseks listi, milles on arvud 1, 4, 5 ja -27.
a = [1, 4, 5, -27]
Listi a elemendi indeksiga 2 väärtus on 5.
Kõik listi elemendid saaksime ükshaaval ekraanile kuvada while-tsükli abil. Funktsioon len annab meile listi pikkuse ehk elementide arvu. Listi a pikkus on 4.
i = 0 while i < len(a): print(a[i]) i += 1
Tegelikult saaksime listiga tegutseda for-tsükli abil, aga seda me selles kursuses ei tee.
FAILID. FAILIDE LUGEMINE REAKAUPA
Õpime ära ühe viisi, kuidas tekstifaile lugeda. Alustuseks võiks Thonnyga koostada ja salvestada tekstifaili nimega andmed.txt, mille esimesel real on inimese nimi, teisel real vanus (täisarvuna) ning kolmandal real meiliaadress (lihtsuse mõttes täpitähti ei kasuta).
NB! Loetav fail peab olema plain-text kujul (laiendiga .txt), Wordi fail (laiendiga .doc vms) näiteks ei sobi. Seepärast soovitamegi kasutada faili loomiseks Thonnyt.
Looge tekstifailiga samasse kausta järgnev programm.
f = open("andmed.txt") nimi = f.readline() vanus = f.readline() aadress = f.readline() print("Nimi:", nimi) print("Vanus:", vanus, "aastat") print("Aadress:", aadress) f.close()
Vaatame nüüd selle programmi keerulisemaid ridu ükshaaval.
f = open("andmed.txt")
- Käsk open otsib failisüsteemist üles soovitud faili ja tagastab viite sellele (antud näites salvestasime selle viite muutujasse f, mis on levinud nimi failide tähistamiseks). Kui tahate avada faili samast kaustast, kus asub programm, siis piisab vaid failinimest koos laiendiga:
f = open('andmed.txt')
.
nimi = f.readline()
- Rida
nimi = f.readline()
loeb failist ühe rea, milleks on meie näites isiku nimi, ning annab selle väärtuse sõnena edasi muutujale nimi. Järgmisel korral sama käsku kasutades loetakse järgmine rida. Meie näites loetakse failist järgmisena vanus.
f.close()
- Käsk
f.close()
ütleb failisüsteemile, et me oleme selle faili kasutamise lõpetanud.
Kui seda programmi katsetada, siis võib märgata, et väljundis tekib iga sisestatud andmejupi järele üks üleliigne tühi rida. Põhjus on selles, et failist lugedes jäetakse iga rea lõppu alles ka failist pärinev reavahetuse sümbol. Nimelt tähistatakse tekstifailides reavahetust sarnaselt Pythoniga: kui Pythoni sõne sisse kirjutame sümboli \n, siis tähendab see Pythoni jaoks reavahetust. Iga kord kui tekstiredigeerijas järgmise rea ette võtate, sisestab programm teie eest faili reavahetuse märgi. See reavahetuse märk jäetakse alles, kui nüüd failist teksti loeme.
NB! Kui Python ütleb (Windowsi arvutis), et ei leia faili, aga olete veendunud, et fail on õiges kaustas olemas, siis tuleks kontrollida ega failinimele pole saanud eksikombel kaks faililaiendit. Segadust võib tekitada asjaolu, et operatsioonisüsteem varjab vaikimisi teatud faililaiendid. Kõige kindlam on muuta Windowsi seadeid nii, et alati näidataks kõiki faililaiendeid. Selleks tuleks mõnes kaustas valida menüüribalt Vaade ja seal panna "linnuke" punkti Failinimede laiendid ette (erinevates Windowsi versioonides võib see olla erinev).
NB! Kui proovida lugeda sisse täpitähtedega teksti, siis võib juhtuda, et saadakse veateade UnicodeDecodeError. Sel juhul tuleb open käsu rakendamisel öelda, millises kodeeringus on tekst, nt open('andmed.txt', encoding='UTF-8')
. UTF-8 asemel võib proovida ka cp1257.
FAILI SISU LUGEMINE ÜHEKORRAGA
Koostage veel üks mitmerealine, suvalise sisuga tekstifail ning salvestage see nimega tekst.txt. Seejärel käivitage (samas kaustas) järgmine näiteprogramm:
f = open('tekst.txt') faili_sisu = f.read() print(faili_sisu) f.close()
Siin kasutasime meetodi readline asemel meetodit read, mis luges ühte sõne-tüüpi muutujasse sisse kogu faili sisu.
FAILIDE KIRJUTAMINE
Järgmine programm demonstreerib andmete kirjutamist tekstifaili:
nimi = input("Palun sisesta oma nimi: ") vanus = input("vanus: ") aadress = input("aadress: ") f = open("andmed2.txt", "w") f.write(nimi + "\n") f.write(vanus + "\n") f.write(aadress + "\n") f.close()
Faili kirjutamiseks tuleb funktsioonile open anda ka teine argument väärtusega "w" (nagu write ehk otsetõlkes kirjuta). Kui sellise nimega fail juba eksisteerib, siis open(..., "w") teeb selle tühjaks. Erinevalt funktsioonist print ei tekita funktsioon write automaatselt reavahetusi. Selleks, et saada eri andmeid eri ridadele, lisasime reavahetuse sümboli käsitsi.
< eelmine | 8. OSA sisukord | järgmine > |