/* * Ohjelmoinnin Perusteet, syksy 2007, harjoitus 3 (24.9. -28.9.) * Esimerkkiratkaisu * tehtävä 15 * * Laadi metodi laskeSyottoKarvo, jolle annetaan luettavien lukujen * lukumäärä parametrina. Metodi laskee ja tulostaa syöttölukujen * keskiarvon. Laadi myös pääohjelma, joka tarjoaa keskiarvojen * laskentapalvelun. Yhdellä käyttökerralla pitää voida laskea * useampia keskiarvoja. Tässä tehtävässä saat olettaa, että syötteet * annetaan virheettöminä. * * Jaakko Sorri 24.9.2007 */ import java.util.Scanner; public class KeskiarvonLaskentaPalvelu { /* Keskiarvo lasketaan jakamalla lukujen summa niiden lukumäärällä */ private static void laskeSyottoKarvo(int lukumäärä) { if (lukumäärä > 0) { // pitää olla jotain laskettavaa, muuten ei tehdä mitään Scanner lukija=new Scanner(System.in); double summa = 0; // tähän kerätään syötettyjen lukujen summa for (int luettu=0; luettu0); } } -------------------------------------------------------------------- /* * Ohjelmoinnin Perusteet, syksy 2007, harjoitus 3 (24.9. -28.9.) * Esimerkkiratkaisu * tehtävä 16 * * Ohjelmoi double-arvon palauttava metodi potenssiin, jonka arvona * on double-parametri korotettuna int-parametrin ilmoittamaan potenssiin. * Myös negatiiviset potenssit ovat mahdollisia. Sovitaan, että tässä * tehtävässä mikä tahansa arvo (myös nolla!) potenssiin nolla on yksi. * (Muistutus: Negatiiviset potenssit ovat positiivisten käänteislukuja, * esim. potenssi(10.0, -1) on 1/10.0, potenssi(10.0, -2) on 1/100.0, jne., ) * * Suunnittele ja toteuta myös pääohjelma, joka tarjoaa käyttäjälle * "potenssien laskentapalvelun". * * Jaakko Sorri 24.9. 2007 */ import java.util.Scanner; public class PotenssiLaskuri { public static Scanner lukija = new Scanner(System.in); /* * Potenssien laskentapalvelu */ public static void main(String[] args){ int jatketaan; double kanta; int exp; System.out.println("*** Tervetuloa potenssilaskuriin! ***" + "Tämä ohjelma laskee potensseja reaaliluvuille."); do{ System.out.print("\nAnna kanta (desimaaliluku): "); kanta = lukija.nextDouble(); System.out.print("\nAnna eksponentti (kokonaisluku): "); exp = lukija.nextInt(); System.out.print("\n" + kanta + "^" + exp + "=\n" + potenssiin(kanta, exp)); System.out.print("\nSyötä 0, jos haluat lopettaa."); jatketaan = lukija.nextInt(); }while(jatketaan != 0); } /* * Laskee lukujen potensseja. 0^0 arvoksi on sovittu 1. */ public static double potenssiin(double kanta, int eksponentti){ double tulos = 1.0; for(int i=0; i 0) return n; else return -n; } } -------------------------------------------------------------------- /* * Ohjelmoinnin Perusteet, syksy 2007, harjoitus 3 (24.9. -28.9.) * Esimerkkiratkaisu * tehtävä 17 * * Yksinkertaisessa radiossa on vain kolme säädintä: päälle/pois-kytkin, * voimakkuuden säädin (arvot 0, 1, ..., 9) ja kuunneltavan kanavan * valinta (2300.0, ..., 26100.0). * * Mallinna radio luokkana Radio. Säätimet toteutetaan metodeina, eli * ns. aksessoreina. Luokassa on oltava myös aksessorit, joilla radion * tilaa voi tutkia. Tietorakenteet (muuttujat) pidetään tietenkin * Radio-olion käyttäjältä piilossa. Niihin pääsee siis käsiksi vain * säädellysti aksessoreja käyttäen. Miten virheelliset käyttöyritykset * hoidetaan? Miten metodit siis toimivat, jos annetaan virheellinen * voimakkuus tai kanava? * * Testaa Radio-luokkaa laatimalla pääohjelma, joka "käyttää radioita". * Tässä tehtävässä ei tarvitse varautua ei-numeerisiin syötteisiin. * Itse asiassa syötteitä ei välttämättä tarvita lainkaan. * * "Mallinnus" tässä tarkoittaa vain sitä, että säätimiä voi säätää ja * niiden arvoja tutkia aksessorimetodeilla Ohjelman kytkeminen todellisen * radion käyttöliittymäksi olisi ihan toinen juttu... Käytä * kurssimateriaalin esimerkkiä Kuulaskuri ratkaisusi mallina. * * Jaakko Sorri 24.9.2007 */ public class Radio { /* * Määritellään vakioita ylläpidettävyyden nimissä. Nämä ovat muuttujia, * joiden arvoa ei voi muuttaa sen jälkeen kun ne ovat kerran saaneet * arvon. */ private static final int VOLMIN = 0; private static final int VOLMAX = 9; private static final double KANMIN = 2300.0; private static final double KANMAX = 26100.0; /* luokan yksityiset kentät */ private boolean päällä; private int volume; private double kanava; /** * ------------konstruktori------------ * Alkuarvot on valittu * "mielivaltaisesti": uusi radio on pois päältä ja sen säätimet * minimiasennossa. */ public Radio() { päällä = false; volume = VOLMIN; kanava = KANMIN; } /** * Metodi vaihdaOnOff toimii virtanappulana eli vaihtaa päällä- muuttujan * arvon vastakkaiseksi. Toisin sanoen, jos radio on päällä tätä metodia * kutsuttaessa, se laitetaan pois päältä. Jos taas se oli poissa päältä, * se laitetaan päälle. */ public void vaihdaOnOff() { if (päällä) päällä = false; else päällä = true; /* * edellisen voi kirjoittaa lyhyemminkin yhdellä lauseella: * päällä != päällä; */ } /** * Metodi säädäVolumea säätää volumea parametrina annetun luvun verran * (positiiviset parametrit lisäävät volumea, negatiiviset vähentävät). Jos * volume menee pois säädetyltä alueelta, se asetetaan kyseisen suuntaiseksi * ääripääksi. */ public void säädäVolumea(int muutos) { // Huom! Ei varauduta ali- tai ylivuotoihin! volume += muutos; if (volume > VOLMAX) { // volat kaakossa volume = VOLMAX; } else if (volume < VOLMIN) { volume = VOLMIN; } } /** * Metodi vaihdaKanavaa säätää kanavaa parametrina annetun luvun verran * (positiiviset parametrit lisäävät, negatiiviset vähentävät). Jos kanava * menee pois säädetyltä alueelta, se asetetaan kyseisen suuntaiseksi * ääripääksi. */ public void vaihdaKanavaa(double muutos) { kanava += muutos; if (kanava < KANMIN) { kanava = KANMIN; } else if (kanava > KANMAX) { kanava = KANMAX; } } /** * Seuraavat kolme metodia mahdollistavat radion nappuloiden asentojen * "katselemisen" yksi kerrallaan. Näitäkin voitaisiin jossakin * radiosovelluksessa tarvita. */ public boolean onkoPäällä() { return päällä; } public int annaVolume() { return volume; } public double annaKanava() { return kanava; } /** * toString-metodi palauttaa radio-olion tilan String-merkkijonona */ public String toString() { return "radio-olio: päällä=" + päällä + ", kanava=" + kanava + ", volume=" + volume; } /** * Testipääohjelma. Testataan kaikki metodit pyytämällä sekä * toteutuskelpoisia että toteutuskelvottomia muutoksia * äänenvoimakkuuden ja kanavan arvoihin. */ public static void main(String[] args) { Radio testi = new Radio(); System.out.println(testi); testi.säädäVolumea(8); System.out.println(testi); testi.säädäVolumea(-4); System.out.println(testi); testi.säädäVolumea(20); System.out.println(testi); testi.säädäVolumea(-30); System.out.println(testi); testi.vaihdaKanavaa(10000); System.out.println(testi); testi.vaihdaKanavaa(-2549); System.out.println(testi); testi.vaihdaKanavaa(40000); System.out.println(testi); testi.vaihdaKanavaa(-30000); testi.vaihdaOnOff(); System.out.println(testi); testi.vaihdaOnOff(); System.out.println(testi); } } -------------------------------------------------------------------- /* * Ohjelmoinnin Perusteet, syksy 2007, harjoitus 3 (24.9. -28.9.) * Esimerkkiratkaisu * tehtävä 18 (osa 1/2) * * Sekuntilaskuri tuntee sekunnit, minuutit ja tunteja vuorokauden * verran. Laskuri voi vain edetä. Kun sekunnit ylittävät arvon 59 * yhdellä, minuutit kasvavat ja sekunnit nollataan. Kun minuutit * ylittävät arvon 59 yhdellä, tunnit kasvavat ja minuutit nollataan. * Kun laskuri ylittää arvon 23:59:59 (23 tuntia, 59 minuuttia, * 59 sekuntia), aloitetaan uudelleen arvosta 0:0:0. * * Toteuta luokka Sekuntilaskuri * public Sekuntilaskuri() luo sekuntilaskurin, jonka alkuarvo on 0:0:0 * public int annaMinuutit() palauttaa arvonaan minuuttien määrän * public int annaSekunnit() palauttaa arvonaan sekuntien määrän * public int annaTunnit() palauttaa arvonaan tuntien määrän * public void lisaaSekunti() lisää sekuntien määrää yhdellä * Varusta luokka metodilla toString(), jonka ansiosta olion arvo saadaan * tulostettua muodossa tunnit:minuutit:sekunnit, siis esimerkiksi * "14:7:53". * * Laadi erillinen pääohjelmaluokka Sekuntilaskuri-luokan "testaamiseen". * Tässä pääohjelmassa ei tarvitse varautua virheellisiin syötteisiin. * Itse asiassa syötteitä ei välttämättä tarvita lainkaan. * * Jaakko Sorri 24.9.2007 */ public class SekuntiLaskuri { // Vakioita eli muuttumattomina pysyviä arvoja. // Nimettyjen vakioiden nimet on tapana kirjoittaa isoilla kirjaimilla. private int MAX_SEKUNNIT = 59; private int MAX_MINUUTIT = 59; private int MAX_TUNNIT = 23; // Aikaa kuvataan olion sisällä tunteina (0...23), minuutteina (0...59) ja // sekunteina (0...59). private int tunnit; private int minuutit; private int sekunnit; /** Luo SekuntiLaskuri-tyyppisen olion. */ public SekuntiLaskuri() { this.tunnit = 0; this.minuutit = 0; this.sekunnit = 0; } /** * Lisää sekuntien määrää yhdellä. Jos vuorokausi tulee täyteen, laskuri * aloittaa alusta. */ public void lisaaSekunti() { if (this.sekunnit < MAX_SEKUNNIT) this.sekunnit++; else { this.sekunnit = 0; if (this.minuutit < MAX_MINUUTIT) this.minuutit++; else { this.minuutit = 0; if (this.tunnit < MAX_TUNNIT) this.tunnit++; else this.tunnit = 0; } } } /** Palauttaa tuntien määrän (0...23). */ public int annaTunnit() { return this.tunnit; } /** Palauttaa minuuttien määrän (0...59). */ public int annaMinuutit() { return this.minuutit; } /** Palauttaa sekuntien määrän (0...59). */ public int annaSekunnit() { return this.sekunnit; } /** * Palauttaa Sekuntilaskuri-tyyppisen olion tilaa kuvaavan String-tyyppisen * olion, esimerkiksi "12:35:8". */ public String toString() { return this.annaTunnit() + ":" + this.annaMinuutit() + ":" + this.annaSekunnit(); } } /* * Ohjelmoinnin Perusteet, syksy 2007, harjoitus 3 (24.9. -28.9.) * Esimerkkiratkaisu * tehtävä 18 (osa 2/2) * * "Testiluokka" SekuntiLaskuri-luokan testaamiseen. * * Jaakko Sorri 24.9.2007 */ public class SekuntiLaskuriTestaaja { /* * Luo SekuntiLaskuri-tyyppisen olion ja tulostaa sen tilan vähän yli * vuorokauden ajalta. * */ public static void main(String[] args) { SekuntiLaskuri laskuri = new SekuntiLaskuri(); for (int i = 0; i < 24 * 60 * 60 + 10; i++) { System.out.println(laskuri.toString()); laskuri.lisaaSekunti(); } } } -------------------------------------------------------------------- /* * Ohjelmoinnin Perusteet, syksy 2007, harjoitus 3 (24.9. -28.9.) * Esimerkkiratkaisu * tehtävä 19 * * Lämpötilan maksimin ja minimin rekisteröintiin käytetään laitetta * MinMax. Laitteelle syötetään lämpötiloja ja siltä voidaan milloin * tahansa kysyä toistaiseksi korkeinta ja toistaiseksi matalinta * lämpötilaa. Kun laite otetaan käyttöön, se on alkutilassa, ja * mittareiden näytöllä ei ole merkitystä. Heti ensimmäisen * mittaustuloksen jälkeen laite antaa järkeviä tuloksia. Laite * voidaan myös myöhemmin asettaa alkutilaan uuden mittaussarjan * rekisteröintiä varten. Laitteelta voidaan kysyä, onko se * alkutilassa vai voiko sen ilmoittamiin lämpötiloihin luottaa. * * Toteuta laite luokkana MinMax, jolla on konstruktorin lisäksi * seuraavat aksessorit: * public void kirjaaLämpötila(double lämpö) * public double mikäOnMinimi() * public double mikäOnMaksimi() * public boolean onAlkutilassa() * public void asetaAlkutilaan() * Laadi luokkaan myös pääohjelmametodi, joka havainnollistaa ja testaa * luokan toimintaa. Tässä tehtävässä ei tarvitse varautua * ei-numeerisiin syötteisiin. Itse asiassa syötteitä ei välttämättä * tarvita lainkaan. * * Jaakko Sorri 24.9.2007 */ import java.util.Scanner; /** * Säilyttää mittaussarjan minimi- ja maksimilämpötilan. Olio on aluksi * alkutilassa. Alkutilassa ollessaan olio palauttaa miniminä ja maksimina aina * lämpötilan 0.0. Erillisellä onAlkutilassa()-metodilla voidaan selvittää, onko * mittauksia jo kirjattu. Olio poistuu alkutilasta, kun jokin todellinen * lämpötila kirjataan. Olion voi halutessaan palauttaa alkutilaan. */ public class MinMax { private double minimi; private double maksimi; private boolean alkutilassa; /** Luo uuden MinMax-tyyppisen olion. Olio on alkutilassa. */ public MinMax() { this.asetaAlkutilaan(); } /** Asettaa olion alkutilaan. */ public void asetaAlkutilaan() { this.minimi = 0.0; this.maksimi = 0.0; this.alkutilassa = true; } /** * Kirjaa lämpötilan. Jos olio on alkutilassa, lämpötila asetetaan sekä * minimiksi että maksimiksi ja alkutilasta poistutaan. Jos olio ei ole * alkutilassa, lämpötila asetetaan minimiksi jos se on pienempi kuin * tähänastinen minimi, ja maksimiksi jos se on suurempi kuin tähänastinen * maksimi. */ public void kirjaaLämpötila(double lämpö) { if (this.alkutilassa) { this.minimi = lämpö; this.maksimi = lämpö; this.alkutilassa = false; } else if (lämpö < this.minimi) this.minimi = lämpö; else if (lämpö > this.maksimi) this.maksimi = lämpö; } /** Palauttaa true, jos olio on alkutilassa, muuten palauttaa false. */ public boolean onAlkutilassa() { return this.alkutilassa; } /** * Palauttaa 0.0, jos olio on alkutilassa, tai pienimmän kirjatun * lämpötilan, jos olio ei ole alkutilassa. (Huomaa, että pienin kirjattu * lämpötila voi olla myös 0.0.) */ public double mikäOnMinimi() { return this.minimi; } /** * Palauttaa 0.0, jos olio on alkutilassa, tai suurimman kirjatun * lämpötilan, jos olio ei ole alkutilassa. (Huomaa, että suurin kirjattu * lämpötila voi olla myös 0.0.) */ public double mikäOnMaksimi() { return this.maksimi; } public String toString() { String merkkijonoesitys; if (this.onAlkutilassa()) merkkijonoesitys = "Ei kirjattuja mittauksia"; else merkkijonoesitys = "minimi=" + this.mikäOnMinimi() + ", maksimi=" + this.mikäOnMaksimi(); return merkkijonoesitys; } /** Esittelee kahden MinMax-tyyppisen olion käyttämistä. */ public static void main(String[] args) { Scanner lukija = new Scanner(System.in); String komento; MinMax turku = new MinMax(); MinMax ivalo = new MinMax(); do { System.out.println(); System.out.println("Lämpötilat Turussa: " + turku.toString()); System.out.println("Lämpötilat Ivalossa: " + ivalo.toString()); System.out.println(); System.out.println("t = kirjataan Turun lämpötila\n" + "i = kirjataan Ivalon lämpötila\n" + "muut = poistutaan ohjelmasta\n"); System.out.print("Valintasi: "); komento = lukija.next(); if (komento.equals("t") || komento.equals("i")) { System.out.print("Lämpötila: "); double lämpötila = lukija.nextDouble(); if (komento.equals("t")) turku.kirjaaLämpötila(lämpötila); else ivalo.kirjaaLämpötila(lämpötila); } } while (komento.equals("t") || komento.equals("i")); } }