Jätkub arvutiprogrammide koostamise põhimõtteid ja –võtteid tutvustav artiklisari, mis algas jaanuaris. Seekord vaatleme alamprogramme, mis võimaldavad kasutada üht programmilõiku mitmes erinevas kohas.
Kodutöö lahendus
Esimese koduse ülesande lahenduse leidmiseks tuleb vaid märgata, et “hinnete lehe” üheveerulises esituses on nimed paaris- ja hinded paaritute numbritega ridadel. Seega võime andmed realt number 2·i tõsta reale i esimesse ja realt number 2·i+1 reale i teise veergu. Kui jõuame i kasvatamisega väärtuseni, kus rida 2·i on tühi, ongi kogu nimekiri töödeldud:
Sheet = ThisComponent.CurrentController.ActiveSheet I = 0 WHILE Sheet.getCellByPosition(0, 2 * I).Formula > ""n = Sheet.getCellByPosition(0, 2 * I).Formula
h = Sheet.getCellByPosition(0, 2 * I + 1).Formula
Sheet.getCellByPosition(0, 2 * I).Formula = ""
Sheet.getCellByPosition(0, 2 * I + 1).Formula = ""
Sheet.getCellByPosition(0, I).Formula = n
Sheet.getCellByPosition(1, I).Formula = h
I = I + 1 WEND
Teine ülesanne on keerulisem ainult selle võrra, et andmete ümberpaigutamist tuleb alustada nimekirja lõpust — muidu kirjutaksime real i olevate andmete ridadele 2·i ja 2·i+1 paigutamisega tagapool olevad veel kasutamata andmed üle. Nimekirja “alt üles” suunas töötlemiseks peame aga kõigepealt eraldi leidma selle lõpu:
Sheet = ThisComponent.CurrentController.ActiveSheet I = 0 ' leiame nimekirja lõpu WHILE Sheet.getCellByPosition(0, I).Formula > ""I = I + 1 WEND ' ja seejärel töötleme "alt üles" WHILE I > 0
I = I – 1
n = Sheet.getCellByPosition(0, I).Formula
h = Sheet.getCellByPosition(1, I).Formula
Sheet.getCellByPosition(0, I).Formula = ""
Sheet.getCellByPosition(1, I).Formula = ""
Sheet.getCellByPosition(0, 2 * I).Formula = n
Sheet.getCellByPosition(0, 2 * I + 1).Formula = h WEND
Õiged lahendused saatsid Andres Vahter, Andres Võsa, Toivo Hein, Toomas Vahter, Kristel Kivikangur, Anu Adler, Allan Voog, Kert Sasi, Aira Lõhmus, Roger Mikomägi ja Harri Poom. Auhinna saab loosi tahtel Kristel Kivikangur, kellel palume toimetusega ühendust võtta.
Alamprogrammid
Suuremate programmide kirjutamisel tuleb tihti ette, et üht programmilõiku on vaja kasutada mitmes erinevas kohas. Programmi kirjutamisel hetkel on muidugi kõige lihtsam lahendus sellest lõigust tekstitoimeti vahenditega mitu koopiat teha, aga pikas perspektiivis ei ole see tavaliselt kuigi hea mõte.
Nimelt juhtub programmi pikemal kasutamisel sageli, et selles ilmneb mingi viga või puudujääk, mille kõrvaldamiseks tuleb programmi muuta. Kui muutmist vajavast lõigust on tehtud mitu koopiat, tuleb muidugi neid kõiki parandada. See on esiteks tüütu ja teiseks toob kaasa riski, et mõni koopia jääb parandamata.
Hoopis parem mõte on vormistada korduvalt kasutatav lõik alamprogrammiks, mis esimeses lähenduses seisneb selles, et me anname sellele programmilõigule nime. Alamprogrammi nime kohtamisel täidab arvuti selle kehas olevad käsud ja jätkab seejärel enne pooleli jäänud tegevust. Oluline on tähele panna, et alamprogrammi poole pöördumisel jätab arvuti meelde, milline põhiprogrammi rida alamprogrammi välja kutsus ja jätkab alamprogrammi täitmise järel põhiprogrammi täitmist pooleli jäänud kohast. (Joonis 1: noolega 1 näidatud väljakutse järel naaseb täitmine põhiprogrammi noolega 2 näidatud reale, noolega 3 näidatud väljakutse järel aga noolega 4 näidatud reale).
Joonis 1: Alamprogrammi korduv kasutamine
Muidugi võivad alamprogrammid ka omakorda teiste alamprogrammide poole pöörduda ja iga kord jätkatakse alaprogrammi täitmise lõppedes selle väljakutsele järgnevast reast. (Joonis 2: kõik liikumised toimuvad nooltel olevate numbrite järjekorras.)
Joonis 2: Alamprogrammide väljakutsete kaskaad
Alamprogrammi parameetrid
Alamprogrammidest oleks üsna vähe kasu, kui iga alamprogramm kõigil käivitamistel alati täpselt sama käsujada täidaks. Praktikas lubavad alamprogrammid enamasti põhiprogrammil oma “tellimust” parameetrite abil täpsustada. Parameetrite alamprogrammile edastamise aparaat koosneb kahest poolest: formaalsetest ja tegelikest parameetritest.
Nende mõistmiseks tuletame natuke meelde matemaatikatunnis õpitut: näiteks funktsiooni f kirjelduses f(x) = 2·x+1 on x formaalne parameeter, mille esinemine avaldises 2·x+1 näitab, kuidas f oma parameetri väärtust kasutab; avaldises f(3)+f(4) esinevad arvud 3 ja 4 on aga tegelikud parameetrid, mis asendatakse avaldisse x asemele, seega saame f(3)+f(4) = (2·3+1)+(2·4+1).
Basicu ja koduste ülesannete juurde tagasi pöördudes märkame, et mõlemas eeltoodud programmis on korduvalt kasutusel operatsioon, mida samasuguseid teisendusi “käsitsi” tegev inimene saavutaks käskude ‘Cut’ ja ‘Paste’ abil: võtame tabeli mingist lahtrist andmed ja nihutame nad teise lahtrisse, tehes lähtelahtri tühjaks. Kui kirjeldame selle alamprogrammina
' Nihutab andmed töölehe s ' lahtrist (x1,y1) lahtrisse (x2,y2) Sub CutPaste(s, x1, y1, x2, y2)t = s.getCellByPosition(x1, y1).Formula
s.getCellByPosition(x1, y1).Formula = ""
s.getCellByPosition(x2, y2).Formula = t End Sub
võime esimese koduse ülesande lahenduse lühendada kujule
Sheet = ThisComponent.CurrentController.ActiveSheet I = 0 WHILE Sheet.getCellByPosition(0, 2 * I).Formula > ""CutPaste(Sheet, 0, 2 * I, 0, I)
CutPaste(Sheet, 0, 2 * I + 1, 1, I)
I = I + 1 WEND
ja teise oma kujule
Sheet = ThisComponent.CurrentController.ActiveSheet I = 0 WHILE Sheet.getCellByPosition(0, I).Formula > ""I = I + 1 WEND WHILE I > 0
I = I – 1
CutPaste(Sheet, 0, I, 0, 2 * I)
CutPaste(Sheet, 1, I, 0, 2 * I + 1) WEND
Protseduurid ja funktsioonid
Alamprogrammid jagunevad kahte liiki: protseduurid ja funktsioonid. Protseduurid teevad midagi, nagu näiteks eelmises lõigus vaadeldud CutPaste. Funktsioonid aga arvutavad välja ja tagastavad mingi väärtuse, sarnanedes rohkem eelmises lõigus vaadeldud matemaatilise funktsiooniga f.
Tabelarvutuse kontekstis pakuvad funktsioonid huvi muuhulgas ka seetõttu, et neid on võimalik kasutada oma töölehe võimaluste avardamiseks. Kui näiteks lisada OpenOffice.org Calc faili Basicu moodul, milles on funktsiooni kirjeldus
' Tagastab mitteneg. täisarvu N numbrite summa Function Ristsumma(N)S = 0
WHILE N > 0
S = S + N MOD 10
N = N \ 10
WEND
Ristsumma = S End Function
võime Ristsumma-t edaspidi kasutada oma töölehe valemites samaväärselt Calc-i sisseehitatud funktsioonidega, kirjutades näiteks
=A1+Ristsumma(A2+A3)
Kodune töö
Uus kodune töö on aga selline:
- täiendada eeltoodud funktsiooni Ristsumma nii, et ta tagastaks “tavalise” ristsumma asemel ühekohalise (arvu N ühekohalise ristsumma saame, kui arvutame arvu N ristsumma S1, seejärel S1 ristsumma S2 jne, kuni jõuame ühekohalise arvuni, näiteks 256→2+5+6=13→1+3=4);
- kirjutada funktsioonid Tahti(S), Tais(S) ja Kaas(S), mis loendavad vastavalt eesti tähestiku tähtede, täishäälikute ja kaashäälikute arvud parameetrina antud tekstis S; muidugi peaks kõik kolm funktsioon tundma nii suuri kui ka väikesi tähti.
AUHINNAD paneb välja MAX 123 — DELLi müügi- ja teeninduskeskus. Seekordseks kuuauhinnaks on kvaliteetsed DELLi subwoofer'iga arvutikõlarid. AASTAAUHINNAKS on DELLi sülearvuti.
Rubriigi autor AHTO TRUU (1972) on WM-data AS tarkvaraarendaja. Viimased kümme aastat tegelenud lisaks põhitööle informaatikavõistluste korraldamisega nii üldhariduskoolide õpilastele kui ka Tartu Ülikooli tudengitele. Eesti Informaatikaolümpiaadi žürii esimees, mitme rahvusvahelise võistluse žürii liige.
Siit saate endale laadida programminäited OpenDocument Spreadsheet vormingus. Nende avamiseks kasutage OpenOffice.org versiooni 2.0 või uuemat.
Faili avamisel hoiatab OpenOffice.org, et see sisaldab makrosid, mis võivad teie arvutit kahjustada. Kui te tahate failis olevaid programme ainult vaadata, võite makrode käivitamise keelata (nupp ‘Disable Macros’). Kui aga tahate programme ka käivitada proovida, peate ise otsustama, kas usaldate makrode käivitamist lubada (nupp ‘Enable Macros’) või mitte.
Programmitekstide vaatamiseks valige pärast faili avamist peamenüüst ‘Tools’ → ‘Macros’ → ‘Organize Macros’ → ‘OpenOffice.org Basic’. Avanevas dialoogiaknas valige kastis ‘Macro from’ vastavatud fail, selle all ‘Standard’, selle all omakorda soovitava programmi nimi. Programmi teksti vaatamiseks vajutage seejärel nuppu ‘Edit’, käivitamiseks aga nuppu ‘Run’.
n = Sheet.getCellByPosition(0, 2 * I).Formula






