Sõned ja lihtsam failitöötlus
Sõned
Programmeerimine pole ainult arvudega manipuleerimine, paljudes programmides on tähtsamal kohal töö tekstiga. Selle tarvis on Pythonis olemas eraldi andmetüüp sõne (ingl string, lühend str), mida kasutatakse justnimelt teksti esitamiseks.
Konkreetsed tekstijupid pannakse programmi tekstis kirja sõneliteraalidena. Enamasti piisab sõneliteraali kirjapanekuks sellest, kui soovitud tekst piiritletakse ülakomade või jutumärkidega, mis on samaväärsed, nt 'Tartu' või "Kauneim linn on Eestis Tartu".
Sõnesid kirja pannes tuleb jälgida, et kui tekib lause, kus on ülakoma või jutumärgid kirjavahemärkidena, siis tuleb see kuidagi eraldada, sest muidu peab Python seda sõne lõpuks.
print('Rock 'N' Roll')
Kui proovime väljastada järgmist lauset, siis annab Python meile süntaksvea. Seda saaks parandada, kui me asendame välimised ülakomad jutumärkidega.
print("Rock 'N' Roll")
Ühe võimalusena on Pythonis veel märk \, mis annab Pythonile teada, et sõnes olev märk on sõne osa.
print('Rock \'N\' Roll')
Langkriipsu \ saab kasutada ka muul otstarbel, nt reavahetusi saab esitada kombinatsiooniga \n. Kui anname muutujale mingi joru teksti ette, siis ta võtab seda kõike ühe reana, ning selleks, et reavahetusi teha, peab sõne vahele panema \n.
a = "Tere tere vana kere!" b = "Tere tere\nvana kere!" print(a) print(b)
Proovi järele, kuidas muutujate a ja b väärtused erinevad.
Nagu näha, on langkriips tekstiliteraalis spetsiaalse tähendusega. Kuidas aga esitada langkriipsu ennast? Lihtne, see tuleb ära märgistada … langkriipsuga!:
print("C:\\Opel\\tarkus.txt")
Kui tekstis on vaja kasutada palju reavahetusi, ülakomasid või jutumärke, siis võib tulemus muutuda kõigi nende \n-de, \'-d või \"-de tõttu väga kirjuks. Seetõttu on Pythonis veel üks sõne kirjapaneku viis – kolmekordsete ülakomade või jutumärkide vahel saab vabalt kasutada tavalisi reavahetusi, ülakomasid ja jutumärke:
print("""T"e"r'e'""")
Sõnede liitmine
Eelnevalt oleme liitnud arve. Näiteks teame, et 3+4 annab tulemuseks 7. Varasemalt oleme kokku puutunud ka sõnede liitmisega, kus plussmärki kasutatakse sõnede kokkupanemiseks. Näiteks
print("tere" + "tore")
väljastab ekraanile "teretore".
Kas sõnesid saab ka korrutada? Proovi, mida teeb näiteks:
print(5 * "Osta elevant ära! ")
Enesekontroll
Tehted sõnedega
Nagu juba eelmisest näitest nägime, siis on Pythonis endas hulk funktsioone, mida saab sõnede töötlemiseks ära kasutada. Siin on mõned näited erinevatest tehetest.
Avaldis | Väärtus | Selgitus |
---|---|---|
'Tere' + 'Madis!' | 'TereMadis!' | + loob kahe sõne põhjal uue sõne |
'Tere' + ' Madis!' | 'Tere Madis!' | Tühikud tuleb vajadusel ise vahele panna |
'Tere' + ' ' + 'Mad' + 'is!' | 'Tere Madis!' | Kokku võib liita ka mitu sõnet |
'nr.' + 1 | Viga!!! | Sõnet ja arvu ei saa niisama ühendada |
'nr.' + str(1) | 'nr.1' | str annab arvule vastava sõne |
'5' + '3' | '53' | Sõnena esitatud arve ei käsitleta arvudena |
int('5') | 5 | int annab sõnele vastava täisarvu |
float('5.3') | 5.3 | float annab sõnele vastava ujukomaarvu |
'xo' * 3 | 'xoxoxo' | Sõne dubleerimine |
len('tere') | 4 | Sõne pikkuse (length) küsimine |
'tere'.upper() | 'TERE' | Muudab sõne tähed suureks |
'TeRe'.lower() | 'tere' | Muudab sõne tähed väikeseks |
'jäääär'.count('ä') | 4 | Loeb kokku etteantud tähe esinemised sõnes |
'tere'.rjust(10) | ' tere' | Sõne paigutamine etteantud „ruumi“, see on abiks nt tabelite moodustamisel. |
'terekest'.rjust(12) | ' terekest' | Selle käsupaariliseks on ljust, katseta ise, mida see teeb! |
'terekest'.rjust(12, 'o') | 'ooooterekest' | Teise argumendiga saab määrata, millist sümbolit ruumi täitmiseks kasutatakse. |
' tere '.strip() | 'tere' | Käsk strip annab sõne ilma alguses ja lõpus olevate tühikute ja reavahetusteta |
'tere'.replace('e','ö') | 'törö' | Funktsioon replace genereerib uue sõne, kus näidatud tähed või alamsõned on asendatud millegi muuga. |
'isamaa'.replace('isa', 'ema') | 'emamaa' | Käske saab kombineerida |
'tere'.islower() | True | Kontrollib, kas sõnes on kõik väikesed tähed |
'tere'.isupper() | False | Kontrollib, kas sõnes on kõik suured tähed |
Selleks, et uurida kõiki sõne käske on loodud ametlik lehekülg: https://docs.python.org/3/library/stdtypes.html#string-methods
Sõnedel tähtedel on kindel järjekord. Neid saab võtta kui järjendeid, mis koosnevad tähtedest. Tänu sellele on võimalik sõnedest erinevaid andmeid kätte saada. Igal tähel sõnes on kindel järjekorranumber, mida kutsutakse indeksiks. Neid hakatakse loetlema 0-st.
Miks alustatakse järjendi elementide nummerdamist 0-st?
Vanemates programmeerimiskeeltes oli taoline valik tingitud järjendite esitusviisist arvuti mälus. Teine põhjus on selles, et nii saab mõnesid keerulisemaid indekseerimisavaldisi veidi lühemalt kirja panna. Kolmas ja kõige olulisem põhjus on see, et enamikus programmeerimiskeeltes on sedasi kogu aeg tehtud ning väga paljud programmeerijad on harjunud taolise nummerdamisega.
sõne = "Tere maailm!" print(sõne[0:4] + " kosmos!")
Katseta, mis ilmub ekraanile.
Kuna esimene indeksi number on 0, miks siis nelja tähe saamiseks pidi 5 indeksi kohta valima?.
Kuna vastav funktsioon ei arvesta valitud lõpu indeksit sisse ehk antud juhul ei arvestata tühikut sisse.
Kuidas vaadelda sõnes tähti ükshaaval? Selleks on mugav võimalus kasutada tsüklit:
sõne = "abc" for täht in sõne: print(täht)
Sõnede video
https://panopto.ut.ee/Panopto/Pages/Viewer.aspx?id=6a71872d-d7bf-482f-8904-ac5400cd47c3
Enesekontroll
Failist lugemine
Olgu meil teksti fail andmed.txt. Selle sisu on järgmine: Taavi Mia Karl Sirli 314
Soovime sealt nimed kätte saada ja neid tervitada.
Selleks, et Python suudaks faili lugeda peab see olema samas kaustas, kus Pythoni (py) fail, või vajadusel andma asukoha, kus fail arvutis asub.
Faili saame avada käsuga open
ja sulgeda käsuga close
. Käsuga @open@ faili avades tuleb tähele panna, et kui failis on sõned, siis peaks ette andma ka kodeeringu. Eesti tähtedega on piisav kodeering UTF-8. Failist rida-haaval lugemiseks saame kasutada käsklust readline
. Näiteks kui tahame eelolevast failist lugeda ja ekraanile väljastada ainult esimese rea, saame seda teha selliselt:
fail = open("tekst.txt", encoding = "UTF-8") print(fail.readline()) fail.close()
Kuna selliselt väljastatakse ekraanile ka failis igal real olev reavahetus, siis tasub proovida failist lugemisel puhastada rida reavahetustest käsuga fail.readline().strip()
. Kaks rida failist saame ekraanile väljastada, kui korrata käsklust readline
.
Kui fail on pikem või me ei tea, mitu rida failis on, siis pole paraku selline lähenemine väga jätkusuutlik. Siis võiks kasutada tsükli abi kuni ridu leidub või on tühi rida selliselt:
fail = open("tekst.txt", encoding = "UTF-8") while True: rida = fail.readline() if not rida: break else: print(rida.strip()) fail.close()
Teine võimalus on lugeda kõiki ridu failist kasutades tsükli konstruktsiooni for rida in fail
. Reavahetuse eemaldamiseks kasutame endiselt käsklust strip
:
fail = open("andmed.txt", encoding = "UTF-8") for rida in fail: print("Tere, " + rida.strip() + "!") fail.close()
Kui soovime aga eristada arvulisi andmeid sõnedest, siis saame need tuvastas if-lausega järgnevalt:
fail = open("andmed.txt", encoding = "UTF-8") for rida in fail: if rida.isdigit(): continue else: print("Tere, " + rida.strip() + "!") fail.close()
Seda näidet kommenteerides võiks lihtsustatult öelda, et:
1. funktsioon open tagastab failis sisalduvad read järjendina, …
2. … mis salvestatakse muutujasse fail ja
3. for-tsükkel käib selle järjendi elemendid ükshaaval läbi.
Kokkuvõttes ei ole muutujas fail siiski mitte järjend, vaid natuke keerulisem väärtus. Õnneks oskab for-tsükkel seda väärtust käsitleda justkui järjendit, seetõttu ei pea me muretsema, kuidas need faili read tegelikult on esitatud. Lisaks kasutasime sõnetöötluse funktsiooni isdigit ja strip. Kuna me soovime tervitada ainult inimesi, siis peaksime kontrollima, kas kõik on ikka sõned. Veel failist lugedes jääb iga rea taha \n märk, sest see aitab Pythonil ära tunda rea lõppu. Selle eemaldamiseks kasutasime käsku strip.
Lugemine veebist
Ka veebist teksti lugemine pole eriti raske – käsu open asemel tuleb kasutada käsku urlopen, mis on vaja eelnevalt importida moodulist urllib.request:
from urllib.request import urlopen vastus = urlopen("http://artscene.textfiles.com/asciiart/simpsons.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("utf-8") print(tekst) vastus.close()
Faili kirjutamine
Varasemalt puutusime kokku, kuidas faili avada ja sealt infot kätte saada. Tegelikult on väga kasulik ka faili asjade lisamine, sest saame seda kasutada andmete salvestamiseks. Selleks, et faili andmeid kirjutada, peame päises deklareerima, et soovime kasutada funktsiooni write.
fail = open("andmed.txt", "w")
w tähendabki write, saame kasutada ka r, mis tähendab read, aga see on ka vaikelahendus, mida ei pea eraldi märkima. Lisaks funktsioonile write on olemas ka funktsioon append, mida tähistatakse a-ga.
Tähelepanek!
Funktsioon Append lisab andmed faili lõppu, aga write kustutab eelneva faili ja
kirjutab etteantud andmed asemele.
Selleks, et faili kirjutada on käsk write. Lisaks kui info on jäjendis, siis saab kasutada käsku writelines.
fail = open("Uus.txt", "w") fail.write("1\n") fail.writelines(["2\n","3\n","4\n","5\n","6\n", "seitse"]) fail.close()
Käivitamisel kirjutatakse faili sisu üle.
fail = open("Uus.txt", "a") fail.write("1\n") fail.writelines(["2\n","3\n","4\n","5\n","6\n", "seitse"]) fail.close()
Selliselt lisatakse andmed faili eelmisi faile muutmata.
Katseta mõlemad viisid läbi. Kapoti all: stdin ja stdout Ilmselt märkasid teatud sarnasust print ja write ning input ja readline vahel. Tegelikult on nende kahe käsupaari seosed palju tihedamad kui paistab. Nimelt käsitletakse operatsioonisüsteemi tasemel kasutaja sisendit justkui mingit virtuaalset faili, millesse tekivad uued read iga kord kui kasutaja klaviatuuril midagi tipib ja vajutab ENTER-it – seda faili nimetatakse stdin-iks ehk standarsisendiks. Analoogselt on olemas virtuaalne fail, kuhu kirjutades ilmuvad read kasutaja konsoolile – seda faili nimetatakse stdout-iks ehk standarväljundiks. Need failid ei asu tegelikult failisüsteemis ja viited neile organiseeritakse iga programmi jaoks operatsioonisüsteemi poolt, seetõttu pole neid kunagi vaja ise avada ega sulgeda. Pythonis saab viited neile failidele kätte moodulist sys ja nende kasutamist demonstreerib järgnev näide:
from sys import stdout, stdin stdout.write("Palun sisesta oma nimi ja vajuta ENTER: ") nimi = stdin.readline().strip() stdout.write("Tere " + nimi + "!")
Käsud print ja input ongi lihtsalt mugavamad viisid nende failide kasutamiseks.
Failist ja veebist lugemise video
Enesekontroll