Funktsioon
Meil võib tulla igapäevaelus ette olukordi, kus me peame mingit tegevust läbi viima mitu korda. Näiteks teeme matemaatika kodutööd, ja seal peab arvutama 100 ringi raadiust ja pindala. See muutub lõpuks päris üksluiseks ja igavaks. Kõik arvutused on ühesugused, ainult ringi andmed on erinevad. Sama asi toimub arvutiprogrammides. Viiakse sageli korduvalt läbi samasid ülesandeid. Väga ebapraktiline oleks kõik ülesanded uuesti läbi kirjutada erinevate andmetega. Selle jaoks, et ennast kordama ei peaks, on mõttekas ühes kohas programm valmis kirjutada ja seda mitmes kohas viidata. Sellist lahendust nimetataksegi funktsiooniks.
def tervitaja(): print("Tere, kuidas läheb?") tervitaja()
Proovi, mis ilmub ekraanile.
Näiteks palju kergem oleks 100 ringi raadiust ja pindala arvutada, kui me anname programmile lihtsalt ringi raadiuse, ja programm arvutab ise valemeid kasutades ringi raadiuse ja pindala.
Parameetrid
Nagu näha, on funktsioonid suureks abiks, kui sama käskude komplekti tahetakse programmis käivitada mitmes kohas. Samas, täpselt sama tegevuse kordamist on vaja siiski üpris harva. Meil ei ole mõtet arvutada 100 korda ringi pindala, mis on 100 cm. Sagedamini on vaja teha midagi sarnast, kuid teatud väikese nüansiga, mis võib erinevatel kordadel varieeruda. Sellise nüansi väljatoomiseks on võimalik funktsioonile lisada parameetreid.
Me oleme juba erinevaid funktsioone kasutanud. Näiteks oleme teksti väljastamiseks kasutanud funktsiooni print ja kasutaja sisendi saamiseks input. Funktsioonidel on tihti sulgudes andmed, millega tegeleda. Kui kirjutame print("Tere maailm!"), siis saab funktsioon endale parameetri "Tere maailm!", millega ta tegelema peab, antud olukorras ekraanile väljastama.
Parameetritega saab teha funktsiooni universaalsemaks – teatud detailid jäetakse funktsiooni väljakutsuja otsustada. Ilma parameetriteta funktsioon on justkui rätsep, kes teeb alati samasuguseid ülikondi, parameetreid võiks aga võrrelda tellija mõõtude ja muude soovidega, mida rätsep oma tegevuses arvesse võtab.
Mitu parameetrit
Parameetreid (ja vastavaid argumente) võib olla ka rohkem kui üks.
def mõõtja(nimi, kaal): kaal = 450 - kaal print("Isane jääkaru kaalub " + str(kaal) + " kilogrammi rohkem kui " + nimi) mõõtja("Ott", 91)
Nagu näed, tuleb funktsiooni väljakutsel argumendid anda samas järjekorras nagu on vastavad parameetrid funktsiooni definitsioonis. Teisisõnu, argumendi positsioon määrab, millisele parameetrile tema väärtus omistatakse.
Funktsiooni defineerimine
Pythonis kasutame funktsiooni defineerimiseks sõna def, peale võtmesõna tuleb funktsiooni nimi, mida kasutame pärast funktsiooni välja kutsumiseks. Funktsiooni nimeks võib valida mida tahes, aga hea programmeerija komme on nimetada funktsioone selle järgi, mida nad teevad. Peale funktsiooni nime tulevad sulud, kus saab määrata funktsiooni argumendid, millega funktsioon pärast tegeleda saab.
Näide: def funktsiooniNimi(argumendid)
import math # Sellega saame kasutada konstanti pi, kujul (math.pi) ringi_raadius = float(input("Sisestage ringi raadius: ")) def ringi_Kalkulaator(raadius): ümbermõõt = 2 * ringi_raadius * math.pi pindala = ringi_raadius* ringi_raadius * math.pi print("Ringi ümbermõõt on: " + str(ümbermõõt)) print("Ringi pindala on: " + str(pindala))
NB! Hetkel programmi täites küsitakse kasutajalt ainult raadiust, aga midagi ei juhtu. Mis võib olla põhjus? Antud olukorras on meil loodud funktsioon Ringi_Kalkulaator, aga programmis pole seda välja kutsutud. Jäta meelde, selleks et funktsiooni kasutada, peab selle välja kutsuma, kasutades selle funktsiooni nime. Vastasel juhul arvab programm, et seda ei pea kasutama. Selleks, et me saaks kasutada funktsiooni Ringi_Kalkulaator, peame peale funktsiooni selle välja kutsuma. Näiteks kirjutame programmi lõppu.
ringi_Kalkulaator(ringi_raadius)
Import
Python mõistab tuhandeid erinevaid käske. Nende paremaks organiseerimiseks on nad jaotatud teemade kaupa gruppidesse, mida nimetatakse mooduliteks. import-lause teeb moodulis olevad funktsioonid programmi jaoks kättesaadavaks.
Eelmises näites importisime pi. Kui soovime moodulist kõiki funktsioone, siis võime kasutada import-lauses funktsiooninime(de) asemel tärni:
from math import * print(sin(0.3)) print(cos(sin(0.3)))
Märkus Kui meil kõiki funktsioone (või vähemalt enamikku neist) vaja ei lähe, siis pole tärniga importimine soovitatav, sest Thonny muutujate tabel täitub ebavajalike ridadaga, ning huvipakkuvaid muutujaid on raskem leida. Samuti on oht, et kogemata valesti kirjutatud muutujanime korral Python mitte ei anna veateadet vaid kasutab meie teadmata mõnd imporditud muutujat.
Importida saab ka moodulit ennast, sel juhul tuleb soovitava funktsiooni nimi kirjutada koos mooduli nimega:
>>> import math >>> print(math.sin(0.5)) 0.479425538604203 >>> print(math.cos(0.5)) 0.8775825618903728
Loenguvideo funktsioonidest, mis juba olemas
Funktsioonid väärtustega
Hetkel nägime ainult, et funktsioon väljastas vajaliku info ekraanile. Tulevikus võib üsna tihti ette tulla, et soovime selle infoga programmis veel midagi teha. Näiteks funktsioon input salvestab muutujas kasutaja sisestatud väärtuse, mitte ei väljasta seda kohe ekraanile. Tänu sellele saame muutujas olevat infot edaspidi veel kasutada. Selleks, et funktsioon tagastaks muutujale sobiva väärtuse, kasutatakse sõna return. Näiteks Pythonis juba olev funktsioon sqrt. See on funktsioon, mis leiab talle etteantud argumendi ruutjuure.
Kui meil on programmis selline rida:
a = sqrt(16)
Mis on a väärtus?
Märkus! Kui nüüd päris täpne olla, siis tegelikult kõik Pythoni funktsioonid tagastavad midagi, isegi print. Need funktsioonid, mille põhieesmärk on mingi tegevus, tagastavad alati ühe spetsiifilise (ja suhteliselt ebahuvitava) väärtuse None. Selle väärtusega ei ole üldjuhul midagi peale hakata. Õnneks ta meid ka ei sega, seega võime teda vabalt ignoreerida.
Vahel on meil vaja ise luua funktsioone, mis vajaliku väärtuse tagastaksid. Näiteks on meil grupp inimesi ja soovime teada, kas nende seas on pensionäre.
päts = 19 meri = 55 ilves = 89 def vanuseKontroll(vanus): if vanus >=65: return True else: return False if vanuseKontroll(päts) or vanuseKontroll(meri) or vanuseKontroll(ilves): print("Inimeste hulgas leidub pensionär!") else: print("Pole ühtegi pensionäri!")
Antud programm kontrollib etteantud inimese vanust. Kui isik on 65 või vanem, siis tagastab tõeväärtuse True. Vastasel juhul False.
Loenguvideo funktsioonidest
Lokaalsed vs globaalsed muutujad
Funktsioonide sees saame kasutada abimuutujaid, mis aitavad meil lahenduseni jõuda.
def käibemaksuEemaldaja(summa): algarv = summa ilma_maksuta = summa / 1.2 käibemaks = algarv - ilma_maksuta print("Käibemaks oli: " + str(käibemaks)) käibemaksuEemaldaja(450)
Näites on abimuutujad: algarv ja ilma_maksuta.
Asi on selles, et funktsiooni kehas kasutusele võetud muutujad on lokaalsed, st nad toimivad ainult funktsiooni sees. Lokaalsed muutujad luuakse funktsiooni igal käivitamisel ja nad kaovad, kui funktsioon oma töö lõpetab. Nende olemasolu on funktsiooni siseasi, see ei paista kuidagimoodi väljapoole. See asjaolu võimaldab meil funktsiooni sees olevatele e lokaalsetele muutujatele vabalt nimesid valida, ilma muretsemata, kas mõnda neist nimedest on juba programmi põhiosas või mõnes teises funktsioonis kasutatud.
Ehk me ei saa väljaspool funktsiooni kasutada loodud abimuutujaid.
Kui me prooviks programmi lisada funktsiooni väljakutse print(algarv), siis ilmuks ekraanile NameError: name 'algarv' is not defined
Programmi põhiosas defineeritud muutujaid nimetatakse globaalseteks muutujateks. Nende nähtavus on suurem – nendele pääseb Python ligi nii programmi põhiosas kui ka funktsioonide sees.
Loenguvideo funktsioonide loomisest. Lokaalne ja globaalne muutuja
Pykkar
Pykkar on virtuaalne robot, kes tegutseb oma virtuaalses maailmas. Ta suudab liikuda, ruute värvida, asju kanda ja tal on andurid mitmesuguste objektide tuvastamiseks. Pykkar on realiseeritud moodulis pykkar (see ei ole Pythoni põhimoodul, seega pead selle tõenäoliselt installima: Thonnys vali Tööriistad → Halda lisapakke... või Tools → Manage Packages ... ning otsi sealt pykkar).
Proovige esimest programminäidet:
from pykkar import * create_world(""" ######## # > # # # # # # # # # ######## """) step() step() step() right()
See programm peaks kuvama väljaku koos liikuva robotiga:
Pykkar mõistab järgmisi käsklusi:
- step() – tee samm edasi.
- right() – pööra 90° paremale.
- take() – korja üles järgmisel ruudul olev koonus. Pykkar suudab transportida ühte koonust korraga.
- put() – pane koonus järgmisele ruudule. Ühel ruudul võib asuda kuni 9 koonust.
- push() – lükka Pykkari ees olevat kasti või koonust.
- paint() – värvi jooksev ruut tumedaks.
- is_wall() – ütleb, kas ees on sein (tagastab True või False).
- is_cone() – ütleb, kas ees on koonus.
- is_box() – ütleb, kas ees on kast.
- is_painted() – ütleb, kas jooksev ruut on värvitud.
- get_direction() – küsib jooksvat suunda (tagastab 'N', 'E', 'S' või 'W').
Pykkari maailm luukase funktsiooniga create_world, millele antakse argumendina ette mitmerealine sõne. Sõne kirjeldab maailma kaarti, iga sümbol tähistab ühte ruutu.
Ruutude tüübid on järgmised:
Sümbol | Tähendus | Näide |
(tühik) | Hele ruut | |
. | Tume ruut | |
# | Sein | |
^ > v < | Pykkar heledal ruudul, nool näitab suunda | |
N E S W | Pykkar tumedal ruudul, täht näitab suunda | |
1 2 ... 9 | Koonuste arv heledal ruudul | |
C | Üks koonus tumedal ruudul | |
b | Kast heledal ruudul | |
B | Kast tumedal ruudul |