4. nädala õpijuhis
Eesmärk
editNädala eesmärgiks on:
- Tutvuda üldisemalt algorimis kasutatava tsükli ehk korduse konstruktsiooniga.
- Mõista võimalusi, mida tsükli kasutamine algoritmis meile ülesannete lahendamiseks juurde annab.
- Mõista tsükli "ehitamise" põhimõtteid ja peamisi vigu, mis tekkida võivad.
- Tutvuda lähemalt eelkontrolliga tsükli tööpõhimõtetega, tema kujutamisega tegevusskeemil (nn
while
-tsükliga) - Saada kogemus lihtsamate ülesannete lahendamisel, mis eeldavad eelkontrolliga tsükli kasutamist.
- Tutvuda lihtsama testimise teooriaga, mida rakendada oma programmide õigsuse kontrollimisel.
- Saada kogemus testide koostamisel.
Lugemiseks ja proovimiseks
edit- Loe materjali tsüklitest Tsükkel programmis: while-lause: peatükid kuni loendamise ja summeerimiseni (kaasaarvatud). Kopeeri materjalist Pythoni keskkonda näited 1 ja 2 ning vaata, kuidas nad töötavad. Muuda korduste arvu. Muuda näidet 1 nii, et programmi töö ajal oleks võimalik sisestada korduste arv.
- Uuri järgmisi while-tsükli näiteid. Kopeeri keskkonda, käivita.
- Loe läbi materjal testimisest. Pööra tähelepanu näitele.
Ülesanded
editÜlesandeid alustame lihtsamatest - näiteks sellisest, kus kasutaja saab otsustadakogu programmi kordamise üle.
Ülesanne 1. Arvude ruudud
editKasutaja sisestab arvu ning programm trükib ekraanile sisestatud arvu ruudu. See on ülilihtne ülesanne, mille kirjutate juba 5 minutiga valmis:
arv = int(input("Sisesta arv: ")) print("Arvu %d ruut on %d." % (arv, arv**2))
Lisame sellele tsükli, mille käivitumist ja töötamist juhib kasutaja oma soovidega:
vastus = "j" # Sunnime tsükli esimesel korral vägisi tööle while vastus == "j": # Kuni kasutaja tahab jätkata ... arv = int(input("Sisesta arv: ")) print("Arvu %d ruut on %d." % (arv, arv**2)) vastus = input("Kas veel [j/e]? ") # Kasutaja soov: iga "j"-st erinev vastus lõpetab tsükli töö. print("Kohtumiseni!")
Sarnast "skeemi" kasutaja soovil kordamise kohta saame kasutada ka edaspidi.
Ülesanne 2 Kahe arvu jagamine
editEelmistest nädalatest peaks tuttav olema nn "nulliga jagamise" programm:
Sisestatakse 2 arvu. Leida nende arvude jagatis selliselt, et 1. arv jagatakse 2. arvuga. Kui arve jagada ei saa, siis anda sobiv veateade (millal ei saa jagada?). Kasuta selleks tavalist if-lauset.
Täiustame "nulliga jagamise" programmi. Täiendused salvestada erinevatesse failidesse:
- Kui jagada ei saa
(jagaja == 0)
, küsida jagajat uuesti - kuni kasutaja mõistliku väärtuse sisestab. - Panna korduma kogu programm vastavalt kasutaja soovile. Programm küsib kasutajalt jätkamise kohta ja kui kasutaja tahab jätkata (st uued arvud sisestada), siis kordub kõik algusest peale.
Selle ülesande lahendamise algoritm sisaldab kahte tsüklit. Soovitav oleks need programmi lisada sammhaaval. St tee oma programm kõigepealt valmis nii, et ta jagajat kontrollib ning vajadusel uuesti sisestada laseb. Edasi täienda programmi eelmisest näitest lähtudes kasutaja soovi küsimise ja kordamisega.
Mõtle kõigepealt ise lahendusalgoritmile. Kui esimesed mõtted olemas, siis see tegevusskeem oleks üks sobiv võimalus ülesande lahendamiseks.
Ülesanne 3 Kontrolltöö hinded
editTeada on punktid, mida õpilased kontrolltöö eest said ja töö maksimaalsed punktid. Loendada, mitu õpilast said töö eest hindeks 4 (hinde neli piirid on 81 .. 90%). Kõik punktid (ka maksimaalsed kontrolltöö punktid) sisestab kasutaja ja peale iga töö sisestamist küsib programm, kas on veel töid jäänud (ehk kas kasutaja soovib jätkata).
Nagu ka eelmises ülesandes alusta mõtlemisest ja tegevusskeemi joonistamisest. Minu poolt pakutav algoritm on järgmine.
Lahendust saab laiendada ka selliselt, et loetakse kokku kõik erinevad hinded ja teatatakse iga töö kohta, mis hinne saadi. Väga soovitav on ka see ülesande variant ära lahendada.
Ülesanne 4. Pauli spordipäev
editKoolis oli spordipäev ja lapsed viskasid palli. Iga õpilase kohta on teada tema parima viske pikkus. Eraldi aga teame Pauli tulemust. Leida, mitmenda koha Paul saavutas.
Ülesande täienduseks sobib lisada võimalik kohtade jagamise tuvastamine. Seega võimalikud vastusevariandid oleksid:
Paul sai palliviskes 4 koha. Paul jagas 2 kuni 4 kohta.
Siin kohal tukeks siis taas mõelda, et mil viisil ülesannet lahendama hakata sobiks. Ja kui kellelgi peaks tekkima mõte, et kõigepealt paneme lapsed paremuse järgi järjekorda. Ja edasi vaatame, kuhu meie lemmiklaps Paul jääb, siis on ta valel teel. Liiga palju tööd ei ole kunagi kasulik teha, järjestada (ehk sorteerida) me veel ei oska ja kõigi laste tulemuste üheaegse meelespidamisega ka hakkama ei saa.
Lahenduse algoritm, mis kasutab kõige lihtsamat loendamist, on siin. Pane tähele, et sellel skeemil ei ole enam täielikult välja kirjutatud kõik laused, mis kordumisega seonduvat infot kasutajalt küsivad.
Edasi täienda algoritmi ja programmi nii, et see suudaks tuvastada kohtade jagamise (selleks loe lisaks kokku, mitu last olid Pauliga samal pulgal ja kasuta saadud tulemust vastuse moodustamisel).
Ülesanne 5. Arvu arvamise mäng
editNo teate küll! Üks mängija mõtleb arvu teatud piirides ja teine mängija katsub seda ära arvata. Antud ülesandes arvuti mõtleb arvu ja mängija hakkab arvama. Arvuti vastab igale arvamisele ja täpsustab, kas pakutud arv oli liiga suur või liiga väike.
Kuidas arvuti arvu välja mõtleb? Selleks otstarbeks on juhuslike arvude generaator. Antud juhul sobiks funktsioon
randint(a, b)
Funktsioon tagastab juhusliku väärtuse x vahemikus a <= x <= b
.
Kasutamise näide:
x=randint(1,10)
Sel juhul saab x täisarvulise väärtuse vahemikust [1..10].
Et arvude genereerimine kulgeb tegelikult alati sama algoritmi järgi, tuleb juhuslike arvude generaator enne esmast kasutamist algväärtustada. Selle jaoks on alati olemas mingi funktsioon. Pythonis on selleks:
seed()
Sel teel välditakse programmi erinevatel käivitamistel samasuguste arvujadade tekkimist.
Tegelikult on see juhuslike arvude funktsioonimaailm tükk maad kirevam ja selle kohta tasuks lugeda Pythoni dokumentatsiooni lehel: http://docs.python.org/py3k/library/random.html
Näiteks saab sealt teada, et tegelikult kutsutakse seed() automaatselt välja, kui random moodul imporditakse ja seega pole seda eraldi vaja teha. Aga lisaks meenub veel järgmine asi, et kuna kogu see "juhuslikkus" on eraldi moodulis, vajab järjekordne moodul kasutusele võtmist:
import random
Ühtlasi võtame teadmiseks, et juhuslike arvude jada ei saa juhuslikum kui seed()
-i iga "arvu tegemise" ette panna. Pigem vastupidi.
Nüüd mängust endast: millal mäng lõpetada?
- kui arv arvatakse ära
- kui liiga palju arvatakse (näiteks üle 5 korra), siis programm teatab, et nii rumal ikka olla ei saa, et niiiii kaua seda ühte õnnetut arvu arvata.
Muide, mida arvad - kui arvud on 100 piires, siis milline on suurim korduste arv, millega peaks õige arvu kindlasti kätte saama? Aga kui arvud on 1000 piires?
Koosta kõigepalt lihtsam programm, mis töötab seni, kuni arv arvatud saab ja alles seejärel proovi raskema variandiga - korduste arvu piiramisega.
Tegevusskeemi mängu kohta leiad siit.
Kui see tehtud, tuleb terve mäng veel korduma panna - Kas soovid veel mängida? jne ...