Oppimateriaali perustuu kevään 2010 kurssiversion materiaaliin ja Arto Wiklan ohjelmointisivustoon. Materiaalin copyright © (aakkosjärjestyksessä): Matti Luukkainen, Matti Paksula, Arto Vihavainen, Arto Wikla. Materiaalia saa vapaasti käyttää itseopiskeluun. Muu käyttö vaatii luvan.

Ohpe-harjoitukset s2010: 4/6 (27.9.-1.10.)

(Muutettu viimeksi 28.9.2010, sivu perustettu 23.9.2010.)

Nämä harjoitukset liittyvät oppimateriaalin luvun III Oliot ja kapselointi, luokka olion mallina melkein kaikkiin alilukuihin 1-22. Siispä Stringejä (III.23) harjoitellaan vasta myöhemmin.

Harjoitustehtävien otsikoilla on värikoodaus: Vihreät tehtävät on syytä tehdä joka tapauksessa. Värittämättömiä ei ole ihan pakko tehdä, mutta nekin ovat hyvin hyödyllisiä ja myös vaikuttavat pisteisiin. Keltaiset tehtävät ovat vähän haastavampia. Nekin lasketaan mukaan harjoituspisteitä määrättäessä, mutta ilmankin niitä harjoituksista voi saada maksimipisteet.

Huom: Jokaisen ohjelmatiedoston alkuun on kirjoitettava kommenttina harjoituskerta, tehtävän numero ja tekijän nimi tyyliin:

// 4. harjoitukset, tehtävä 2.1, Oili Opiskelija

Huom: Nimeä tiedostot tehtävän otsikon mainitsemalla nimellä.

Aikalaskureita

Tuntilaskuri.java

Tuntilaskuri on laite, joka nappia painaen etenee vuorokauden tunnista toiseen.

Tuntilaskurin API on

Tässä valmis pääohjelma Tuntilaskurin kokeilemiseen:

    public static void main(String[] args) {
        Tuntilaskuri tuntilaskuri = new Tuntilaskuri();

        System.out.println("tuntilaskurin arvo "+ tuntilaskuri.getTunti());
        tuntilaskuri.etene();
        System.out.println("tuntilaskurin arvo "+ tuntilaskuri.getTunti());

        // mennään vuorokausi eteenpäin
        for ( int i=0; i<24; i++ )
            tuntilaskuri.etene();

        System.out.println("tuntilaskurin arvo "+ tuntilaskuri.getTunti());
    }

Ja esimerkin tulostuksen pitäisi olla:

tuntilaskurin arvo 0
tuntilaskurin arvo 1
tuntilaskurin arvo 1

Minuuttilaskuri.java

Minuuttilaskuri on laite, joka nappia painaen etenee vuorokauden minuutista toiseen.

Minuuttilaskurin API on

Pääohjelma pikku apulaisineen Minuuttilaskurin kokeilemiseen:

    public static void main(String[] args) {

        Minuuttilaskuri minuuttilaskuri = new Minuuttilaskuri();

        tulostaAika(minuuttilaskuri);            // testi 1

        minuuttilaskuri.etene();
        tulostaAika(minuuttilaskuri);          // testi 2

        // edetään 2 tuntia
        for (int i = 0; i < 120; i++) {
            minuuttilaskuri.etene();
        }
        tulostaAika(minuuttilaskuri);         // testi 3

        // edetään vuorokausi
        for (int i = 0; i < 24*60; i++) {
            minuuttilaskuri.etene();
        }
        tulostaAika(minuuttilaskuri);         // testi 4
    }

    private static void tulostaAika(Minuuttilaskuri minuuttilaskuri) {
        System.out.println("minuuttilaskurin arvo " + minuuttilaskuri.getTunti() + ":" +
                                                      minuuttilaskuri.getMinuutti());
    }

Vihjeitä ratkaisustrategiaan (Matti Luukainen): Pääohjelma sisältää neljä testiä

  1. aika tulostuu alussa oikein
  2. aika tulostuu minuutin etenemisen jälkeen oikein
  3. aika tulostuu oikein kun yli tunti on kulunut
  4. aika tulostuu oikein kun yli vuorokausi on kulunut

Toteuta aluksi "tyhjä luokka", joka ei tee mitään, mutta "ensimmäinen testi" menee jo läpi:

minuuttilaskurin arvo 0:0
minuuttilaskurin arvo 0:0
minuuttilaskurin arvo 0:0
minuuttilaskurin arvo 0:0

Ohjelmoi minuutit etenemään, toinen testi kuntoon:

minuuttilaskurin arvo 0:0
minuuttilaskurin arvo 0:1
minuuttilaskurin arvo 0:121
minuuttilaskurin arvo 0:1561

Seuraavana askeleena minuutit toimimaan oikein, tunnit edelleen rikki:

minuuttilaskurin arvo 0:0
minuuttilaskurin arvo 0:1
minuuttilaskurin arvo 0:1
minuuttilaskurin arvo 0:1

Lopulta tunnitkin kulkemaan:

minuuttilaskurin arvo 0:0
minuuttilaskurin arvo 0:1
minuuttilaskurin arvo 2:1
minuuttilaskurin arvo 2:1

Sekuntilaskuri.java

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. Laskuri siis laskee: 0:0:0, 0:0:1, ..., 0:0:59, 0:1:0, 0:1:1, 0:1:2, ..., 0:59:57, 0:59:58, 0:59:59, 1:0:0, 1:0:1,..., 23:59:58, 23:59:59, 0:0:0.

Sekuntilaskurin API:

Laadi myös sovellus, joka esittelee laskurin käyttöä.

Opintopistelaskuri

TyomaaraMuunnin.java (ja OpintopisteetTunneiksi.java)

Ohjelmoi väline TyomaaraMuunnin, joka osaa laskea opintopisteiden "laskennallisen" työmäärän. Yhden opintopisten lasketaan vaativan 27 työtuntia

Saat esittelypääohjelman valmiina, ks. alla. Toteuta siis itse luokka TyomaaraMuunnin, joka osaa tehdä mainitun muunnoksen. Luokassa on konstruktorin lisäksi oltava ainakin toString()-metodi, joka palauttaa TyomaaraMuunnin-olion merkkiesityksen alla olevan esimerkin mukaisena. Konstruktorille annetaan parametreina kurssin nimi, opintopistemäärä ja kurssin kesto.

public class OpintopisteetTunneiksi {
  public static void main(String[] args) {

     TyomaaraMuunnin ohpe = new TyomaaraMuunnin("Ohjelmoinnin perusteet", 5, 6);
     TyomaaraMuunnin ohja = new TyomaaraMuunnin("Ohjelmoinnin jatkokurssi", 4, 6);

     System.out.println(ohpe);
     System.out.println("---");
     System.out.println(ohja);
  }
}

Vaadittu tulostusasu:

Kurssin Ohjelmoinnin perusteet (5 op) laskennallinen työmäärä:
Yhteensä 135 tuntia
Viikossa 22.5 tuntia
---
Kurssin Ohjelmoinnin jatkokurssi (4 op) laskennallinen työmäärä:
Yhteensä 108 tuntia
Viikossa 18.0 tuntia

Vihje: Nyt olion on muistettava myös String-tyyppinen arvo. Ohjelmoi siis luokkaan kenttä (=ilmentymämuuttuja) tyyliin:

  private String kurssinNimi;

TyomaaraLaskin.java

Tee luokkaa TyomaaraMuunnin käyttäen ohjelma, joka kysyy kurssin nimen, opintopisteet ja keston. ja työmäärää. Tämän jälkeen ohjelma tulostaa tiedot samoin kuin edellisessä tehtävässä:

Kurssin nimi?    Musiikin historia
Opintopisteitä?  10
Kesto viikkoina? 14

Kurssin Musiikin historia (10 op) laskennallinen työmäärä:
Yhteensä 270 tuntia
Viikossa 19.28571429 tuntia

Varaston käyttöä

Kahvikirjanpito.java

Toteuta oppimateriaalin luokan Varasto avulla vuorovaikutteinen eli keskusteleva eli interaktiivinen ohjelma, joka pitää kirjaa jäljellä olevan kahvin määrästä. Varastotilanteen muutokset ohjelmoidaan otaVarastosta()- ja lisaaVarastoon()-aksessoreilla.

Älä muokkaa luokkaa Varasto. Voit vaikka ajatella, että olet ostanut vain luokkatiedoston eli ByteCode-sisältöisen .class-tiedoston, eikä käytössäsi edes ole lähdekielistä versiota.

Koska luokan valmis toString() ei sovellu tähän tehtävään, ohjelmoi itse apumetodi private static String tilannetiedotus(Varasto v)-metodi, joka palauttaa arvonaan tähän tehtävään soveltuvan merkkiesityksen kahvinkeittimen tilasta.

Tässä ohjelmaraakile:

import java.util.Scanner;
public class Kahvikirjanpito {
    public static Scanner lukija = new Scanner(System.in);
    public static void main(String[] args) {

        Varasto kahvi = new Varasto(3.0, 2.0);

        System.out.println("Kahvikassa");
        System.out.println("1\tJuo kahvi");
        System.out.println("0\tPoistu\n");

        // tänne pääohjelman muu logiikka
    }

    // tänne pääohjelman apumetodit
}

Ohjelman suorituksen pitää näyttää seuraavalta:

Kahvikirjanpito
1   Juo kahvi
0   Poistu

Kahvia on jäljellä 2.0/3.0 kuppia
Valitse toiminto: 1

Kahvia on jäljellä 1.0/3.0 kuppia
Valitse toiminto: 1

Kahvia on jäljellä 0.0/3.0 kuppia
Valitse toiminto: 1

Kahvi on loppu!

Kahvia on jäljellä 0.0/3.0 kuppia
Valitse toiminto: 0

KahvikirjanpitoPlus.java

Laajenna toteutusta siten, että ohjelmaan tulee uusi toiminto: kahvin keittäminen. Kahvin keittäminen on mahdollista kaikissa ohjelman vaiheissa, mutta kahvia ei voi keittää enempää kuin tilaa on jäljellä.

Kahvikirjanpito
1   Juo kahvi
2   Keitä kahvia
0   Poistu

Kahvia on jäljellä 2.0/3.0 kuppia
Valitse toiminto: 2
Kuinka monta kuppia keitetään: 2

Ei mahdu!

Kahvia on jäljellä 2.0/3.0 kuppia
Valitse toiminto: 2
Kuinka monta kuppia keitetään: 1

Kahvia on jäljellä 3.0/3.0 kuppia
Valitse toiminto: 0

Viljavarasto.java

Eräs viljavarastotyyppi muodostuu kahdesta viljasiilosta. Vain ensimmäinen siilo on varustettu lastauslaittein. Viljaa voidaan siirtää siilosta toiseen. Viljavaraston varsinaiset viljasäiliöt pitää toteuttaa käyttäen kurssimateriaalin luokakaa Varasto.

Ratkotaan tehtävä paloittain: API annetaan paloittain. Voit ratkoa tehtäväsarjan editoimalla samoja ohjelmatiedostoja Viljavarasto.java ja ViljavarastoEsittely.java yhä täydellisemmiksi.

... yksipyttyinen ...

API:

Ohjelmoi myös sovellus ViljavarastoEsittely.java, joka selkeästi ja kattavasti havainnollistaa Viljavaraston käyttöä.

Vihje: Tässä siis Viljavaraston piilossa pidettyyn kenttään luodaan Varasto-luokan ilmentymä, Varasto-olio, tyyliin:

public class Viljavarasto {
  // piilossa pidetty tietoranne:
  private Varasto siilo;
  ...

  // kostruktori:
  public Viljavarasto(...) {
    ...
    siilo = new Varasto(...);
    ...
  }
  ...
}

... kaksipyttyinen vajaana ...

API:

Ohjelmoi myös sovellus ViljavarastoEsittely.java, joka selkeästi ja kattavasti havainnollistaa Viljavaraston käyttöä.

... kaksipyttyinen ...

Täydennetään edellisen kohdan API:a vielä parilla tärkeällä lisämetodilla:

Ohjelmoi myös sovellus ViljavarastoEsittely.java, joka selkeästi ja kattavasti havainnollistaa Viljavaraston käyttöä.

Viljavarastomestari.java

Laadi sovellus viljavarastomestarille viljavaraston kirjanpitoon. Ohjelma on keskusteleva eli interaktiivinen. Keskustelun yksityiskohdat voit päättää itse. Alla on esimerkkejä/ideoita siitä, millaisista asioista keskustellaan. Voit ohjelmoida keskustelun toisinkin, jos keksit tyylikkäämmän tavan!

Tervetuloa mestari!

Miten suuri on 1. siilo? 2000
Miten suuri on 2. siilo? 10000

Toiminnot:
1 Tulosta varastotilanne
2 Lisää viljaa
3 Ota viljaa
4 Siirrä viljaa
5 Lopeta

? 1
1: 0.0, 2: 0.0

? 2
Paljonko lisätään? 314
Ok!

? 1
1: 314.0, 2: 0.0

? 4
Suunta? (1 = ensimmäiseen, 2 = toiseen) 2
Paljonko? 100
Ok!

? 1
1: 214.0, 2: 100.0

? 7
Virheellinen komento!
Toiminnot:
1 Tulosta varastotilanne
2 Lisää viljaa
3 Ota viljaa
4 Siirrä viljaa
5 Lopeta

? 3
Paljonko otetaan? 1000
Ok! Sait 214.0

? 1
1: 0.0, 2: 100.0

? 5
Näkemiin!