58128-1 Johdatus ohjelmointiin: 1. välikoe 28.10.1997 ====================================================================== 1. ====================================================================== Tarkastusselostus, 1. tehtävä. (5 pistettä) Tarkasti Marko Ullgrén Selitä täsmällisen tiiviisti käsitteet: (Jokainen kohta on yhden pisteen arvoinen) metodin muuttuja Mallivastaus Muuttuja on arvon säilytyspaikka, "laatikko, jonka kyljessä on nimi". Muuttujalla on aina tietty tyyppi (alkeis- tai oliotyyppi), joka on määritellään muuttujan esittelyssä, joten se voi pitää sisällään vain tietyn tyyppisiä arvoja. Metodin muuttuja esitellään metodin ("aliohjelman") sisällä, eikä siihen voi viitata muualta. Sillä ei ole oletusalkuarvoa, ja se luodaan jokaista metodin suorituskertaa varten uudestaan. Pisteytys Pelkästä itsestäänselvyyden toteamisesta, eli vastauksesta "metodin muuttuja on metodin oma/sisäinen muuttuja", ei saanut pisteitä. Puoli pistettä sai suhteellisen helposti, jos oli tiennyt edes jotain tämän lisäksi. Yhteen pisteeseen vaadittiin muuttuja-käsitteen ja metodin muuttujan erityispiirteiden selvittäminen, tai jos muuttujan selvitys puuttui, niin ansiokas metodin muuttujan erityispiirteiden(alkuarvo, suorituskertakohtaisuus, näkyvyys) selittäminen. lause Mallivastaus 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;} Pisteytys Yhden pisteen sai, jos tiesi lauseen olevan suoritusta, eikä sotkenut siihen mitään arvoja. Puoli pistettä sai pelkästä esimerkistä. lauseke Mallivastaus Lausekkeella on arvo. Lauseke voi olla esimerkiksi aritmeettinen laskutoimitus (jolloin sillä on numeerinen arvo), totuusarvoinen lauseke (totuusarvo), sijoituslauseke tai arvon palauttavan metodin kutsu. Pisteytys Yhden pisteen sai, jos tiesi lausekkeella olevan jonkin arvon, joka voi olla mitä tahansa tyyppiä. Puoli pistettä sai vaillinaisella selityksellä, pelkällä esimerkillä vailla selityksiä ei pisteitä saanut. Parametri Mallivastaus Parametri on metodin muuttuja, joka esitellään metodin nimen perässä sulkeiden sisällä. Tämä metodin sisällä määritelty parametri on nk. muodollinen parametri, joka saa alkuarvokseen metodia kutsuttaessa metodin kutsussa annetun todellisen parametrin arvon. Metodilla voi olla useampia parametreja, tai sitten ei yhtään. Pisteytys Puoli pistettä sai, jos kertoi, että parametri on metodille välitettävä arvo. Yhteen pisteeseen vaadittiin selvitystä muodollisista ja todellisista parametreista, ei välttämättä näillä termeillä, jos idea oli oikein. Kuormittaminen Mallivastaus Kuormittamisella tarkoitetaan usean samannimisen metodin ohjelmoimista. 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. Pisteytys Tämä tehtävä oli selkeästi parhaiten osattu. Yhden pisteen sai mallivastauksen asiat sisältävästä vastauksesta, puoli pistettä, jos vastauksesta puuttui jokin olennainen asia tai siinä oli jokin asiavirhe. ====================================================================== 2. ====================================================================== Jukka M J Manner: Tässä oman tehtäväni mallivastaus ja arvosteluperusteet: public class Tehtava2 { public static void main(String[] args) { int alaraja, ylaraja; System.out.println(" Tama ohjelma kysyy sinulta kahta rajaa ja sen jalkeen lukua naiden valiin."); do { System.out.print("Anna alaraja:"); alaraja=Lue.kluku(); System.out.print("Anna ylaraja:"); ylaraja=Lue.kluku(); if(ylaraja <= alaraja+1) System.out.println("Huonot rajat, anna uudestaan..."); } while(!(ylaraja > alaraja +1)); // Voidaan jattaa "+1" pois... System.out.println("\nLuku "+lueValilta(alaraja,ylaraja)+" oli OK."); } public static int lueValilta(int alaraja, int ylaraja) { int luettu=0; do { System.out.print("Anna luku valilla]"+alaraja+","+ylaraja+"[:"); luettu=Lue.kluku(); if((luettu <= alaraja) || (luettu >= ylaraja)) System.out.println("Luku ei kelpaa..."); } while((luettu <= alaraja) || (luettu >= ylaraja)); // Ehtolauseeseen voisi myos laittaa "((luettu < alaraja) || /luettu > // ylaraja)), jotta rajat huomioitaisiin mukaan eli luku pitaa olla // valilla [alaraja,ylaraja] return luettu; } } /* Ongelmia tuottivat - Raja-arvojen tarkistaminen (-0.5p -> -1 piste, jos ei mitaan tarkistuksia) - Metodin piti palauttaa ARVONAAN hyväksytty luku (-0.5 p.) - Paluuarvoa ei käytetty. Joskaan tämä seikka ei ole suoranaisesti virhe, se AINAKIN on huonoa ohjelmointityyliä: mita hyötyä on paluuarvosta, jos sitä ei käytetä? (-0,5 p.) - Metodin tuli kysellä lukua sitkeästi (-0.5 -> -1.5 p. tilanteen mukaan) - Metodin tuli olla "static" (-0.5 p.) - Ohjelma saattoi joutua loputtomaan silmukkaan (-0.5 p.) - Muista pikkuvirheistä rokotettiin 0.5 pistetta Raja-arvojen tarkistamisessa hyväksyttiin erilaiset vaihtoehdot (lopettaa suorituksen tai kysyä uudestaan), kunhan tarkistuksia oli edes jollain lailla suoritettu. */ ====================================================================== 3. ====================================================================== Johdatus ohjelmointiin S97 1. välikoe tehtävä 3, tarkastusselostus 18.11.1997 / Marko Orasaari Tehtävästä noin puolet pisteistä tulee ohjelman oikeasta rakenteesta ja toiston toteuttamisesta ja toinen puoli muusta tehtävästä, oikeasta syötteiden lukemisesta, tuloksen tulostamisesta, virheellisten syötteiden suodattamisesta. Tehtävä on arvosteltu kahdesta suunnasta: hyvissä vastauksissa (3-6 pistettä) on virheistä ja puutteista pudotettu pisteitä ja heikommissa vastauksissa (<3 pistettä) on annettu pisteitä niistä osista, jotka ovat oikein. Selkeistä kirjoitusvirheistä ei ole otettu virhettä. Virheitä: pienehkö syntaksivirhe 0.5-1 p vakava kielioppvirhe 1.5-2 p lievä looginen toimintavirhe 1 p vakava virhe ohjelman toimintalogiikassa 2-3 p toiston puuttuminen 3 p epäselvä ulkoasu (esim. puuttuva sisennys) 0.5-1 p liukulukujen suora yhtäsuuruusvertailu 0.5 p ---------------------------------------------------------------------- public class KoeTehtava3 { public static void main(String[] args) { double sivu1,sivu2; char jatko; System.out.println("Ohjelma laskee suorakulmion alan"); System.out.println("Aidosti positiiviset luvut käyvät sivun"+ "pituuksiksi \n"); // tehdään, kunnes käyttäjä haluaa lopettaa do { // luetaan sivunpituudet System.out.print("Anna 1. sivu: "); sivu1=Lue.dluku(); while(sivu1<=0){ System.out.println("Ei kelpaa, anna >0"); sivu1=Lue.dluku(); } System.out.print("Anna 2. sivu: "); sivu2=Lue.dluku(); while(sivu2<=0){ System.out.println("Ei kelpaa, anna >0"); sivu2=Lue.dluku(); } //tulostetaan ala System.out.println("neliön ala on "+sivu1*sivu2); // kysytään käyttäjältä jatko-ohjeet System.out.println("Haluatko laskea uudelleen (k/e)"); jatko = Lue.merkki(); } while(jatko!='e' && jatko!='E'); } } ====================================================================== 4. ====================================================================== 1. välikokeen tehtävässä 4 pyydettiin toteuttamaan yksinkertainen Radio- luokka, jolla on kolme säädintä: on/off-kytkin, äänenvoimakkuuden säädin ja kuunneltavan kanavan valintasäädin. Luokkaan tulee siis sisällyttää ainakin kolme privaattia attribuuttia: virtakytkin, aanenvoimakkuus ja radiokanava. Lisäksi tulee olla olemassa ainakin kolme metodia em. attribuuttien arvojen manipuloimiseksi sekä tietysti ainakin yksi konstruktori. Virtakytkintä toteutettiin pääasiassa int-,String ja boolean-tyyppisinä. Kaikki toteutukset hyväksyttiin - kunhan ne vain toimivat. Äänenvoimakkuus on selvästikin toteutettava int-tyyppisenä (sai olla myös short tai long) ja vastaavasti kanava on toteuttava double-tyyppisenä (sai olla myös float). Jos attribuutit eivät olleet privaatteja, menetti yhden pisteen. Metodeja toteutettiin monenlaisina variantteina. Eksoottisimmistakin ratkaisuista sai pisteet kotiin, jos ratkaisu oli vain toimiva. Konstruktorin puuttuminen aiheutti yhden pisteen menetyksen. Staattisilla metodeilla menetti yhden pisteen ja jos oli vielä otsaa tehdä metodeista sekä privaatteja että staattisia menetti kaksi pistettä. Systemaattisista syntaksivirheistä menetti pisteen tai puoli (riippuen siitä kuinka paha virhe oli käsitteellisesti). Syntaksivirhe tulkittiin systemaattiseksi, jos se esiintyi vastauksessa useammin kuin kerran. Esimerkiksi 0:n ja 1:n käyttäminen totuusarvoina oli yhden miinuspisteen arvoinen suoritus. Jos vastauksessa oli paljon virheitä, antoi se negatiivista "impaktia" tehtävän arvosteluun rajatapauksissa. Tehtävässä pyydettiin lisäksi selvittämään, miten Radio-olioita luodaan ja käytetään. Jos ei ollut selventänyt yksikäsitteisesti tietävänsä, miten olio luodaan ja miten se kutsuu metodeitaan menetti yhden pisteen. Yksikäsitteiseksi selvittämiseksi ei tulkittu esimerkiksi lausetta: "Uusi Radio-olio luodaan new-käskyllä". Sen sijaan vastaukset "Radio-olio luodaan new-käskyllä esimerkiksi seuraavasti: Radio sony = new Radio();" tai "Olio luodaan new-käskyllä seuraavasti: Luokka olionNimi = new Luokka(parametrit);, missä Luokka(parametrit) on jokin määritelty konstruktori." Vastaavasti se miten olion attribuutteja voi manipuloida metodeilla edellytti yksikäsitteistä tietämyksensä esittämistä: joko "Radio-olio kutsuu metodiaan esimerkiksi seuraavasti: sony.kytkin();" tai "Olio kutsuu metodiaan seuraavasti: olionNimi.metodiNnimi(parametrit);". Jos puuttui jompi kumpi edellämainituista menetti puoli pistettä. Luokan testaamisesta olisi saanut jo oman erillisen tehtävänsä (ja itseasiassa oman kurssinsa). Näin muodoin: Mikäli vastauksesta kävi ilmi, että luokkaa voi testailla main-metodilla ja tutkimalla metodien palauttamia arvoja, niin ei menettänyt pisteitä. Tehtävä arvosteltiin edellämainittujen rajoitteiden puitteissa opiskelijanäkökulmasta suopeasti, sillä Radio-luokan toteuttamista ei rajattu tehtävän annossa kovinkaan tarkasti. Seuraavassa eräs ehdotus luokan radio toteuttamiseksi: public class Radio { private boolean virtaKytkin; private int aanenVoimakkuus; private double radioKanava; // Konstruktori public Radio() { this.virtaKytkin = false; this.aanenVoimakkuus = 0; this.radioKanava = 2300; } // Aksessorit /* Metodi virtakytkin asettaa radio-olion attribuutin virtaKytkin arvon negaatiokseen */ public void kytkin() { this.virtaKytkin = !this.virtaKytkin; } /* Metodi saadaVoimakkuus palauttaa true-arvon, jos parametrina annettu uusi äänenvoimakkuus on validi (so. se kuuluu joukkoon {0,1,...,9}) ja asettaa radio-olion aanenVoimakkuus-attribuutin arvoksi tuon nimenomaisen arvon. Muulloin metodi palauttaa false-arvon ja radio-olion aanenVoimakkuus-attribuutti pysyy muuttumattomana. */ public boolean saadaVoimakkuus(int uusiVoimakkuus) { if (0<=uusiVoimakkuus && uusiVoimakkuus<=9) { this.aanenVoimakkuus = uusiVoimakkuus; return true; // voimakkuuden säätäminen onnistui } else return false; // voimakkuuden säätäminen epäonnistui } /* Metodi saadaKanava palauttaa true-arvon, jos parametrina annettu uusi radiokanava on validi (so. se kuuluu joukkoon [2300,26100]) ja asettaa radio-olion radioKanava-attribuutin arvoksi tuon nimenomaisen arvon. Muulloin metodi palauttaa false-arvon ja radio-olion radiokanava-attribuutti pysyy muuttumattomana. */ public boolean saadaKanava(double uusiKanava) { if (2300<=uusiKanava && uusiKanava<=26100) { this.radioKanava = uusiKanava; return true; // kanavan vaihto onnistui } else return false; // kanavan vaihto epäonnistui } public double mikaKanava() { return this.radioKanava; } public int mikaVoimakkuus() { return this.aanenVoimakkuus; } public boolean onkoPaalla() { return this.virtaKytkin; } public String toString() { if (this.virtaKytkin) return "Radio on päällä, äänenvoimakkuus on " + this.aanenVoimakkuus +" ja radio on kanavalla "+ this.radioKanava; else return "Radio ei ole päällä"; } public static void main(String[] args) { Radio sony = new Radio(); sony.kytkin(); // radio päälle if (!sony.saadaVoimakkuus(100)) System.out.println("Väärä äänenvoimakkuus"); if (!sony.saadaVoimakkuus(-1)) System.out.println("Väärä äänenvoimakkuus"); if (sony.saadaVoimakkuus(4)) System.out.println("Oikea äänenvoimakkuus"); if (!sony.saadaKanava(100)) System.out.println("Väärä kanava"); if (!sony.saadaKanava(26101)) System.out.println("Väärä kanava"); if (sony.saadaKanava(15000)) System.out.println("Oikea kanava"); System.out.println(sony); sony.kytkin(); // Radio pois päältä System.out.println(sony); } } ======================================================================