< eelmine | 5. nädala sisukord | järgmine > |
5.3 Argumendid, muutujad
MITU FUNKTSIOONI KOOS
Vaatame näiteid, kus funktsioone kasutatakse nii, et ühe väärtus on teise argumendiks.
ümardatud_sisestatud_arv = round(float(input("Sisestage arv "))) print("See arv ümardatult on " + str(ümardatud_sisestatud_arv))
Olge head ja testige seda suhteliselt kokkusurutud programmi.
Selle esimene rida teeb tegelikult palju asju. Tegevus algab “seestpoolt”.
- Funktsiooniga input küsitakse kasutaja käest arv. Funktsiooni input väärtus on sõne tüüpi.
- Funktsioon float võtab argumendiks sõne ja tema enda väärtuseks saab vastav ujukomaarv (murdarv). (Teiste sõnadega: Funktsioon tagastab vastava ujukomaarvu. Või veel kõnekeelsemalt: Funktsioon muudab sõne vastavaks ujukomaarvuks.)
- Funktsioon round võtab argumendiks ujukomaarvu ja ümardab selle täisarvuks.
Lõpuks määratakse see täisarv muutuja ümardatud_sisestatud_arv väärtuseks.
Niimoodi teise funktsiooni argumendiks saab olla ainult väärtust tagastav funktsioon. Sellisena saab muidugi kasutada ka isekirjeldatud funktsioone, nt
def summa(x,y): return x + y a = summa(summa(1, 3)*2, 4)
Kokkuvõtva ülevaate eelmisest näiteprogrammist annab järgmine video
Ülesanne
ARGUMENTIDEST VEEL
Eelnevates näidetes olid meil argumentideks tavaliselt arvud või sõned, vastavalt konkreetsele funktsioonile muidugi. Olenevalt funktsioonist võivad argumendid olla ka hoopis muud tüüpi. Nagu juba eespool nägime, võib argumentide arv olla funktsioonidel ka erinev. Samuti ei pea argumendid olema omavahel sama tüüpi.
Koostame funktsiooni, mille argumendiks on fail ja tagastatakse sõnede järjend, mille elemendid on read sellest failist.
def failist_sõnejärjendisse(fail): järjend = [] for rida in fail: järjend += [rida.strip()] # järjend.append(rida.strip()) # strip() võtab lõpust ära reavahetuse fail.close() return järjend
Eks me saime ju nö otse failistki for-tsükli abil ridahaaval toimetada. Nüüd aga saame järjendi elemendile (mis vastab faili reale) ka indeksi abil juurde. Samuti oleme reavahetuse ka rea lõpust eemaldanud.
def failist_sõnejärjendisse(fail): järjend = [] for rida in fail: järjend += [rida.strip()] # järjend.append(rida.strip()) # strip() võtab lõpust ära reavahetused fail.close() return järjend failinimi = input("Sisestage failinimi ") fail = open(failinimi, encoding="UTF-8") sõned = failist_sõnejärjendisse(fail) print(sõned) print(sõned[3])
See funktsioon tagastas järjendi. See on üheks võimalikuks viisiks mitme väärtuse tagastamiseks. Nimelt saab tegelikult alati tagastada vaid ühe väärtuse. Kui on mitut vaja tagastada, tuleb kasutada sobivat andmestruktuuri, mis siis ühena teisi hõlmab.
Mõnikord on konkreetse argumendi väärtus peaaegu alati sama ja oleks tüütu seda alati uuesti ette anda. Sellisel juhul saame kasutada vaikeväärtust. Kui funktsiooni väljakutsel pole seda argumenti näidatud, siis saab argumendi väärtuseks vaikeväärtus.
def kas_kiiruse_ületamine(kiirus, piirkiirus = 90): return kiirus > piirkiirus print(kas_kiiruse_ületamine(100)) print(kas_kiiruse_ületamine(90, 70))
Vaikeväärtus on ka funktsiooni print
argumendil end
. Nimelt vaikimisi vahetab print
rida, argument end = "\n"
. Võime aga ka ise selle argumendi väärtuse ette anda.
print("Väljastatav tekst ", end = "lõppu juurde")
Sõnedega oleme kasutanud ka funktsioone, mis on sõnega ühendatud punktiga.
print("tartu".capitalize()) print("Tartu".endswith("tu")) print("Tartu".upper()) linn = "Tartu" print(linn.lower())
Tundub nagu oleks sellisel juhul argument mitte sulgudes vaid hoopis funktsiooni ees. Põhimõtteliselt see nii ongi. Selliseid funktsioone nimetatakse meetoditeks ja need on väga tavalised objektorienteeritud programmeerimises. Meie siin kursusel kasutame meetodeid küll (just eriti sõnede puhul), aga põhjalikum käsitlus jääb selle kursuse raamest välja.
LOKAALSED JA GLOBAALSED MUUTUJAD
Olgu meil programm, milles on defineeritud funktsioon ja siis seda rakendatud.
def summa_funktsioon(a, b, c): summa = a + b + c return summa print(summa_funktsioon(1, 2, 3))
Pannes programmi tööle saame ekraanile arvu 6, mis muidugi ongi 1 + 2 + 3 korral oodatud.
Lisame programmile rea print(summa)
.
def summa_funktsioon(a, b, c): summa = a + b + c return summa print(summa_funktsioon(1, 2, 3)) print(summa)
Saame veateate, mis väidab, et NameError: name 'summa' is not defined
. Nimi summa
ei ole defineeritud (kirjeldatud). Kuna funktsiooni sees toimuv on funktsiooni "siseasi", siis tõepoolest muutujat summa
pole väljaspool funktsiooni olemas. Sellist funktsiooni kehas (kirjelduses) defineeritud muutujat nimetatakse lokaalseks muutujaks. Kui tõstame printimise funktsiooni kirjelduse sisse, siis on kõik korras.
def summa_funktsioon(a, b, c): summa = a + b + c print(summa) return summa print(summa_funktsioon(1, 2, 3))
Esimene 6 tuleb ekraanile print(summa)
toimel ja teine 6 print(summa_funktsioon(1, 2, 3))
toimel.
Samuti on lokaalsed ka funktsiooni argumendid. Muutuja b
on funktsiooni sees täiesti olemas.
def summa_funktsioon(a, b, c): summa = a + b + c print(b) return summa print(summa_funktsioon(1, 2, 3))
Funktsioonist väljas aga mitte.
def summa_funktsioon(a, b, c): summa = a + b + c return summa print(summa_funktsioon(1, 2, 3)) print(b)
Lokaalsed muutujad luuakse funktsiooni igal käivitamisel uuesti ja nad hävivad, kui funktsioon töö lõpetab. Lokaalsed muutujad on funktsiooni siseasi, väljast neid näha pole. Neile saab panna sama nime, mis juba programmi põhiosas kasutuses (või mõnes teises funktsioonis kasutuses olnud).
Näiteks on järgmises programmis nii funktsioonis kui põhiprogrammis muutuja summa
.
def summa_funktsioon(a, b, c): summa = a + b + c return summa summa = 10 print(summa_funktsioon(1, 2, 3)) print(summa)
Näeme, et viimases reas on muutuja summa
väärtus just see, mis ta põhiprogrammis sai – funktsioonis toimuv tema väärtust ei muuda.
Põhiprogrammis defineeritud muutujad on globaalsed muutujad. Nende väärtusi saab kasutada nii põhiprogrammis kui ka funktsioonide sees. Kui aga funktsioonis on sama nimega lokaalne muutuja, siis globaalset muutujat seal kasutada ei saa. Eelmises näites just nii oligi.
Järgmises näites aga saab globaalset muutujat funktsioonis kasutada, sest sellenimelist lokaalset muutujat funktsioonis pole.
def summa_funktsioon(a, b, c): summa = a + b + c + gm return summa gm = 17 # globaalne muutuja print(summa_funktsioon(1, 2, 3))
Kui me ei tea, mitu arvu on vaja kokku liita, võime kasutada summeerimiseks globaalset muutujat.
def summa_akumulaator(a): global summa summa += a return summa summa = 0 summa_akumulaator(1) summa_akumulaator(2) summa_akumulaator(3) print(summa)
Võtmesõna global
on funktsioonis summa_akumulaator
vajalik, sest muutujad, millele funktsiooni sees omistatakse väärtus, on vaikimisi lokaalsed.
Teatud juhtudel on globaalsete muutujate kasutamine funktsioonis ebasoovitav ja nii võib näiteks ka kontrollülesannete automaatkontrolli tagasiside sellele tähelepanu juhtida.
KOKKUVÕTE
Funktsioonid e. alamprogrammid võimaldavad (sageli küllalt keerulise) programmilõigu panna kirja ühekordselt, aga kasutada seda mitmes erinevas kohas.
Funktsiooni definitsiooni (kirjelduse) e def-lause kehas olevad laused jäetakse esialgu lihtsalt meelde. Neid saab hiljem käivitada, kirjutades funktsiooni nime koos sulgudega. Sellist tegevust nimetatakse funktsiooni väljakutseks e rakendamiseks.
Funktsiooni defineerimisel saab jätta mõned detailid lahtiseks. Täpne töö sõltub etteantud argumentide väärtustest.
Funktsioone võib jaotada kahte gruppi – ühed teevad midagi ära, kuid ei tagasta midagi, ja teised arvutavad midagi ning tagastavad tulemuse.
Selleks, et funktsiooni saaks kasutada avaldises, peab ta arvutatud väärtuse tagastama. Väärtuse tagastamiseks kasutatakse võtmesõna return
.
Programmi põhiosas defineeritud muutujaid nimetatakse globaalseteks muutujateks, funktsiooni sees defineeritud muutujaid lokaalseteks muutujateks.
< eelmine | 5. nädala sisukord | järgmine > |