3. Funktion avulla yleistetään
sääntöjä
Tällä jaksolla opimme määrittelemään funktioita. Funktio on tapa
yleistää sääntöjä. Sen sijaan, että kirjoittaisimme
(/ (+ 1 2) 2)
(/ (+ 4 5) 2)
Kirjoitamme em. säännön yleisessä eli abstraktissa muodossa
muuttujien a ja b avulla:
(/ (+ a b) 2)
Lisäksi tarvitsemme rakenteen, jolla saamme nimen säännölle
(keskiarvo) sekä arvot muuttujille a ja b.
(define (keskiarvo a b)
(/ (+ a b) 2)
KOODIAAPINEN MOOC - SYKSY 2015
(keskiarvo 1 2)
(keskiarvo 4 5)
Funktion määrittely Funktion kutsuminen
6. Funktion käsite tulee
matematiikasta
KOODIAAPINEN MOOC - SYKSY 2015
MÄÄRITTELYJOUKKO ARVOJOUKKO
3 9
neliö-funktio
-3
Funktio toimii aina samalla tavalla samalle syötteelle.
neliö : Luku -> Luku
𝑓 𝑥 = 𝑥2
12. Esimerkki : risti-funktio
1) Funktion esittely:
;; risti : Luku Luku Väri -> Kuva
2) Funktion määrittely:
(define (risti a b väri)
(overlay (rectangle a b ”solid” väri)
(reactangle b a ”solid” väri)))
3) Funktion kutsuminen:
(risti 20 50 ”blue”)
12
13. Funktion kutsuminen
(toisen funktion sisältä = apufunktion kutsuminen)
13
(define (pallot r väri)
(beside (ympyrä r väri)
(ympyrä r väri)))
> (pallot 30 ”blue”)
argumentteina käytetään nyt
pallot-funktion parametreja r ja väri
(ympyrä on tässä apufunktio)
14. Funktion testaaminen
Koska funktio toimii aina samalla tavalla samalle syötteelle
(argumenttien arvoille), voidaan funktion koodin oikeellisuudesta
varmistua kirjoittamalla testikoodia (check-expect).
Check-expect vertaa funktiokutsun palauttamaa arvoa odotusarvoon:
14
(check-expect (risti 20 50 ”blue”)
)
(check-expect (risti 20 50 ”blue”)
(overlay (rectangle 20 50 ”solid” ”blue”)
(reactangle 20 20 ”solid” ”blue”)))
funktiokutsu
odotusarvo = se mitä pitäisi
tulla paluuarvona, jos
funktio toimii oikein
TAI
15. Funktio, joka palauttaa luvun
15
ARGUMENTIT
400
PALUUARVO
25
10 000
x
y
MUUTTUJAT
(PARAMETRIT)
𝑎 ∙ 𝑏
16. Esimerkki: pinta-ala-funktio
1) Funktion esittely:
;; pinta-ala : Luku Luku -> Luku
2) Funktion määrittely:
(define (pinta-ala a b)
(* a b))
3) Funktion kutsuminen (testaaminen käsin):
> (pinta-ala 400 25)
4) Funktion testaaminen (automaattisesti):
(check-expect (pinta-ala 400 25)
10000)
16
funktiokutsu
odotusarvo
17. Kirjoita oma funktio
0. tarkoitus: kirjoita lyhyt kuvaus siitä mitä funktiosi tekee
(vaihtoehtoisesti selitä tämä kaverillesi sanallisesti.) Pääasia, että
ymmärrät mitä olet tekemässä.
1. esittely: keksi funktiollesi nimi, listaa tarvittavien muuttujien
tietotyypit ja päätä mitä tietotyyppiä funktiosi palauttaa.
2. määrittely: keksi muuttujille (parametreille) nimet, kirjoita
funktion koodi parametrien avulla.
3. testaus:
◦ kutsu funktiotasi interaktioikkunasta eri argumenttien arvoilla
TAI
◦ kirjoita testit check-expect:in avulla ja aja koodi
17
kommenttejaajettavaakoodia
18. Funktion suunnittelu -
apufunktiot
Funktion koodaaminen suoraan, ilman suunnittelua, on vaikeaa. Ongelmaa
kannattaakin lähestyä funktion suunnitteluportaat – menetelmän mukaisesti
askel askeleelta. Menetelmässä oleellista on miettiä ensin miten funktion
tulisi toimia. Tämä tehdään kirjoittamalla testit ennen varsinaista funktion
määrittelemistä. Tämä auttaa ymmärtämään miten funkion tulisi toimia ja
sen jälkeen on helpompaa kirjoittaa myös itse funktio.
Toinen funktion suunnittelussa huomioitava asia on toiminnallisuuden
jakaminen pienemmiksi paloiksi eli apufunktioiksi.
Jokaisen funktion pitäisi tehdä vain yksi asia.
Yhdistelemällä funktioita saadaan aikaan monimutkaisempia funktioita.
18
Funktio
Apufunktio 1
Apufunktio 2
19. Funktion suunnitteluportaat
0) Selvitä itsellesi mitä funktiosi tekee: kirjoita tarkoitus kommenttiriville.
1) Keksi funktiollesi kuvaava nimi, listaa millaista muuttuvaa tietoa se
käsittelee ja millaista tietoa se tuottaa: kirjoita esittely kommenttiriville.
2) Kirjoita funktiollesi runko (stub): keksi muuttujille
(parametreille) kuvaavat nimet ja aseta paluuarvoksi ”jotain”.
3) Kirjoita funktion käytölle esimerkit/testit (check-
expect), käyttämällä konkreettisia arvoja. Testaa.
4) Kirjoita funktion toteutus. Testaa.
20. Suunnittele oma funktio
0. tarkoitus: kirjoita lyhyt kuvaus siitä mitä funktiosi tekee (vaihtoehtoisesti
selitä tämä kaverillesi sanallisesti.) Pääasia, että ymmärrät mitä olet
tekemässä.
1. esittely: keksi funktiolle nimi, listaa tarvittavien muuttujien tietotyypit ja
päätä mitä tietotyyppiä funktiosi palauttaa
2. runko (stub): keksi muuttujille nimet, ja kirjoita ”tyhmä funktio” eli stub,
joka ei vielä tee mitään järkevää mutta joka ottaa vastaan argumentteja ja
palauttaa oikeaa tyyppiä olevan ”tyhmän” vastauksen esim. 0 (luku) tai
empty-image (kuva).
3. esimerkit: kirjoita esimerkkejä miten funktiotasi voisi kutsua, ja mitä se
tulee palauttamaan (check-expect). Testaa testit painamalla ”run”. Jos testit
toimivat ne ilmoittavat, että funktiossa on vikaa, ja juuri näin pitäisikin
käydä, koska käytössä on vasta tyhmä ”stub”.
4. toteutus: kirjoita nyt funktiosi toteutus eli korvaa ”tyhmä” paluuarvo
järkevällä koodilla, käytä apunasi esimerkkejä. Usein esimerkin koodin voi
kopioida suoraan funktion toteutukseksi sijoittamalla muuttujien
(parametrien) nimet oikeille kohdille. Testaa funktiosi painamalla ”run” ->
testien pitäisi mennä läpi, jos funktio on koodattu oikein.
20
kommenttejaajettavaakoodia
21. Tee funktio, joka laskee jonkin
kappaleen pinta-alan tai tilavuuden
1) Päätä nimi, sekä muuttujien määrät ja tyypit sekä paluuarvon tyypit
2) Päätä muuttujien nimet, kirjoita funktion runko (stub).
3) Kirjoita esimerkit (=testit), siitä miten funktio tulee toimimaan (testaa
esimerkit ajamalla ”run”)
4) Kirjoita funktion koodi
5) Paina ”run”
6) Kokeile vielä interaktioikkunassa toimiiko
Vihje: Jos tarvitset laskussasi π:tä, se on Racket:issä pi. Katso myös
seuraavat diat!
21
23. Esimerkki: ympyrälieriön-
tilavuus-funktio
1) Päätetään funktion nimi : sen parametrien tyypit -> paluuarvon tyyppi
;; ympyrälieriön-tilavuus : Luku Luku -> Luku
2) Annetaan funktiolle ja sen parametreille nimet (stub):
(define (ympyrälieriön-tilavuus h r)
0) ; stub
3) Selvitetään esimerkkien (testien) avulla miten se toimii:
(check-within (ympyrälieriön-tilavuus 400 25)
(* 400 (* pi (sqr 25)))
0.001)
(check-within (ympyrälieriön-tilavuus 100 50)
(* 100 (* pi (sqr 50)))
0.001)
4) Kirjoitetaan funktio loppuun (jatketaan stubia):
(define (ympyrälieriön-tilavuus h r)
(* h (* pi (sqr r))))
23
Huom! Check-expect
ei toimi tässä, koska
π:n arvo on likiarvo.
Likiarvoja sisältäviä
tuloksia pitää testata
käyttämällä check-
within – funktiota,
jolle annetaan
tarkkuus kolmantena
argumenttina.