| ValuuttaMuunnos.java |
1 package demo12;
2
3 import java.io.*;
4 import java.util.Iterator;
5 import java.util.Map;
6 import java.util.Set;
7 import java.util.TreeMap;
8 import java.util.Map.Entry;
9
10
11
12 import fi.jyu.mit.ohj2.*;
13
14 /**
15 * Ohjelmalla vaihdetaan valuuttoja
16 * Versioon 1.1 lis?tty Valuutat -luokan rajapintaa
17 * uusia metodeja, mm. getVaihdettuMaara, getValuutat
18 * @author Vesa Lappalainen
19 * @version 1.0, 15.03.2003
20 * @version 1.1, 09.04.2003
21 *
22 *
23 *
24 * Tietorakenne treemapiksi, demo12 teht. 1-2
25 *
26 *
27 * @author Antti My?h?nen
28 */
29 public class ValuuttaMuunnos {
30 // #DYNAMICIMPORT
31
32 /**
33 * Muunnetaan valuuttaa
34 * @param args ei k?yt?ss?
35 * @throws IOException jos jokin menee pieleen tiedoston luvussa
36 */
37 public static void main(String[] args) throws IOException {
38 Valuutat valuutat = new Valuutat();
39 /*
40 valuutat.lisaa(1.0,"mk");
41 valuutat.lisaa(5.7,"$");
42 valuutat.lisaa(5.9,"EUROA");
43 valuutat.lisaa(0.6,"SKr");
44 */
45 if (!valuutat.lue()) {
46 System.out.println("Valuuttoja ei saa luettua");
47 return;
48 }
49
50 ValuuttaNaytto naytto = new ValuuttaNaytto(valuutat);
51
52 while (naytto.kysy()) {
53 naytto.tulosta();
54 }
55
56 }
57
58 /**
59 * Luokka yhdelle valuutalle ja sen muunnoskertoimelle
60 * @author Vesa Lappalainen
61 * @version 1.0, 15.03.2003
62 */
63 public static class Valuutta {
64 private double maara;
65
66 private String valuutannimi;
67
68 /**
69 * Alustetaan valuutta
70 * @param maara valuutan m??r?
71 * @param valuutannimi yksikk?
72 * @example
73 * <pre name="test">
74 * Valuutta val = new Valuutta(2,"lati");
75 * val.toString() === "2.00 lati";
76 * </pre>
77 */
78 public Valuutta(double maara, String valuutannimi) {
79 this.maara = maara;
80 this.valuutannimi = valuutannimi;
81 }
82
83 /**
84 * Alustetaan jonolla joka on muotoa 10 SKr
85 * @param jono josta valuutan tiedot etsit??n.
86 * @example
87 * <pre name="test">
88 * Valuutta val = new Valuutta("10 SKr"); // NOPMD
89 * val.toString() === "10.00 SKr";
90 * </pre>
91 */
92 public Valuutta(String jono) {
93 parse(jono);
94 }
95
96 /**
97 * Otetaan valuutan tiedot jonosta jonka muoto on 10 SKr
98 * @param jono josta valuutan tiedot etsit??n.
99 * <pre name="test">
100 * Valuutta val = new Valuutta("");
101 * val.parse("10 SKr");
102 * val.toString() === "10.00 SKr";
103 * </pre>
104 */
105 public final void parse(String jono) {
106 StringBuffer sb = new StringBuffer(jono);
107 maara = Mjonot.erotaDouble(sb, maara);
108 valuutannimi = Mjonot.erota(sb, '|', valuutannimi);
109 }
110
111 /**
112 * @return valuutan tiedot muodossa 10.00 SKr
113 */
114 @Override
115 public String toString() {
116 return Mjonot.fmt(maara, 4, 2) + " " + valuutannimi;
117 }
118
119 /**
120 * Verrataan vastaako valuutta hakumaskia.
121 * Hakumaskin alkuosan pit?? t?sm?t?.
122 * @param maski Hakumaski
123 * @return true jos vastaa
124 * <pre name="test">
125 * Valuutta val = new Valuutta("10 SKr");
126 * val.onko("SKr") === true; // NOPMD
127 * val.onko("s") === true;
128 * val.onko("Dkr") === false;
129 * val.onko("kr") === false;
130 * val.onko(".kr") === true;
131 * val.onko("$") === false;
132 * Valuutta val2 = new Valuutta("1.6 $");
133 * val2.onko("$") === true;
134 * val2.onko("s") === false;
135 * </pre>
136 */
137 public boolean onko(String maski) {
138 String umaski = maski.toUpperCase().replaceAll("\\$", "\\\\\\$")
139 + ".*";
140 String val = valuutannimi.toUpperCase();
141 return val.matches(umaski);
142 }
143
144 /**
145 * Vertaa onko parametrina tuodussa valuutassa sama yksikk?
146 * @param obj verrattava valuutta
147 * @return true jos sama valuuttajono
148 * <pre name="test">
149 * Valuutta val = new Valuutta("10 SKr");
150 * Valuutta val2 = new Valuutta(0,"s");
151 * Valuutta val3 = new Valuutta(0,"$");
152 * val.onko(val2) === true;
153 * val.onko(val3) === false;
154 * </pre>
155 */
156 public boolean onko(Object obj) {
157 if (obj instanceof String)
158 return onko((String) obj);
159 if (obj instanceof StringBuffer)
160 return onko(((StringBuffer) obj).toString());
161 if (!(obj instanceof Valuutta))
162 return false;
163 return onko(((Valuutta) obj).valuutannimi);
164 }
165
166 /** @return valuutan kerroin (sama kuin m??r?) */
167 public double getKerroin() {
168 return maara;
169 }
170
171 /** @return valuutan m??r? */
172 public double getMaara() {
173 return maara;
174 }
175
176 /** @return Valuutan yksikk? */
177 public String getValuutannimi() {
178 return valuutannimi;
179 }
180
181 /**
182 * Asetetaan valuutan yksikk?
183 * @param valuutannimi asetettava yksikk?
184 */
185 public void setValuutta(String valuutannimi) {
186 this.valuutannimi = valuutannimi;
187 }
188
189 }
190
191 /**
192 * Luokka valuuttojen tallentamiselle
193 * @author Vesa Lappalainen
194 * @version 1.0, 15.03.2003
195 */
196 public static class Valuutat {
197 //private int lkm = 0;
198 private Valuutta ekaValuutta;
199
200 private Map<String, Valuutta> alkiot = new TreeMap<String, Valuutta>();
201
202
203 /**
204 * Lis?t??n tietorakenteeseen uusi valuutta.
205 * @param val lis?tt?v? valuutta.
206 * @example
207 * <pre name="test">
208 * Valuutat valuutat = new Valuutat();
209 * Valuutta skr = new Valuutta("10 SKr");
210 * valuutat.lisaa(new Valuutta("1 e"));
211 * valuutat.lisaa(skr);
212 * valuutat.lisaa(new Valuutta("1.6 $"));
213 * valuutat.ekanValuutannimi() === "e";
214 * valuutat.getKerroin("$") ~~~ 1.6;
215 * valuutat.get("s") === skr;
216 * valuutat.get("$") == skr === false;
217 * </pre>
218 */
219 public void lisaa(Valuutta val) {
220 alkiot.put(val.getValuutannimi(), val);
221 if (getAlkiotSize() == 1) ekaValuutta = val;
222 }
223
224 /**
225 * Lis?t??n tietorakenteeseen uusi valuutta.
226 * @param kerroin lis?tt?v?n valuutan kerroin
227 * @param valuutta listt?v?n valuutan yksikk?
228 * @example
229 * <pre name="test">
230 * Valuutat valuutat = new Valuutat();
231 * valuutat.lisaa(1,"e");
232 * valuutat.lisaa(10,"SKr");
233 * valuutat.lisaa(1.6,"$");
234 * valuutat.ekanValuutannimi() === "e";
235 * valuutat.getKerroin("$") ~~~ 1.6;
236 * valuutat.get("s").getValuutannimi() === "SKr";
237 * valuutat.getValuutannimi("s") === "SKr";
238 * </pre>
239 */
240 public void lisaa(double kerroin, String valuutta) {
241 lisaa(new Valuutta(kerroin, valuutta));
242 }
243
244
245 /**
246 * Palauttaa valuuttatietojen lukum??r?n
247 * @return valuuttatietojen lukum??r?
248 */
249 public int getAlkiotSize() {
250 return alkiot.size();
251 }
252
253
254 /**
255 * Palautetaan ensimm?isen tietorakenteessa olevan
256 * valuutan yksikk?.
257 * @return ensimm?isen valuutan yksikk?
258 */
259 public String ekanValuutannimi() {
260 if (getAlkiotSize() <= 0)
261 return "";
262 return ekaValuutta.getValuutannimi();
263
264 }
265
266 /**
267 * Etsit??n hakujonoa vastaava valuutta
268 * @param valuutannimi etsitt?v?n valuutan yksikk?
269 * @return null jos ei l?ydy, muuten l?ytynyt valuutta.
270 */
271 public Valuutta get(String valuutannimi) {
272 //if (alkiot.get(valuutannimi) != null) return alkiot.get(valuutannimi);
273
274 Set<Map.Entry<String, Valuutta>> entrySet = alkiot.entrySet();
275 Iterator<Entry<String, Valuutta>> iteraattori = entrySet.iterator();
276
277 while ( iteraattori.hasNext() ) {
278 Valuutta temp = iteraattori.next().getValue();
279 if ( temp.onko(valuutannimi) ) return temp;
280 }
281 return null;
282 }
283
284 /**
285 * Etsit??n hakujonoa vastaavan valuutan kerroin.
286 * @param valuutannimi etsitt?v?n valuutan yksikk?
287 * @return valuutan kerroin tai 1.0 jo ei l?ydy.
288 */
289 public double getKerroin(String valuutannimi) {
290 Valuutta val = get(valuutannimi);
291 if (val == null)
292 return 1.0;
293 return val.getKerroin();
294 }
295
296 /**
297 * Etsit??n hakujonoa vastaavan valuutan kerroin.
298 * @param valuutta etsitt?v? valuutan hakujono valuutassa
299 * @return valuutan kerroin tai 1.0 jo ei l?ydy.
300 */
301 public double getKerroin(Valuutta valuutta) {
302 return getKerroin(valuutta.getValuutannimi());
303 }
304
305 /**
306 * Etsit??n hakujonoa vastaavan valuutan yksikk?
307 * @param valuutannimi etsitt?v?n valuutan yksikk?
308 * @return valuutan kerroin tai 1.0 jo ei l?ydy.
309 */
310 public String getValuutannimi(String valuutannimi) {
311 Valuutta val = get(valuutannimi);
312 if (val == null)
313 return "";
314 return val.getValuutannimi();
315 }
316
317 /**
318 * Etsit??n hakujonoa vastaavan valuutan yksikk?
319 * @param valuutta etsitt?v? valuutan hakujono valuutassa
320 * @return valuutan kerroin tai 1.0 jo ei l?ydy.
321 */
322 public String getValuutta(Valuutta valuutta) {
323 return getValuutannimi(valuutta.getValuutannimi());
324 }
325
326 /**
327 * Luetaan valuutat.dat nimesest? tiedostosta valuutat.
328 * @return true jos lukeminen onnistui false jos tiedosto ei aukea.
329 * @throws IOException jos jokin menee pieleen tiedoston k?sittelyss?.
330 */
331 public boolean lue() throws IOException {
332 BufferedReader fi = Tiedosto.avaa_lukemista_varten("valuutat.dat");
333 if (fi == null)
334 return false;
335
336 try {
337 String jono;
338 while ((jono = fi.readLine()) != null) {
339 if ("".equals(jono))
340 continue;
341 lisaa(new Valuutta(jono)); // NOPMD - pakko luoda silmukassa
342 }
343 } finally {
344 fi.close();
345 }
346
347 return true;
348 }
349
350 /**
351 * Palautetaan haettavaa valuuttaa vastaava summa kantavaluutassa.
352 * @param nimi haettavan valuutan hakujono
353 * @param maara raham??r? joka muutetaan kantavaluuttaan.
354 * @return raham??r? muutettuna kantavaluuttaan.
355 */
356 public double getVaihdettuMaara(String nimi, double maara) {
357 return getKerroin(nimi) * maara;
358 }
359
360 /**
361 * Palautetaan valuutassa olevaa hakujonoa vastaava valuutta-olio
362 * kantavaluuttana.
363 * @param val valuutta jossa on hakujono ja m??r? joka muutetaan kantavaluuttaan.
364 * @return tiedot kantavaluuttana
365 * @example
366 * <pre name="test">
367 * Valuutat valuutat = new Valuutat();
368 * valuutat.lisaa(1,"e");
369 * valuutat.lisaa(10,"SKr");
370 * valuutat.lisaa(1.6,"$");
371 * valuutat.getVaihdettuMaara("s",3.0) ~~~ 30.0;
372 * valuutat.getVaihdettu(new Valuutta(3.0,"s")).toString() === "30.00 e";
373 * valuutat.getVaihdettu(new Valuutta(3.0,"$")).toString() === "4.80 e";
374 * </pre>
375 */
376 public Valuutta getVaihdettu(Valuutta val) {
377 double vaihdettu_maara = getVaihdettuMaara(val.getValuutannimi(),
378 val.getMaara());
379 return new Valuutta(vaihdettu_maara, ekanValuutannimi());
380 }
381
382 /**
383 * Palautetaan merkkijonotaulukkona kaikkien valuuttojen nimet
384 * @return valuuttojen nimet merkkijonotaulukossa.
385 * @example
386 * <pre name="test">
387 * Valuutat valuutat = new Valuutat();
388 * valuutat.lisaa(1,"e");
389 * valuutat.lisaa(10,"SKr");
390 * valuutat.lisaa(1.6,"$");
391 * String nimet[] = valuutat.getValuuttojenNimet();
392 * nimet.length === 3;
393 * nimet[0] === "e";
394 * nimet[1] === "SKr";
395 * nimet[2] === "$";
396 * </pre>
397 */
398 public String[] getValuuttojenNimet() {
399 String nimet[] = new String[getAlkiotSize()];
400
401 Set<Map.Entry<String, Valuutta>> entrySet = alkiot.entrySet();
402 Iterator<Entry<String, Valuutta>> iteraattori = entrySet.iterator();
403
404 for (int i = 0; i < getAlkiotSize(); i++)
405 nimet[i] = iteraattori.next().getKey();
406 return nimet;
407 }
408
409 }
410
411 /**
412 * N?ytt?luokka valuuttojen k?ytt?miseksi konsolisovelluksesta.
413 * @author Vesa Lappalainen
414 * @version 1.0, 15.03.2003
415 *
416 * @example
417 * <pre name="test">
418 * @example
419 * <pre name="test">
420 * #import fi.jyu.mit.ohj2.Suuntaaja;
421 *
422 * Valuutat valuutat = new Valuutat();
423 * valuutat.lisaa(1,"e");
424 * valuutat.lisaa(10,"SKr");
425 * valuutat.lisaa(1.6,"$");
426 * ValuuttaNaytto naytto = new ValuuttaNaytto(valuutat);
427 *
428 * Suuntaaja.StringInput si = new Suuntaaja.StringInput();
429 * Suuntaaja.StringOutput so = new Suuntaaja.StringOutput();
430 *
431 * si.input(""); naytto.kysy() === false;
432 * si.input("loppu"); naytto.kysy() === false;
433 * so.reset();
434 * si.input("3 s"); naytto.kysy() === true;
435 * so.reset(); naytto.tulosta(); so.ero("3.00 SKr on 30.00 e\n") === null;
436 * si.input("3 $"); naytto.kysy() === true;
437 * so.reset(); naytto.tulosta(); so.ero("3.00 $ on 4.80 e\n") === null;
438 * si.input("2"); naytto.kysy() === true;
439 * so.reset(); naytto.tulosta(); so.ero("2.00 $ on 3.20 e\n") === null;
440 * si.input("k lati"); naytto.kysy() === true; // Yksikk?? ei l?ydy
441 * so.reset(); naytto.tulosta(); so.ero("2.00 on 2.00 e\n") === null;
442 * si.input(""); naytto.kysy() === false;
443 *
444 * si.palauta(); so.palauta();
445 *
446 * </pre>
447 * </pre>
448 */
449 public static class ValuuttaNaytto {
450 private final Valuutat valuutat;
451
452 private final Valuutta valuutta = new Valuutta("");
453
454 /**
455 * Alustetaan n?ytt? k?ytt?m??n valuuttataulukkoa.
456 * @param valuutat valuuttataulukko jota k?ytet??n.
457 */
458 public ValuuttaNaytto(Valuutat valuutat) {
459 this.valuutat = valuutat;
460 }
461
462 /**
463 * Kysyt??n valuutan tietoja.
464 * @return true jos kysely onnistui.
465 */
466 public boolean kysy() {
467 String jono = Syotto.kysy("M??r? ja valuutta");
468
469 if ("".equals(jono))
470 return false;
471 if ("loppu".equals(jono))
472 return false;
473
474 valuutta.parse(jono);
475 String val = valuutat.getValuutta(valuutta);
476 valuutta.setValuutta(val);
477
478 return true;
479 }
480
481 /**
482 * Tulostetaan kysytyn valuutan tiedot.
483 */
484 public void tulosta() {
485
486 Valuutta vaihdettu = valuutat.getVaihdettu(valuutta);
487 System.out.println(valuutta + " on " + vaihdettu);
488 }
489
490 }
491
492 }