Aiheita: luokkamäärittelyä, for, try-catch, match, lohkoja, ..., funktioita, sulkeumia, ...
Jos käytät Scalan rakenteita, joita ei ole vielä luennoilla käsitelty, kommentoi ohjelmasi kunnolla! Varaudu myös selittämään, miten olet ohjelmoinut ja mitä ohjelmatekstisi tarkoittaa!
MinSek-arvoja (olioita) konstruoidaan antamalla minuutit ja sekunnit, pelkät sekunnit tai ei mitään alkuarvoa. Minuutit ja sekunnit saavat olla mitä tahansa kokonaislukuja, myös negatiivisia. Jos alkuarvoa ei anneta, syntyvä aika on 0:00.
Esimerkki:
// konstruointi ja negatiiviset parametrit var a = new MinSek(2,11) println(a) // 2:11 a = new MinSek(2,-11) println(a) // 1:49 a = new MinSek(-2,11) println(a) // -1:49 a = new MinSek(-2,-11) println(a) // -2:11 a = new MinSek(66) println(a) // 1:06 Huom: sekunnit siis aina 2 numerolla! a = new MinSek println(a) // 0:00 println(new MinSek(-21)) // -0:21 a = new MinSek(1,601) println(a) // 11:01 // infix operaatiot + ja - kahdelle MinSek-arvolle val b = new MinSek(2,45) val c = new MinSek(49) println(b + " ja " + c) // 2:45 ja 0:49 a = b + c println(a) // 3:34 println(b - c) // 1:56 println(c - b) // -1:56 println(b - c + a) // 5:30 println(b - a) // -0:49 // infix-operaatiot * ja / MinSek-arvolle ja kokonaisluvulle a = new MinSek(2,11) println(a) // 2:11 println(a * 2) // 4:22 println(a / 2) // 1:05 println(a * -2) // -4:22 println(a / -2) // -1:05 // prefix-operaatio - vastaluvun laskentaan println(-a) // -2:11 println(-(-a)) // 2:11
Esimerkki:
// kasvattava ja vähentävä sijoitusoperatio kahdelle MinSek-arvolle val d = new MinSek(3, 14) val e = new MinSek(-3, -10) println(d + " ja " + e) // 3:14 ja -3:10 d += e println(d) // 0:04 d -= e println(d) // 3:14 // kasvattava ja vähentävä sijoitusoperatio MinSek-arvolle ja kokonaisluvulle val f = new MinSek(3, 14) println(f) // 3:14 f += 61 println(f) // 4:15 f -= 6000 println(f) // -95:45 // kertova ja jakava sijoitusoperaatio MinSek-arvolle ja kokonaisluvulle val g = new MinSek(3, 14) println(g) // 3:14 g *= 2 println(g) // 6:28 g /= 3 println(g) // 2:09 // onko seuraava vaarallista? val h = new MinSek val i = h println(h + " ja " + i) // 0:00 ja 0:00 h += 666 println(h + " ja " + i) // 11:06 ja 11:06
Tee komentotulkista vikasietoinen eli varaudu virhetilanteisiin mahdollisimman kattavasti. Anna myös selkeät virheilmoitukset. Ellet muista, mikä on komentotulkki, katso peruskurssien ikivanhan materiaalin lukua 6.
object Sisakkain extends App { val a=1; val b=2; val c=3 def f = { val b=20; val c=30 def ff = { val c=300 println(a+"/"+b+"/"+c) } println(a+"/"+b+"/"+c) ff } def g = { def gg = { f 60 } val a=40; val b=gg; println(a+"/"+b+"/"+c) f } println(a+"/"+b+"/"+c) f; { val a=1000 g println(a+"/"+b+"/"+c) } }On helppoa suorittaa ohjelma ja havaita, että se tulostaa:
1/2/3 1/20/30 1/20/300 1/20/30 1/20/300 40/60/3 1/20/30 1/20/300 1000/2/3Mutta miksi? Selitä jokaisen println-operaation ohjelmakohdan "nimiavaruus", so. mitä kukin tunnus tarkoittaa missäkin. Selitä ohjelman määrittelyrakenne: miten ohjelman osat sisältävät toisiaan. Selitä myös ohjelman kutsurakenne: millä tavoin ohjelman osat kutsuvat toisiaan.
object Kirjasto { def summa(termi: (Int) => Double, lkm: Int) = { var s=0.0 for (i <- 1 to lkm) s += termi(i) s } }Eräs sovellus käyttää kirjaston työkalua:
object Sovellus extends App { def harm(i: Int) = 1.0/i println( Kirjasto.summa(harm, 4) ) def geom(i: Int) = 1.0/(i*i) println( Kirjasto.summa(geom, 4) ) println( Kirjasto.summa(_ +0.5, 4) ) var laskuri=0.0 def mitaMita(i: Int) = {laskuri+=1; laskuri} println( Kirjasto.summa(mitaMita, 4) ) var ed=1; var seur=1; var alussa=1 def f(i: Int) = if (alussa<3) {alussa+=1; 1} else {val uus=ed+seur; ed=seur; seur=uus; uus} println( Kirjasto.summa(f, 4) ) }On helppoa suorittaa sovellus ja todeta sen tulostavan:
2.083333333333333 1.4236111111111112 12.0 10.0 7.0Mutta miksi se näin tulostaa? Näytä miten muuttujien ja parametrien arvot muuttuvat ohjelman suorituksen aikana.