Ohpe-kokeen 1. tehtävän arvosteluperusteet, tarkastuskertomus ja esimerkki From: A Jaakko J Nurro 2.12. 15:35:40 ------------------------------------------------------------------------- Tehtävä on arvosteltu varsin ankarasti, koska olisi mukava että ohjelmointikurssista läpi päässeet osaisivat nyt edes joten kuten ohjelmoida tällaisenkin luokan.'Oikein' tarkoittaa tässä sitä, että yksityiskohta olisi mennyt javana kääntäjästä läpi ja/tai ajettuna toimii tehtävänannon vaatiman mukaisesti. Pisteytysperusteet: Pisteitä oli siis jaossa 16. Alla on erittely mistä asioista sai pisteitä, jos ne olivat oikein. Luokalla luokan rakenne 1p esim. kentät ovat private, metodit public tästä ei tullut pisteitä jos oli mitään poikkeamia, tai javan syntaksia luokalle ei ollut osattu. Konstruktori alustaa kentät oikein 2p Tyypillinen virhe oli, ettei käsitellyt negatiivisia parametreja tehtävänannon vaatimalla tavalla. Silloin ei saanut pisteitä. Toinen yleinen virhe oli, ettei määritellyt oikeassa paikassa, metodien ulkopuolella, olion muuttujia, joita käsitteli täällä. Silloin ei saanut pisteitä myöskään aksessoreista, jotka käsittelivät määrittelemättömiä muuttujia. Aksessori käyttötankissaOn() palauttaa oikean arvon 1p Aksessori varmuustankissaOn() palauttaa oikean arvon 1p Aksessori onKäyttölupa() palauttaa oikean arvon 1p Metodi asetaKäyttölupa() asettaa arvon oikein 1p Aksessorit osattiin yleensä hyvin, tosin jotkut eivät osanneet määritellä olion kenttiä, jolloin näistäkään ei saanut pisteitä, varsinkaan kun joillakin ilmeisesti samaksi tarkoitetun muuttujan nimi ja semantiikka vaihtelivat metodista toiseen. Metodi lisääÖljyä() lisää öljyä oikein negatiivinen parametri tulkitaan nollaksi 1p varmuustankkiin tulee öljyä oikein 1p käyttötankkiin tulee öljyä oikein 1p metodi palauttaa oikean arvon 1p Metodi otaÖljyä() ottaa öljyä oikein negatiivinen parametri tulkitaan nollaksi 1p käyttötankista otetaan öljyä oikein 1p varmuustankista otetaan öljyä oikein 1p metodi palauttaa oikean arvon 1p Metodi toString() palauttaa selkeän merkkijonoesityksen öljyvaraston tilasta 1p Tilalla tässä tapauksessa tarkoitettiin kenttien arvoja. Jos yksikin puuttui, tästä ei saanut pisteitä. Huom! Jos metodin suoritus kohtaa returnin, ja se suoritetaan, metodin suoritus päättyy eikä returnin jälkeisiä rivejä suoriteta sillä kertaa. Tätä moni ei ollut ottanut huomioon, vaikka se on vakava virhe. Javassa koottu lause (lohko) ilmaistaan {} -sulkeilla. En yrittänytkään tulkita paperille koodattuja sisennyksiä kootun lauseen ilmaiseviksi lohkoiksi. Javalle isot ja pienet kirjaimet ovat nimissä ja koodissa eri kirjaimia. Jos koodasi paperia 'caps lock päällä' ei saanut ensimmäistä hyvinmuodostuneisuuspistettä. Jotkut olivat määrittäneet metodeissa tarvittavia apumuuttujia olion kentiksi. Tästä en sakottanut, mutta se on rumaa ja voi olla vaarallistakin. Jos muuttujaa ei tarvita metodin ulkopuolella mihinkään, se oikeastaan suorastaan tulee määritellä metodin sisäiseksi. Totuusarvoisten muuttujien arvon vertailu if-lauseen ehdossa on tarpeetonta, ja voi olla vaarallistakin. Jotkut olivat hienosti toteuttaneet erillisen Tankki-luokan ja käyttivät sen olioita Oljyvaraston tankkeina. Tämä oli hienoa, tosin joskus tankit piilottivat esim. kokonsa, mikä olisi ollut Oljyvaraston metodin toString() kannalta relevantti tilatieto. Esimerkki (tällaisesta olisin antanut täydet pisteet, muustakin sai): public class Oljyvarasto { private double vtVetoisuus, ktVetoisuus, vtÖljyä, ktÖljyä; private boolean vtKäyttölupa; public Oljyvarasto(double käyttötankki, double varmuustankki) { if (käyttötankki > 0) ktVetoisuus = käyttötankki; else ktVetoisuus = 0; if (varmuustankki > 0) vtVetoisuus = varmuustankki; else vtVetoisuus = 0; vtÖljyä = 0; ktÖljyä = 0; vtKäyttölupa = false; } public double käyttötankissaOn() { return ktÖljyä; } public double varmuustankissaOn() { return vtÖljyä; } public boolean onKäyttölupa() { return vtKäyttölupa; } public void asetaKäyttölupa(boolean lupaKäyttää) { vtKäyttölupa = lupaKäyttää; } public double lisääÖljyä(double määrä) { if (määrä < 0) return 0; double mahtuu = vtVetoisuus - vtÖljyä; if (mahtuu >= määrä) { // mahtuuko varmuustankkiin? vtÖljyä += määrä; return 0; } else { // ei mahdu pelkästään varmuustankkiin vtÖljyä = vtVetoisuus; // täytetään varmuustankki määrä -= mahtuu; // loput laitettavaksi käyttötankkiin mahtuu = ktVetoisuus - ktÖljyä; if (mahtuu >= määrä) { // mahtuuko käyttötankkiin? ktÖljyä += määrä; return 0; } else { // kaikki ei mahtunut käyttötankkiinkaan ktÖljyä = ktVetoisuus; // täytetään käyttötankkikin määrä -= mahtuu; return määrä; // palautetaan mitä jäi yli } } } public double otaÖljyä(double määrä) { if (määrä < 0) return 0; if (määrä <= ktÖljyä) { // saadaanko kaikki käyttötankista? ktÖljyä -= määrä; return määrä; } // tästä eteenpäin ei saatu kaikkea käyttötankista if (!vtKäyttölupa) { // jos ei saada ottaa varmuustankista määrä = ktÖljyä; // otetaan kaikki käyttötankissa oleva ktÖljyä = 0; // tankki tyhjenee return määrä; // suoritus päättyy } // tästä eteenpäin ei suoriteta jos ei ole käyttölupaa double saldo = ktÖljyä; // paljonko tähän mennessä on saatu öljyä ktÖljyä = 0; // käyttötankki tyhjäksi if (määrä - saldo <= vtÖljyä) { // saadaanko loput varmuustankista vtÖljyä -= (määrä - saldo); return määrä; // saatiin kaikki mitä pyydettiin } else { // kaikkea ei saatu saldo += vtÖljyä; vtÖljyä = 0; return saldo; // palautetaan mitä tankeissa oli jäljellä } } public String toString() { String kuvaus = "Öljyvarasto: Käyttötankki "+ ktÖljyä + "/" + ktVetoisuus + " Varmuustankki "+ vtÖljyä + "/" + vtVetoisuus; if (vtKäyttölupa) kuvaus += ", varmuustankkia lupa käyttää"; return kuvaus; } }