Funktiot

Tähän mennessä olemme jo käyttäneet muutamia Pythonin sisäänrakennettuja funktioita kuten print, input ja round

  • print-funktio tulostaa sille annetut parametrit (mutta ei palauta mitään arvoa)
  • input-funktio tulostaa sille annetun parametrin ja palauttaa käyttäjän syöttämän merkkijonon
  • round-funktio pyöristää liukulukuja haluttuun tarkkuuteen tai kokonaisluvuiksi

Lisäksi olemme käyttäneet funktioita tyyppimuunnoksiin:

tilavuus = float(input("Anna tilavuus:\n"))

Yllä float-funktio tekee siis tyyppimuunnoksen merkkijonosta liukuluvuksi.

Pythonissa on useita sisäänrakennettuja funktioita ja erilaiset ohjelmakirjastot sisältävät lukuisia funktioita eri käyttötarkoituksiin. 

Tällä kierroksella opit kirjoittamaan omia funktioita. Niiden avulla toistuvien tehtävien suorittaminen helpottuu ja koodin rakenne pysyy selkeämpänä.

Funktioiden määrittely

Funktiolla on tavallisesti joku selkeä tehtävä, esimerkiksi tietty laskutoimitus

  • Funktiolla voi olla parametreja (ei ole pakko olla)
  • Funktio voi palauttaa arvoja (ei ole pakko palauttaa)
  • Funktio voi suorituksen aikana tehdä lähes mitä vaan, eli se on periaatteessa aliohjelma
Esimerkki 1

Tarkastellaan ohjelmaa, jossa määritellään funktio tuplaa ja käytetään sitä:

# Määritellään ensin funktio tuplaa käyttäen def-avainsanaa
# Funktio ajetaan vasta, kun sitä kutsutaan pääohjelmasta
def tuplaa(luku):
    # Huomaa, miten funktion sisältö on sisennetty
    return luku * 2

# Pääohjelma alkaa tästä (ei sisennystä)
# Kutsutaan funktiota "tuplaa"
iso_luku = tuplaa(12)
print(iso_luku)

  • Funktio määritellään avainsanalla def, jonka jälkeen tulee funktion nimi (tuplaa)
  • tuplaa-funktiolla on yksi parametri, jonka nimi on luku (suluissa nimen jälkeen)
  • return-avainsanan jälkeen tulee funktion paluuarvo (tässä tapauksessa parametri luku kerrottuna kahdella).
  • Kun olemme määritelleet funktion tuplaa, voimme kutsua sitä pääohjelmassa.
  • Lopuksi ohjelma tulostaa 24, eli 12 * 2
Esimerkki 2

Tarkastellaan toista esimerkkiohjelmaa, jossa määritellään funktio tiheys ja käytetään sitä:

# Määritellään ensin funktio tiheys käyttäen def-avainsanaa
def tiheys(tilavuus, massa):
    # Funktio palauttaa kappaleen tiheyden
    # Funktion parametrit:
    #   Tilavuus: Kappaleen tilavuus (m^3)
    #   Massa:    Kappaleen massa (kg)
    # Jos funktiota kutsutaan epäfysikaalisella parametrilla, se 
    # tulostaa virheilmoituksen ja palauttaa arvon -1
    
    # Tarkistetaan ensin, että parametrit ovat fysikaalisesti mielekkäät
    if tilavuus <= 0:
        print("Virheellinen tilavuus")
        return -1
    elif massa <= 0:
        print("Virheellinen massa")
        return -1
    else:
        return massa / tilavuus

# Pääohjelma alkaa tästä (ei sisennystä)
# Kysytään arvot käyttäjältä
V = float(input("Anna kappaleen tilavuus (m^3):\n"))
m = float(input("Anna kappaleen massa (kg):\n"))
# Kutsutaan tiheys-funktiota annetuilla arvoilla
rho = tiheys(V, m)
# Tarkistetaan funktion paluuarvo. -1 tarkoittaa virhettä
if rho == -1:
    print("Tiheyden laskeminen epäonnistui")
else:
    print("Kappaleen tiheys on:", round(rho,3), "kg/m^3")

  • Tässä esimerkissä funktion tiheys suorittama laskutoimitus oli hyvin yksinkertainen.
  • Oikeissa ohjelmissa funktio voi suorittaa hyvinkin monimutkaisia operaatioita. Nämä monimutkaiset operaatiot kannattaa nimenomaan "paketoida" funktioihin
  • Koodin testaaminen ja virheiden etsiminen on helpompaa, kun se on jaettu funktioihin
  • Hyvin kirjoitetut ja dokumentoidut funktiot ovat helposti uudelleenkäytettävissä uusissa ohjelmissa

Esimerkki 3

Tässä tapauksessa meillä on funktio kysy_suure, joka hoitaa vuorovaikutuksen käyttäjän kanssa:

# Ensin määritellään funktio. Sitä kutsutaan pääohjelmasta.
def kysy_suure(suure):
    # Funktio kysyy liukulukua käyttäjältä, kunnes annettu arvo on > 0
    # Parametri suure on merkkijono, esim. "massa (g)"
    arvo = -1
    while arvo <= 0: 
        arvo = float(input("Anna " + suure + ":\n"))
        if arvo > 0:
            return arvo
        else:
            print("Virheellinen arvo")
        
# Pääohjelma alkaa täältä
# Kysytään massa ja moolimassa funktion kysy_suure avulla
moolimassa = kysy_suure("moolimassa (g/mol)")
massa = kysy_suure("massa (g)")
n = massa / moolimassa
print("Ainemäärä on", round(n,2), "mol")

Etuna on se, että virheellisten arvojen käsittely while-silmukan avulla tarvitsee kirjoittaa vain kerran. Jos emme käyttäisi funktiota, ratkaisu voisi näyttää tältä:

# Luetaan moolimassa
arvo = -1
while arvo <= 0: 
    arvo = float(input("Anna moolimassa (g/mol):\n"))
    if arvo > 0:
        moolimassa = arvo
    else:
        print("Virheellinen arvo")
  
# Luetaan massa
arvo = -1
while arvo <= 0: 
    arvo = float(input("Anna massa (g):\n"))
    if arvo > 0:
        massa = arvo
    else:
        print("Virheellinen arvo")
        
n = massa / moolimassa
print("Ainemäärä on", round(n,2), "mol")

  • Jälkimmäinen ratkaisu ei ole kovin paljon ensimmäistä pidempi, mutta kuvittele tilanne, jossa suureita pitäisi lukea kymmenen kappaletta. Tällöin funktion kysy_suure käyttäminen helpottaa koodin kirjoittamista merkittävästi. 
  • Jos koodiin täytyisi tehdä joku muutos, esimerkiksi vaihtaa virheilmoitus "Virheellinen arvo" joksikin muuksi, ensimmäisessä kysy_suure-funktiota käytettäessä riittää funktion kysy_suure päivittäminen, eikä muutosta tarvitse tehdä moneen paikkaan.

Tehtävä 2.1.1

Tehtävä 2.1.2