Komplette überarbeitung der Kosten berechnung

Hinzufügen des Kreditkartenbezahlens
Veränderung um speicherung der Schulden zu garantieren
Vorbereitung für kommentation, fehler suche
main
Leon Maximilian Löhle 2024-10-07 23:09:39 +02:00
parent d4ead6ec4b
commit 423e6e33b0
5 changed files with 137 additions and 154 deletions

View File

@ -9,6 +9,7 @@ public class Main {
Scanner sc = new Scanner(System.in); Scanner sc = new Scanner(System.in);
Parkhaus parkhaus = new Parkhaus(); Parkhaus parkhaus = new Parkhaus();
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm"); SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm");
String einfahrtenzeit;
sdf.setLenient(false); sdf.setLenient(false);
while (true) { while (true) {
try { try {
@ -36,7 +37,14 @@ public class Main {
String kennzeichenEinfahrt = sc.nextLine(); String kennzeichenEinfahrt = sc.nextLine();
System.out.println("Wann sind Sie in das Parkhaus eingefahren. Bitte im Format TT.MM.JJJJ SS:MM"); System.out.println("Wann sind Sie in das Parkhaus eingefahren. Bitte im Format TT.MM.JJJJ SS:MM");
String einfahrtEingabe = sc.nextLine(); String einfahrtEingabe = sc.nextLine();
Date einfahrtZeit = sdf.parse(einfahrtEingabe); Date einfahrtZeit;
if (einfahrtEingabe.isEmpty()) {
einfahrtZeit = new Date();
System.out.println("Es wird die aktuelle Systemzeit : " + sdf.format(einfahrtZeit) + " verwendet");
} else {
einfahrtZeit = sdf.parse(einfahrtEingabe);
System.out.println("Eingegebene Einfahrtzeit " + sdf.format(einfahrtZeit));
}
Auto auto = new Auto(kennzeichenEinfahrt, einfahrtZeit); Auto auto = new Auto(kennzeichenEinfahrt, einfahrtZeit);
parkhaus.addAuto(auto); parkhaus.addAuto(auto);
break; break;
@ -45,46 +53,51 @@ public class Main {
System.out.println("Bitte geben Sie das Kennzeichen des Fahrzeugs ein, welches ausfahren soll :"); System.out.println("Bitte geben Sie das Kennzeichen des Fahrzeugs ein, welches ausfahren soll :");
String kennzeichenAusfahrt = sc.nextLine(); String kennzeichenAusfahrt = sc.nextLine();
auto = parkhaus.autoFinden(kennzeichenAusfahrt); auto = parkhaus.autoFinden(kennzeichenAusfahrt);
if (auto == null) { System.out.println("Wann wurde aus dem Parkhaus ausgefahren? Bitte im Format TT.MM.JJJJ SS:MM");
System.out.println("Keine Auto gefunden mit diesem Kennzeichen gefunden."); String ausfahrtEingabe = sc.nextLine();
Date ausfahrtZeit;
if (ausfahrtEingabe.isEmpty()) {
ausfahrtZeit = new Date();
System.out.println("Es wird die aktuelle Systemzeit : " + sdf.format(ausfahrtZeit) + " verwendet");
} else { } else {
System.out.println("Wann sind Sie aus dem Parkhaus ausgefahren. Bitte im Format TT.MM.JJJJ SS:MM"); ausfahrtZeit = sdf.parse(ausfahrtEingabe);
String ausfahrtEingabe = sc.nextLine(); System.out.println("Es wird die ausfahrzeit: " + sdf.format(ausfahrtZeit) + " verwendet");
Date ausfahrtZeit = sdf.parse(ausfahrtEingabe);
double kosten = parkhaus.berechneParkKosten(auto, ausfahrtZeit);
auto.setSchulden(auto.getSchulden() + kosten);
parkhaus.ausfahrt(kennzeichenAusfahrt, ausfahrtZeit);
} }
parkhaus.ausfahrt(kennzeichenAusfahrt, ausfahrtZeit);
break; break;
case 3: case 3:
System.out.println("Für welches Kennzeichen sollen die Parkgebühren bezahlt werden"); System.out.println("Für welches Kennzeichen sollen die Parkgebühren bezahlt werden");
String kennzeichenBezahlt = sc.nextLine(); String kennzeichenBezahlt = sc.nextLine();
auto = parkhaus.autoFinden(kennzeichenBezahlt); auto = parkhaus.autoFinden(kennzeichenBezahlt);
if (auto == null) { System.out.println("Wann bezahlen Sie? Bitte im Format TT.MM.JJJJ SS:MM ");
System.out.println("Keine Auto gefunden mit diesem Kennzeichen gefunden."); String bezahltEingabe = sc.nextLine();
Date bezahltZeit;
if (bezahltEingabe.isEmpty()) {
bezahltZeit = new Date();
System.out.println("Es wird die aktuelle Systemzeit : " + sdf.format(bezahltZeit) + " verwendet");
} else { } else {
System.out.println("Wann bezahlen Sie? Bitte im Format TT.MM.JJJJ SS:MM "); bezahltZeit = sdf.parse(bezahltEingabe);
String bezahltEingabe = sc.nextLine(); System.out.println("Es wird die Bezahlzeit: " + sdf.format(bezahltZeit) + " verwendet");
Date bezahltZeit = sdf.parse(bezahltEingabe);
System.out.println(parkhaus.berechneParkKosten(auto, bezahltZeit));
parkhaus.ausfahrt(kennzeichenBezahlt, bezahltZeit);
auto.setSchulden(0);
} }
System.out.println("Bitte geben Sie die 16 Stellige Nummer Ihrer Visa Karte ein");
String kreditkartennummer = sc.nextLine();
parkhaus.bezahlen(kennzeichenBezahlt, bezahltZeit, kreditkartennummer);
break; break;
default: default:
System.out.println("Falsche Eingabe bitte nur 1,2 oder 3 eingeben"); System.out.println("Falsche Eingabe bitte nur 1,2,3 oder 4 eingeben");
break; break;
} }
} } catch (ParseException e) {
catch (ParseException e) {
System.out.println("Leider haben Sie ein Datum eingegeben was nicht existiert"); System.out.println("Leider haben Sie ein Datum eingegeben was nicht existiert");
System.out.println("Bitte veruschen Sie es erneut"); System.out.println("Bitte veruschen Sie es erneut");
} }
} }
sc.close(); sc.close();
} }

View File

@ -9,6 +9,7 @@ public class Parkhaus {
private int maxPlatz; private int maxPlatz;
private int platz; private int platz;
private List<Auto> autos; private List<Auto> autos;
private List<Auto> ausgefahrene;
public double getMaxNachtPreis() { public double getMaxNachtPreis() {
return maxNachtPreis; return maxNachtPreis;
@ -43,8 +44,9 @@ public class Parkhaus {
} }
public Parkhaus() { public Parkhaus() {
this.ausgefahrene = new ArrayList<Auto>();
this.preis = 1.0; this.preis = 1.0;
this.maxPlatz = 1; this.maxPlatz = 180;
this.platz = getMaxPlatz(); this.platz = getMaxPlatz();
this.maxNachtPreis = 5; this.maxNachtPreis = 5;
this.maxTagesPreis = 15; this.maxTagesPreis = 15;
@ -52,11 +54,24 @@ public class Parkhaus {
} }
public void addAuto(Auto auto) { public void addAuto(Auto auto) {
Auto vorhandenesAuto = autoFinden(auto.getKennzeichen());
if (vorhandenesAuto != null) {
System.out.println("Ein Auto mit diesem Kennzeichen ist bereits eingefahren.");
return;
}
Auto ausgefahrenesAuto = autoFinden(auto.getKennzeichen());
if (ausgefahrenesAuto != null) {
auto.setSchulden(ausgefahrenesAuto.getSchulden());
ausgefahrene.remove(ausgefahrenesAuto);
System.out.println("Das Auto hat noch Schulden von " + auto.getSchulden() + " €.");
}
if (platz <= 0) { if (platz <= 0) {
System.out.println("Das Parkhaus ist voll, Sie können nicht mehr einfahren!"); System.out.println("Das Parkhaus ist voll, Sie können nicht mehr einfahren!");
} else { } else {
autos.add(auto); autos.add(auto);
platz -= 1; platz -= 1;
System.out.println("Das Auto mit dem Kennzeichen " + auto.getKennzeichen() + " ist eingefahren.");
} }
} }
@ -66,9 +81,62 @@ public class Parkhaus {
return auto; return auto;
} }
} }
for (Auto auto : ausgefahrene) {
if (auto.getKennzeichen().equals(kennzeichen)) {
return auto;
}
}
return null; return null;
} }
public void bezahlen(String kennzeichen, Date bezahltZeit, String kreditkartennummer) {
Auto auto = autoFinden(kennzeichen);
if (auto == null) {
System.out.println("Für dieses Kennzeichen ist leider kein Auto vorhanden.");
return; // Methode beenden, falls das Auto nicht gefunden wird
}
double aktuelleKosten = berechneParkKosten(auto, bezahltZeit);
double gesamtSchulden = auto.getSchulden() + aktuelleKosten;
System.out.println("Für die Parkdauer fallen Kosten in Höhe von " + aktuelleKosten + " € an.");
System.out.println("Ihre Gesamtschulden betragen: " + gesamtSchulden + " €.");
System.out.println("Bitte geben Sie Ihre 16-stellige VISA-Kreditkartennummer ein:");
if (!istGueltigeVisaKarte(kreditkartennummer)) {
System.out.println("Ungültige Kreditkartennummer! Bitte versuchen Sie es erneut.");
return;
}
System.out.println("Zahlung erfolgreich! Ihre Schulden wurden beglichen.");
auto.setSchulden(0);
}
private boolean istGueltigeVisaKarte(String kreditkartenNummer) {
if (kreditkartenNummer.length() != 16 || !kreditkartenNummer.startsWith("4")) {
return false;
}
return algoPruf(kreditkartenNummer);
}
private boolean algoPruf(String kartennummer) {
int summe = 0;
boolean verdoppeln = false;
for (int i = kartennummer.length() - 1; i >= 0; i--) {
int ziffer = Character.getNumericValue(kartennummer.charAt(i));
if (verdoppeln) {
ziffer *= 2;
if (ziffer > 9) {
ziffer -= 9;
}
}
summe += ziffer;
verdoppeln = !verdoppeln;
}
return summe % 10 == 0;
}
public void ausfahrt(String kennzeichen, Date ausfahrtZeit) { public void ausfahrt(String kennzeichen, Date ausfahrtZeit) {
Auto auto = autoFinden(kennzeichen); Auto auto = autoFinden(kennzeichen);
if (auto == null) { if (auto == null) {
@ -76,50 +144,56 @@ public class Parkhaus {
return; return;
} }
auto.setAusfahrtZeit(ausfahrtZeit); auto.setAusfahrtZeit(ausfahrtZeit);
double kosten = berechneParkKosten(auto, ausfahrtZeit); double neueKosten = berechneParkKosten(auto, ausfahrtZeit);
System.out.println("Die Koste für das Fahrzeug mit dem eingegebenen Kennzeichen " + kennzeichen + "betragen:"); double bestehendeSchulden = auto.getSchulden();
System.out.println(kosten); auto.setSchulden(bestehendeSchulden + neueKosten);
System.out.println("Da Sie ohne zu Zahlen gegangen sind werden Ihnen die Parkkosten in Höhe von " + neueKosten + "€ hinzugefügt.");
System.out.println("Gesamtschulden belaufen sich jetzt auf: " + auto.getSchulden() + "€.");
autos.remove(auto); autos.remove(auto);
ausgefahrene.add(auto);
platz += 1; platz += 1;
} }
public double berechneParkKosten(Auto auto, Date ausfahrtZeit) { public double berechneParkKosten(Auto auto, Date ausfahrtZeit) {
Date einfahrtZeit = auto.getEinfahrtZeit(); Date einfahrtZeit = auto.getEinfahrtZeit();
if (einfahrtZeit == null || ausfahrtZeit == null) { long parkMinuten = (ausfahrtZeit.getTime() - einfahrtZeit.getTime()) / 60000;
System.out.println("Es wurde keine Ein- oder ausfahrtzeit gesetzt!"); long kostenMinuten = parkMinuten - 15;
} else if (ausfahrtZeit.before(einfahrtZeit)) {
System.out.println("Das ausfahren darf nicht vor dem einfahren liegen! ");
}
long parkDauerMinuten = (ausfahrtZeit.getTime() - einfahrtZeit.getTime()) / (1000 * 60);
double kosten = 0; double kosten = 0;
if (parkDauerMinuten < 0) { if (parkMinuten <= 15) {
System.out.println("Diese Eingaben sind nicht möglich"); System.out.println("Kiss and Ride, die ersten 15 Minuten sind kostenlos");
return 0;
} }
int einFahrtStunde = einfahrtZeit.getHours(); long parkTage = (long) Math.ceil(parkMinuten / (60.0 * 24));
int ausFahrtStunde = ausfahrtZeit.getHours();
if (einFahrtStunde >= 20 || ausFahrtStunde <= 6) { for (int tag = 0; tag < parkTage; tag++) {
if (parkDauerMinuten <= 15) { long restMinuten = kostenMinuten - (tag * 24 * 60);
return 0; long stundenAmTag = Math.min(restMinuten / 60, 24);
}
kosten = maxNachtPreis;
} else {
if (parkDauerMinuten <= 15) {
return 0;
}
parkDauerMinuten -= 15;
long parkDauerStunden = (parkDauerMinuten / 60) + 1;
kosten = parkDauerStunden * preis;
if (parkDauerStunden > 24) { double nachttarifKosten = 0;
kosten = maxTagesPreis; for (int stunde = 0; stunde < stundenAmTag; stunde++) {
int aktuelleStunde = (einfahrtZeit.getHours() + stunde) % 24;
if (aktuelleStunde >= 20 || aktuelleStunde < 6) {
nachttarifKosten += 1;
if (nachttarifKosten > maxNachtPreis) {
nachttarifKosten = maxNachtPreis;
break;
}
}
} }
double tagKosten = Math.min(stundenAmTag, 24) * preis + nachttarifKosten;
tagKosten = Math.min(tagKosten, maxTagesPreis);
kosten += tagKosten;
} }
if (auto.getEAuto()) { if (auto.getKennzeichen().endsWith("E")) {
kosten *= 0.8; kosten *= 0.8;
} }
return kosten; return kosten;
} }
} }

View File

@ -1,104 +0,0 @@
Ich:
Ich habe ein Problem mit Java Code. Ich habe ein Parkhaus programmiert und in der Main Klasse einen Switch-Case. Es wird abgefragt ob man einfahren möchte, bezahlen, ausfahren oder beenden möchte. Nachdem man einfahren auswählt soll man sein kennzeichen und danch das Datum mit Uhrzeit eingeben. Dies passiert über 1,2,3 oder 4 und einem scanner der das eingegebene int ließt. Wenn ich jetzt aber zum beispiel 1 für einfahren wählt wird die eingabe des kennzeichens komplett übersprungen und man kann nur noch direkt das Datum eingeben
ChatGpt:
Es klingt so, als ob es ein Problem mit der Verarbeitung der Benutzereingaben in deinem Switch-Case gibt. Wenn du das Kennzeichen nach der Auswahl des Menüpunktes für das Einfahren abfragen möchtest, solltest du sicherstellen, dass die Eingabeaufforderung für das Kennzeichen direkt nach der Auswahl erfolgt und nicht von einer anderen Eingabe überschrieben wird.
Hier ist ein einfaches Beispiel, das zeigt, wie du das implementieren kannst. Ich werde die Struktur deines Switch-Case darstellen, um das Einfahren, Bezahlen, Ausfahren und Beenden zu demonstrieren:
```java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean running = true;
while (running) {
System.out.println("Wählen Sie eine Option:");
System.out.println("1. Einfahren");
System.out.println("2. Bezahlen");
System.out.println("3. Ausfahren");
System.out.println("4. Beenden");
int option = scanner.nextInt();
scanner.nextLine(); // Leere Zeile einlesen, um den Scanner zu reinigen
switch (option) {
case 1:
System.out.print("Geben Sie Ihr Kennzeichen ein: ");
String kennzeichen = scanner.nextLine();
System.out.print("Geben Sie das Datum mit Uhrzeit ein: ");
String datum = scanner.nextLine();
System.out.println("Auto mit Kennzeichen " + kennzeichen + " ist eingefahren am " + datum);
break;
case 2:
// Logik zum Bezahlen
System.out.println("Bezahlen...");
break;
case 3:
// Logik zum Ausfahren
System.out.println("Ausfahren...");
break;
case 4:
running = false; // Programm beenden
break;
default:
System.out.println("Ungültige Auswahl, bitte versuchen Sie es erneut.");
break;
}
}
scanner.close();
}
}
```
### Erläuterungen:
1. **`scanner.nextLine();` nach `scanner.nextInt();`**: Dies wird verwendet, um den Scanner zu reinigen. Wenn der Benutzer eine ganze Zahl eingibt, bleibt ein Zeilenumbruch im Eingabepuffer. Durch das Hinzufügen von `scanner.nextLine();` wird dieser Zeilenumbruch entfernt, sodass die nächste `nextLine()`-Eingabeaufforderung korrekt funktioniert.
2. **Eingabeaufforderungen**: Die Eingabeaufforderungen für das Kennzeichen und das Datum werden direkt nach der Auswahl der Option gestellt.
### Tipps zur Fehlersuche:
- Stelle sicher, dass die Scanner-Objekte nicht an anderer Stelle in deinem Code das Verhalten beeinflussen.
- Überprüfe, ob du beim Einlesen der Optionen den richtigen Typ verwendest (z. B. `nextInt()` für ganze Zahlen und `nextLine()` für Strings).
- Achte darauf, dass das Programm nicht vorzeitig beendet wird oder in einen unerwarteten Zustand gerät, der die Eingabeaufforderungen überspringt.
Wenn du weitere Details zu deinem bestehenden Code teilst, kann ich dir gezielter helfen!
Ich:
Ist das einlesen einer leeren zeile nach dem Int einlesen notwendig?
ChatGPT:
Ja, das Einlesen einer leeren Zeile nach dem Scannen eines `int` mit `scanner.nextInt()` ist notwendig, wenn du danach mit `scanner.nextLine()` weitere Eingaben vom Benutzer erfassen möchtest. Hier ist der Grund dafür:
- **Eingabepuffer**: Wenn du eine ganze Zahl mit `nextInt()` liest, wird nur die Zahl selbst aus dem Eingabepuffer gelesen. Der Zeilenumbruch (Enter-Taste), den der Benutzer gedrückt hat, bleibt jedoch im Puffer. Das bedeutet, dass die nächste `nextLine()`-Eingabe (die erwartet, dass der Benutzer einen String eingibt) sofort den verbleibenden Zeilenumbruch liest und nicht auf die Eingabe des Benutzers wartet.
### Beispiel:
Wenn du dies nicht tust:
```java
int option = scanner.nextInt(); // Benutzer gibt 1 ein und drückt Enter
String kennzeichen = scanner.nextLine(); // Diese Zeile liest den Zeilenumbruch und überspringt die Eingabe
```
Der `kennzeichen`-String wird leer sein, weil der Zeilenumbruch sofort gelesen wird, ohne dass der Benutzer die Möglichkeit hat, etwas einzugeben.
### Lösung:
Um sicherzustellen, dass die Benutzeraufforderung korrekt funktioniert, solltest du nach dem Scannen der Zahl `nextLine()` aufrufen, um den Zeilenumbruch zu konsumieren:
```java
int option = scanner.nextInt();
scanner.nextLine(); // Liest den Zeilenumbruch
String kennzeichen = scanner.nextLine(); // Jetzt kann der Benutzer korrekt das Kennzeichen eingeben
```
Wenn du sicherstellen möchtest, dass die Eingabeaufforderungen für das Kennzeichen und das Datum wie gewünscht funktionieren, ist dieser Schritt wichtig.

Binary file not shown.