9. Tsükkel
Sageli on vaja täita mingeid käske korduvalt: trükkida mitu korda sama sõna, teha sama tehet, joonistada ühesuguseid kujundeid jne. Ühest küljest oleks liiga töömahukas kopeerida sama koodi kümneid, tuhandeid või miljoneid kordi, teisest küljest ei pruugi me alati programmi kirjutades veel teadagi, mitu korda mingit operatsiooni on vaja teha. Kas programmi kasutaja soovib joonistada 10 või 1000 kolmnurka?
Korduvate operatsioonide puhul kasutatakse programmeerimises tsükleid. Tsükleid on kaht tüüpi:
- While-tsükkel e. tsükkel, mis kordab valitud käske seni, kuni määratud tingimus (tsüklitingimus) on tõene (ka eelkontrolliga tsükkel).
- For-tsükkel e. tsükkel, mis kordab valitud käske kindel arv kordi (ka määratud tsükkel).
While-tsükkel
Eelkontrolliga tsükli puhul kontrollitakse enne käskude täitma asumist mingi tingimuse tõesust. Kuni tingimus on tõene (tsüklitingimuses kasutatav tsüklimuutuja vastab tingimusele), täidetakse tsüklis olevaid käske, kui aga mitte, väljutakse tsüklist e. minnakse järgmisele reale pärast tsüklit sisaldavat plokki. Sarnaselt tingimuslausega kasutatakse koolonit ja korratavate ridade plokk on eristatud taandega.
Järgnevas näites võrdsustatakse muutuja i väärtus ühega ning väljastatakse i väärtusi ja suurendatakse i väärtust ühe võrra seni, kuni i väärtus pole enam väiksem kui 5. Seega muutub i väärtus ühest neljani ning ekraanile trükitakse neli rida.
i = 1 while i < 5: print("i väärtus on " + str(i)) i = i + 1
While-tsüklit on kasulik kasutada siis, kui pole teada, palju kordi on vaja koodiridu korrata, näiteks korratakse, kuni kasutaja sisestab nõuetele vastavad andmed (alles siis minnakse edasi ja töödeldakse neid) või kuni kasutaja soovib lõpetetada programmi töö. Tsükli täitmise igal sammul peaks tsüklimuutuja väärtust muutma, vastasel korral on tsükli tingimus pidevalt tõene ja tsükkel jääb lõpmatult tööle. Vajadusel saame programmi täitmist katkestada klahvikombinatsiooniga Ctrl + C. Kui soovime erandkorras, et tsüklit läbitakse "lõpmatuseni" (näiteks et seda tsükli sees mingite käskudega katkestada), võime kirjutada "while True:" ("True" on alati tõene).
For-tsükkel
Määratud tsükli puhul toimub tsüklimuutuja muutmine juba tsükli enda poolt: tsüklimuutujale antakse väärtusi etteantud järjendist. Tsükli täitmine lõpeb, kui järjendis enam elemente pole. Järjendiks on komaga eraldatud elemendid, mis on paigutatud nurksulgude vahele. Kuna näites olevates print-käskudes on kaustatud sõnede liitmist pluss-märgiga, peame esimese näite puhul, kus i on täisarv, teisendama i sõneks (str(i)).
for i in [0, 1, 2, 3, 4]: print("i väärtus on " + str(i))
for i in ["esimene", "teine", "kolmas"]: print("i väärtus on " + i)
Järjendi võib luua ka tsükli täitmise ajal e. nö. dünaamiliselt, selleks kasutame funktsiooni range(), kus sulgudesse võib lisada üks kuni kolm täisarvulist (vajadusel ka negatiivset) argumenti:
- range(stop) – täisarvude järjend alates nullist kuni väärtuseni stop-1
range(6) # Jada 0, 1, 2, 3, 4, 5
- range(start, stop) – täisarvude järjend alates väärtusest start kuni väärtuseni stop-1
range(1,6) # Jada 1, 2, 3, 4, 5
- range(start, stop, step) – täisarvude järjend alates väärtusest start kuni väärtuseni stop-1 sammuga step
range(1,6,2) # Jada 1, 3, 5
Tsükli katkestamine
Mõnikord on vaja katkestada tsüklit ka täidetavate käskude keskel. Selleks kasutatakse käske "break" ja "continue". Break lõpetab tsükli täitmise ning programm jätkab tsüklile järgnevate käskude täitmisega, continue katkestab aga käesoleva täitmiskorra täitmise ja alustab (kui tingimused on täidetud) uut täitmiskorda. Katkestada saab nii while- kui for-tsüklit.
Alltoodud näites väljastatakse i väärtusi seni, kuni i on saanud võrdseks 3-ga, seejärel väljutakse tsüklist.
for i in range(5): if i == 3: break print("i väärtus on " + str(i))
Järgmises näites väljastatakse i väärtusi nullist kuni neljani, kuid väljastamisel jäetakse vahele i väärtusega 2.
for i in range(5): if i == 2: continue print("i väärtus on " + str(i))
Topelttsükkel, mitmekordne tsükkel
Tsükleid saab paigutada ka üksteise sisse, mis suurendab veelgi nende kasutamise kasutegurit. Näiteks korrutustabeli puhul saame muuta nii esimest kui teist tegurit: anname ühe väärtuse esimesele tegurile ja väärtustame järjest erinevate väärtustega teist tegurit, siis anname esimesele tegurile uue väärtuse ja taas väärtustame järjest erinevate väärtustega teist tegurit. Kuna on tegemist mitme tsükliga, peame kasutama ka mitut tsüklimuutujat. Kuna üks tsükkel on teise sees, tuleb taane lisada ka teisele korduslausele ning selle sees olevad käsud peavad olema eristatud kahekordse taandega.
for i in range(10): # Esimese teguri väärtustamine # Teisele tegurile kõikvõimalike väärtuste andmine # iga esimese teguri väärtustamise korral for j in range(10): # Korrutustehte väljatrükk koos tühikuga, rida ei vahetata print(i*j, " ", end = "") print() # Reavahetus enne iga esimese teguri väärtuse muutmist
Üldiselt
While-tsükli üldine kuju:
while <avaldis>: <käsk_1> <käsk_2>
For-tsükli üldine kuju:
for <muutuja> in <järjend>: <käsk_1> <käsk_2>
For-tsükkel koos funktsiooniga range(), tsüklimuutuja saab väärtusi kuni arvuni "stop" (viimane välja arvatud):
for <muutuja> in range(<stop>): <käsk>
For-tsükkel, mille puhul lõpetatakse täitmine siis, kui toodud tingimus on tõene:
for <muutuja> in <jarjend>: if <tingimus>: break <käsud, mida täidetakse iga tsüklikorra ajal>
For-tsükkel, vahele jäetakse tsüklis olevate käskude täitmine sel tsüklirilingi ajal, mil toodud tingimus on tõene:
for <muutuja> in <jarjend>: if <tingimus>: continue <käsud, mida täidetakse iga tsüklikorra ajal>
Näidisülesanne
Ülesanne. Loo programm, mis küsib kasutajalt sõnu ja ütleb, kas sisestatud sõna algab k-tähega või mitte. Kui kasutaja sõnu enam ei sisesta, vaid vajutab lihtsalt sisestusklahvile, lõpetatakse programmi töö.
Lahendus. Küsime kõigepealt kasutajalt sisendit ja kontrollime, kas sõna esimene täht e. sümbol indeksiga 0 (vt. peatükki "Sõned") on "k" või mitte:
sona = input("Sisesta sõna: ") if sona[0] == "k": print("Sõna", sona, "algab k-tähega.") else: print("Sõna", sona, "ei alga k-tähega.")
Praegu küsitakse sõna vaid üks kord. Korduvaks küsimiseks peame kasutama tsüklit. Kuna me ei tea, mitut sõna kasutaja soovib sisestada, valime while-tsükli. While-tsükkel nõuab meilt tingimuse määramist, millal üldse tsüklit läbitakse. Lisame while-tsüklil ümber eelmise koodi ja laseme sel praegu korduda lõpmatuseni (testimisel katkestame klahvikombinatsiooniga Ctrl+C):
while True: sona = input("Sisesta sõna: ") if sona[0] == "k": print("Sõna", sona, "algab k-tähega.") else: print("Sõna", sona, "ei alga k-tähega.")
Ülesande tingimuste järgi peaks kasutaja saama programmi töö lõpetada, vajutades lihtsalt sisestusklahvi. Praegusel juhul antakse meile tühja sisendi puhul viga "index out of range" e. indeks on piiridest väljas: meie tingimus kontrollib esimest sümbolit (sona[0]), aga kui sõna puudub, sisaldab see null sümbolit. Meie ülesande puhul sisenetakse tsüklisse siis, kui midagi on sisestatud, seega võime kontrollida, kas sisestatud sõna pikkus on suurem kui 0 või kas sisestatud sõna ei ole "" (jutumärgid algavad ja lõpevad, nende vahel pole midagi). Valime näiteks teise variandi: kontrollime, kas sõna ei ole "". Kui see on tõene (sõna ei ole võrdne ""), kontrollime esimest tähte, vastasel juhul katkestame ("break") programmi töö. Nii on meil vaja tingimus kirjutada tingimuse sisse:
while True: sona = input("Sisesta sõna: ") if sona != "": if sona[0] == "k": print("Sõna", sona, "algab k-tähega.") else: print("Sõna", sona, "ei alga k-tähega.") else: break
Creative Commons litsentsiga Autorile viitamine + Mitteäriline eesmärk 3.0 Eesti (CC BY-NC 3.0 EE) - https://creativecommons.org/licenses/by-nc/3.0/ee/