Osa 4

Lisää funktioista

Funktioiden määrittely tapahtuu avainsanan def avulla:

def viesti():
    print("Tämä tulee funktiosta")

Näin määriteltyä funktiota nimeltä viesti kutsutaan seuraavasti:

viesti()

Tällöin ohjelman tulostus on seuraava:

Esimerkkitulostus

Tämä tulee funktiosta

Funktion parametrit

Funktiolla voi olla yksi tai useampi parametri. Parametrit määritellään suluissa funktion nimen jälkeen.

Esimerkiksi seuraavassa koodissa funktiolla tervehdi on yksi parametri ja funktiolla summa on kaksi parametria.

def tervehdi(nimi):
    print("Moikka,", nimi)

def summa(a, b):
    print("Parametrien summa on", a + b)
tervehdi("Emilia")
summa(2, 3)
Esimerkkitulostus

Moikka, Emilia Parametrien summa on 5

Testien virheilmoitukset

Jos ohjelmasi ei toimi oikein, antavat testit enemmän tai vähemmän hyvän virheilmoituksen. Virheilmoitus kannattaa ehdottomasti lukea huolellisesti.

Joissain tilanteissa virheilmoitus ei kerro tarkemmin, mistä on kyse. Esimerkiksi seuraavassa tehtävässä saatat törmätä seuraavaan virheeseen:

4 2 0a

Virhe kertoo, että tehtävän funktiota viiva pitäisi pystyä kutsumaan seuraavasti:

viiva(5, "")

Varsinainen ongelma paljastuu, kun kokeillaan, mitä funktiokutsu tekee, eli kopioidaan virheilmoituksen kertoma funktiokutsu koodiin ja painetaan vihreää kolmiota:

4 2 0b

Koodin suorituksen viimeiset rivit kertovat, mikä on vikana: koodin rivi 4 aiheuttaa virheen IndexError: string index out of range. Kuten edellisessä osassa mainittiin, syy tälle on se, että koodissa yritetään indeksoida merkkijonon ulkopuolelle. Tällä kertaa syynä on se, että yritetään hakea nollan pituisen merkkijonon ensimmäistä merkkiä.

Loading

Sisäkkäiset kutsut

Voimme kutsua funktiota myös toisen funktion sisältä. Esimerkiksi seuraavassa ohjelmassa funktio tervehdi_monesti kutsuu funktiota tervehdi halutun määrän kertoja:

def tervehdi(nimi):
    print("Moikka,", nimi)

def tervehdi_monesti(nimi, kerrat):
    while kerrat > 0:
        tervehdi(nimi)
        kerrat -= 1

tervehdi_monesti("Emilia", 3)
Esimerkkitulostus

Moikka, Emilia Moikka, Emilia Moikka, Emilia

Loading
Loading
Loading
Loading
Loading
Loading

Funktion paluuarvo

Funktiot voivat myös palauttaa arvoja. Esimerkiksi Pythonin valmis funktio input palauttaa käyttäjän antaman syötteen. Funktion palauttama arvo voidaan esimerkiksi sijoittaa muuttujaan:

sana = input("Anna sana: ")

Myös kokonaislukujen lukemisessa yhdessä funktion input kanssa käytettävä funktio int palauttaa arvon:

luku = int(input("Anna kokonaisluku: "))

Funktio int saa parametrinaan funktion input palauttaman merkkijonon ja palauttaa sen kokonaislukutyyppisenä.

Funktion arvon palauttaminen return-komennolla

Myös itse määrittelemämme funktiot voivat palauttaa arvoja käyttämällä komentoa return. Esimerkiksi seuraava funktio summa palauttaa annettujen lukujen summan:

def summa(a, b):
    return a + b

vastaus = summa(2, 3)

print("Summa:", vastaus)
Esimerkkitulostus

Summa: 5

Seuraavassa on vielä toinen esimerkki, jossa funktio kysyy käyttäjän nimen ja palauttaa sen:

def kysy_nimi():
    nimi = input("Mikä on nimesi? ")
    return nimi

nimi = kysy_nimi()
print("Moikka,", nimi)
Esimerkkitulostus

Mikä on nimesi? Anna Moikka, Anna

Kannattaa huomata, että komento return lopettaa funktion suorituksen saman tien. Niinpä voimme tehdä seuraavan funktion:

def pienin(a,b):
    if a < b:
        return a
    return b

print(pienin(3, 7))
print(pienin(5, 2))

Tässä ideana on, että jos a on pienempi kuin b, niin funktio palauttaa arvon a ja päättyy. Muuten funktion suoritus jatkuu eteenpäin, jolloin se palauttaa arvon b.

Esimerkkitulostus

3 2

Voimme myös käyttää return-komentoa siihen, että poistumme funktiosta palauttamatta mitään:

def tervehdi(nimi):
    if nimi == "":
        print("???")
        return
    print("Moikka,", nimi)

tervehdi("Emilia")
tervehdi("")
tervehdi("Matti")

Jos nimi on tyhjä merkkijono, niin funktio tulostaa ??? ja päättyy.

Esimerkkitulostus

Moikka, Emilia ??? Moikka, Matti

Funktion paluuarvojen käyttö

Kuten olemme jo nähneet, funktioiden paluuarvoja on mahdollista sijoittaa muuttujiin:

def summa(a, b):
    return a + b

tulos = summa(4, 6)
print("Summa on", tulos)
Esimerkkitulostus

Summa on 10

Koska funktion paluuarvo käyttäytyy kuten mikä tahansa arvo, ei apumuuttuja ole tarpeen ja paluuarvoa on mahdollista käyttää suoraan komennon print parametrina:

print("Summa on", summa(4, 6))

Voimme myös antaa funktion palauttaman arvon toiselle funktiolle:

def summa(a, b):
    return a+b

def erotus(a, b):
    return a-b

tulos = erotus(summa(5, 2), summa(2, 3))
print("Vastaus on", tulos)
Esimerkkitulostus

Vastaus on 2

Tässä tapauksessa suoritetaan ensin sisemmät funktiokutsut summa(5, 2) ja summa(2, 3), joiden palauttamat arvot 7 ja 5 käytetään ulomman funktiokutsun parametreina.

Ulompi funktiokutsu erotus(7, 5) palauttaa arvon 2, joka sijoitetaan muuttujan tulos arvoksi ja tulostetaan ruudulle.

Funktioiden palauttamat arvot toimivat täysin samalla tavalla kuin mitkä tahansa arvot Pythonissa. Niitä voidaan tulostaa, sijoittaa muuttujaan, käyttää osana lausekkeita tai käyttää parametreina muissa funktiokutsuissa.

Arvon palauttaminen, return ja print

Joskus aloittelija hämmentyy funktioiden paluuarvon ja funktiossa tapahtuvan tulostuksen välistä eroa. Tarkastellaan kahta versiota funktiosta, joka selvittää kahden parametrinsa maksimiarvon:

def maksimi1(a, b):
    if a > b:
        return a
    else:
        return b

def maksimi2(a, b):
    if a > b:
        print(a)
    else:
        print(b)

vastaus = maksimi1(3, 5)
print(vastaus)

maksimi2(7, 2)
Esimerkkitulostus

5 7

Molemmat funktiot näyttävät toimivan hyvin, kumpikin selvittää maksimiarvon. Funktioissa on kuitenkin eräs ratkaiseva ero. Funktioista ensimmäinen maksimi1 palauttaa selvittämänsä arvon. Se ei itse tulosta mitään, eli jos suoritetaan koodi

maksimi1(3, 5)

ei näytä tapahtuvan mitään. Funktion paluuarvo on siis otettava talteen muuttujaan, jos se halutaan tulostaa:

vastaus = maksimi1(3, 5)
print(vastaus)

Funktioista toinen maksimi2 taas tulostaa itse print-komentoa käyttäen lukujen maksimin, eli riittää kutsua

maksimi2(7, 5)

ja maksimi tulostuu ruudulle. Tämän funktion huono puoli on kuitenkin se, että funktion selvittämää arvoa ei ole mahdollista saada funktion ulkopuolelle muun ohjelman käsiteltäväksi. Tämän takia arvon palauttava funktio on useimmiten parempi vaihtoehto.

Loading
Loading
Loading

Parametrin tyyppi

Kerrataan vielä tähän mennessä läpikäydyt tyypit:

TyyppiPythonissaEsimerkki
Kokonaislukuint23
Liukulukufloat-0.45
Merkkijonostr"Pekka Python"
TotuusarvoboolTrue

Kun kutsumme funktiota, funktio toimii oikein vain, jos annamme sille sopivan tyyppiset parametrit. Tarkastellaan esimerkkinä seuraavaa funktiota:

def tulosta_monesti(viesti, kerrat):
    while kerrat > 0:
        print(viesti)
        kerrat -= 1

Funktio toimii mainiosti, jos kutsumme sitä näin:

tulosta_monesti("Moikka", 5)
Esimerkkitulostus

Moikka Moikka Moikka Moikka Moikka

Kuitenkaan funktio ei toimi, jos annamme sille väärän tyyppisen parametrin:

tulosta_monesti("Moikka", "Emilia")
Esimerkkitulostus

TypeError: '>' not supported between instances of 'str' and 'int'

Tässä ongelmaksi tulee, että funktion jälkimmäistä parametria kerrat vertaillaan kokonaislukuun 0. Kun parametri on "Emilia" eikä kokonaisluku, tämä aiheuttaa virheen.

Voimme antaa funktion määrittelyssä tyyppivihjeen, joka ilmaisee, millaista tietoa parametreihin on tarkoitus sijoittaa:

def tulosta_monesti(viesti : str, kerrat : int):
    while kerrat > 0:
        print(viesti)
        kerrat -= 1

Tämä kertoo funktion käyttäjälle, että parametrin viesti on tarkoitus olla merkkijono, kun taas parametrin kerrat on tarkoitus olla kokonaisluku.

Vastaavasti funktion paluuarvon tyypin voi vihjata funktion määrittelyssä:

def kysy_nimi() -> str:
    nimi = input("Mikä on nimesi? ")
    return nimi

Tämä kertoo funktion käyttäjälle, että funktion on tarkoitus palauttaa merkkijono.

Huomaa kuitenkin, että tyyppivihje ainoastaan neuvoo, mikä tyypin tulisi olla, mutta ei valvo sitä. Jos funktiolle annetaan väärän tyyppinen parametri tai se palauttaa väärän tyyppisen arvon, funktio suoritetaan kuitenkin, mutta se toimii mahdollisesti väärin.

Loading...
:
Loading...

Log in to view the quiz

Seuraava osa: