36 Faili kirjutamine
Tühja faili kirjutamine
Eespool oleme tutvunud mitmete võimalustega, kuidas failist andmeid lugeda. Failid on meil juba olemas olnud või oleme need ise tekstiredaktoriga teinud. Nüüd vaatame, kuidas isetehtud programmiga andmeid faili kirjutada. Selleks pakub võimalusi funktsioon write
(ingl kirjuta).
Järgmine programm kirjutab kasutajalt küsitud andmed faili.
Näiteprogramm. Faili kirjutamine I
nimi = input("Palun sisesta oma nimi: ") vanus = input("vanus: ") aadress = input("aadress: ") f = open("andmed3.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). 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 andmeid eri ridadele, lisasime reavahetuse sümboli käsitsi.
Proovime kirjutada programmi, mis küsib kasutajalt kaks failinime. Esimene fail peaks olema juba olemas ja seal peaks olema mingi tekst. Teine fail võiks olla uus. Programmi ülesanne on võtta esimese faili sisu, teisendada see suurtähtedesse ning kirjutada teise faili.
Näiteprogramm. Ühest failist teise ümberkirjutamine
doonorNimi = input("Mis failist info võtta? ") aktseptorNimi = input("Millisesse faili info pannakse? ") doonorFail = open(doonorNimi, encoding="UTF-8") aktseptorFail = open(aktseptorNimi, "w") for rida in doonorFail: aktseptorFail.write(rida.upper()) doonorFail.close() aktseptorFail.close()
Ka faili kirjutamiseks saab määrata kodeeringu, näiteks open(aktseptorNimi, "w", encoding="UTF-8")
.
Failile juurde kirjutamine
Kui funktsiooni open
teine argument on "a"
, siis kirjutatakse olemasoleva faili lõpust edasi ning varasem sisu säilib muutmata. Kui sellist faili pole, siis see luuakse. Ka siin saab määrata kodeeringu, näiteks open(failiNimi, "a", encoding="UTF-8")
. Argument "a"
tuleb ingliskeelsest sõnast append (lisa).
Temperatuurid veebist faili
Kirjutame programmi, mis loeb aadressilt http://meteo.physic.ut.ee/ aasta 2017 jaoks iga päeva keskmise temperatuuri ja kirjutab selle faili. Ühe aasta andmete töötlemine võtab aega umbes pool minutit. Programmis kasutatakse kahekordset tsüklit, mille põhjalikum käsitlus jääb siinsetest materjalidest välja.
Näiteprogramm. Temperatuurid veebist faili
from urllib.request import urlopen fail = open("andmed.txt", "a") # fail avatakse juurde kirjutamiseks päevad = [31,28,31,30,31,30,31,31,30,31,30,31] aasta = 2017 for kuu in range(1,13): # välimine tsükkel kuude järjenumbrite kaupa for päev in range(1, päevad[kuu-1]+1): # sisemine tsükkel päevade kaupa # konkreetse päeva andmed vastus = urlopen("http://meteo.physic.ut.ee/et/showperiod.php?type=setday&year="+str(aasta)+"&month="+str(kuu)+"&day="+str(päev)) baidid = vastus.read() tekst = baidid.decode() otsitav = "<SMALL>keskmine</SMALL><BR><B>" algus = tekst.index(otsitav) # leitakse õige koht temp_algus = algus + len(otsitav) # siit algab temperatuur deg = tekst.index(" °") # siin lõpeb temp = tekst[temp_algus:deg] # viilutades leitakse temperatuur # funktsioon rjust paneb ühekohalisele päeva ja kuu järjenumbrile 0 ette, et oleks kahekohaline. fail.write(str(päev).rjust(2,"0")+"."+str(kuu).rjust(2,"0")+"."+str(aasta)+": "+str(temp)+"\n") vastus.close() fail.close()
Enesekontroll (1 küsimus)
Šifreerimine
Tegeleme natuke salakirjadega. Me ei kirjuta faili mitte sümboli enda, vaid mingi kindla teise sümboli. Näiteks kui me kirjutame tähe A
asemel tähestikus 4 kohta edasi paikneva tähe E, siis sõne AEG
asemel kirjutaksime hoopis EIK
. Sellise tegevuse nimetus on nihkešiffer, mis on ajalooliselt tuntud meetod salakirja kirjutamiseks. Kui nihe on teada, siis on teksti lihtne isegi käsitsi dešifreerida, arvutist rääkimata. Ka tundmatu nihke korral on võimalik šiffer üsna kiiresti murda.
Kuna me tahame tähti järjekorranumbri alusel nihutada, siis oleks mõistlik tähed nummerdada. Loomulik oleks näiteks A järjekorranumbriks võtta 1, B korral 2 jne. Seda me siiski ei tee, sest tähtedel ja paljudel teistel (sealhulgas nähtamatutel) märkidel on sellised järjekorranumbrid juba olemas. Vastava järjekorranumbri saame teada funktsiooniga ord
. Katseta näiteks käske:
print(ord("A")) print(ord("a")) print(ord("ä")) print(ord("õ")) print(ord(" "))
Näiteks näeme, et täpitähed on meie ülejäänud tähestikust hoopis eemal, kuna need pole osa ladina põhisümbolitest.
Funktsiooniga chr
saame teada arvule vastava märgi:
print(chr(65))
Proovi ka päris suurte arvudega. Pikemalt on sellest juttu silmaringimaterjalis.
Kirjutame nüüd programmi, mis sisestatud sõne šifreeritult faili kirjutaks:
Näiteprogramm. Šifreeritud kirjutamine
def kodeeri(sümbol, nihe): return chr(ord(sümbol) + nihe) def šifreeri(failinimi, nihe): f = open(failinimi, "w") kiri = input("Sisesta lause ") for sümbol in kiri: f.write(kodeeri(sümbol, nihe)) f.close() failinimi = input("Faili nimi? ") nihe = int(input("Nihe? ")) šifreeri(failinimi, nihe)
Katseta šifreerimise programmi.
Järgmiseks on meil loomulikult tarvis šifreeritud fail tagasi loetavaks sõnumiks muuta. Pakume siin mõned juhtnöörid:
- Funktsioon
dekodeeri
on funktsioonilekodeeri
üsna sarnane. Kui šifreerimisel tuli nihe liita, siis dešifreerimisel tuleb see lahutada. - Kui šifreerimisel avati fail kirjutamiseks, siis dešifreerimisel tuleb see avada lugemiseks.
-
Sümbolite ühekaupa käsitlemiseks saab kasutada sellist tsüklit
while True: sümbol = f.read(1) # loetakse üks sümbol if sümbol == "": # kui sümboleid enam pole break # tsükkel katkestatakse print(dekodeeri(?????????), end = "") # reavahetust ei tule
Küsimärgid tuleb asendada vastavalt sellele, kuidas funktsioon
dekodeeri
tehtud on.