ITI0011-2015:harjutus 06

Allikas: Kursused
Mine navigeerimisribale Mine otsikasti

Harjutuse tähtaeg on 11. praktikum (10.-11. märts).

Üldine informatsioon harjutuste kohta: ITI0011:harjutused.

Kirjeldus

Kirjutada programm, mis salvestab inimeste kaalud faili ja oskab neid sealt lugeda. Failis on inimese eesnimi ja tema kaal. Näiteks võib fail olla selline:

mati 100
kati 70

See tähendab, et mati kaalub 100 (kg) ja kati kaalub 70 (kg).

Programm küsib kasutajalt nime. Kui selline nimi on failis olemas, kuvatakse kasutajale selle inimese kaal. Kui inimest failis pole, siis küsitakse kasutajalt kaal. Programmi lõppedes kirjutatakse kõik uued andmed faili.

Näiteks kui eelmise näitefaili puhul sisestab kasutaja "mati", kirjutab programm välja 100 (kuna selline info on failis olemas). Kui kasutaja sisestab "toomas", küsib programm kaalu (kuna sellist inimest failis pole). Hiljem (näiteks programmist väljudes) kirjutatakse info faili. Nüüd on fail näiteks selline:

mati 100
kati 70
toomas 90

See programmiosa, mis küsib kasutajalt nime ja kaalu, on teile ette tehtud main meetodis. Seda osa võite soovi korral muuta, aga otseselt vajadust pole. Automaattestid main meetodit ei testi.

Teie peaksite implementeerima ülejäänud meetodid.

Näpunäiteid

Vaata faili kirjutamise näidet: Java:Faili kirjutamine.

Kõige lihtsam on teha nii, et faili uuendamine kirjutab terve faili üle. Selleks on eelnevalt kogu faili sisu loetud klassimuutujasse. writeWeights meetodis siis tuleb klassimuutuja läbi käia ja kogu info faili kirjutada.

Faili formaat

Natuke täpsemalt faili formaadist. Nagu eelnevalt näide oli, võib fail olla kujul:

nimi1 kaal1
nimi2 kaal2

Kui mitu inimest on sama kaaluga, tuleks need ühele reale panna:

nimi1 [nimi2] [nimi3] kaal1
nimi4 [nimi5] [nimi6] kaal2

Näiteks konkreetselt:

mati kalle peeter 100
kadri kati 70

Sellise faili sisu tähendab seda, et nii mati, kalle kui peeter kaaluvad 100 (kg). Samamoodi kadri ja kati kaaluvad mõlemad 70 (kg).

Seega:

  • faili igal real on vähemalt üks nimi
  • faili iga rea viimasel positsioonil on alati kaal
  • faili real võib nimesid olla rohkem kui üks
  • kõik faili ühel real olevad inimesed kaaluvad ühe palju, vastavalt märgitud kaalule viimasel positsioonil
  • kõik nimed koosnevad vaid ladina väiketähtedest
  • nimed ja kaal on eraldatud ühe tühikuga
  • sama kaaluga nimed peaks olema ühel real. Kui selle realiseerimine tundub raske, pane iga nimi ja kaal eraldi reale (päris 100% testitulemust sedasi ei saa).

Teie programm peab oskama sellist faili lugeda ja kirjutada.

Mall

<source lang="java"> import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;

/**

* Caching to file.
* You have a file of weights. Every person has a weight
* in kilograms.
* All the names are unique (there are no duplicate names).
* A name is connected to the weight. Example of file:

*

 * mati 100
 * kati 70
 * 
* 
* This means that mati has a weight of 100 and 
* kati has a weight of 70. If there are names which
* have the same weight, those should be grouped together
* in one line:

*

 * mati juri 100
 * kati kerli 70
 * 
* 
* The general format of the file is:

*

 * name1 [name2] [name3] weight1
 * name4 [name5] [name6] weight2
 * 
* 
* Every line has at least one name and weight.
* A line can consist of additional names
* (all names come before weight). Names consist
* only of characters (not numbers, spaces, commas etc.).
* 
* @author Ago
*
*/

public class EX06 {

/** * The main part. * In this exercise, the main code is provided. * You can modify this code as this method is not tested. * * @param args Command line arguments * @throws IOException Exception which can happen during input reading */ public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader( new InputStreamReader(System.in));

String filename = "weights.txt"; // the program should also work with non-existing file. // in that case there are no name-weight pairs readWeights(filename); while (true) { System.out.println("Name:"); String name = reader.readLine(); if (name == null || name.equals("")) { writeWeights(filename); System.out.println("exiting"); break; } if (name.contains(" ")) { System.out.println("no spaces allowed!"); continue; } Integer weight = getWeight(name); if (weight == null) { System.out.println("Person does not exist in DB."); while (true) { System.out.println("Weight:"); String weightLine = reader.readLine(); if (weightLine != null) { try { weight = Integer.parseInt(weightLine); if (weight > 10 && weight < 200) { setWeight(name, weight); break; } // note that this is not the requirement for other methods // it's just here to add some filtering example

// note2: there is no "else" sentence here. // but as within if-block, "break" breaks out from while, // we get here only if if-block is not executed. // so, we could have this part also in "else" part. System.out.println("weight should be > 10 and < 200"); } catch (NumberFormatException e) { System.out.println("not a number"); } }

} // end of while (true) - asking the weight

} else { System.out.println(name + " weighs " + weight); } } // end of while (true) - asking names reader.close(); }

/** * Sets the weight of the person with the given name. * The weight should be stored in a class variable. * This method should not try write anything to the file. * @param name The name of the person * @param weight The weight of the person */ public static void setWeight(String name, Integer weight) { // TODO: you should store name and weight somehow // tip: HashMap is probably a good idea }

/** * Opens a file with the given name and reads all * the data from it. If the file does not exist, * the method should just catch that error and * no name-weight pairs will be stored. * @param filename */ public static void readWeights(String filename) { String fileContents = ""; // TODO: read file contents


parseWeights(fileContents); }

/** * Parses names and weights from the given string. * This method is usually called by readWeights(String).

*

* This method should not read anything from the file. * All the information needed for this method is provided * as a String argument. *

* The information should be stored in a class variable, * which might be for example HashMap. * * @param contents File contents to parse */ public static void parseWeights(String contents) { // TODO: implement // here you have to split the contents into // names and weights and store them in a // class variable for later use. } /** * Writes weight information from a class variable * into file. * @param filename The filename to be written. * Notice! the file will be overwriten. */ public static void writeWeights(String filename) { // TODO: implement // open the file // write information into file // close the file } /** * Given the person name, the method should return the person's weight. * If the weight does not exist (in a class variable, which also means * that it does not exist in file), NULL is returned. * @param name Person name * @return Weight if the person name exists in the cache (file), * NULL otherwise. */ public static Integer getWeight(String name) { // name exists? // if yes, return the weight // if no, return null return null; } } </source>