Tarkastusselostuksia ja mallivastauksia 1. välikokeeseen 13.3.1998: ========================================================================= 1. ========================================================================= Marko Ullgren: Selitä tiiviin täsmällisesti: Yleistä: Kustakin kohdasta oli jaossa yksi piste, yhteensä siis enintään neljä pistettä. Vastausten arvostelussa perusteena pidin käsitteen ymmärtämistä: jos vastauksellaan osoitti sisäistäneensä kysytyn asian, sai yhden pisteen, jos osoitti olevansa asiasta melkein perillä, sai puoli pistettä. Ymmärryksensä saattoi osoittaa monilla muillakin tavoilla kuin seuraavassa olevilla mallivastauksilla. Pelkistä esimerkeistä ja arvauksista ilman perusteluja ei kuitenkaan pisteitä herunut. lause ja lauseke Lause on ohjelmointikielen käsky, joka suorittaa jotain. Päättyy puolipisteeseen tai on suljettu aaltosulkeiden sisään. Ei omaa arvoa. Esim. System.out.println(), {metodinkutsu(); b=i%4;} Lausekkeella on arvo. Tämä arvo voi olla mitä tahansa tyyppiä. Lauseke voi olla esimerkiksi aritmeettinen laskutoimitus (jolloin sillä on numeerinen arvo), totuusarvoinen lauseke (totuusarvo), sijoituslauseke tai arvon palauttavan metodin kutsu. parametrivälitys Parametri on metodin sisäinen muuttuja, joka määritellään metodin nimen perässä sulkeiden sisällä. Tämän niinsanotun muodollisen parametrin alkuarvoksi kopioidaan metodin kutsussa annetun todellisen parametrin arvo metodia kutsuttaessa. Kuten muutkin metodin muuttujat, parametri hävitetään metodin suorituksen päätyttyä, ja luodaan joka kutsua varten uudestaan. Parametri on ns. arvoparametri: muodollisen parametrin arvon muuttaminen ei muuta todellisen parametrin arvoa. kuormittaminen Kuormittamisella tarkoitetaan usean samannimisen metodin ohjelmoimista samaan luokkaan. Samannimisten metodien ohjelmoiminen on sallittua vain, jos nämä poikkeavat toisistaan parametreiltaan, eli parametreja on eri määrä ja/tai ne ovat eri tyyppisiä. Kun metodia kutsutaan, valitaan metodeista se, jonka muodolliset parametrit parhaiten vastaavat kutsun todellisia parametreja. Kuormitetut operaattorit ovat eri asia kuin kuormittamimen, javassa ei ole mahdollista itse kuormittaa operaattoreita. olio Olio on luokan ilmentymä. Luokassa määritellään jokin toiminnallisuus, ja olio toteuttaa tämän. Oliolla on sisäistä rakennetta: tyypillisesti kenttiä (muuttujia) ja metodeita. Olio pitää siis sisällään tietoa ja tarjoaa välineet tämän tiedon käsittelyyn. Hyvään ohjelmointitapaan kuuluu pitää luokan kentät piilossa ulkomaailmalta, ja tarjota ainoastaan hallitut välineet (ns. aksessorimetodit) näiden kenttien sisältämän tiedon käsittelyyn. Tällöin voi ajatella olion olevan abstraktin tietotyypin ilmentymän; se erottaa tarkasti sen mitä tehdään siitä miten se tehdään. Oliomuuttujan arvona on aina viite olioon. Uusi olio saadaan käyttöön määrittelemällä ensin oliotyyppinen muuttuja (Olio olio;) ja luomalla sen arvoksi viite uuteen olioon (olio = new Olio() ). ========================================================================= 2. ========================================================================= Matti Pauna: Arviointiperusteet: - pieni ohjelmointivirhe: vähennys 1/2 - 1 pistettä kappaleelta - tietojen oikeellisuuden tarkistamatta jättäminen: vähennys 2 pistettä - jos ei toteuteta uudelleen laskentaa vähennetään 2 pistettä ------------------------------------------------------------------------- public class Laatikko { private static double kysySuure(String suureenNimi) { double vastaus; do { System.out.println("Anna " + suureenNimi + ", oltava positiivinen"); vastaus = Lue.dluku(); if (vastaus <= 0) System.out.println(suureenNimi + ":n täytyy olla positiivinen!"); } while (vastaus <= 0); return vastaus; } public static void main(String[] args) { double syvyys, leveys, korkeus; char vastaus; do { System.out.println("Lasketaan laatikon tilavuus"); syvyys = kysySuure("syvyys"); leveys = kysySuure("leveys"); korkeus = kysySuure("korkeus"); System.out.println("Laatikon tilavuus on "+syvyys*leveys*korkeus); System.out.println("Jatketaanko? (e lopettaa, muut jatkavat)"); vastaus = Lue.merkki(); } while (vastaus != 'e' && vastaus != 'E'); } } ========================================================================= 3. ========================================================================= Asko Saura: PISTEYTYS * Toimiva siisti metodi: 5 .. 2 p -2 p Väärä algoritmi. Väärä returnin käyttö. -1 p Metodin sisäinen näkyvyysrikkomus. Väärä for-lauseen käyttö. Potenssiin(x,n) palauttikin Potenssiin(x,n+-1). void-metodi, silti toimiva. Väärä algoritmi neg. potensseille, muuten OK. -1/2 p Paljon puuttuvia puolipisteitä (;). Väärä for-lauseen indeksointi. Väärä vertailuoperaattori (<, <=, ==, !=, >=, >). Muuttujia esittelemättä. Harhaanjohtava tuloste (ei tässä mitään tarvinnut edes tulostaa). HUOM. Double-nollalla jako ei oikeastaan ole laittomuus, siitä seuraa arvo 'infinity'. ------------------------------------------------------------------------- /* Potenssiin1.java * Johdatus ohjelmointiin / 1. VK tehtävä 3 * asaura 12.10.1997 TKTL * * potenssiinkorotusta * */ public class Potenssiin1 { /* VARSINAINEN KOETEHTÄVÄ */ /* Palauta kanta^potenssi. */ public static double potenssiin (double kanta, int potenssi) { double tulos = 1.0; // jos potenssi == 0, niin tulos aina 1 if (potenssi < 0) { // jos potenssi oli negatiivinen kanta = 1 / kanta; // kannasta käänteisluku // (0-doublejako -> infinity) potenssi = 0 - potenssi; // potenssista vastaluku } for (int p = 0; p < potenssi; p++) // toista |potenssi| kertaa tulos = tulos * kanta; // kerro tähänastinen kantaluvulla return tulos; } /* main-metodi testaukseen. */ public static void main(String[] args) { System.out.println(potenssiin(10.0,-1)); System.out.println(potenssiin(10.0,1)); System.out.println(potenssiin(10.0,5)); System.out.println(potenssiin(0.0,5)); System.out.println(potenssiin(0.0,-5)); } } ========================================================================= 4a. ========================================================================= Jussi Sarkkinen: Tehtävän maksimipistemäärä 4p. Täydet pisteet saa ratkaisulla, jossa luokka, sen muuttujat sekä konstruktori(t) ja muut metodit on määritelty oikein (mukaanlukien arvonpalauttavat aksessorimetodit!). Sitten se ikävä osuus eli ... - pienestä ohjelmointivirheestä sakotetaan 1/2 - 1 p. - jossain metodissa on sen toimintaa oleellisesti haittaava virhe, sakotetaan 1p. (yksittäisen tarkistuksen tms. puute 1/2p) - oleellisten osien puuttuumisesta (konstruktori, jokin aksessori tms.) sakotetaan 1 - 2 p. Arvonpalauttavien aksessorien puutteesta sakotetaan seuraavanlaisesti: - jos vain toString() toteutettu mutta luokka muilta osin täydellinen, ei sakkoa - jos ei mitään arvonpalauttavia toteutettu, sakkoa 1 1/2p (malli "kaivo") Yksityiskohtien ja toteutuksen johdonmukaisuuden arvioinnissa olin lempeä, mutta täysien pisteiden saantiin vaadin kyllä "nappisuoritusta". --------------------------------------------------------------------- /********************************************************************** * Johdatus ohjelmointiin Kevät 98 - 1. välikoe tehtävä 4a. * * Jussi Sarkkinen 19.3.1998 * * * * Ratikka-luokan toteutus * **********************************************************************/ public class Ratikka { // Tarvittavat suureet luokan yksityisinä muuttujina: private double vauhti; private boolean kiskoJarru; private boolean ovetAuki; // Konstruktori ilman alkuarvoja (alkuarvoilla lienee turha): public Ratikka() { this.vauhti=0.0; this.kiskoJarru=false; this.ovetAuki=false; } // Aksessorit arvojen kyselyyn: public double annaVauhti() { return this.vauhti; } public boolean onkoJarruPäällä() { return this.kiskoJarru; } public boolean onkoOvetAuki() { return this.ovetAuki; } public void asetaVauhti(double vauhti) { if (!kiskoJarru) // Testataan onko jarru päällä { this.vauhti = vauhti; if (this.vauhti > 60.0) // Pidetään vauhti rajoissa this.vauhti = 60.0; if (this.vauhti < -10.0) this.vauhti = -10.0; } else { System.out.println("Ei voi kiihdyttää: Kiskojarru päällä!"); } } public void ilmaJarru(double jarrutus) { if (jarrutus >0 && jarrutus < 100) this.vauhti -= this.vauhti*jarrutus/100; // Toimii molempiin suuntiin... } public void kiskoJarru() { this.kiskoJarru = !this.kiskoJarru; // Jarru päälle/pois this.vauhti=0.0; // Vauhti pois } public void oviNappi() { this.ovetAuki = !this.ovetAuki; // Ovet auki/sulki } public String toString() { String tila = "Ratikan nopeus on: "+this.vauhti+".\n"; if (this.ovetAuki) tila = tila + "Ovet ovat auki.\n"; else tila = tila + "Ovet ovat kiinni.\n"; if (this.kiskoJarru) tila = tila + "Kiskojarru on päällä."; else tila = tila + "Kiskojarru on pois päältä."; return tila; } } ========================================================================= 4b. ========================================================================= Kari Vasko: Tehtävässä 4b tuli toteuttaa vuorovaikutteinen sovellus raitiovaununkuljettajalle. Sovelluksen tuli tarjota kuljettajalle joukko komentoja, joilla raitiovaunun tilaa voidaan manipuloida. Saadakseen täydet pisteet oli voitava muuttaa raitiovaunun nopeutta, ovien tilaa sekä tarjottava mahdollisuus portaalliselle (ilmajarru) että portaattomalle (kiskojarru) jarrutukselle. Nopeuden säätäminen portaallisesti integer-arvojoukossa sallittiin. Pisteitä menetti seuraavasti: Silmukka puuttuu -1 Silmukan ehto on väärin -0.5 Yhtäsuuruuden vertailu luvuilla väärin (if (i=j)) -0.5 Yhtäsuuruuden vertailu merkkijonoilla väärin -0.5 Jos käyttäjä ei voi juuri mitenkään vaikuttamaan nopeuden säätöön jarrutukseen tms. -1 - -2 Luokkakohtainen metodi määritelty oliokohtaiseksi -1 (static vs. non-static) Private-kenttään viitataan suoraan -1 Jokin muu pieni systemaattinen syntaktinen virhe -0.5 Useita pieniä systemaattisia syntaktisia virheitä -1 - -2.5 Paranormaaleista hämäryyksistä lähti pisteitä seuraavasti: Metodi toisen metodin sisällä -1.5 Olion metodeita kutsutaan ilman olio-viitettä -1.5 Olion luonti ilman, että olion tyyppi on määritelty -0.5 Metodissa puhutaan toisen metodin sisäisistä muuttujista -1.5 Static-metodissa höpistään this:seistä -1 Rajatapauksissa arvosteluun vaikutti sisennyksen puuttuminen sekä kryptisesti nimetyt muuttujat. ------------------------------------------------------------------------ /********************************************************************** * Johdatus ohjelmointiin Kevät 98 - 1. välikoe tehtävä 4b * * Kari Vasko 16.4.1998 * * Luokka käyttää Jussi Sarkkisen Ratikka-luokan toteutusta * * RatikanKuljettaja-luokan toteutus * **********************************************************************/ public class RatikanKuljettaja { public static void menu() { System.out.println("Raitiovaunun kuljetusohjeet\n"); System.out.println(" K - Kaasu"); System.out.println(" I - Ilmajarru"); System.out.println(" J - Kiskojarru"); System.out.println(" O - Avaa/Sulje ovet"); System.out.println(" M - Menu"); System.out.println(" Kaikki muut syötteet lopettavat ajon"); } public static void kaasuta(Ratikka raitioVaunu) { System.out.println("Paljonko laitetaan kaasua?"); raitioVaunu.asetaVauhti(Lue.dluku()); } public static void ilmaJarruta(Ratikka raitioVaunu) { System.out.println("Montakos prosenttia ilmajarrutellaan?"); double maara = Lue.dluku(); while((maara > 100) || (maara < 0)) { System.out.print("Luvun tulee olla välillä [0,100]."+ "\nSyötä uudestaan: "); maara = Lue.dluku(); } raitioVaunu.ilmaJarru(maara); } public static void main(String[] args) { Ratikka kolmeTee = new Ratikka(); String komento; boolean loppu = false; menu(); while(!loppu) { System.out.print("Anna komento: "); komento = Lue.rivi(); if (komento.equalsIgnoreCase("k")) kaasuta(kolmeTee); else if (komento.equalsIgnoreCase("i")) ilmaJarruta(kolmeTee); else if (komento.equalsIgnoreCase("j")) kolmeTee.kiskoJarru(); else if (komento.equalsIgnoreCase("o")) kolmeTee.oviNappi(); else if (komento.equalsIgnoreCase("m")) menu(); else loppu = true; // Tulostetaan lopuksi raitiovaunun tila System.out.println(kolmeTee); } System.out.println("Ajo loppui. Hyvää päivänjatkoa!"); } } ---------------------------------------------------------------------------