Ohjelmointi 1, syksy 2007 -- Demo 5

Tehtävät julkaistaan:
 Tiistain luennolla 9.10.2007
Palautus viimeistään:
 16.10.2007 klo 18
100% tehtävistä tarkoittaa:
 6 kpl tehty

Kokeillaan uutta, aiempaa kevyempää nousujohteisuutta.

Nyt on nähty aivan kaikki perusrakenteet, joilla suoritusjärjestys määrätään (poikkeuksetkin kertaalleen) ja kaikki perustietorakenteet. Tutustutaan tässä demossa niihin edelleen lisää. Pääasiassa tarvittavat Javan APIn osat ovat String, StringBuilder, Scanner.

Contents

Koodauskäytänteet

Tehtävä 1:

Tämä on erittäin todennäköinen yhden tenttikysymyksen malli: Seuraava ohjelmakoodi on Javan syntaksin mukaista, mutta ei ole vaadittavien käytäntöjen mukainen. Korjaa koodi Java Code Conventions -suosituksen mukaiseksi. Perustele jokainen tekemäsi muutos lyhyesti (pieni kommentti muutoskoodisi perään)

Demossa vastauksesi on kokonainen Javan käännösyksikkö. Varmista että se kääntyy ja toimii vielä muutoksiesi jälkeenkin.

Huono koodi:

// Huono koodi. Korjaa käytänteiden mukaiseksi ja nimeä uudelleen!
// Tässä on try-catch-finally -rakenne, joka ei ole kummempi kuin
// muutkaan lohkorakenteet. Käytä vaikkapa if-else -lauseesta tuttuja
// käytäntöjä.

import java.io.*;
import java.util.Scanner;

    public class HuonoKoodi{

    public static boolean numeroiKoodirivit(
    String tiednimi, PrintStream out){
            FileInputStream syotevirta;
            InputStreamReader virranlukija;
            BufferedReader puskuroituLukija = null;

        try{
            syotevirta = new FileInputStream(tiednimi);
            virranlukija = new InputStreamReader(syotevirta);
            puskuroituLukija = new BufferedReader(virranlukija);
            String rivi; int rnum = 0;
            while((rivi = puskuroituLukija.readLine()) != null){
                out.printf("/*%3d*/  %s%n", ++rnum, rivi);}
        } catch (IOException ioe){
            ioe.printStackTrace(System.err);
            return false;
        } finally {
            try {
                if (puskuroituLukija != null){
                puskuroituLukija.close();
                }
            } catch(IOException ioe) {
            ioe.printStackTrace(System.err);
                return false;
            }}return true;
    }

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

    System.out.print("Anna tiedoston nimi>");
    String tiedostonimi = sc.nextLine();

    if (tiedostonimi.equals("")){
            System.err.println("Ei annettu nimeä");
            return;
        }

        if (!numeroiKoodirivit(tiedostonimi, System.out)){
            System.err.println("Tuli ongelmia!!");
        }
    }
    }

Tenttiin tulevassa koodissa lienee vähemmän korjattavaa, koska se tehdään paperille eikä käytössä ole kätevää tekstieditoria. Notaatio tentissä on jotakin seuraavanlaista: Jokaisen korjattavan kohdan osalta ilmoita alkuperäisestä koodista korvattavan rivin numero ja kirjoita korvaava rivi (tai useampia, jos tarve vaatii). Kirjoita jokainen välilyönti selvästi näkyviin! Jos rivejä pitää poistaa, merkkaa tämä kirjoittamalla "POISTA: rivinumero(t)".

Tehtävä 2:

Kustakin seuraavista merkkijonoista, kerro onko syntaksin mukaan mahdollisuus nimetä Javassa jokin asia sillä. Jos ei ole, kerro miksi ei. Jos on, kerro onko se järkevää. Jos on järkevääkin, kerro mikä asia voisi kannattaa nimetä sillä tavoin ja mikä taas ei. Voit copy-pastata tehtävänannon WWW-versiosta vastauspohjan:

Nimiyrite          Sallittu   Järkevä    Selitys,
                   (on/ei)    (on/ei)    ts. Miksi ei ole sallittu?
                                             Miksi ei ole järkevä?
                                             Jos on, mitä nimeäisit näin.

int                ei         --         int on varattu sana (kokonaislukutyyppi)
int2
l1l
l_1
i
O0
O1
jäätikönPaksuus
KäpälänPuristus
LyhytHetki
Double
double
KILPIKONNA
KILPI_KONNA
KeWL_MUUttUjA
hinta€
hinta£
hinta_euroina
isValid
onToimiva

Muuttuvainen merkkijono

Tehtävä 3:

Käytä StringBuilder -merkkijonoa seuraavan tehtävän toteuttamiseen:

Kirjoita aliohjelma, joka korvaa merkkijonosta char -tyyppisenä parametrina annetun merkin esiintymät toisella char -tyyppisenä parametrina annetulla merkillä. Toteuta algoritmi itse käyttäen metodeja charAt() ja setCharAt()! (Tällaiset perusjutut voipi olla valmiina, mutta harjoitellaan nyt tekemään itse!)

Aliohjelman pitää muuttaa parametrina annetun merkkijono-olion sisältöä (eli se ei voi olla String vaan sen pitää olla valmiiksi StringBuilder).

Aliohjelmaa käyttävä testiohjelma esim. seuraavasti:

Jono alussa: Kuumaa kahvia aamulla
Jono sitten: KUUmaa kahvia aamUlla
Jono sitten: xUUmaa kahvia aamUlla
Jono sitten: xUUm-- k-hvi- --mUll-

Käyttäjän syöte

Tehtävä 4:

Luennolla oli taannoin esimerkkinä tanssilattian suunnitteluohjelma:

http://www.cc.jyu.fi/~nieminen/ohj1/esim/luento06/Tanssilattia2.java

Korjaa ohjelmaa (kaikin tavoin, jotka koet osaavasi) ja ainakin siten että lopputulos ei kaadu väärin syötettyyn lukuarvoon, vaan antaa käyttäjän syöttää uudelleen kirjoitusvirheen jälkeen. Mihin tahansa kehotteeseen on voitava syöttää "kilpikonna", "Uralin pihjalava" tai mitä tahansa eikä ohjelman toiminta saa loppua.

Tehtävä 5:

Kaikki tarvittava löytyy aiemmista esimerkeistä ja Integer-luokan dokumentaatiosta (metodit signatuureilla valueOf(String) ja parseInt(String,int) ). Try-catch -rakenne on uusi.

Tee aliohjelma, joka pyytää konsolikäyttäjältä nelijärjestelmässä koodatun luvun (siis lukujärjestelmä, jossa on numerot 0,1,2 ja 3). Tee siitä näppärä ja käyttömukava - siis kysytään niin kauan kunnes käyttäjä antaa oikeellisen syötteen, ja tyhjällä rivillä tulee paluuarvoksi oletusarvo, joka myös annetaan parametrina.

Tee pääohjelma, jolla käyttäjän antama nelijärjestelmän luku tulostetaan kymmenjärjestelmässä.

Tehtävä 6:

Toteuta lukujärjestelmien harjoittelupeli: Peli valitsee satunnaisia kokonaislukuja väliltä 0-65535 (16 bitillä esitettäviä lukuja), näyttää ne binäärijärjestelmässä ja pyytää pelaajaa syöttämään saman luvun heksalukuna päätteelle. Peli kertoo välittömästi oikean vastauksen ja positiivisen palautteen, jos pelaaja tiesi oikein.

Ohjelman kannalta ei tarvita montaa muunnosta ja ne ovat kaikki automaattisia. Löytyvät Integer -luokan dokumentaatiosta.

Kokeillessasi kannattaa juurruttaa itsellesi ideaa bittijonon muuntamisesta 16-kantaiseksi luvuksi ja toisin päin. (Tärkeätä tietotekniikassa ja siksi melko varma tenttikysymys!) Sehän tapahtuu neljän bitin sarjoissa, joista jokaisesta tulee yksi numero, esim.:

1111110001011010 = fc5a

koskapa neljän sarjat ovat heksanumeroina:

1111  1100  0101  1010
f     c     5     a

kymmenjärjestelmässä siis:

15    12    5     10

Bonussektori

Tehtävä 7:

En tiedä, onko tämä kovin vaativa, jonkin verran vaativa vai ei juurikaan vaativa. Bonussektorilla tämä varmuuden vuoksi on eikä varsinaisissa kysymyksissä :-).

Katso mallia esimerkkiohjelmasta Kirjoitusnopeustesti.java ja vaikka aiemmasta demosta, jossa tehtiin satunnaisluku. Tee pikkunäppärä peli, jolla treenataan lukujärjestelmämuunnosten nopeutta. Esim:

Bittiharjoittelupeli
--------------------

Näytän satunnaisen korkeintaan 16-bittisen bittijonon.  Sinun tulee
kirjoittaa luku heksadesimaalilukuna mahdollisimman nopeasti.
Loppuu, kun annat tyhjän rivin.

0110110010000000>ac80
Oikein. Seuraava:
1111010000100001>abcd
Väärin. Seuraava:

Jne. Kunnes käyttäjä kirjoittaa tyhjän rivin. Lopussa tulostetaan pelaajan tekemien heksamuunnosten nopeus eli oikeita muunnoksia/minuutti.