191 lines
6.3 KiB
Python
191 lines
6.3 KiB
Python
"""
|
|
Kapitel 12: Exceptions & Fehlerbehandlung 🛡️🛑
|
|
=============================================
|
|
Schulabgleich: 26.0 Exceptions & Fehlerklassen
|
|
|
|
Aufgabe:
|
|
Erstelle ein sicheres Bankkonto- & Geldautomat-System mit benutzerdefinierten
|
|
Exceptions und sauberer Fehlerbehandlung über try-except-else-finally.
|
|
"""
|
|
|
|
from typing import Optional
|
|
|
|
|
|
# ==============================================================================
|
|
# TODO 1: Eigene Exception-Klassen definieren
|
|
# ==============================================================================
|
|
# Erstelle eine Basis-Exception-Klasse 'BankFehler', die von 'Exception' erbt.
|
|
# Erstelle dann 4 abgeleitete Exception-Klassen, die alle von 'BankFehler' erben:
|
|
# 1. UngueltigePinError
|
|
# 2. KontoGesperrtError
|
|
# 3. NichtGenugGuthabenError
|
|
# 4. UngueltigerBetragError
|
|
# ==============================================================================
|
|
|
|
class BankFehler(Exception):
|
|
pass
|
|
|
|
|
|
class UngueltigePinError(BankFehler):
|
|
pass
|
|
|
|
|
|
class KontoGesperrtError(BankFehler):
|
|
pass
|
|
|
|
|
|
class NichtGenugGuthabenError(BankFehler):
|
|
pass
|
|
|
|
|
|
class UngueltigerBetragError(BankFehler):
|
|
pass
|
|
|
|
|
|
# ==============================================================================
|
|
# TODO 2: Klasse Bankkonto
|
|
# ==============================================================================
|
|
class Bankkonto:
|
|
def __init__(self, inhaber: str, pin: str, kontostand: float = 0.0):
|
|
"""
|
|
Initialisiert ein Bankkonto.
|
|
Attribute:
|
|
- self.inhaber: str = inhaber
|
|
- self.pin: str = pin
|
|
- self.kontostand: float = float(kontostand)
|
|
- self.gesperrt: bool = False (Standardwert)
|
|
- self.fehlversuche: int = 0 (Zählt falsche PIN-Eingaben)
|
|
|
|
WICHTIG:
|
|
- Falls kontostand < 0 ist, wirf UngueltigerBetragError!
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
def pin_pruefen(self, eingegebene_pin: str) -> bool:
|
|
"""
|
|
Prüft die eingegebene PIN.
|
|
|
|
Ablauf:
|
|
1. Wenn self.gesperrt True ist:
|
|
-> Wirf sofort KontoGesperrtError("Konto ist gesperrt!")
|
|
2. Wenn eingegebene_pin == self.pin:
|
|
-> Setze self.fehlversuche = 0 zurück
|
|
-> Gib True zurück
|
|
3. Wenn eingegebene_pin != self.pin:
|
|
-> Erhöhe self.fehlversuche um 1
|
|
-> Wenn self.fehlversuche >= 3:
|
|
- Setze self.gesperrt = True
|
|
- Wirf KontoGesperrtError("PIN 3-mal falsch. Konto wurde gesperrt!")
|
|
-> Andernfalls:
|
|
- Wirf UngueltigePinError(f"Falsche PIN! Noch {3 - self.fehlversuche} Versuche.")
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
def einzahlen(self, betrag: float) -> float:
|
|
"""
|
|
Zahlt einen Betrag auf das Konto ein.
|
|
|
|
Regeln:
|
|
1. Wenn self.gesperrt:
|
|
-> Wirf KontoGesperrtError
|
|
2. Wenn betrag <= 0:
|
|
-> Wirf UngueltigerBetragError
|
|
3. Erhöhe self.kontostand um betrag und gib den neuen kontostand zurück.
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
def abheben(self, betrag: float, pin: str) -> float:
|
|
"""
|
|
Hebt Geld vom Konto ab.
|
|
|
|
Regeln:
|
|
1. Prüfe zuerst die PIN mit self.pin_pruefen(pin)
|
|
(wirft bei falscher PIN oder Sperre automatisch die passende Exception)
|
|
2. Wenn betrag <= 0:
|
|
-> Wirf UngueltigerBetragError
|
|
3. Wenn betrag > self.kontostand:
|
|
-> Wirf NichtGenugGuthabenError
|
|
4. Ziehe betrag von self.kontostand ab und gib den neuen kontostand zurück.
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
def sperren(self) -> None:
|
|
"""Sperrt das Konto manuell."""
|
|
self.gesperrt = True
|
|
|
|
def entsperren(self, admin_passwort: str) -> bool:
|
|
"""
|
|
Entsperrt das Konto, wenn admin_passwort == 'ADMIN123' ist.
|
|
Setzt self.gesperrt = False und self.fehlversuche = 0.
|
|
Falls das Passwort falsch ist, wirf UngueltigePinError.
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
def __str__(self) -> str:
|
|
"""
|
|
Gibt einen Status-String zurück:
|
|
z.B. "Bankkonto(Max, Stand: 150.00€, Status: AKTIV)"
|
|
bzw. "Bankkonto(Max, Stand: 150.00€, Status: GESPERRT)"
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
|
|
# ==============================================================================
|
|
# TODO 3: Geldautomat-Auszahlung mit try - except - else - finally
|
|
# ==============================================================================
|
|
def geldautomat_abheben(konto: Bankkonto, betrag: float, pin: str) -> str:
|
|
"""
|
|
Führt eine Abhebung an einem Geldautomaten durch und fängt alle Fehler sauber ab.
|
|
|
|
Verwende die vollständige try-except-else-finally-Struktur:
|
|
|
|
Ablauf:
|
|
1. Erstelle eine leere Liste 'meldungen = []'
|
|
2. try:
|
|
konto.abheben(betrag, pin)
|
|
except UngueltigePinError as e:
|
|
meldungen.append(f"PIN-Fehler: {e}")
|
|
except KontoGesperrtError as e:
|
|
meldungen.append(f"Sicherheits-Fehler: {e}")
|
|
except NichtGenugGuthabenError as e:
|
|
meldungen.append(f"Deckungs-Fehler: {e}")
|
|
except UngueltigerBetragError as e:
|
|
meldungen.append(f"Betrags-Fehler: {e}")
|
|
except BankFehler as e:
|
|
meldungen.append(f"Bank-Fehler: {e}")
|
|
else:
|
|
meldungen.append(f"Auszahlung erfolgreich: {betrag:.2f}€ ausgezahlt. Neuer Stand: {konto.kontostand:.2f}€")
|
|
finally:
|
|
meldungen.append("Bitte Karte entnehmen.")
|
|
|
|
3. Gib die Meldungen mit ' | '.join(meldungen) als einzelnen String zurück.
|
|
"""
|
|
# TODO: Implementieren
|
|
pass
|
|
|
|
|
|
# ==============================================================================
|
|
# Kleiner Test zum Ausprobieren im Terminal:
|
|
# (python3 aufgabe.py)
|
|
# ==============================================================================
|
|
if __name__ == "__main__":
|
|
konto = Bankkonto("Anna", "1234", 250.0)
|
|
print("Konto erstellt:", konto)
|
|
|
|
print("\n--- Test 1: Erfolgreiche Abhebung ---")
|
|
resultat = geldautomat_abheben(konto, 50.0, "1234")
|
|
print(resultat)
|
|
|
|
print("\n--- Test 2: Falsche PIN ---")
|
|
resultat = geldautomat_abheben(konto, 50.0, "9999")
|
|
print(resultat)
|
|
|
|
print("\n--- Test 3: Zu viel abheben ---")
|
|
resultat = geldautomat_abheben(konto, 500.0, "1234")
|
|
print(resultat)
|