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õnedel on kindlad väärtused. Kui näiteks inimese jaoks on a ja A sama täht, siis arvuti jaoks see nii ei ole, kui me just nii eraldi ei määra. Selle tulemusena ei saa me nii lihtsalt tähti sorteerida kui tahame neid tähestiku järjekorda. Kuna Python paneb esimesteks suured tähed ja siis alles väikesed tähed. Näiteks:
a = "abCdeFg" b = "".join(sorted(a)) print(b)
Programm loob kõigepealt sõnest a listi, seejärel muudab ta sõneks ja viimaseks väljastab ekraanile. Ekraanile ilmub:
CFabdeg
See ei ole küll tähestiku järjekorras. Aga Pythoni jaoks on ta selle ilusti ära sorteerinud.
a = "abCdeFg" b = "".join(sorted(a.lower())) print(b)
Nüüd kasutasime käsku, mis muutis kõik väiketähtedeks. Väljastati:
abcdefg
Nüüd väljastas programm ekraanile meile meelepärasema variandi.
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 |
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.
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 fail, või andma asukoha, kus fail arvutis asub.
fail = open("andmed.txt") 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 sõnejärjendina …
2. … mis salvestatakse muutujasse fail
3. for-tsükkel käib selle järjendi elemendid ükshaaval läbi.
Tegelikult 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 soovisime tervitada ainult inimesi, siis pidime 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() 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