# Ja Nein Abfrage und andere Probleme



## FX202 (24. Mrz 2016)

Guten Abend,

da ich absoluter Java Anfänger wird man vielleicht in meinem geposteten Code sehen.
Ich hatte erst ein paar wenige Stunden Unterricht.
Das Programm funktioniert wie es soll obwohl es sicher eine elegantere Lösung gibt.
Mir sind ein paar Dinge unklar.

Erstens:  Ja / Nein Abfrage
Sie funktioniert bis zu einem gewissem Grad.
Wenn ich einen anderen Buchstaben verwende wie j oder n, wird es so behandelt wie wenn ich n drücken würde. Das Programm wird beendet.
Das will ich natürlich nicht. Im derzeitigen Code habe ich auch noch keine Bedinungen für dieses Problem geschaffen weil ich ehrlich gesagt nicht weiß wie ich das mache.

Zweitens: Wenn man aufgefordert wird eine Zahl einzugeben und stattdessen einen Buchstaben verwendet bricht das Programm ab und schreibt mir eine InputMismatchException hin.
Wäre jemand so nett und könnte mir das erklären.
Und für Verbesserungsvorschläge wäre ich auch dankbar.
Wie gesagt ich hatte bisher nicht soviele Unterrichtseinheiten in der Schule und der unten angeführte Code ist nur mein erster Versuch selbstständig etwas zu schaffen.

Liebe Grüße

fx202


PS: ich benutze Netbeans 8.1



```
package zeit;

import java.util.Calendar;
import java.util.Scanner;

/**
*
* @author fx202
*
* Das ist ein Zeitberechnungsprogamm um herauszufinden wann man nach Hause
* gehen darf. Die Sollzeiten richten sich nach den Firmen Zeiten die man da
* sein muss um die sogenannten V-Tage einzuarbeiten FÃ¼r Montag bis Freitag
* gilt: 8 Stunden und 15 Minuten FÃ¼r Freitag gilt: 5 Stunden und 45 Minuten
* Die regulÃ¤re Pause von 30 Minuten wird bei nicht ausstempeln automatisch
* abgezogen Wenn man lÃ¤nger als 30 Minuten abwesend ist wird diese Zeit zu den
* 30 Minuten dazugezÃ¤hlt. Stempelt man unter 30 Minuten wieder ein werden nur
* 30 Minuten Pause verrechnet
*/
public class Zeit {

    static Scanner input = new Scanner(System.in);                              //Eingabe
    static int STUNDEN;                                                         // Die Stunden die der User eingibt
    static int MINUTEN;                                                         // Die Minuten die der User eingibt
    static int MODOH = 480;                                                     // Die 8 Stunden Sollzeit von Montag bis Donnerstag
    static int FRH = 300;                                                       // die 5 Stunden Sollzeit am Freitag
    static int MODOM = 45;                                                      // Die 45 minuten Sollzeit von Montag bis Donnerstag inklusive 30 Minuten Pause
    static int FRHM = 45;                                                       // Die 45 Minuten Sollzeit am Freitag ohne Pause
    static int ZEITTENHOURS = 600;                                              // Der Minutenwert fÃ¼r 10 Stunden
    static String pause;                                                        // Die Pausenzeit die der User eingibt
    static int MINUTENP;                                                        // Der Wert der Pausenzeit
    static int ISTZEITH;                                                        // Die berechneten Stunden
    static int ISTZEITM;                                                        // die berechneten Minuten                                              
    static String programm;

    public static void main(String[] args) {
        System.out.println("Herzlich Willkommen zu der Zeitberechnung!");       // Eine Willkommensmeldung
        Calendar cal = Calendar.getInstance();                                  // Datumsaufruf
        System.out.println("Heute ist der " + cal.get(Calendar.DAY_OF_MONTH) // Der derzeitige Tag
                + "." + (cal.get(Calendar.MONTH) + 1) + "."
                + // das derzeitige Monat und Jahr 
                cal.get(Calendar.YEAR));
        System.out.println("Es ist genau " + (cal.get(Calendar.HOUR_OF_DAY)) // Die derzeitige Uhrzeit
                + ":" + (cal.get(Calendar.MINUTE) + " Uhr."));
        System.out.println("Es ist die " + cal.get(Calendar.WEEK_OF_YEAR) // Die derzeitige Kalender Woche
                + ". Kalenderwoche.");

        do {
            zeitEingabeStunden();                                               // Die Methode mit der die Stunden eingeben werden                                                                    
            zeitEingabeMinuten();                                               // Die Methode mit der die Minuten eingeben werden                                                               
            String Zeit = String.format("%02d:%02d", STUNDEN, MINUTEN);         // Eine Zeitformatierung
            System.out.println("Du bist um " + Zeit + " Uhr erschienen.");
            System.out.println();                                               // Die Eingebene Uhrzeit im richtigen Format                                                              
            pause();                                                            // Die Methode mit der die Pause abgefragt wird
            System.out.println();
            montagBisDonnerstag();                                              // Die Methode mit der die Zeit berechnent wird fuer Montag bis Donnerstag
            System.out.println();
            freitag();                                                          // Die Methode mit der die Zeit fuer Freitag berechnet wird
            System.out.println();
          
          
          
            System.out.println("Nochmal ausfuehren (j/n)?");
            programm = input.next();

            if (programm.equalsIgnoreCase("n")) {
                System.out.println("Baba!");
                break;
            }

            if (programm.equalsIgnoreCase("j")) {
                System.out.println("ok, nochmal");
            }

        } while (programm.equalsIgnoreCase("j") || programm.equalsIgnoreCase("n"));

    }

    public static int zeitEingabeStunden() {

        do {                                                                    // Eine do-while Schleife um eine korrekte Stundenzeit in Int zu erhalten
            System.out.println("Wann bist erschienen?");

            STUNDEN = input.nextInt();

            if (STUNDEN < 0) {
                System.out.println("Falsches Stundenformat!");
            } else if (STUNDEN > 23) {
                System.out.println("hmm, bloed. Der Tag endet mit 23:59.");
            } else {
                break;
            }
        } while (STUNDEN >= 0 || STUNDEN <= 23);
        return STUNDEN;                                                         // Wenn die Eingabe korrekt ist wird die Stundenanzahl zurueckgegeben
    }

    public static int zeitEingabeMinuten() {
        do {                                                                    // Eine do-while Schleife um eine korrekte Minutenzeit in int zu erhalten
            System.out.println("Bitte die Minuten eingeben.");
            MINUTEN = input.nextInt();

            if (MINUTEN < 0) {
                System.out.println("Es gibt nur 60 Minuten.");
            } else if (MINUTEN > 59) {
                System.out.println("Hat dir niemand die Uhrzeit erklaert?");
            } else {
                break;
            }
        } while (MINUTEN >= 0 || MINUTEN <= 59);
        return MINUTEN;                                                         // Wenn die Eingabe korrekt ist wird die Minutenanzahl zurueckgegeben
    }

    public static int pause() {

        do {                                                                    // Eine do-while Schleife um die Pausenzeiten abzufragen
                                                                                // sollten diese unter 30 Minuten liegen wird sie ignoriert
            System.out.println("Hast du Pause gemacht? (j/n)");
            pause = input.next();

            if (pause.matches("n")) {
                System.out.println("Es wird automatisch eine halbe Stunde abgezogen.");
                break;
            }

            if (pause.matches("j")) {
                System.out.println("Wie lange (Eingabe in Minuten)?");
                MINUTENP = input.nextInt();
                if (MINUTENP < 30) {
                    System.out.println("Pausen zwischen 0 - 30min werden ignoriert.");
                    MINUTENP = 0;
                } else if (MINUTENP > 30) {
                    MINUTENP = MINUTENP - 30;
                }
            }

        } while (pause.equalsIgnoreCase("n") && pause.equalsIgnoreCase("j"));

        return MINUTENP;
    }

    public static void montagBisDonnerstag() {
        ISTZEITH = ((STUNDEN * 60) + (MODOH));
        ISTZEITH = ISTZEITH / 60;
        if (ISTZEITH > 23) {
            ISTZEITH = ISTZEITH - 24;

        }
        ISTZEITM = ((MINUTEN) + MODOM + MINUTENP);
        do {
            if (ISTZEITM > 59) {
                ISTZEITH = ISTZEITH + 1;
            }

            if (ISTZEITM > 59) {
                ISTZEITM = ISTZEITM - 60;
            }
        } while (ISTZEITM > 59);

        String Minutenmodo = String.format("%02d", ISTZEITM);
        String Stundenmodo = String.format("%02d", ISTZEITH);

        System.out.println("Du darfst von Montag bis Donnerstag den Arbeitsplatz fruehestens um " + Stundenmodo + ":" + Minutenmodo + "Uhr verlassen.");
        System.out.println();

        ISTZEITH = ((STUNDEN * 60) + (ZEITTENHOURS));
        ISTZEITH = ISTZEITH / 60;
        if (ISTZEITH > 23) {
            ISTZEITH = ISTZEITH - 24;

        }
        ISTZEITM = ((MINUTEN) + MODOM + MINUTENP);
        do {
            if (ISTZEITM > 59) {
                ISTZEITH = ISTZEITH + 1;
            }

            if (ISTZEITM > 59) {
                ISTZEITM = ISTZEITM - 60;
            }
        } while (ISTZEITM > 59);
        String Minutenmodo10h = String.format("%02d", ISTZEITM);
        String Stundenmodo10h = String.format("%02d", ISTZEITH);

        System.out.println("Die taegliche Arbeitzeit von maximal 10 Stunden wird ab " + Stundenmodo10h + ":" + Minutenmodo10h + "Uhr ueberschritten.");

    }

    public static void freitag() {
        ISTZEITH = ((STUNDEN * 60) + (FRH));
        ISTZEITH = ISTZEITH / 60;
        if (ISTZEITH > 23) {
            ISTZEITH = ISTZEITH - 24;
        }
        if (MINUTENP <= 30) {
            MINUTENP = 0;
        }

        ISTZEITM = ((MINUTEN) + FRHM + MINUTENP);
        do {
            if (ISTZEITM > 59) {
                ISTZEITH = ISTZEITH + 1;
            }

            if (ISTZEITM > 59) {
                ISTZEITM = ISTZEITM - 60;
            }
        } while (ISTZEITM > 59);
        String Minutenfr = String.format("%02d", ISTZEITM);
        String Stundenfr = String.format("%02d", ISTZEITH);

        System.out.println("Du darfst am Freitag fruehestens um " + Stundenfr + ":" + Minutenfr + "Uhr gehen.");

    }

}
```


----------



## Joose (24. Mrz 2016)

FX202 hat gesagt.:


> Erstens:  Ja / Nein Abfrage
> Sie funktioniert bis zu einem gewissem Grad.
> Wenn ich einen anderen Buchstaben verwende wie j oder n, wird es so behandelt wie wenn ich n drücken würde. Das Programm wird beendet.
> Das will ich natürlich nicht. Im derzeitigen Code habe ich auch noch keine Bedinungen für dieses Problem geschaffen weil ich ehrlich gesagt nicht weiß wie ich das mache.



Wenn du einen anderen Buchstaben als "j" oder "n" eingibst dann reagiert dein Programm nicht wie wenn du "n" eingibst  Es wird kein "Baba!" ausgegeben.
Eine Bedingung könnte lauten wenn "programm" nicht "j" und nicht "n" ist dann setze es auf "j". Die Bedingung deiner Schleife trifft dann wieder zu und die Schleife wird erneut ausgeführt.



FX202 hat gesagt.:


> Zweitens: Wenn man aufgefordert wird eine Zahl einzugeben und stattdessen einen Buchstaben verwendet bricht das Programm ab und schreibt mir eine InputMismatchException hin.
> Wäre jemand so nett und könnte mir das erklären.



Du verwendest von deinem Scanner die Methode "nextInt", hier wird probiert von den eingelesenen Zeichen probiert eine Zahl zu "erstellen". Da aber Buchstaben keine gültige Ziffern für eine Zahl sind wird eine Exception geworfen. Dein Programm behandelt keine Exceptions und bricht daher ab.
Um eine Exception zu behandeln solltest du dich in das Thema try/catch einlesen.



FX202 hat gesagt.:


> Und für Verbesserungsvorschläge wäre ich auch dankbar.



Allgemein: Variablen werden in lowerCamelCase geschrieben und nicht durchgehend in Großbuchstaben (<- das wären dann Konstanten)

```
if (programm.equalsIgnoreCase("n")) {
                System.out.println("Baba!");
                break;
            }
            if (programm.equalsIgnoreCase("j")) {
                System.out.println("ok, nochmal");
            }
```
Kein Fehler aber schöner und performanter: Verwende auch else bzw. else if
Wenn "programm" den Wert "n" hat dann kann die 2.if Bedingung nicht wahr sein und müsste auch gar nicht mehr geprüft werden.
Außerdem würdest du damit dein Problem 1 lösen können 


```
public static int zeitEingabeStunden() {

        do {                                                                    // Eine do-while Schleife um eine korrekte Stundenzeit in Int zu erhalten
            System.out.println("Wann bist erschienen?");

            STUNDEN = input.nextInt();

            if (STUNDEN < 0) {
                System.out.println("Falsches Stundenformat!");
            } else if (STUNDEN > 23) {
                System.out.println("hmm, bloed. Der Tag endet mit 23:59.");
            } else {
                break;
            }
        } while (STUNDEN >= 0 || STUNDEN <= 23);
        return STUNDEN;                                                         // Wenn die Eingabe korrekt ist wird die Stundenanzahl zurueckgegeben
    }

    public static int zeitEingabeMinuten() {
        do {                                                                    // Eine do-while Schleife um eine korrekte Minutenzeit in int zu erhalten
            System.out.println("Bitte die Minuten eingeben.");
            MINUTEN = input.nextInt();

            if (MINUTEN < 0) {
                System.out.println("Es gibt nur 60 Minuten.");
            } else if (MINUTEN > 59) {
                System.out.println("Hat dir niemand die Uhrzeit erklaert?");
            } else {
                break;
            }
        } while (MINUTEN >= 0 || MINUTEN <= 59);
        return MINUTEN;                                                         // Wenn die Eingabe korrekt ist wird die Minutenanzahl zurueckgegeben
    }
```
Diese beiden Methoden schauen sich von der Struktur her sehr ähnlich. -> doppelter Code
Die einzigen Unterschiede sind die Grenzwerte und Texte. Hier könnte man den Code vereinfachen so das die do/while Schleife nur 1x geschrieben werden muss.


```
public static int frageNachZahl(int untereGrenze, int obereGrenze, String abfrageText, String fehlerText) {
   int zahl;
   do {
     System.out.println(abfrageText);
     zahl = input.nextInt();

     if (zahl < untereGrenze) {
       System.out.println(fehlerText);
     } else if (zahl > obereGrenze) {
       System.out.println(fehlerText);
     } else {
       break;
     }
   } while (zahl >= untereGrenze || zahl <= obereGrenze);
   return zahl;
}

public void zeitEingabeMinuten() {
    MINUTEN = frageNachZahl(0, 59, "Bitte die Minuten eingeben:", "Das ist keine gültige Angabe für Minuten!");
}
```
 

```
if (pause.matches("n")) {

            if (pause.matches("j")) {
```
Strings sollten mit equals verglichen werden.

In deiner Methode "montagBisDonnerstag" hast du wieder sehr ähnlichen Code, diese könnte man wahrscheinlich ebenfalls auslagern in eine Methode um doppelten Code zu vermeiden. 
Der Code von der Methode "freitag" schaut diesem ebenfalls ähnlich.

Ansonsten lässt sich noch sagen: Methoden stellen Tätigkeiten dar, daher sollten ihr Name auch eine Tätigkeit sein => "berechneZeit", "frageNach", "kalkuliere", ...
Außerdem sollten die Methodennamen sprechend sein, anhand des Namen sollte der Leser schon erkennen können was die Methode macht. "freitag" ist ein schlechter Name, ich kann nur erkennen das die Methode etwas mit Freitag zu tun hat, aber ob sie mir mein Essen bestellt oder für mich Lotto spielt kann ich nicht erkennen. "berechneArbeitszeitFreitag" wäre das schon besser.


----------



## FX202 (24. Mrz 2016)

Vielen Dank für deine Zeit und die Kritik.
Von try und catch habe ich schon etwas gelesen. Konnte es aber bisher nicht korrekt anwenden. Werde mich etwas mehr in try/catch einlesen.
Ja du hast recht die Methoden ähneln sich bzw sind fast gleich, nur ist mir kein anderer Weg eingefallen ich werde deinen Vorschlag anwenden.
Das hat mir schon geholfen.
Vielen Dank Joose
mfg
fx202


----------



## FX202 (24. Mrz 2016)

Lieber Joose,
deine vorgeschlagenen Methoden (fragNachZahl und zeitEingabe) funktionieren wunderbar
habe den ursprünglichen code nun vereinfacht mit:

```
public static int frageNachZahl(int untereGrenze, int obereGrenze, String abfrageText, String fehlerText) {
        int zahl;
        do {
            System.out.println(abfrageText);
            zahl = input.nextInt();

            if (zahl < untereGrenze) {
                System.out.println(fehlerText);
            } else if (zahl > obereGrenze) {
                System.out.println(fehlerText);
            } else {
                break;
            }
        } while (zahl >= untereGrenze || zahl <= obereGrenze);
        return zahl;
    }
```
und:

```
public static void zeitEingabe() {
        stunden = frageNachZahl(0, 23, "Bitte die Stunden eingeben:", "Das ist keine gültige Angabe für Stunden!");
        minuten = frageNachZahl(0, 59, "Bitte die Minuten eingeben:", "Das ist keine gültige Angabe für Minuten!");
```

Deine Vorschlag mit der [j/n] Abfrage habe ich nun auch geändert auf :

```
System.out.println("Programm Neustart? Programm mit [n] beenden");
  programm = input.next();
  if (programm.equalsIgnoreCase("n")) {
  System.out.println("Baba!");
  break;
  }
  if (programm.equalsIgnoreCase("j")) {
  System.out.println("ok, nochmal");
  }
  } while ((!programm.equals("j")) || !programm.equals("n"));
```

mit else oder else if bin ich irgendwie nicht klar gekommen aber liegt wohl an mir und weils schon etwas zu spät ist.

Ich bedanke mich trotzdem nochmal

gn8
fx202


----------



## Xyz1 (24. Mrz 2016)

FX202 hat gesagt.:


> PS: ich benutze Netbeans 8.1



löblich.

So hätte ich die j/n Frage gebastelt, bei einem Fehler wird's Programm beendet, du kannst noch einen Catch drum machen:

```
/**
     * @author DerWissende on 03/24/2016
     * @param args
     */
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int modus = 1;
        while (true) {
            String line;
            int index;
            switch (modus) {
                case 1:
                    System.out.println("j, n oder x eingeben:");
                    line = input.nextLine();
                    if (line.equalsIgnoreCase("j")) {
                        modus = 2;
                    } else if (line.equalsIgnoreCase("n")) {
                        modus = 3;
                    } else {
                        modus = 4;
                    }
                    break;
                case 2:
                    System.out.println("In welchen Modus soll gewechselt werden (Zahl)?:");
                    line = input.nextLine();
                    index = Integer.parseInt(line);
                    modus = index;
                    break;
                case 3:
                    System.out.println("In welchen Modus soll gewechselt werden (Zahl)?:");
                    line = input.nextLine();
                    index = Integer.parseInt(line);
                    modus = index;
                    break;
                case 4:
                    System.out.println("In welchen Modus soll gewechselt werden (Zahl)?:");
                    line = input.nextLine();
                    index = Integer.parseInt(line);
                    modus = index;
                    break;
                default:
                    throw new AssertionError();
            }
        }
    }
```


----------



## Joose (24. Mrz 2016)

FX202 hat gesagt.:


> mit else oder else if bin ich irgendwie nicht klar gekommen aber liegt wohl an mir und weils schon etwas zu spät ist.



Hier ein Beispiel mit if/else if

```
boolean running = false;
do {
   System.out.println("Programm Neustart? Programm mit [n] beenden");
   programm = input.next();
   if (programm.equalsIgnoreCase("n")) {
     System.out.println("Baba!");
     running = false;
   } else if (programm.equalsIgnoreCase("j")) {
     System.out.println("ok, nochmal");
     running = true;
   } else {
     System.out.println("fehlerhafte eingabe");
     running = true;     
   }
} while (running);
```


----------

