Aufgabe 3.1 (Laboraufgabe, CSV-Ein- und Ausgabe)wg/Lehre/Vorlesung-SS2009/Loesungen_3.… ·...

download Aufgabe 3.1 (Laboraufgabe, CSV-Ein- und Ausgabe)wg/Lehre/Vorlesung-SS2009/Loesungen_3.… · Übungen zu „Objektorientierte Programmierung in Java“ PD Dr. Wolfgang Goerigk Sommersemester

If you can't read please download the document

Transcript of Aufgabe 3.1 (Laboraufgabe, CSV-Ein- und Ausgabe)wg/Lehre/Vorlesung-SS2009/Loesungen_3.… ·...

  • bungen zu Objektorientierte Programmierung in Java PD Dr. Wolfgang Goerigk Sommersemester 2009

    Aufgabe 3.1 (Laboraufgabe, CSV-Ein- und Ausgabe)

    Eine hufig wiederkehrende Aufgabe ist das Einlesen von sog. comma separated values (.csv), wie sie beispielsweise von Spreadsheet-Programmen (Excel o..), von Kalender-Programmen oder auch aus Datenbanken exportiert werden knnen. Diese Dateien haben i.a. die folgende Form:

    Nettobetrag;Mehrwertsteuersatz;Bruttobetrag;Waehrung

    1000,75;19;;

    2000,00;7;;$

    3000,00;19;;Euro

    Der Separator ist im deutschsprachigen Umfeld hufig ";" statt ",", weil "," in Fliekommazahlen verwendet wird. Pro Zeile mssen nicht alle Felder belegt sein (z.B. ist das Bruttobetrag-Feld in dem o.a. Beispiel leer), aber die Anzahl der Felder ist immer gleich. Manche Felder enthalten Zahlen (z.B. Nettobetrag (double) und Mehrwertsteuersatz (int) im o.a. Beispiel), manche Zeichenreihen (z.B. oder Euro im Feld Waehrung des o.a. Beispiels). Im csv-Format ist die Kopfzeile nicht obligatorisch. Sie dient aber zur Benennung der Spalten, aber auch als auch als Muster fr die Anzahl der Spalten. Die erste Datenzeile ist also i.a. die zweite Zeile der Datei.

    Schreiben Sie ein Programm, das die Datei Mehrwertsteuer.csv (s.o.) und in der gleichen Form auf die Standardausgabe wieder ausgibt, allerdings zustzlich mit berechnetem Bruttobetrag, also in der Form

    Nettobetrag;Mehrwertsteuersatz;Bruttobetrag;Waehrung

    1000,75;19; 1190,89; 2000,00;7; 2140,00;$ 3000,00;19; 3570,00;Euro

    Hinweise:

    1. Benutzen Sie die Klasse java.util.Scanner zweimal: o Einmal mit dem Argument new File("Mehrwertsteuer.csv"), um den Dateiinhalt

    zeilenweise einzulesen und o einmal mit der jeweils eingelesenen Zeile als String-Argument, um die einzelnen Datenstze

    zu separieren. Die Methode Scanner useDelimiter (String pattern) liefert zu einem Scanner einen neuen, der die in pattern enthaltene Zeichenreihe, z.B. ";", als Separator verwendet.

    2. Die Klasse java.text.DecimalFormat knnen Sie verwenden, um den berechneten Bruttowert wiederum in einer lokalisierten (deutschen) Form mit "," als Dezimalpunkt und z.B. zwei Nachkommastellen auszugeben. Die Zeile

    s = new DecimalFormat("0.00").format(x);

    liefert zur Zahl x einen solchen String in s.

    Musterlsungen Serie 3

  • Lsung:

    package Serie_3;

    import java.io.File;

    import java.io.FileNotFoundException;

    import java.io.PrintStream;

    import java.util.Scanner;

    import java.text.*;

    public class Aufgabe_3_1 {

    public static void main(String[] args) throws FileNotFoundException {

    Scanner scanner =

    new Scanner(new File("Mehrwertsteuer.csv")).useDelimiter(";");

    String header = scanner.nextLine();

    String line;

    double netto, brutto;

    int mwst;

    String brutto_string, waehrung;

    // -----------------------------------------------

    // Zeilenweises Einlesen und Verarbeiten der Datei

    // "Mehrwertsteuer.csv"

    // --------------------

    while (scanner.hasNextLine()) {

    Scanner sc =

    new Scanner(scanner.nextLine()).useDelimiter(";");

    netto = sc.nextDouble();

    mwst = sc.nextInt();

    sc.next();

    waehrung = sc.next();

    brutto = netto + netto * mwst / 100.0;

    brutto_string = new DecimalFormat("0.00").format(brutto);

    System.out.println

    (netto + ";" + mwst + ";" + ";"

    + brutto_string + ";" + waehrung);

    }

    }

    }

    Bei dieser Aufgabe sind vor allem zwei Dinge wichtig:

    1. Wechsel des Eingabemediums: Statt von der Kommandozeile oder der Standard-Eingabe (Konsole) lesen wir die Eingabedaten jetzt aus einer Datei. Die eigentliche Berechnung bleibt davon i.W. unberhrt.

    2. Mit Schleifen knnen wir die Eingabedatei zeilenweise einlesen, verarbeiten und zeilenweise wieder ausgeben. Fr die Unabhngigkeit von der Lnge der Eingabedatei (der Anzahl der Zeilen) ist die while-Schleife wichtig: Solange noch eine Zeile vorhanden ist, lies sie, verarbeite die Daten und gebe die Resultate aus.

  • Aufgabe 3.2 (Laboraufgabe, CSV-Ausgabe)

    Ergnzen Sie Ihr Programm aus Aufgabe 3.1 so, dass es die Ausgabe zustzlich in eine Textdatei (z.B. Ergebnis.csv) ausgibt. Fgen Sie dabei sowohl in der Kopfzeile als auch in den Datenzeilen zwischen den Feldern "Mehrwertsteuersatz" und "Bruttobetrag" eine neue Spalte "Mehrwertsteuer" ein, die in den Datenzeilen die berechnete Mehrwertsteuer enthlt.

    Zur Probe knnen Sie die entstehende Datei beispielsweise in Excel oder OpenOffice Calc einlesen.

    Lsung:

    package Serie_3;

    import java.io.File;

    import java.io.FileNotFoundException;

    import java.io.PrintStream;

    import java.util.Scanner;

    import java.text.*;

    public class Aufgabe_3_2 {

    public static void main(String[] args) throws FileNotFoundException {

    Scanner scanner =

    new Scanner(new File("Mehrwertsteuer.csv")).useDelimiter(";");

    PrintStream output = new PrintStream("Ergebnis1.csv");

    // -----------------------------------

    // Ausgabe der Kopfzeile der csv-Datei

    // -----------------------------------

    String header = scanner.nextLine();

    String n = "Nettobetrag", m1 = "Mehrwertsteuersatz",

    m2 = "Mehrwertsteuer",

    b = "Bruttobetrag", w = "Waehrung",

    sep = ";";

    header = n+sep+m1+sep+m2+sep+b+sep+w;

    output.println(header);

    double netto, brutto, steuer;

    int mwst;

    String brutto_string, waehrung, steuer_string;

    // -----------------------------------------------

    // Zeilenweises Einlesen und Verarbeiten der Datei

    // "Mehrwertsteuer.csv"

    // --------------------

    while (scanner.hasNextLine()) {

    Scanner sc =

    new scanner(scanner.nextLine()).useDelimiter(";");

    netto = sc.nextDouble();

    mwst = sc.nextInt();

  • sc.next();

    waehrung = sc.next();

    brutto = netto + netto * mwst / 100.0;

    brutto_string = new DecimalFormat("0.00").format(brutto);

    steuer = netto * mwst / 100.0;

    steuer_string = new DecimalFormat("0.00").format(steuer);

    output.println

    (netto + ";" + mwst + ";" + steuer + ";"

    + brutto + ";" + waehrung);

    }

    }

    }

    Bei dieser Aufgabe passiert sichts weiter als ein Wechsel des Ausgabemediums. Statt auf die Standardausgabe schreiben wir nun die Resultate in eine Datei, d.h auf einen PrintStream.

    Aufgabe 3.3 (Laboraufgabe, CSV-Ausgabe)

    Berechnen Sie Mehrwertsteuer und Bruttobetrag fr alle Nettobetrge zwischen 0,- und 30.000,- im Abstand 1.000,- , d.h. fr die Nettobetrge 0,- , 1000 , 2000 usw. Geben Sie die zugehrigen Daten analog Aufgabe 3.2 in eine csv-Datei aus.

    Zusatz (freiwillig):

    Versuchen Sie, die Daten so in eine csv-Datei zu schreiben, dass Sie diese mit Excel oder OpenOffice Calc einlesen und in einem Diagramm hbsch darstellen knnen.

    Lsung:

    package Serie_3;

    import java.io.File;

    import java.io.FileNotFoundException;

    import java.io.PrintStream;

    import java.text.*;

    public class Aufgabe_3_3 {

    public static void main(String[] args) throws FileNotFoundException {

    PrintStream output = new PrintStream("Ergebnis2.csv");

    // -----------------------------------

    // Ausgabe der Kopfzeile der csv-Datei

    // -----------------------------------

    String n = "Nettobetrag", m1 = "Mehrwertsteuersatz",

    m2 = "Mehrwertsteuer",

    b = "Bruttobetrag", w = "Waehrung", sep = ";";

    String header = n+sep+m1+sep+m2+sep+b+sep+w;

    output.println(header);

    double netto, brutto, steuer;

  • int mwst = 19;

    String brutto_string, steuer_string;

    // ------------------------------------------

    // Ausgabe fuer 0,-, 1000,-, ..., 30.000,--

    // in die Datei Ergebnis2.csv

    // --------------------------

    for (netto = 0; netto

  • import java.util.Scanner;

    import java.text.*;

    public class Aufgabe_3_3 {

    public static void main(String[] args) throws FileNotFoundException {

    Scanner scanner = new Scanner(new File("Bankauszuege.csv"))

    .useDelimiter(";");

    scanner.nextLine(); // Ueberlese die Kopfzeile

    //--------------------------------------

    // Die csv-Datei enthaelt die 10 Spalten

    //

    // buchungsdatum (Datum)

    // valuta (Datum)

    // betrag (double)

    // waehrung (String)

    // empf1 (String)

    // empf2 (String)

    // primanota (String)

    // blzempf (String)

    // ktoempf (String)

    // zweck (String)

    //

    // --------------

    double betrag;

    String zweck;

    double sum_betrag = 0.0, sum_ueb = 0.0;

    // ---------------------------------------------

    // Lese und verarbeite die csv-Datei zeilenweise

    // ---------------------------------------------

    while (scanner.hasNextLine()) {

    Scanner sc =

    new Scanner(scanner.nextLine()).useDelimiter(";");

    // ----------------------------------------------------

    // Beende die Schleife, falls die eingelesene Zeile die

    // Zeile ";;;;;;;;;" ist (buchungsdatum = "")

    // -------------------------------------------

    if (sc.next().equals("")) // buchungsdatum

    break;

    sc.next(); // valuta

    betrag = sc.nextDouble();

    sum_betrag = sum_betrag + betrag;

    sc.next(); // waehrung

    sc.next(); // empf1

    sc.next(); // empf2

    sc.next(); // primanota

    sc.next(); // blzempf

    sc.next(); // ktoempf

    zweck = sc.next();

    if (zweck.equals("UEBERWEISUNG")) {

    sum_ueb = sum_ueb + betrag;

    }

    //String sum = new DecimalFormat("0.00").format(sum_betrag);

    }

  • // -----------------------------------------------------------

    // Einlesen der letzten Zeile. In der dritten Spalte steht der

    // alte Saldo

    // ----------

    Scanner sc = new Scanner(scanner.nextLine()).useDelimiter(";");

    sc.next();

    sc.next();

    double saldo = sc.nextDouble();

    // -----------------------

    // Vorbereiten der Ausgabe

    // -----------------------

    String oldSaldo = new DecimalFormat("0.00").format(saldo);

    String sumBetrag = new DecimalFormat("0.00").format(sum_betrag);

    String newSaldo =

    new DecimalFormat("0.00").format(sum_betrag + saldo);

    String ueberw = new DecimalFormat("0.00").format(sum_ueb);

    // -------

    // Ausgabe

    // -------

    System.out.println("Alter Saldo: " + oldSaldo);

    System.out.println("Summe Bewegungen: " + sumBetrag);

    System.out.println("Neuer Saldo: " + (newSaldo));

    System.out.println("Summe UEBERWEISUNGEN: " + ueberw);

    }

    }

    Aufgabe 3.5 (Hausaufgabe, Guter und schlechter Programmierstil)

    Gegeben sei das folgende Programm:

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

    Test t = new Test();

    System.out.println(t.doSomething(1000));}

    double doSomething(int schritte) {double pi=0.0;

    10

    for(double i=0,n=-1.0,z=1.0;i

  • public class Test {

    // ----------------------------------------------------------------------

    // Hauptprogramm. Berechnet eine Naeherung fr die Kreiszahl Pi mit einer

    // Schrittzahl von 1000. Erhhung der Schrittzahl erhht die

    // Genauigkeit der Naeherung

    // --------------------------

    public static void main(String[] args) {

    Test t = new Test();

    System.out.println(t.berechne_pi(1000));

    }

    // -----------------------------------------------

    // Berechnung von Pi durch die alternierende Reihe

    // Pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + 1/17 -...

    //

    // schritte = Anzahl der Iterationsschritte

    // ----------------------------------------

    double berechne_pi(int schritte) {

    double pi = 0.0;

    double nenner = -1.0, zaehler = 1.0;

    for (int i = 0; i < schritte; i++) {

    nenner = nenner + 2;

    pi = pi + zaehler / nenner;

    zaehler = -zaehler;

    }

    return pi * 4;

    }

    }

    Das Programm berechnet eine Nherung der Kreiszahl mithilfe der alternierenden Reihe

    Pi/4 = 1 - 1/3 +

    1/5 - 1/7 +

    1/9 - 1/11 +

    1/13 - 1/15 +

    1/17 -...

    Aufgabe 3.6 (Hausaufgabe, Zahlen raten)

    Das Spiel Zahlen raten funktioniert so: Ein Spieler A (der Computer) denkt sich eine Zahl zwischen 0 und einer bestimmten Obergrenze aus. Der Spieler B (Benutzer) muss nun versuchen, die Zahl zu erraten. Nach jedem Versuch bekommt er dazu von A den Hinweis, ob seine geratene Zahl zu gro oder zu klein ist. Errt er die Zahl richtig, endet das Spiel. Ein Dialog auf der Konsole knnte z.B. wie folgt aussehen:

    Bitte geben Sie eine Zahl zwischen 1 und 100 ein:

    35

    Zahl zu klein. Bitte erneut versuchen:

    75

    Zahl zu gross. Bitte erneut versuchen:

    50

    Gewonnen. Sie haben 3 Versuche bentigt

    Programmieren Sie das Spiel. Zu Beginn ermittelt das Programm eine zu ratende Zufallszahl zwischen 1 und 100, z.B. durch

    int zufallsZahl = (int) (Math.random() * 100 + 1);

    Die statische Methode java.lang.Math.random() liefert eine Zufallszahl zwischen im Intervall [0..1).

  • Im Erfolgsfall wird die Anzahl der Versuche ausgegeben. Wenn Sie Lust und Zeit haben, spielen Sie Ihr Spiel solange, bis Sie die Zahl ebenfalls in hchstens drei Versuchen erfolgreich geraten haben.

    Lsung:

    package Serie_3;

    import java.io.*;

    import java.util.*;

    public class Zahlenraten {

    public static void main (String[] args) throws Exception {

    // ------------------------------

    // Zufallszahl zwischen 1 und 100

    // ------------------------------

    int zufallsZahl = (int) (Math.random() * 100 + 1);

    int anzahlVersuche = 1;

    Scanner input = new Scanner(System.in);

    System.out.println("Rate eine Zahl zwischen 0 und 100:");

    int eingabe = input.nextInt();

    // -------------------------------------------------------

    // Lese solange int-Werte von der Standardeingabe, bis die

    // eingegebene Zahl gleich der anfangs berechneten Zufallszahl ist.

    // ----------------------------------------------------------------

    while (eingabe != zufallsZahl) {

    anzahlVersuche++;

    if (eingabe < zufallsZahl) {

    System.out.println("Zahl zu klein. Nocheinmal:");

    eingabe = input.nextInt();

    }

    else if(eingabe > zufallsZahl) {

    System.out.println("Zahl zu gro. Nocheinmal:");

    eingabe = input.nextInt();

    }

    }

    System.out.println

    ("Erraten mit "+ anzahlVersuche +" Versuch(en)");

    }

    }