Luku 3.3: Kokemuksia ja totuusarvoja
Kertausta: GoodStuff
Luvussa 2.1 tutustuit esimerkkiin siitä, miten GoodStuff-ohjelman luokat toimivat yhteen. Se kannattaa nyt kerrata. Tässä uusinta:
GoodStuff-ohjelman osat
Tässä luvussa alamme tutkia GoodStuff-sovelluksen Scala-ohjelmakoodia. Se koostuu seuraavista osista.
Pakkaus o1.goodstuff
:
Experience
-luokka kuvaa kokemuksista tehtyjä muistikirjamerkintöjä; yksi luokan ilmentymä on yksi merkintä. Tätä luokkaa tutkitaan tässä luvussa ja vähän seuraavassakin.Category
-luokan avulla voidaan koota useita kokemusolioita yhteen kokemuskategoriaan. Kullakin kategorialla on nimi ja hinnoitteluyksikkö (esim. hotelliyö). Kategoriaan myös liittyy tieto siitä, mikä kyseisen kategorian kokemuksista on käyttäjän suosikki. Tähän luokkaan tutustumme luvussa 4.2.
Pakkaus o1.goodstuff.gui
:
CategoryDisplayWindow
on luokka, joka kuvaa eräänlaisia käyttöliittymäikkunoita. Annetussa muodossaan GoodStuff-sovelluksessa on tasan yksi tällainen ikkuna hotellikategorialle, mutta periaatteessa niitä voisi olla useitakin. Ikkuna on toteutettu Swing-kirjastolla, josta kerrotaan luvussa 12.4.GoodStuff
on yksittäisolio, jolla on erikoistehtävä: se toimii sovelluksen käynnistysoliona (luku 2.7). Kyseessähän on tiedostoGoodStuff.scala
, josta käsin olet käynnistänyt sovelluksen IntelliJ’ssä.
Tässä luvussa siis keskitymme luokkaan Experience
. Samalla osoittautuu oitis, että on
syytä tutustua erääseen uuteen Scalan perustietotyyppiin ja siihen liittyviin yleisempiin
ohjelmoinnin käsitteisiin.
Lue dokumentaatiota!
Etsi nyt käsiisi Experience
-luokan Scaladoc-dokumentaatio
GoodStuff-moduulista IntelliJ’ssä tai tämän sivun alun
moduulilinkistä. Lue se. Jatka vasta, kun olet lukenut sen.
Muiden samaan moduuliin kuuluvien luokkien dokumentaatiota ei ole tarpeen nyt lukea.
Experience
-kokeilu
Kokeillaan Experience
-luokan käyttöä REPLissä. Experience
-oliolle annetaan luotaessa
luontiparametreiksi nimi, kuvaus, hinta ja arvosana. Annetussa sovelluksessa
merkinnät koskivat hotellikokemuksia, mutta se ei ole oleellista. Tehdään nyt vaihtelun
vuoksi vaikkapa viinikokemuksia kuvaavia olioita:
val wine1 = Experience("Il Barco 2001", "ookoo", 6.69, 5)wine1: Experience = o1.goodstuff.Experience@a62427
Experience
-luokkaa voi käyttää sen Scaladoc-dokumentaatiossa kuvatulla tavalla. Tässä
pari esimerkkiä:
wine1.nameres0: String = Il Barco 2001 wine1.valueForMoneyres1: Double = 0.7473841554559043
Jotta GoodStuff-ohjelma voisi pitää kirjaa tietyn kategorian suosikista, sen täytyy
pystyä vertailemaan kokemusmerkintöjä niiden arvosanojen perusteella. Experience
-luokkaan
on määritelty kaksikin tähän liittyvää metodia: isBetterThan
ja chooseBetter
. Näistä
ensimmäisen ymmärtäminen edesauttaa jälkimmäisen ymmärtämistä; siksi aloitamme siitä.
Kokeillaan nyt isBetterThan
-metodia ja pureudutaan chooseBetter
-metodiin seuraavassa
luvussa.
val wine2 = Experience("Tollo Rosso", "turhahko", 6.19, 3)wine2: Experience = o1.goodstuff.Experience@140b3c7 wine2.isBetterThan(wine1)res2: Boolean = false
Metodi vertailee toisiinsa sitä kokemusta, jolle metodia on kutsuttu, ja sitä, joka on annettu parametriksi. Se palauttaa arvon, joka kertoo, onko ensin mainitun olion arvosana parametriolion arvosanaa korkeampi.
Paluuarvo ei kuitenkaan näytä ihan tutulta. Mikä on arvo
false
ja mikä on Boolean
-tietotyyppi, jota se edustaa?
Totuusarvot ja Boolean
Kaksijakoiset tilanteet ovat ohjelmissa erittäin yleisiä: Onko tämä luku suurempi kuin tuo? Onko kirjanpito-ohjelmaan jo kirjattu tietyn henkilön asiakastiedot? Onko käyttäjä laittanut rastin tiettyyn ruutuun? Valitsiko pelaaja mustat vai valkoiset nappulat? Oliko Shift-näppäin pohjassa, kun hiirellä klikattiin? Onko ötökkä törmännyt esteeseen?
On siis tarve totuusarvoille, tarkemmin sanoen Boolen logiikalle (Boolean logic). Boolen logiikassa käytetään tasan kahta totuusarvoa, tosi ja epätosi.
Boolean
-tyypistä
"Totta" ja "tarua" vastaavat Scalassa true
ja false
. Nämä sana ovat ovat Scalan
varattuja sanoja, eli niitä ei voi käyttää esimerkiksi muuttujien niminä.
Scalassa totuusarvoja kuvaa tietotyyppi Boolean
, joka on määritelty pakkauksessa
scala
ja on siis aina käytettävissä Scala-ohjelmissa Int
- ja String
-tyyppien
tapaan. true
ja false
ovat Boolean
-tyyppisiä literaaleja eli koodiin
sellaisenaan kirjoitettuja arvoja samaan tapaan kuin vaikkapa 123
ja -1
ovat
Int
-tyyppisiä literaaleja.
val paaviOnKatolilainen = truepaaviOnKatolilainen: Boolean = true val maapalloOnLittea = falsemaapalloOnLittea: Boolean = false
Mitään muita Boolean
-arvoja true
n ja false
n lisäksi ei ole olemassa. (Vertaa:
erilaisia merkkijonoja ja lukuja on vaikka kuinka paljon.) Boolen logiikassa asiat
ovat puhtaasti joko totta tai epätotta; ne eivät voi olla "pääosin totta" tai
"luultavasti tarua" tai muuta vastaavaa.
Pelkkä yksittäinen totuusarvoliteraalikin on lauseke, jonka arvo on kyseinen totuusarvo itse:
falseres3: Boolean = false
Tarvitaanko erillinen Boolean
?
Voisiko isBetterThan
-metodi palauttaa merkkijonon "yes"
tai
"no"
Boolean
-arvon sijaan? Tai jonkin luvun: sovitaan vaikkapa,
että nolla tarkoittaa epätotta ja kaikki muut luvut totta?
Periaatteessa kyllä, ja käytännössäkin jälkimmäistä ehdotusta sovelletaan joissakin ohjelmointikielissä. Kuitenkin Scalassa ja monessa muussa ohjelmointikielessä on erillinen tietotyyppi totuusarvojen kuvaamiseen. Erillisen tietotyypin käyttäminen usein selkeyttää ohjelmakoodia ja mahdollistaa myös paremmat automaattiset virhetarkastukset ja -ilmoitukset. Näin voidaan esimerkiksi varmistaa, että totuusarvomuuttujaan ei vahingossakaan sijoiteta muuta kuin juuri totuusarvo.
Totuusarvojen käyttöä
Voit käyttää totuusarvoja tuttuun tapaan esimerkiksi muuttujiin sijoituksissa, parametrilausekkeissa ja metodien paluuarvoina:
println("Totuus on " + paaviOnKatolilainen)Totuus on true val oliParempi = wine2.isBetterThan(wine1)oliParempi: Boolean = false val viiniOnParempiKuinSeItse = wine2.isBetterThan(wine2)viiniOnParempiKuinSeItse: Boolean = false
Lukuihin ja merkkijonoihin liittyy operaattoreita kuten +
. Niin totuusarvoihinkin.
Yksi totuusarvo-operaattoreista on !
. Tämä huutomerkkioperaattori luetaan "ei" tai
englantilaisittain "not". Se "kääntää" totuusarvon, joka sen perään kirjoitetaan, eli
false
sta tulee true
ja toisin päin. Esimerkiksi:
!oliParempires4: Boolean = true
Tässä siis lausekkeen !oliParempi
arvo on true
. Muuttujan oliParempi
arvoon
tämän lausekkeen evaluoiminen ei vaikuta yhtään mitenkään, vaan muuttujassa on edelleen
false
.
Sen lisäksi, että voidaan käyttää literaaleja, totuusarvoja syntyy myös arvoja vertailemalla:
Vertailuoperaattorit
Scalan vertailuoperaattoreilla voi muodostaa lausekkeita, joissa vertaillaan osalausekkeiden arvoja.
Operaattori |
Merkitys |
---|---|
|
suurempi kuin |
|
pienempi kuin |
|
suurempi tai yhtä suuri kuin |
|
pienempi tai yhtä suuri kuin |
|
yhtä suuri kuin |
|
erisuuri kuin |
Huomaa, että vertailuoperaattorit kirjoitetaan <=
ja >=
. Niitä ei kirjoiteta =<
tai =>
(joista jälkimmäisellä on Scalassa ihan muu merkitys; siitä lisää myöhemmin).
Muistisääntö: kirjoita samassa järjestyksessä kuin luetkin: pienempi (<
) tai yhtä suuri
(=
) kuin.
Lukujen vertailua
Vertaileminen tuottaa Boolean
-arvoja:
10 <= 10res5: Boolean = true 20 < (10 + 10)res6: Boolean = false val ikavuodet = 20ikavuodet: Int = 20 val onAikuinen = ikavuodet >= 18onAikuinen: Boolean = true ikavuodet == 30res7: Boolean = false 20 != ikavuodetres8: Boolean = false
Vertailtaviksi voi kirjoittaa mitä vain tietotyypiltään sopivia lausekkeita. Ne evaluoidaan ja niiden arvoja verrataan toisiinsa.
Yhtäsuuruutta vertaillessa on aina käytettävä kahta yhtäsuuruusmerkkiä. Tämä unohtuu aluksi helposti. Yksi yhtäsuuruusmerkkihän on käytössä ihan muissa yhteyksissä, kuten muuttujaan sijoittamisessa ja metodin määrittelyn alussa.
Alla on totuusarvoja sisältävä animaatio. Osaatko jo animaatiota katsomatta päätellä pelkästä koodista, mitä se tulostaa?
Erilaisia vertailuja
Kokeile tässä välissä REPLissä totuusarvoja ja vertailuoperaattoreita.
Kokeile operaattoreita myös muilla arvoilla kuin luvuilla. Merkkijonoja voi vertailla
samaan tapaan kuin lukuja, ja Boolean
-arvoja voi myös vertailla keskenään.
Jatka eteenpäin seuraaviin harjoituksiin, kun olet kokeillut vertailuoperaattoreiden käyttöä REPLissä.
Vertailuharjoituksia
Tarvitsemme totuusarvoja ja vertailuoperaattoreita jatkossa vähän väliä. Olisi hyvä, jos ne tulisivat mahdollisimman pian sujuvasti selkärangasta, jotta et joudu niitä liikaa miettimään monimutkaisempaa kokonaisuutta laatiessa tai lukiessa. Niinpä alla on koko joukko pieniä totuusarvoharjoitteita. Kokeile/päättele ja kirjoita vastaukset. Älä tässäkään tyydy vain arvaamaan tai kopioimaan REPListä, vaan mieti myös miksi ja koettele päätelmiäsi REPLissä.
Minitehtävä: pystykuva
Kuvia jaotellaan joskus pysty- ja vaakakuviin (portrait vs. landscape). Pystykuvan korkeus on suurempi kuin sen leveys ja vaakakuvalla vastaavasti toisin päin.
Nouda Miscellaneous-moduuli. Älä välitä nyt sen muusta sisällöstä;
paikanna vain tiedosto misc.scala
. Kirjoita tuohon tiedostoon
vaikutukseton funktio isPortrait
, joka
ottaa yhden
Pic
-tyyppisen parametrinpalauttaa
true
, jos annetun kuvan korkeus on leveyttä suurempipalauttaa
false
muutoin (eli jos kuva on neliön muotoinen tai vaakakuva).
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Olioiden yhtäsuuruudesta
Olioita voi vertailla toisiinsa operaattoreilla ==
ja !=
. Mutta mitä yhtäsuuruus
tarkoittaa vaikkapa kokemusolioiden tapauksessa?
Tutki asiaa itse REPLissä vastatessasi seuraavaan tehtävään. (Käynnistä REPL GoodStuff-moduuliin.)
Huomaat: pelkästään se, että kahden olion ominaisuudet ovat samanarvoiset, ei riitä tekemään kahdesta oliosta "yhtäsuuria".
Esimerkit ==
-operaattorista yllä vertailivat pelkästään muuttujien sisältöä eli niitä
viittauksia, jotka muuttujiin on tallennettu. Ne eivät verranneet varsinaisia olioita
lainkaan. Esimerkiksi wine1 == wine4
on false
, koska kyseessä ei ole kaksi viittausta
samaan olioon vaan kaksi viittausta kahteen samanlaiseen mutta erilliseen olioon.
wine1 == wine3
taas on true
, koska molempien muuttujien arvona on viittaus täsmälleen
samaan olioon; viittaukset vievät samaan paikkaan.
Yleisesti ottaen se, miten yhtäsuuruusvertailu olioille toimii, riippuu olioiden tyypistä. Itse määritetyille tietotyypeille se on oletusarvoisesti ns. identiteettivertailu eli toimii kuin kokemusolioille yllä. Toisaalta monilla Scalan valmiilla tietotyypeillä on tietotyyppikohtaiset määritelmät yhtäsuuruudelle. Hyvä esimerkki tästä ovat puskurit: on määritelty, että kaksi kokonaan erillistäkin puskuria ovat yhtäsuuret, jos niillä on sama sisältö. Tämä käy ilmi seuraavasta REPL-esimerkistä:
val erasPuskuri = Buffer(2, 10, 5, 4)erasPuskuri: Buffer[Int] = ArrayBuffer(2, 10, 5, 4) val toinenPuskuri = Buffer(2, 10, 5)toinenPuskuri: Buffer[Int] = ArrayBuffer(2, 10, 5) erasPuskuri == toinenPuskurires9: Boolean = false toinenPuskuri += 4res10: Buffer[Int] = ArrayBuffer(2, 10, 5, 4) erasPuskuri == toinenPuskurires11: Boolean = true
Experience
-luokan toteutus
Vertailuoperaattorein varustettuina voimme nyt laatia Experience
-luokalle ohjelmakoodin.
Aloitetaan hahmottelemalla toteutus pseudokoodina:
class Experience(vaadi luontiparametreiksi nimi, kuvaus, hinta ja arvosana, jotka
kaikki tallennetaan sellaisenaan kiintoarvoisiin ilmentymämuuttujiin):
def valueForMoney = palauta arvosanasi ja hintasi osamäärä
def isBetterThan(another: Experience) = palauta totuusarvo, joka kertoo,
onko oma arvosanasi korkeampi kuin
parametriksi annetun kokemusolion arvosana
end Experience
Vertailumetodimme saa parametriksi viittauksen vertailukohtana
olevaan Experience
-olioon. Parametrimuuttujan nimi voi olla
esimerkiksi another
. Ajatus on tältä osin samankaltainen kuin
Pos
-luokan xDiff
- ja yDiff
-metodeissa (luku 2.5), joissa
myös käsiteltiin this
-oliota ja parametrina osoittamaa toista
saman luokan ilmentymää.
Tässä Scala-toteutus:
class Experience(val name: String, val description: String, val price: Double, val rating: Int):
def valueForMoney = this.rating / this.price
def isBetterThan(another: Experience) = this.rating > another.rating
end Experience
Mitään muuta uutta tässä esimerkissä ei ole, kuin että metodin
paluuarvo tuotetaan vertailuoperaattorilla ja on siis Boolean
-tyyppinen.
Pikkutehtävä: totuusarvoinen ilmentymämuuttuja
Valmisteleva kertaus
Palautetaan mieleen Asiakas
- ja Tilaus
-luokat:
val testihenkilo = Asiakas("T. Testaaja", 12345, "test@test.fi", "Testitie 1, 00100 Testaamo")testihenkilo: Asiakas = o1.luokkia.Asiakas@a7de1d val testitilaus = Tilaus(10001, testihenkilo)testitilaus: Tilaus = o1.luokkia.Tilaus@18c6974
Tehtävänanto
Boolean
-arvot sopivat myös olion ominaisuuksien kuvaamiseen. Esimerkiksi kustakin
tilauksesta voitaisiin kirjata, onko se kallis mutta nopea pikatilaus vai ei. Tilauksilla
voisi tällöin olla onPika
-niminen ilmentymämuuttuja:
testitilaus.onPikares12: Boolean = false testitilaus.onPika = true
Lisää Oliointro-moduulin Tilaus
-luokkaan tällainen ilmentymämuuttuja. Sen
arvon tulee siis olla aluksi false
, mutta arvoa voi muuttaa sijoituskäskyllä kuten yllä.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Odds-tehtävä (osa 6/9)
Hyödynnetään Boolean
-tietotyyppiä kehittäessämme viimeksi luvussa 2.7 käsiteltyä
Odds-ohjelmaa taas vähän eteenpäin.
(Jos et tehnyt tuohon moduuliin liittyviä tehtäviä viime kierroksella, käy aiemmat vaiheet nyt läpi; voit käyttää tälle tehtävälle pohjana niiden esimerkkiratkaisuja, jotka löytyvät linkeistä tehtävien kohdalta määräajan jälkeen.)
Tehtävänanto
Laadi metodi isLikely
, jolla voi selvittää, onko Odds
-olion kuvaama tapahtuma
todennäköinen vai ei. Tapahtuma katsotaan tässä todennäköiseksi, jos Odds
-olio kuvaa
sen toteutumisen olevan todennäköisempää kuin sen toteutumatta jäämisen. Esimerkiksi
kuutosen heittäminen nopalla ei ole todennäköistä, mutta "minkä vaan muun kuin kuutosen"
heittäminen on:
val rollingSix = Odds(5, 1)rollingSix: Odds = o1.odds.Odds@d4c0c4 val notRollingSix = Odds(1, 5)notRollingSix: Odds = o1.odds.Odds@a5e42e rollingSix.isLikelyres13: Boolean = false notRollingSix.isLikelyres14: Boolean = true
Laadi myös metodi isLikelierThan
, jolla voi selvittää kahdesta tapahtumasta
todennäköisemmän:
rollingSix.isLikelierThan(notRollingSix)res15: Boolean = false notRollingSix.isLikelierThan(rollingSix)res16: Boolean = true rollingSix.isLikelierThan(rollingSix)res17: Boolean = false
Ohjeita ja vinkkejä
Lisää metodit tiedostoon
Odds.scala
.Voit käyttää käynnistysoliota
OddsTest2
metodiesi testaamiseen. Tuo pikkuohjelma on annettu valmiina, joskin sen sisältö on "kommentoitu ulos", jotta koodi ei tuottaisi virheilmoituksiaisLikely
- jaisLikelierThan
-metodien puuttumisesta ennen kuin olet ne toteuttanut. Poista kommenttimerkit testiohjelmasta, kun olet ensin kirjoittanut pyydetyt metoditOdds
-luokkaan, ja aja ohjelma.Kuten luvun 2.7 edellisessä Odds-tehtävässä, myös nyt on tarkoitus, että testiohjelma
OddsTest2
kutsuuOdds
-luokkaan kirjattuja metodeita. Älä nytkään kopioiOdds
-luokan määrittelyä tai sen osia testiohjelmaan.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
FlappyBug-tehtävä (osa 11/17: Game Over)
Olet varmasti jo huomannut, ettei ötökkäpelimme este estä mitään. Pannaan peli pysähtymään esteen koskettaessa ötökkää.
Pohjustus: näkymien isDone
-metodi
Luvussa 3.1 tutkimme esimerkkiohjelmaa, joka kasvatti klikatessa ruudulla näkyvää
ympyrää. Siinä oli tällainen View
-olio:
object klikkausnakyma extends View("Klikkauskokeilu"):
def makePic = sininenTausta.place(circle(klikkauslaskuri.arvo, White), Pos(100, 100))
override def onClick(klikkauskohta: Pos) =
klikkauslaskuri.etene()
println("Klikkaus koordinaateissa " + klikkauskohta + "; " + klikkauslaskuri)
end klikkausnakyma
View
-oliolle voi lisätä myös isDone
-metodin, joka säätelee sitä, milloin käyttöliittymä
lakkaa käsittelemästä klikkauksia, tikityksiä ja muita käyttöliittymätapahtumia:
object pysahtyvaKlikkausnakyma extends View("Klikkauskokeilu"):
def makePic = sininenTausta.place(circle(klikkauslaskuri.arvo, White), Pos(100, 100))
override def onClick(klikkauskohta: Pos) =
klikkauslaskuri.etene()
println("Klikkaus koordinaateissa " + klikkauskohta + "; " + klikkauslaskuri)
override def isDone = klikkauslaskuri.arvo > 10
end pysahtyvaKlikkausnakyma
isDone
palauttaa Boolean
-arvon, joka määrittää, onko
käyttöliittymä jo "valmis" eli voidaanko tapahtumankäsittely
jättää sikseen. Tässä esimerkissä klikkausten käsittely
lopetetaan, kun laskurin arvo on yli 10.
Toteutuksemme korvaa oletustoteutuksen, joka palauttaa aina
false
eikä siis pysäytä käyttöliittymää lainkaan. Siksi
tässäkin override
(luku 3.1).
View
-olio kutsuu itse omaa isDone
-metodiaan kunkin kellonlyömän tai muun tapahtuman
jälkeen tarkastaakseen, pitäisikö jo lopettaa. Tähän tarkastustiheyteen voi vaikuttaa
(vain) epäsuorasti tikitystahtia säätämällä (luku 3.1).
Tehtävänanto
Tee kolme asiaa:
Määrittele
Obstacle
-luokkaan metodi, jolla selvitetään, koskettaako este ötökkää.Määrittele
Game
-luokkaan äskeistä metodia käyttävä metodi, joka kertoo, onko peli päättynyt pelaajan tappioon esteeseen osumisen vuoksi.Määrittele FlappyBugin käyttöliittymään
isDone
-metodi, joka huolehtii siitä, että käyttöliittymä pysähtyy pelin päättyessä.
Tarkemmin sanoen:
Lisää
Obstacle
-luokkaan vaikutukseton metoditouches
, joka selvittää onko este parhaillaan ötökän kohdalla vai ei.Se ottaa ainoaksi parametrikseen viittauksen
Bug
-olioon.Se palauttaa
Boolean
-arvon.Se selvittää etäisyyden kyseisen esteen (
this
) ja parametrin osoittaman ötökän välillä ja muodostaa paluuarvonsa tämän etäisyyden perusteella. Paluuarvo ontrue
jos ja vain jos etäisyys on pienempi kuin ötökän ja esteen säteet (radius
) yhteensä; muuten se onfalse
.Etäisyys lasketaan suoraa viivaa pitkin ötökän ja esteen keskipisteiden välillä. Apuna voit käyttää
Pos
-luokandistance
-metodia (luku 2.5).
Lisää
Game
-luokkaan alla annettu metodiisLost
, joka määrittää, onko pelaaja hävinnyt pelin. Tämä metodi käyttää ensin laatimaasitouches
-metodia: peli on hävitty nimenomaan silloin, jos pelin (toistaiseksi ainoa) este koskettaa ötökkää.def isLost = this.obstacle.touches(this.bug)
Lisää FlappyBugin
View
-oliolleisDone
-metodi, joka palauttaatrue
pelaajan hävittyä pelin jafalse
muuten. Käytännössä siis peli pysähtyy ötökän osuessa esteeseen.Ota
isDone
-metodissa mallia yllä olevasta klikkausohjelmasta. Metodin rungoksi riittää yksinkertaisesti yksiisLost
-metodikutsu.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.
Opiskelijakysymys metodien vaikutuksellisuudesta (esim. isLost
)
Mietin isLost
-metodin osalta: miksi tämä ei
ole vaikutuksellinen? Pelihän loppuu, eikö se
ole ulkoinen vaikutus? Vai onko se vaikutukseton
siksi, koska se vain tarkistaa, osuuko ötökkä
esteeseen, ei sinänsä muuta mitään pelin tilaa?
Vaikutuksellisten ja vaikutuksettomien metodien
kanssa on vielä vähän hakemista, esimerkiksi
[View
-luokan] isDone
tuntuu kovin
vaikutukselliselta, mutta ei ilmeisesti ole.
Tosiaan molemmat mainitut metodit luetaan vaikutuksettomiksi. Se ei tarkoita, etteikö noilla metodeilla voisi olla merkitystä sen kannalta, miten jokin niitä kutsuva ohjelma käyttäytyy. Tuo merkitys vain on epäsuora ja toteutuu noiden metodien ulkopuolella.
Vaikutuksettomuus tarkoittaa, että noiden metodien kutsuminen itsessään ei tuota vaikutusta noiden metodien ulkopuolelta havaittavaan tilaan tai toimintaan. Ne eivät vaihda minkään muuttujan arvoa tai tulosta mitään. Niiden kutsuminen ei itsessään lopeta peliä tai päätä ohjelman suoritusta.
Pelin isLost
ainoastaan selvittää erään tiedon pelin tilasta
ja raportoi sen kutsujalleen Boolean
-arvona. Näkymän isDone
vastaavasti vain selvittää erään tiedon näkymän esittämästä
mallista (tässä sattumalta juuri isLost
-metodia apuna käyttäen).
Se on sitten eri asia, mitä View
noita metodeja käytettyään
ja paluuarvon saatuaan tekee. View
lopettaa tapahtumien
käsittelemisen yksityisellä metodillaan, joka on vaikutuksellinen.
Perusajatus on, että tuo vaikutuksellinen metodi kutsuu View
’n
omaa isDone
-metodia — ja jos isDone
palauttaa true
,
pysäytetään näkymä.
Yhteenvetoa
"Kyllä vai ei" -ilmiöitä kuvataan tietokoneohjelmissa usein Boolen logiikan arvoina "tosi" ja "epätosi", joille on monissa kielissä määritelty oma tietotyyppi.
Scalassa Boolen logiikan arvoja edustaa tietotyyppi
Boolean
. Tämäntyyppisiä arvoja on tasan kaksi:true
jafalse
. Niitä voi käyttää literaaleina Scala-ohjelmakoodissa.Totuusarvoja saadaan myös käyttämällä vertailuoperaattoreita, esimerkiksi vertailemalla, onko tietty lukuarvo pienempi kuin toinen vai ei.
Tapa, jolla arvojen yhtäsuuruus määritellään riippuu tietotyypistä. Kyseessä voi olla identiteettivertailu tai samanlaisuusvertailu jonkin ominaisuuden tai ominaisuuksien mukaan.
Lukuun liittyviä termejä sanastosivulla: totuusarvo; vertailuoperaattori.
Palaute
Huomaathan, että tämä on henkilökohtainen osio! Vaikka olisit tehnyt lukuun liittyvät tehtävät parin kanssa, täytä palautelomake itse.
Tekijät
Tämän oppimateriaalin kehitystyössä on käytetty apuna tuhansilta opiskelijoilta kerättyä palautetta. Kiitos!
Materiaalin luvut tehtävineen ja viikkokoosteineen on laatinut Juha Sorva.
Liitesivut (sanasto, Scala-kooste, usein kysytyt kysymykset jne.) on kirjoittanut Juha Sorva sikäli kuin sivulla ei ole toisin mainittu.
Tehtävien automaattisen arvioinnin ovat toteuttaneet: (aakkosjärjestyksessä) Riku Autio, Nikolas Drosdek, Kaisa Ek, Joonatan Honkamaa, Antti Immonen, Jaakko Kantojärvi, Onni Komulainen, Niklas Kröger, Kalle Laitinen, Teemu Lehtinen, Mikael Lenander, Ilona Ma, Jaakko Nakaza, Strasdosky Otewa, Timi Seppälä, Teemu Sirkiä, Joel Toppinen, Anna Valldeoriola Cardó ja Aleksi Vartiainen.
Lukujen alkuja koristavat kuvat ja muut vastaavat kuvituskuvat on piirtänyt Christina Lassheikki.
Yksityiskohtaiset animaatiot Scala-ohjelmien suorituksen vaiheista suunnittelivat Juha Sorva ja Teemu Sirkiä. Teemu Sirkiä ja Riku Autio toteuttivat ne apunaan Teemun aiemmin rakentamat työkalut Jsvee ja Kelmu.
Muut diagrammit ja materiaaliin upotetut vuorovaikutteiset esitykset laati Juha Sorva.
O1Library-ohjelmakirjaston ovat kehittäneet Aleksi Lukkarinen, Juha Sorva ja Jaakko Nakaza. Useat sen keskeisistä osista tukeutuvat Aleksin SMCL-kirjastoon.
Tapa, jolla käytämme O1Libraryn työkaluja (kuten Pic
) yksinkertaiseen graafiseen
ohjelmointiin, on saanut vaikutteita tekijöiden Flatt, Felleisen, Findler ja Krishnamurthi
oppikirjasta How to Design Programs sekä Stephen Blochin oppikirjasta Picturing Programs.
Oppimisalusta A+ luotiin alun perin Aallon LeTech-tutkimusryhmässä pitkälti opiskelijavoimin. Nykyään tätä avoimen lähdekoodin projektia kehittää Tietotekniikan laitoksen opetusteknologiatiimi ja tarjoaa palveluna laitoksen IT-tuki; sitä ovat kehittäneet kymmenet Aallon opiskelijat ja muut.
A+ Courses -lisäosa, joka tukee A+:aa ja O1-kurssia IntelliJ-ohjelmointiympäristössä, on toinen avoin projekti. Sen suunnitteluun ja toteutukseen on osallistunut useita opiskelijoita yhteistyössä O1-kurssin opettajien kanssa.
Kurssin tämänhetkinen henkilökunta löytyy luvusta 1.1.
Joidenkin lukujen lopuissa on lukukohtaisia lisäyksiä tähän tekijäluetteloon.
Kun kokemusolion
isBetterThan
-metodia kutsutaan, sille pitää antaa parametriksi viittaus johonkin kokemusolioon, johon "puhuteltavaa" oliota verrataan.