Arto Wikla 2011. Materiaalia saa vapaasti käyttää itseopiskeluun. Muu käyttö vaatii luvan.

Ohjelmoinnin jatkokurssi: harjoitukset s2011: 6/6 (5.-9.12.)

(Muutettu viimeksi 5.12.2011, sivu perustettu 23.11.2011.)

Sivun sisältö voi vielä muuttua!

Nämä harjoitukset liittyvät oppimateriaalin lukuihin 10 – 13.

Kaikki harjoitustehtävät on syytä tehdä. Jotkin tehtävät on merkitty keltaisella värillä. Ne ovat ehkä hieman muita haastavampia. Ilman niitäkin harjoituksista voi saada maksimipisteet, mutta ne lasketaan silti mukaan harjoituspisteitä määrättäessä – ne voivat siis korvata joitakin haasteettomampia tehtäviä tms. Mutta ennen kaikkea noista keltaisista tehtävistä sitä vasta oppiikin!

Huom:

Sovellus ja keskustelutapa riippumattomiksi

Peruskurssilla käytetty ponnahdusikkunakirjasto Pop.java (luku 1) ja 5. viikon harjoituksissa toteutettu komentotulkki-ikkunassa keskusteleva Shell-java-kirjasto sisältävät joukon samantapaisia ja myös samanotsikkoisia metodeita. Molemmissa on myös metodeita, joita toisessa ei ole.

Javan rajapintaluokkatekniikkaa käyttäen on mahdollista erottaa sovelluksen logiikka ja jonkin työkalun käyttö hyvin riippumattomiksi toisistaan; sovelluksen ja työkalun jakama rajapinta muodostuu pelkästään Javan rajapintaluokan luettelemista operaatioiden nimistä. Luonnollisestikin operaatioiden täytyy myös toimia "riittävän" samaan tapaan.

Javan rajapintaluokassa voi olla vain ilmentymämetodeita eli ei-staattisia metodeita. Kirjastoluokissa Pop.java ja Shell.java operaatiot on toteutettu luokkametodeina.

Kun haluamme käyttää ohjelman keskustelun toteuttamiseen rajapintaluokan tyyppistä oliota, meidän on muokattava kirjastoluokista vastaavia "olion malliksi" soveltuvia luokkia. Se tehdään kohta.

Rajapintaluokka Keskustelija.java

Ohjelmoi rajapintaluokka Keskustelija, joka luettelee metodit kysyString, kysyInt, kysyDouble ja ilmoita.

Huomaa että ilmoita-metodista tarvitaan koko joukko kuormitettuja versioita. Huomaamista helpottaa tutustuminen Pop.java-luokkaan.

Pop.java => PopOlio.java

Muokkaa luokasta Pop.java olion malliksi soveltuva luokka PopOlio.

Käyttöesimerkki:

PopOlio keskustelu = new PopOlio();

keskustelu.ilmoita("Yhteenlaskin");
int eka  = keskustelu.kysyInt("Anna ensimmäinen luku: ");
int toka = keskustelu.kysyInt("Anna toinen luku: ");
keskustelu.ilmoita("Lukujen summa on " + (eka+toka));

Kun ohjelma suoritetaan, nähdään ponnahdusikkunoita peruskurssilta tuttuun tapaan.

Selitystä: Pop-luokkaa käytettäessä kutsuttiin luokkametodeita tyyliin Pop.ilmoita(...), nyt luodaan PopOlio-luokan ilmentymä ja kutsutaan sen ilmentymämetodeita tyyliin keskustelu.ilmoita(...).

Koska PopOlio toteuttaa kaikki rajapintaluokan Keskustelija vaatimat metodit, ilmoita luokan otsikossa luokan toteuttavan koko kyseisen rajapintaluokan.

Shell.java => ShellOlio.java

Muokkaa luokasta Shell.java olion malliksi soveltuva luokka ShellOlio.

Täydennä luokkaa ilmentymämetodilla ilmoita, joka ei muuta tee kuin kutsuu System.out.prinln-metodia itse saamallaan parametrilla. Muista kuitenkin kuormittaa metodi kaikin tarpeellisin parametrein.

Käyttöesimerkki:

ShellOlio keskustelu = new ShellOlio();

keskustelu.ilmoita("Yhteenlaskin");
int eka  = keskustelu.kysyInt("Anna ensimmäinen luku: ");
int toka = keskustelu.kysyInt("Anna toinen luku: ");
keskustelu.ilmoita("Lukujen summa on " + (eka+toka));

Ohjelmanpätkän suoritus:

Yhteenlaskin
Anna ensimmäinen luku: 7
Anna toinen luku: 12
Lukujen summa on 19

Huomaa että luokassa tarvitaan yksityinen kenttä Scanner-olioa varten.

Koska ShellOlio toteuttaa kaikki rajapintaluokan Keskustelija vaatimat metodit, ilmoita luokan otsikossa luokan toteuttavan koko kyseisen rajapintaluokan.

Onnenlukusovellus ja Keskustelija-tyyppinen olio

Laaditaan esimerkkinä yksinkertainen sovellus, joka ohjelmoidaan ottamatta kantaa siihen, käydäänko keskustelu ponnahdusikkunoin vai komentotulkki-ikkunassa. Keskustelu siis ohjelmoidaan tapahtuvaksi Keskustelija-rajapintaluokan metodein. Kun sovellus luodaan, parametriksi kelpaa mikä vain olio, jonka luokka toteuttaa kyseisen rajapintaluokan.

Harjoitellaanpa samalla assosiaatiolistan HashMap<K,V> käyttöä!

Sovellus tarjoaa seuraavan onnenlukujen hallintapalvelun:

Ohjelman luuranko voi näyttää vaikkapa seuraavanlaiselta:

public class OnnenlukujenHallinta {

  private Keskustelija keskustelu;
  private HashMap<String,Integer> onnenluku;

  public OnnenlukujenHallinta(Keskustelija keskustelu) {
    this.keskustelu = keskustelu;
    this.onnenluku = ...
    ...
  }
  ...

  public void run() {
    // Kun tätä metodia kutsutaan, palvelu käynnistyy.
    // Kun tämän metodin suoritus päättyy, palvelu päättyy.
    ...
  }
  ...
}

Ja tähän tapaan OnnenlukujenHallinta-oliota käytetään:

OnnenlukujenHallinta onnetar = new OnnenlukujenHallinta( .. jokin Keskustelija...);

onnetar.run();

Sovellus ponnahdusikkunoin ja komentotulkki-ikkunassa keskustellen

Havainnollista OnnenlukujenHallinta-sovelluksen käyttöä ponnahdusikkunoin (PopOlio) ja komentotulkki-ikkunassa (ShellOlio). Voit tehdä tämän kahtena eri ohjelmana tai yhden ohjelman kahtena vaiheena.

Kirjallisuuden jatkotutkimusta

Jatketaan kirjallisuudentutkimuksen välineiden laadintaa. Saattaa toisinaan olla kiinnostavaa selvittää, millaiset sanat seuraavat ja edeltävät toisiaan jossakin kielessä, kirjallisuuden lajissa tai yksittäisellä kirjailijalla.

Sanasuodatin.java, vaihe 1

Laadi luokka Sanasuodatin, jonka ilmentymä luodaan antamalla tekstitiedostoon liitetty File-olio.

Alustava API:

Esimerkki:

// luodaan File-olio tekstiTdsto
...
Sanasuodatin virta = new Sanasuodatin(tekstiTdsto);
int sanaLkm = 0;
while (virta.onVielaSanoja()) {
  String sana = virta.seuraava();
  sanaLkm = sanaLkm + 1;
}
...

Sanasuodatin.java, vaihe 2

Edellisen version "sanat" voivat sisältää mitä tahansa merkkejä, pilkkuja, pisteitä, yms. Kuitenkin kun sanoja tutkitaan, olisi hyvä voida samaistaa sanat lauseen keskellä ja lopussa – siis pilkuista ja pisteistä yms. pitäisi päästä eroon. Sanan sisällä sijaitsevat erikoismerkit on kuitenkin syytä säilyttää: siellä voi olla sanaan kuuluvia yhdysviivoja, heittomerkkejä, yms.

Toisinaan voi olla tarpeellista samaistaa myös isolla ja pienellä kirjoitetut sanat: esimerkiksi "Kissa" lauseen alussa ja "kissa" lauseen keskellä.

Kehittyneen version API:

Esimerkki:

// luodaan File-olio tekstiTdsto
...
Sanasuodatin virta = new Sanasuodatin(tekstiTdsto);
virta.isotPieniksi(true); 
int sanaLkm = 0;
while (virta.onVielaSanoja()) {
  String sana = virta.seuraava();
  sanaLkm = sanaLkm + 1;
}
...

SananSeuraajat.java

Toteuta luokka SananSeuraajat, tietorakenne, johon voidaan tallettaa pareja (sana, sanaluettelo). Luokka tarjoaa palvelut:

Vihjeitä: Seuraajaluettelotietorakenteen toteutuksessa voi käyttää sellaista HashMap-oliota, joka esittää assosiaatioita String-merkkijonon ja siihen liittyvän ArrayList<String>-olion välillä.

Käyttöesimerkki:

SananSeuraajat lelut = new SananSeuraajat();

lelut.lisaaSanalleSeuraaja("Maija", "nukke");
lelut.lisaaSanalleSeuraaja("Maija", "nalle");
lelut.lisaaSanalleSeuraaja("Maija", "kudin");

lelut.lisaaSanalleSeuraaja("Pekka", "auto");
lelut.lisaaSanalleSeuraaja("Pekka", "mittari");
lelut.lisaaSanalleSeuraaja("Pekka", "miekka");

System.out.println(lelut.mitkaSeuraavatSanaa("Maija"));
System.out.println(lelut.mitkaSeuraavatSanaa("Pekka"));
System.out.println(lelut.mitkaSeuraavatSanaa("Kalle"));

System.out.println(lelut);

Tulostus:

[nukke, nalle, kudin]
[auto, mittari, miekka]
null
{Maija=[nukke, nalle, kudin], Pekka=[auto, mittari, miekka]}

Toinen tapa tehdä SananSeuraajat.java

Edellä SananSeuraajat toteutettiin siten, että seuraajat esitettiin ArrayList<String>-olioina. Luontevampaa olisi ehkä esittää seuraajat joukkona, vaikkapa siis HashSet<String>-olioina. Ainoa muutos API-kuvauksessa on yhden metodin paluuarvon tyyppi:

Edellisen version käyttöesimerkki kelpaa tähän sellaisenaan.

SeuraajaAnalyysi.java

Laadi edellisten tehtävien luokkia Sanasuodatin ja SananSeuraajat käyttäen sovellus SeuraajaAnalyysi. Ohjelman tehtävä on selvittää annetussa tekstitiedostossa kaikkien sanojen välittömät seuraajasanat. Tässä tutkimuksessa halutaan samaistaa sanat joissa ainoat erot ovat kirjainten "koko", so. isot ja pienet kirjaimet tulkitaan kaikki pieniksi siten kuin Sanasuodatin-luokan kehittyneempi versio taitaa.

Ohjelma kysyy ensin tiedoston nimen ja tarjoaa sitten palvelun yksittäisen sanan seuraajien selvittämiseen.

Ohjelman testiversiossa myös koko seuraajaluettelon tulostaminen on hyödyllistä.

Testiaineistoa kirjallisuuden tutkimukseen:

Huomaa että Rautatie ja Huckleberry Finn ovat suoraan Gutenberg-projektin tarjoamassa muodossa. Jos haluat luotettavia tutkimustuloksia, tiedostoista kannattaa editoida pois turhat osat.

Käyttöesimerkki:

Minka tiedoston sanojen seuraajat haluat tutkia? Tyhjä lopettaa.
Ratatie.txt
Tiedostoa Ratatie.txt ei loydy!
Minka tiedoston sanojen seuraajat haluat tutkia? Tyhjä lopettaa.
Rautatie.txt
Minka sanan seuraajat haluat tietaa? Tyhjä lopettaa.
kissa
[maitoansa, pankon, oli]
Minka sanan seuraajat haluat tietaa? Tyhjä lopettaa.
kännykkä
null
Minka sanan seuraajat haluat tietaa? Tyhjä lopettaa.
hevonen
[huurussa, luimistaa, ja]
Minka sanan seuraajat haluat tietaa? Tyhjä lopettaa.

Kuu kasvaa

Luennoilla (luku 13) tutustuttiin Kuulaskuri-luokkaa käyttävään graafiseen sovellukseen Kuu, joka näyttää nappia painellen kuukausien etenemisen. Kehitellään tätä sovellusta.

Nimetyt kuukaudet

Kurssimateriaalin luvussa 8 kehiteltiin Kuulaskuri-luokka osaamaan kuukausien nimet. Muokkaa graafinen sovellus Kuu näyttämään kuukauden numeron sijasta kuukauden nimi. Käytä laskennan logiikan toteuttamiseen (eli ns. mallina) luvun 8 luokkaa KuulaskuriPlus.

Uusi Kuu näyttää seuraavalta:

kuva maaliskuu.png

Kuulle vuodet

Eikö asiakkaille mikään riitä? Nyt ne haluavat vielä vuodetkin näkyviin laskurissaan. No, kunhan hinnasta sovitaan...

Kehittele Kuu osaamaan myös vuosiluvut. Aloitusajankohdaksi asetetaan tammikuu 2010.

Luvun 8 Kuulaskuri-versiot eivät ehkä ole sellaisinaan tähän tehtävään täysin käyttökelpoisia ainakaan ihan helposti – voit siis joutua kehittelemään myös itse laskennan logiikkaa, "kuumoottoria", jonkin verran. Mutta se näkyy sitten myös laskussa! [Itse täydentäisin KuulaskuriPlus-luokkaa aksessorilla, joka palauttaa kuukauden nimen. Aliluokka KuulaskuriPlusPlus tietenkin sitten perii tuonkin ominaisuuden...]

Aina vaan hienompi Kuu näyttää seuraavalta:

kuva maaliskuu2038.png

Kuu sovelmaksi

Muokkaa hienoimmasta Kuu-sovelluksestasi www-sivulla käytettävä Kuu-sovelma.

Tukkimiehen taskulaskin

Tukkimies pitää kirjaa vetämällä viivan vihkoon aina kun puu on kaadettu. Viivojen määrä on kaadettujen puiden eli tukkien määrä. Viivahan on tukin yksinkertaistettu kuva! Jos yöllä käy tukkivarkaita, tukkimies pyyhkii viivoja pois vihostaan.

Tukkimies laskee siis seuraavin numeroin yhdestä kymmeneen: |, ||, |||, ||||, |||||, ||||||, |||||||, ||||||||, |||||||||, ||||||||||.

Esimerkkejä tukkimiehen algebrasta – tukkimies tarvitsee vain yhteen- ja vähennyslaskun:

| + | = ||
||| + |||| = |||||||
||||| - || = |||
||| - || = |
||| - ||| =

Kuten viimenen esimerkki osoittaa, nollaa tukkimies ei tunne: kun vaikkapa kolmesta vähennetään kolme, jäljelle ei jää mitään. Vihko on tyhjä. Tapaus ei silti ole virhetilanne.

Suurin luku, jonka tukkimies tuntee on |||||||||||||||||||||, kymmenjärjestelmässä siis 21. Tukkimies taitaa osata pelata venttiä?

Aritmetiikan virhetilanteet ja "arvot" virheen seurauksena ovat tyyppiä:

|| - ||| = ALIVUOTO!
||||||||||||||||||||| + || = YLIVUOTO!

Jos virhearvolla yritetään laskea, virhearvo ei muutu miksikään:

(|| - |||) + ||| = ALIVUOTO!

Tukkilaskin.java: lay-out

Toteuta ensin Tukkilaskimen lay-out:
(Tämä on vain kuva, mutta alempana tällä sivulla on myös (toivottavasti) toimiva Tukkilaskin-sovelma.)

kuva Tukkilaskin.png

Vihje: Tässä esimerkissä arvokenttä, numeronäppäin ("|") ja toimintonäppäimet (plus, miinus, on, clear) on toteutettu kukin omana paneelinaan (JPanel), joiden kunkin asemointi on GridLayout ((1,1), (1,1) ja (1,4)). Paneelit on koottu yhteen BorderLayout-asemoinnilla.

TLaskentalogiikka.java

Tukkimiehen aritmetiikan algebran toteuttaa TLaskentalogiikka-luokka. Logiikan peruskäsitteet ovat puskuri, muisti, yhteenlasku, vähennyslasku ja nollaus. Puskurin ja muistin maksimipituus on 21 ja ne voivat sisältää vain "yksijärjestelmän" numeromerkkeja "|".

Vihje: Aritmetiikan toteuttamisessa String-metodi length() lienee näppärä väline? Yhteenlaskukin on pelkkää katenointia...

Käyttöesimerkki:

TLaskentalogiikka lask = new TLaskentalogiikka();

System.out.println("lasketaan 3+2");

// kolmonen puskuriin:
System.out.println("kolmesti lisaaNumero");
lask.lisaaNumero();           // puskuri: | muisti:
lask.lisaaNumero();           // puskuri: || muisti:
lask.lisaaNumero();           // puskuri: ||| muisti:

System.out.println("plus");
lask.plus();                  // puskuri:  muisti: |||

// kakkonen puskuriin:
System.out.println("kahdesti lisaaNumero");
lask.lisaaNumero();          // puskuri: | muisti: |||
lask.lisaaNumero();          // puskuri: || muisti: |||

System.out.println("tulosOn");
lask.tulosOn();
System.out.println("Puskurissa on 2+3: " + lask.getPuskuri()); // puskuri: |||||

// lisätään summaan vielä ykkönen

System.out.println("plus");
lask.plus();                 // puskuri:  muisti: |||||
lask.lisaaNumero();          // puskuri: | muisti: |||||
lask.tulosOn();
System.out.println("Puskurissa on (2+3)+1: " + lask.getPuskuri()); // puskuri: ||||||

System.out.println("nollaa");
lask.nollaa();               // puskuri:  muisti:

System.out.println("Lasketaan 7-2");
// seitsemän puskuriin:
lask.lisaaNumero();   // puskuri: | muisti:
lask.lisaaNumero();   // puskuri: || muisti:
lask.lisaaNumero();   // puskuri: ||| muisti:
lask.lisaaNumero();   // puskuri: |||| muisti:
lask.lisaaNumero();   // puskuri: ||||| muisti:
lask.lisaaNumero();   // puskuri: |||||| muisti:
lask.lisaaNumero();   // puskuri: ||||||| muisti:
System.out.println("Puskurissa on 7: " + lask.getPuskuri()); // puskuri: |||||||

System.out.println("miinus");
lask.miinus();        // puskuri:  muisti: |||||||

// kaksi puskuriin:
lask.lisaaNumero();   // puskuri: | muisti: |||||||
lask.lisaaNumero();   // puskuri: || muisti: |||||||

lask.tulosOn();
System.out.println("Puskurissa on 7-2: " + lask.getPuskuri()); // |||||

lask.nollaa();
System.out.println("Kokorajoitus:");
lask.lisaaNumero(); lask.lisaaNumero(); lask.lisaaNumero();
lask.lisaaNumero(); lask.lisaaNumero(); lask.lisaaNumero();
lask.lisaaNumero(); lask.lisaaNumero(); lask.lisaaNumero();
lask.lisaaNumero(); lask.lisaaNumero(); lask.lisaaNumero();
lask.lisaaNumero(); lask.lisaaNumero(); lask.lisaaNumero();
lask.lisaaNumero(); lask.lisaaNumero(); lask.lisaaNumero();
lask.lisaaNumero();  // ||||||||||||||||||| muisti:
lask.lisaaNumero();  // |||||||||||||||||||| muisti:
lask.lisaaNumero();  // ||||||||||||||||||||| muisti:
lask.lisaaNumero();  // ||||||||||||||||||||| muisti:
lask.lisaaNumero();  // ||||||||||||||||||||| muisti:
lask.lisaaNumero();  // ||||||||||||||||||||| muisti:
lask.lisaaNumero();  // ||||||||||||||||||||| muisti:

System.out.println("Ylivuoto, lisätään tuohon 1:");
lask.plus();         // puskuri:  muisti: |||||||||||||||||||||
lask.lisaaNumero();  // puskuri: | muisti: |||||||||||||||||||||
lask.tulosOn();
System.out.println("Puskurissa on: " + lask.getPuskuri()); // puskuri: YLIVUOTO!

System.out.println("Alivuoto, lasketaan 1-2:");

lask.nollaa();       // puskuri:  muisti:
lask.lisaaNumero();  // puskuri: | muisti:
lask.miinus();       // puskuri:  muisti: |
lask.lisaaNumero();  // puskuri: | muisti: |
lask.lisaaNumero();  // puskuri: || muisti: |
lask.tulosOn();
System.out.println("Puskurissa 1-2: " + lask.getPuskuri()); // puskuri: ALIVUOTO!

Tukkilaskin.java

Toteuta tukkimiehelle toimiva taskulaskin muokkamalla pelkän lay-outin osaavasta ohjelmasta laskutaitoinen ohjelma. Laskentapalvelut saadaan TLaskentalogiikka-oliolta.

Huomaa miten tämä laskin poikkeaa tutuista laskimista: Plus- tai miinus-näppäimen painaminen tyhjentää näytön. Tyhjä näyttö tarkoittaa nollaa; "nolla" tukkimiehen lukujärjestelmässä on sama kuin "ei mitään".

Seuraavan tehtävän esimerkistä voi tutkailla, miten laskin käyttäytyy!

Tukkilaskin sovelmaksi

Tukkimiehellä ei aina ole kannettavaa metsällä mukanaan, mutta nettitaitoinen kännykkähän jokaiselta jo alkaa löytyä...

Muokkaa tukkimiehen taskulaskinsovelluksesta selaimella suoritettava sovelma (applet).

Tämän tapainen sen tulisi olla:

Selain ei ymmärrä Javaa!

Roomalaisen tukkimiehen taskulaskin: Calcolatore.java

Roomalainen tukkimies osaa eräitä lyhennysmerkintöjä tukkeja esittävien viivojen jonoille: Hän lyhentää viittä tarkoittavan luvun "|||||" muotoon "V" ja kymmentä tarkoittavan luvun "||||||||||" muotoon "X". Viivansakin hän kirjoittaa tavanomaista tukkimiestä tyylikkäämmin muotoon "I".

Muita varsinaisten roomalaisten numeroiden hienouksia roomalainen tukkimies ei tunne; esimerkiksi "IV" ja "IX" eivät ole hänelle lukuja vaan väärin muodostettuja ilmauksia. Hän kirjoittaa esimerkiksi luvun neljä muodossa "IIII". Kuuteentoista roomalainen tukkimies laskee seuraavaan tapaan: "I", "II", "III", "IIII", "V", "VI", "VII", "VIII", "VIIII", "X", "XI", "XII", "XIII", "XIIII", "XV", "XVI", ...

Myöskään "X":ää suuremmille luvuille roomalaisella tukkimiehellä ei ole lyhennysmerkintöjä. Esimerkiksi luvun 119 hän ilmaisee kirjoittamalla "XXXXXXXXXXXVIIII".

Luvut esitetään aina siten, että mahdolliset "X":t ovat alussa, niitä seuraa – jos seuraa – korkeintaan yksi "V". Luvun lopussa on korkeintaan neljä merkkiä "I". Ja kuten tavallisella tukkimiehellä, roomalaisellakin "nolla" on "ei mitään".

Muokkaa ensin TLaskentalogiikka roomalaiseksi logiikaksi RTLaskentalogiikka. Huomaa että laskennan sisäinen toteutus kannattaa säilyttää ennallaan: String-metodilla length() aritmetiikka on helpompaa kuin roomalaisia lyhenteitä käyttäen. Ainoastaan siis getPuskuri()-metodin palautusarvo pitää muuttaa roomalaiseen muotoon. Olisikohan mitään ideaa toteuttaa RTLaskentalogiikka TLaskentalogiikka-luokan aliluokkana...

Vihje: Kannattanee muistella String-metodia replace(...), ..., mahtaisikohan jokin tyyli replace("IIIIIIIIII", "X") olla käyttökelpoinen?

Ylivuodon käsittely on myös syytä harkita uudelleen: Käytössä olkoon edelleen 21 merkkipaikkaa, mutta lyhenteiden ansiosta suurin roomalaisen tukkimiehen laskimen esittämä luku on XXXXXXXXXXXXXXXXXXXXX eli meille desimaalikoille 210. Ja se siis on esitettävissä. Kuitenkin vaikkapa 209 eli XXXXXXXXXXXXXXXXXXXXVIIII aiheuttaa ylivuodon. Ratkaisevaa RTLaskentalogiikka-ylivuodon aiheutumisessa on siis lukuilmauksen merkkipituus, ei luvun varsinainen arvo.

Laskimen toteuttaminen muunnetulla logiikalla ei enää sitten paljon vaivaa aiheuta. Näppäimistö säilyy samana. Roomalaisessakin laskimessa on vain yksi numeronäppäin, mutta viiden painalluksen jälkeen näyttöön ilmestyy "V", yhdeksän painalluksen jälkeen "VIIII" ja kymmenen jälkeen "X", jne.

Tässä esimerkissä numeronäppäintä on painettu neljäkymmentäyhdeksän kertaa tai tuo luku on jonkin laskutoimituksen tulos:

kuva Calcolatore.png

Sovelmana jotakin seuraavanlaista:

Selain ei ymmärrä Javaa!

(Ei ole perusteellisesti testattu!)

Kurssikysely

Vastaa kurssikyselyyn ja vakuuta ohjaaja siitä!

Vastaa kurssikyselyyn osoitteessa http://ilmo.cs.helsinki.fi/kurssit/servlet/Valinta. Valitse Ohjelmoinnin jatkokurssi. Muista myös lähettää lomake! Lähetysnäppäin on lomakkeen lopussa. Vastaukset ovat anonyymejä, joten ei tarvitse ujostella... Ja tästäkin tehtävästä siis saa "rastin", kunhan vain vakuuttaa ohjaajan siitä, että vastattu on.

Vastauksilla ihan oikeasti on merkitystä laitoksen opetusta kehitettäessä! Myös tuo viimeinen kohta, vapaa teksti, on mitä tärkein: siellä voi antaa täsmäpalautetta ja loistavia kehitysideoita!