31 Argumendid, muutujad
Mitu funktsiooni koos
Vaatame programmi, 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))
Katseta seda suhteliselt kokkusurutud programmi. Selle esimesel real sooritatakse hulk tegevusi. Tegevused algavad “seestpoolt”.
- Funktsiooniga
input
küsitakse kasutaja käest arv. Funktsiooniinput
väärtus on sõnetüüpi. - Funktsioon
float
võtab argumendiks sõne ja tema enda väärtuseks saab vastav ujukomaarv. 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:
def summa(x,y): return x + y a = summa(summa(1, 3)*2, 4)
Video
Vaata ka eelmise ülesande kohta käivat kokkuvõtvat videot.
Enesekontroll (1 ülesanne)
Erinevad argumendid. Mitu tagastatavat väärtust
Eelnevates näidetes olid funktsioonide argumentideks tavaliselt arvud või sõned. Olenevalt funktsioonist võivad argumendid olla ka hoopis muud tüüpi. Nagu me eespool nägime, võib argumentide arv olla funktsioonidel erinev. Samuti ei pea ühe funktsiooni argumendid olema omavahel sama tüüpi.
Käsk return
tagastab ainult ühe väärtuse. Kui on vaja tagastada mitu väärtust, tuleb esmalt moodustada sobiv andmestruktuur, mis teisi väärtusi hõlmab.
Koostame funktsiooni, mille argumendiks on fail ja tagastatakse sõnede järjend, mille elemendid on read sellest failist:
Näiteprogramm. Failist lugemise funktsioon
def failistSõnejärjendisse(fail): järjend = [] for rida in fail: järjend += [rida.strip()] # alternatiivselt: järjend.append(rida.strip()) # strip() võtab lõpust ära reavahetuse fail.close() return järjend failinimi = input("Sisestage failinimi ") fail = open(failinimi, encoding="UTF-8") sõned = failistSõnejärjendisse(fail) print(sõned) print(sõned[3])
Meie loodud funktsioon tagastab järjendi. See on üks viis, kuidas mitut väärtust tagastada.
Vaikeväärtus
Mõnikord on konkreetse argumendi väärtus peaaegu alati sama ja oleks tüütu seda iga kord 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:
Näiteprogramm. Vaikeväärtusega funktsioon
def kasKiiruseÜletamine(kiirus, piirkiirus = 90): return kiirus > piirkiirus print(kasKiiruseÜletamine(100)) print(kasKiiruseÜletamine(90, 70))
Vaikeväärtus on ka funktsiooni print
argumendil end, millega määratakse väljastatava sõne lõppu lisatav(ad) sümbol(id). Vaikimisi on lõpus reavahetus, sest argument on vaikimisi
. Me võime sellele argumendile anda ka teistsuguse väärtuse:end = "\n"
print("Väljastatav tekst ", end = "lõppu juurde")
Meetodid
Sõnede peatükis kasutasime funktsioone, mis on sõnega ühendatud punktiga:
print("tartu".capitalize()) print("Tartu".endswith("tu")) print("Tartu".upper()) linn = "Tartu" print(linn.lower())
Tundub, nagu sellisel juhul pole 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. Siinsetes materjalides me küll kasutame meetodeid (eriti sõnede puhul), aga põhjalikumalt neid ei käsitle.
Lokaalsed ja globaalsed muutujad
Eelmises peatükis mainisime, et funktsiooni sees loodavad muutujad ei ole kättesaadavad funktsioonist väljaspool. Loome näiteks funktsiooni:
def summaFunktsioon(a, b, c): summa = a + b + c return summa print(summaFunktsioon(1, 2, 3))
Programmi tööle pannes saame ekraanile arvu 6, mis ongi 1 + 2 + 3 korral oodatud tulemus. Lisame programmile rea
:print(summa)
def summaFunktsioon(a, b, c): summa = a + b + c return summa print(summaFunktsioon(1, 2, 3)) print(summa)
Saame veateate tekstiga NameError: name 'summa' is not defined
ehk nimi summa ei ole defineeritud (kirjeldatud). Kuna funktsiooni sees toimuv on funktsiooni “siseasi”, siis tõepoolest pole muutujat summa väljaspool funktsiooni olemas. Sellist funktsiooni kehas (kirjelduses) defineeritud muutujat nimetatakse lokaalseks muutujaks. Kui sooritame printimise funktsiooni kirjelduse sees, toimib see tavapäraselt:
def summaFunktsioon(a, b, c): summa = a + b + c print(summa) return summa print(summaFunktsioon(1, 2, 3))
Nüüd ilmub 6 ekraanile kahel korral: esmalt funktsiooni sees oleva
tõttu ja teist korda print(summa)
print(summaFunktsioon(1, 2, 3))
tõttu.
Samuti on lokaalsed ka funktsiooni argumendid. Muutuja b on funktsiooni sees täiesti olemas:
def summaFunktsioon(a, b, c): summa = a + b + c print(b) return summa print(summaFunktsioon(1, 2, 3))
Funktsioonist väljas aga mitte:
def summaFunktsioon(a, b, c): summa = a + b + c return summa print(summaFunktsioon(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 on programmi põhiosas (või mõnes teises funktsioonis) kasutuses olnud.
Näiteks on järgmises programmis nii funktsioonis kui põhiprogrammis muutuja summa:
def summaFunktsioon(a, b, c): summa = a + b + c return summa summa = 10 print(summaFunktsioon(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 samanimelist globaalset muutujat seal kasutada ei saa. Eelmises näites just nii oligi.
Järgmises näites saab globaalset muutujat funktsioonis kasutada, sest sellenimelist lokaalset muutujat funktsioonis pole:
def summaFunktsioon(a, b, c): summa = a + b + c + gm return summa gm = 17 # globaalne muutuja print(summaFunktsioon(1, 2, 3))
Teatud juhtudel on globaalsete muutujate kasutamine funktsioonis ebasoovitav, kuid seda me siinsetes materjalides ei vaatle.
Kokkuvõte
Funktsioonid ehk alamprogrammid võimaldavad (sageli küllalt keerulise) programmilõigu panna kirja üks kord, aga kasutada seda mitmes erinevas kohas.
Funktsiooni definitsiooni (kirjelduse) ehk 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 ehk 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 ja teised arvutavad ja tagastavad midagi.
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.