Materjalid koostas ja kursuse viib läbi
Tartu Ülikooli arvutiteaduse instituudi programmeerimise õpetamise töörühm
< eelmine | 5. OSA sisukord | järgmine > |
5.1 Tsükkel
KORDUV TEGEVUS
Kui püüda arvuti võimalikke plusse välja tuua, siis üheks oluliseks neist on kahtlemata võime mingeid tegevusi kiiresti ja korduvalt sooritada. Nii saab teha arvutusi, midagi andmetest otsida, erinevaid variante läbi vaadata jpm. Arvutid on läinud järjest kiiremaks ja nii saavad paljud asjad tehtud praktiliselt silmapilkselt. Samas on ülesandeid, mille lahendamiseks kulub ikkagi rohkem aega kui tahaks, isegi kui mitu arvutit korraga ülesannet lahendama panna. Näiteks ilmaennustus on selline keeruline ülesanne.
Kui tahta mingeid asju korduvalt teha, siis võivad ju programmid väga pikaks minna? Näiteks kui tahame, et programm väljastaks ekraanile viis korda üksteise alla Tere!
, siis kõlbaks selline programm.
print("Tere!") print("Tere!") print("Tere!") print("Tere!") print("Tere!")
Saja korra jaoks tuleks siis programm vastavalt pikem. Tegelikult on programmeerimiskeeltes olemas head võimalused selliste korduste lühemaks esituseks. Kõigepealt püütakse aru saada, mis on see korduv tegevus, mis päris samasugusena (või kindlate reeglite järgi muudetuna) tuleb ikka ja jälle teha. Selles näites on selleks rida print("Tere!")
. Teise asjana tuleb läbi mõelda, mitu korda me tahame seda tegevust teha. See võib olla meil ette teada, aga võib sõltuda ka mingitest välistest asjaoludest, näiteks kasutaja poolt antud vastusest. Pole ju mõtet parooli uuesti küsida, kui juba õige on sisestatud.
Korduvaid tegevusi realiseeritakse tsüklite abil. Vastavaid vahendeid võib konkreetses programmeerimiskeeles olla mitmeid. Näiteks Pythonis on olemas while-tsükkel ja for-tsükkel. Meie alustame eelkontrolliga tsüklist, mille põhimõte on teatud mõttes sarnane valikulausega. Sellist tsüklit kutsutaksegi while-tsükliks, sest reeglina on programmeerimiskeeltes just võtmesõna while selles tähenduses kasutusel. Erinevus if-lausest on selles, et pärast seda, kui tsükli sisus olevad laused on täidetud, minnakse uuesti tingimust kontrollima. Kui tingimus ikka veel kehtib, siis täidetakse sisu edasi jne. Kui mingil hetkel tingimust kontrollides see enam ei kehti, siis lõpetatakse tsükli täitmine. Tsükli sisus olevad laused peavad olema taandatud sarnaselt if-lauses olevatele lausetele.
Eelkontrolliga tsükli plokkskeem näeb välja selline:
Tsükli jätkamistingimus on (nagu ka if-lause tingimus) tõeväärtustüüpi. Kui tingimus on täidetud (tingimusavaldise väärtus on tõene), siis minnakse tsükli sisu täitma, kui aga pole täidetud, siis minnakse tsüklist välja.
Tavaliselt on tingimus esitatud võrdlemisena, aga võib näiteks olla ka lihtsalt tõeväärtus True
. Või hoopis tõeväärtus False
. See viimane on küll üsna mõttetu: nii karm “piirivalvur”, et kunagi kedagi edasi ei lubata. Variandi while True
puhul on tegemist lõpmatu tsükliga, sest tingimusavaldis on alati väärtusega True
. Teoreetiliselt jääbki see tsükkel igavesti tööle. Praktiliselt siiski ilmselt pannakse arvuti millalgi kinni, toimub elektrikatkestus vms. Kui me nüüd Pythonis meelega või kogemata sellise programmi teeme, mis igavesti tööle jääb, siis ei ole meil katkestamiseks siiski vaja arvutit kinni panna. Nimelt saame Thonnys programmitöö katkestada Stop-märgiga nupu või klahvikombinatsiooni Ctrl + F2 abil. (Hoiame all Ctrl-klahvi ja vajutame samaaegselt alla F2-klahvi, mis on klaviatuuri ülemisel real.) (Keskkonnas IDLE katkestatakse programmitöö hoopis Ctrl + C abil.) Tegelikult saab lõpmatut tsüklit kasutada ka päris sihipäraselt sellises olukorras, kus tuleb näiteks midagi aktiivselt oodata. Sellisel juhul on tsüklist väljasaamine teisiti organiseeritud.
Ülesanne
Meie aga tahame ikkagi, et tsükli abil viis korda Tere! ekraanile tuleks. Seega peab olema midagi, mis tsükli sisus muutub nii, et just pärast viiendat korda “piirivalvur” enam tsükli sisu juurde ei luba. Kuidas me inimlikult sellises olukorras loendaksime? Üks võimalus oleks näiteks sõrmedel lugeda ja nii meeles hoida, kui palju kordi juba tehtud. Põhimõtteliselt teeme sarnaselt ka programmeerides. Võtame ühe muutuja, mille nimeks saagu i. Muide just i ongi sageli sellise loendaja nimeks. Olgu i väärtus esialgu 0: i = 0
. Igal tsükli sammul liidame väärtusele 1. Varem olid näited, kus muutujale saime erinevaid väärtusi anda mingite teiste muutujate või näiteks arvude ja tehete abil. Nüüd aga on vaja selle sama muutuja väärtust muuta. Saame seda teha sellise avaldisega
i = i + 1
Võimalik, et selline võimalus vajab natuke harjumist. Kui vaatame koolimatemaatikat, siis võib see paista üsna kummaline, aga võrdusmärgi tähendus on siin natuke teine. Vasak pool näitab, et muutuja i saab uue väärtuse. Paremal pool on avaldis, millega see uus väärtus arvutatakse. Selles arvutamises kasutatakse ka muutuja i senist väärtust. Enne programmi kokkupanekut mõtleme veel jätkamistingimusele. Selleks sobib i < 5
, sest kui i on esialgu 0 ja igal sammul liidetakse 1, siis just 5 sammuga jõuame niikaugele, et tingimus i < 5
ei ole enam täidetud. Panemegi nüüd programmi kokku. Olulisel kohal on taas koolon ja taandamine.
i = 0 while i < 5: print("Tere!") i = i + 1
Jätkamistingimus (i < 5
) on täidetud, kui esimest korda tsükli juurde jõuame, sest 0 < 5. Pärast esmakordset sisu täitmist on i väärtus 1 ja jätkamistingimus ikkagi täidetud, sest 1 < 5. Pärast 2 korda on i väärtus 2 ja ikka saame jätkata, kuna 2 < 5. Ja siis i on 3 ja ikka 3 < 5. Ja siis i on 4 ja ikka 4 < 5. Ja siis i on 5 ja kontrollime, kas i < 5? Kas 5 < 5? Ei ole, sest 5 ja 5 on võrdsed, seega võrratus 5 < 5 ei kehti.
Lisame programmile ühe rea, mis i väärtuse ekraanile tooks, siis saame seda paremini jälgida.
i = 0 while i < 5: print("Tere!") i = i + 1 print(i)
Pange programm tööle.
Kuna muutuja väärtuse muutmist eelmise väärtuse alusel tuleb päris sagedasti ette, siis on selleks ka lühemad variandid olemas. Näiteks a = a + 3
asemel võime kirjutada a += 3
. Samasugused variandid on ka lahutamise (-), korrutamise (*), jagamise (/), täisarvulise jagamise (//), jäägi leidmise (%) ja astendamise (**) jaoks.
Ülesanne
Ülesanne
Ülesanne
Ülesanne
Ülesanne
Eelmises osas tutvusime kilpkonnagraafikaga ja tegime näiteprogrammina ruudu.
Näiteprogramm. Ruut
from turtle import * # * lisamisel imporditakse kõik kilpkonna käsud forward(100) # Kilpkonn liigub edasi 100 pikslit left(90) # Kilpkonn pöörab 90° vasakule forward(100) # Kordame eelnevaid käske, sest ruudul on neli külge left(90) forward(100) left(90) forward(100) exitonclick() # Saame akna sulgeda hiireklõpsuga
On näha, et kilpkonn peab täitma korduvalt samu käske: minema 100 pikslit edasi ja pöörama seejärel 90° vasakule. Tegemist on tsüklilise tegevusega, seega saame kasutada tsüklit.
Kirjutame programmi ümber nii, et ruut joonistatakse while-tsüklit rakendades.
Näiteprogramm. Ruut II
from turtle import * i = 0 # Muutuja i väärtus on esialgu 0 while i < 4: # Kilpkonn joonistab tsükli abil ruudu. Tsükli keha läbitakse neli korda. forward(100) left(90) i = i + 1 # Muutuja i väärtust suurendatakse ühe võrra exitonclick()
Pange see programm tööle ja püüdke seda modifitseerida nii, et joonistataks hoopis võrdkülgne kolmnurk. Mis sellisel juhul on ruudust erinev? Külgi on kolm ja pöörama peab ... Aga proovige ise!
< eelmine | 5. OSA sisukord | järgmine > |