Olemme jo käyttäneet monia erilaisia komentoja: sijoitusta, laskutoimituksia, vertailua, if:iä, for:ia ja whileä. Ruudulle tulostaminen on tehty "komentoa" print
käyttäen. Listan pituus tunnistetaan "komennolla" len
. Tuttuja ovat myös input
ja int
.
Huomaamme, että jälkimmäinen joukko edellä lueteltuja komentoja poikkeaa if:istä, for:ista, while:stä ym. siinä, että komennon perässä on sulut ja joskus sulkujen sisällä komennolle annettava tieto. "Sulkuihin päättyvät" eivät oikeastaan olekaan komentoja vaan funktioita.
Teknisesti ottaen funktio tarkoittaa koodinpätkää, jota voi kutsua muualta ohjelmakoodista. Koodirivi print("olen metodi!")
siis tarkoittaa, että kutsutaan funktiota, joka suorittaa ruudulle tulostamisen. Funktion suorituksen jälkeen palataan siihen kohtaa missä ennen funktiokutsua oltiin menossa. Funktiolle suluissa annettua tietoa kutsutaan funktion parametriksi.
Parametrin lisäksi funktiolla voi olla paluuarvo. Esim. tuttu koodinpätkä:
syote = input("Kerro jotain: ")
sisältää kutsun funktioon input
jolle annetaan parametrina merkkijono joka käyttäjälle näytetään. Funktiolla on paluuarvona käyttäjän syöttämä merkkijono. Vastaavasti paljon käyttämämme kokonaisluvun lukeminen:
luku = int(input("Anna kokonaisluku: "))
sisältää kaksi funktiokutsua. Ensin kutsutaan funktiota input
, jonka paluuarvona on merkkijono. Funktion input
palauttama merkkijono annetaan heti parametrina funktiolle int
, joka palauttaa parametrina annetun merkkijonon kokonaislukuna.
Funktiokutsuja voi siis ketjuttaa siten, että "sisemmästä" funktiokutsusta palautunut arvo annetaan "ulommalle" funktiokutsulle parametrina.
Funktiokutsuja on oikeastaan kahdenlaisia. Osa liittyy muuttujiin siten, että muuttujan nimen jälkeen tulee piste ja sen jälkeen funktion nimi. Osa taas on erillisiä. Esimerkiksi listamuuttujilla on funktio append
, jota käytetään yhdessä listamuuttujan kanssa listamuuttuja.append(3)
. Tämä yhdistäminen johtuu yksinkertaistaen siitä, että tiedettäisiin mihin listaan lisätään.
Opimme hiukan myöhemmin tarkemmin mistä tässä pisteen vasemmanpuoleisessa osassa on kyse.
Tähän mennessä käyttämämme metodit ovat kaikki olleet pythonin valmiita funktioita. Hetken kuluttua opimme tekemään myös omia funktioita.
Olemme tähän mennessä ohjelmoineet ohjelmamme siten, että kaikki tapahtuu yhdessä jatkumossa ja koodia luetaan ylhäältä alas.
Edellä puhuttiin jo funktioista, ja mainittiin että "funktio tarkoittaa koodinpätkää, jota voi kutsua muualta ohjelmakoodista". Pythonin valmiita funktioita on käytetty jo oikeastaan ensimmäisestä ohjelmasta lähtien.
Valmiiden funktioiden käytön lisäksi ohjelmoija voi kirjoittaa itse funktioita joita sovellus kutsuu. Oikeastaan on hyvin poikkeuksellista jos ohjelmassa ei ole yhtään itse kirjoitettua funktiota. Tästälähtien lähes jokainen ohjelma sisältääkin itsekirjoitettuja funktioita.
Kirjoitetaan tästä eteenpäin (kunnes toisin opitaan!) funktiot lähdekoodin yläosaan, ja funktioita itse käyttävä ohjelma funktioiden alapuolelle:
# ensin funktiomäärittelyt def hei(): print("No heipä hei!") return # ja sitten ohjelma joka käyttää funktioita! print("No hei.") hei()
Ylläolevassa esimerkissä on luotu oma funktio nimeltä hei
. Funktio määritellään komennolla def
jonka jälkeen tulee funktion nimi, eli nimi jolla funktiota kutsutaan. Funktion nimen jälkeen tulee sulut ja kaksoispiste. Kaksoispisteen jälkeen alkaa lohko, jonka sisällä määritellään funktion toiminnallisuus.
Ylläolevassa esimerkissä funktio päätetään komennolla return
, joka voidaan vapaasti suomentaa joko palaa tai palauta. Tutustumme arvon palauttaviin funktioihin hieman myöhemmin.
Kun ylläoleva esimerkki ajetaan, tulostuu seuraavanlainen teksti:
No hei. No heipä hei!
Lähdekoodin suoritus siis alkaa funktiomäärittelyiden jälkeen. Ensin tulee vastaan komento print("No hei.")
, joka oikeasti kutsuu pythonin valmista tulostusfunktiota print
. Kun rivi suoritetaan, tulostuu näytölle teksti "No hei.". Tämän jälkeen mennään seuraavalle riville, jossa on komento hei()
. Python-tulkki näkee suluista että kyseessä on funktiokutsu ja etsii hei
-nimisen funktion. Funktio hei
suoritetaan, eli ajetaan komento print("No heipä hei!")
, jota seuraa komento return
. Komento return
tarkoittaa tässä tapauksessa sitä, että palataan takaisin kohtaan josta funktiota kutsuttiin. Funktiokutsun hei()
jälkeen ei ole muita komentoja, ja ohjelman suoritus päättyy.
Itsekirjoitetun funktion kutsuminen on helppoa, kirjoitetaan funktion nimi ja perään sulut ja puolipiste. Seuraavassa esimerkissä kutsutaan funktiota tervehdi
ensin kerran ja sen jälkeen useita kertoja.
# ensin funktiomäärittelyt def tervehdi(): print("Terveisiä funktiosta tervehdi!") return # ja sitten ohjelma joka käyttää funktioita! print("Kokeillaan onnistuuko funktion kutsuminen:") tervehdi() print("Näyttää siltä, kokeillaan vielä:") tervehdi() tervehdi() tervehdi()
Ohjelman suoritus saa aikaan seuraavan tulosteen:
Kokeillaan onnistuuko funktion kutsuminen: Terveisiä funktiosta tervehdi! Näyttää siltä, kokeillaan vielä: Terveisiä funktiosta tervehdi! Terveisiä funktiosta tervehdi! Terveisiä funktiosta tervehdi!
Tässä siis huomionarvoista on, että koodin suoritus etenee siten, että pääohjelman rivit suoritetaan ylhäältä alas yksi kerrallaan. Koodirivin ollessa funktiokutsu, mennään suorittamaan funktion koodirivit jonka jälkeen palataan siihen kohtaan josta kutsu tapahtui, tai tarkemmin ottaen funktiokutsun jälkeiseen kohtaan.
Jatkossa kun esittelemme funktioita, emme erikseen mainitse että niiden täytyy sijaita omalla paikallaan. Funktioita ei esimerkiksi voi määritellä toisen funktion sisällä.
Tee funktio tulostaTeksti
, joka tulostaa
tekstin "Alussa olivat suo, kuokka ja python."
Ohjelman tulostus:
Alussa olivat suo, kuokka ja python.
Laajenna edellistä ohjelmaasi siten, että pääohjelma kysyy käyttäjältä, montako kertaa teksti tulostetaan eli montako kertaa metodia kutsutaan.
Ohjelman tulostus:
Kuinka monta kertaa tulostetaan? 7 Alussa olivat suo, kuokka ja python. Alussa olivat suo, kuokka ja python. Alussa olivat suo, kuokka ja python. Alussa olivat suo, kuokka ja python. Alussa olivat suo, kuokka ja python. Alussa olivat suo, kuokka ja python. Alussa olivat suo, kuokka ja python.
Funktiosta saa huomattavasti monikäyttöisemmän antamalla sille parametreja. Parametrit ovat muuttujia, jotka määritellään funktion ylimmällä rivillä funktion nimen jälkeen olevien sulkujen sisällä. Kun funktiota kutsutaan, sen parametreille annetaan arvot kutsuvaiheessa.
Seuraavassa esimerkissä määritellään parametrillinen funktio tervehdi
, jolla on tekstityyppinen parametri nimi
def tervehdi(nimi): print("Hei " + nimi + ", terveiset funktiosta!")
Kutsutaan funktiota tervehdi
siten, että parametrin nimi
arvoksi asetetaan ensimmäisellä kutsulla Matti
ja toisella kutsulla Arto
.
# ensin funktiomäärittelyt def tervehdi(nimi): print("Hei " + nimi + ", terveiset funktiosta!") # sitten ohjelman toiminnallisuus tervehdi("Matti") tervehdi("Arto")
Hei Matti, terveiset funktiosta! Hei Arto, terveiset funktiosta!
Aivan kuten kutsuttaessa pythonin valmista print
-metodia, voi oman metodin kutsussa parametrina käyttää monimutkaisempaa ilmausta:
nimi1 = "Pihla" nimi2 = "Toivanen" tervehdi( nimi1 + " " + nimi2 ) ika = 24 tervehdi("Juhana " + str(ika) + " vuotta")
Hei Pihla Toivanen, terveiset funktiosta! Hei Juhana 24 vuotta, terveiset funktiosta!
Molemmissa tapauksissa funktiolla on edelleen vain 1 parametri. Parametrin arvo lasketaan ennen funktion kutsumista. Ensimmäisessä tapauksessa parametrin arvo saadaan merkkijonokatenaationa nimi1 + " " + nimi2
joka siis on arvoltaan Antti Mikkola ja jälkimmäisessä tapauksessa merkkijonokatenaatiosta "Juhana " + str(ika) + " vuotta"
.
Listan käyttö parametrina onnistuu ilman ongelmia:
def tulostaAlkiot(lista): for alkio in lista: print(alkio) luvut = [1, 2, 3, 4, 5] tulostaAlkiot(luvut)
1 2 3 4 5
Huomaa että parametrin nimi funktion sisällä voi olla aivan vapaasti valittu, nimen ei tarvitse missään tapauksessa olla sama kuin kutsuvassa ohjelmassa. Edellä listaa kutsutaan metodin sisällä nimellä lista
, metodin kutsuja taas näkee saman listan luvut
-nimisenä.
Funktiolla voidaan määritellä useampia parametreja. Tällöin metodin kutsussa parametrit annetaan samassa järjestyksessä.
def tervehdi(nimi, mistaTerveiset): print("Hei " + nimi + ", terveiset " + mistaTerveiset)
kuka = "Matti" terveiset = "Kyröjoelta" tervehdi(kuka, terveiset) tervehdi(kuka, terveiset + " ja Kumpulasta")
Jälkimmäisessä tervehdi
-funktion kutsussa toinen parametri muodostetaan katenoimalla muuttujaan terveiset
teksti " ja Kumpulasta"
. Tämä suoritetaan ennen varsinaista funktion suoritusta.
Hei Matti, terveiset Kyröjoelta Hei Matti, terveiset Kyröjoelta ja Kumpulasta
Pääohjelmamme, eli tässä vaiheessa alhaalla oleva koodi, ei suinkaan ole ainoa joka voi kutsua funktioita. Funktiot voivat kutsua myös toisiaan. Tehdään funktio tervehdiMontaKertaa
, joka tervehtii käyttäjää useasti funktion tervehdi
avulla:
def tervehdi(nimi): print("Hei " + nimi + ", terveiset funktiosta!") def tervehdiMontaKertaa(nimi, kerrat): for i in range(kerrat): tervehdi(nimi) tervehdiMontaKertaa("Antti", 3) print("ja") tervehdiMontaKertaa("Martin", 2)
Tulostuu:
Hei Antti, terveiset funktiosta! Hei Antti, terveiset funktiosta! Hei Antti, terveiset funktiosta! ja Hei Martin, terveiset funktiosta! Hei Martin, terveiset funktiosta!
Tee funktio tulostaTahtia
,
joka tulostaa annetun määrän tähtiä
tulostaTahtia(5) tulostaTahtia(3) tulostaTahtia(9)
Ohjelman tulostus:
***** *** *********
Tee funktio tulostaViesti
, joka tulostaa
annetun viestin tähdillä reunustettuna.
Käytä funktiossa apuna funktiota tulostaTahtia
.
Tee ohjelma seuraavaan runkoon:
tulostaViesti("Tervetuloa!"); tulostaViesti("ABC"); tulostaViesti("Hei hei!");
Ohjelman tulostus:
*************** * Tervetuloa! * *************** ******* * ABC * ******* ************ * Hei hei! * ************
Tee funktio tulostaViestit
,
joka tulostaa listassa annetut viestit tähdillä reunustettuina.
Käytä funktiossa apuna funktiota tulostaViesti
.
lista = ["Tervetuloa", "ABC", "Hei hei!"]; tulostaViestit(taulukko);
Ohjelman tulostus:
*************** * Tervetuloa! * *************** ******* * ABC * ******* ************ * Hei hei! * ************
Tee funktio tulostaMerkkeja
,
joka tulostaa annetun määrän annettuja merkkejä.
tulostaMerkkeja(5, 'A'); tulostaMerkkeja(3, 'B'); tulostaMerkkeja(9, 'C');
Ohjelman tulostus:
AAAAA BBB CCCCCCCCC
Yritetään muuttaa funktion sisältä pääohjelman muuttujan arvoa.
def kasvataKolmella(): x = x + 3 x = 1 kasvataKolmella() print(x)
Ohjelma ei kuitenkaan toimi, sillä funktio ei näe muuttujaa x
.
Yleisemminkin voi todeta, että pääohjelman muuttujat eivät suoraan näy muuttujat eivät näy funktioiden sisään, ja funktioiden muuttujat eivät näy muille funktioille tai pääohjelmalle. Yleisesti käytetty keino tiedon viemiseen funktioon on funktiolle annettavan parametrin käyttö.
Python mahdollistaa funktioiden määrittelyn siten, että ne näkevät funktioiden ulkopuolella määritellyt muuttujat avainsanan global
avulla. Seuraavassa yllä esitetty esimerkki uudestaan, tällä kertaa globaalia muuttujaa käyttäen.
def kasvataKolmella(): global x x = x + 3 x = 1 kasvataKolmella() print(x)
4
Globaalien muuttujien käyttöä ohjelmissa kannattaa kuitenkin välttää, ja tyytyä tässä vaiheessa palauttamaan yksi arvo funktiota kohti.
Funktio voi myös palauttaa arvon. Edellä olevissa esimerkeissä funktiot eivät palauttaneet mitään arvoa. Tämä on merkitty joko jättämällä return
-lause pois funktiomäärittelystä, tai jättämällä return
omalle rivilleen.
def tervehdi(): print("Heippa vaan!") return
Arvon palauttavaa funktiota määriteltäessä annetaan funktiossa olevalle return
-komennolle palautettava muuttuja. Seuraavassa funktio joka palauttaa aina luvun 10.
def palautetaanAinaKymppi(): return 10
Jotta funktion kutsuja voisi käyttää paluuarvoa, tulee paluuarvo ottaa talteen muuttujaan:
luku = palautetaanAinaKymppi() print("metodi palautti luvun " + str(luku))
Funktion paluuarvo siis sijoitetaan muuttujaan aivan kuin mikä tahansa muukin arvo. Paluuarvo voi toimia myös osana mitä tahansa lauseketta:
luku = 4 * palautetaanAinaKymppi() + palautetaanAinaKymppi() / 2 - 8 print("laskutoimituksen tulos " + str(luku))
Seuraavassa esimerkissä määritellään funktio summan laskemiseen. Tämän jälkeen funktiota käytetään laskemaan luvut 2 ja 7 yhteen, funktiokutsusta saatava paluuarvo asetetaan muuttujaan lukujenSumma
.
def summa(eka, toka): return eka + toka lukujenSumma = summa(2, 7); print("Lukujen 2 ja 7 summa on " + str(lukujenSumma))
Laajennetaan edellistä esimerkkiä siten, että käyttäjä syöttää luvut.
def summa(eka, toka): return eka + toka eka = int(input("Anna ensimmäinen luku: ")) toka = int(input("Anna toinen luku: ")) print("Luvut ovat yhteensä: " + str(summa(eka,toka)))
Kuten huomataan, funktion paluuarvoa ei tarvitse välttämättä sijoittaa muuttujaan, se voi olla osana tulostuslausetta aivan kuten mikä tahansa muukin arvo. Kannattaa kuitenkin huomata, että merkkijonoon liitettäessä kokonaislukumuuttujat tulee muuttaa myös teksti- tai merkkijonotyyppisiksi funktiokutsulla str
.
Seuraavassa esimerkissä funktiota summa kutsutaan kokonaisluvuilla, jotka saadaan summa
-metodin paluuarvoina.
def summa(eka, toka): return eka + toka a = 3 b = 2 summienSumma = summa(summa(1,2), summa(a,b)) # 1) suoritetaan sisemmät metodit: # summa(1,2) = 3 ja summa(a,b) = 5 # 2) suoritetaan ulompi metodi: # summa(3,5) = 8 print(summienSumma)
8
Seuraava funktio laskee syötteinään saamiensa luvun keskiarvon. Metodi käyttää apumuuttujia summa
ja ka
. Metodin sisäisen muuttujan määrittely tapahtuu tutulla tavalla.
def keskiarvo(luku1, luku2, luku3): summa = luku1 + luku2 + luku3 ka = summa/3.0 return ka
Tee funktio summa
, joka laskee
listan lukujen summan.
Tee metodi seuraavaan runkoon:
lista = [3, 2, 7, 2] print "Summa: " + str(summa(lista))
Ohjelman tulostus:
Summa: 14
Tee funktio keskiarvo
, joka laskee listan
lukujen keskiarvon. Funktiossa kannattaa käyttää
apuna funktiota summa
.
lista = [3, 2, 7, 2] print("Keskiarvo: " + str(keskiarvo(lista)))
Ohjelman tulostus:
Keskiarvo: 3.5
Tee ohjelma, joka kertoo, onko käyttäjän antama luku listassa.
Lista määritellään koodin alussa seuraavasti:
luvut = [7, 2, 4, 8]
Esimerkkitulostuksia:
Anna luku: 4 Luku on listassa.
Anna luku: 3 Lukua ei ole listassa.