3. Unterrichtsblock

Fehlerbehandlung mit try & except

Wenn in einem Programm ein Fehler passiert, bricht Python ab und zeigt eine Fehlermeldung. Das passiert schnell, zum Beispiel bei einer falschen Eingabe. Mit try und except fängt dein Programm den Fehler ab und reagiert selbst darauf, statt abzustürzen.

Probiere zuerst aus: Was passiert bei diesem Code? Lies die letzte Zeile der Fehlermeldung. Dort stehen der Fehlertyp (ValueError) und eine Erklärung.

zahl = int("abc")
print("Das wird nie erreicht")

try und except

Im try-Block steht der Code, bei dem ein Fehler passieren kann. Tritt ein Fehler auf, springt Python sofort in den except-Block.

try:
    zahl = int(input("Gib eine Zahl ein: "))
    print("Doppelt so viel:", zahl * 2)
except ValueError:
    print("Das war keine Zahl!")

Bestimmte Fehler abfangen

Man kann mehrere except-Blöcke für verschiedene Fehlertypen anlegen. Mit as e erhältst du die Original-Fehlermeldung.

try:
    a = int(input("Zähler: "))
    b = int(input("Nenner: "))
    print(a / b)
except ValueError:
    print("Bitte ganze Zahlen eingeben.")
except ZeroDivisionError as e:
    print("Fehler:", e)

Häufige Fehlertypen:

  • ValueError: Der Wert passt nicht, z. B. int("abc")
  • TypeError: Falscher Datentyp, z. B. "Alter: " + 42
  • ZeroDivisionError: Teilung durch 0
  • IndexError: Der Listenindex existiert nicht
  • KeyError: Der Dictionary-Schlüssel existiert nicht
  • NameError: Die Variable ist nicht definiert
  • FileNotFoundError: Die Datei existiert nicht

Hinweis: Ein except: ohne Fehlertyp fängt jeden Fehler ab, auch Tippfehler im eigenen Code. Dadurch bleiben Fehler unsichtbar. Gib deshalb immer den erwarteten Fehlertyp an. Eine Liste aller Fehlertypen findest du unter docs.python.org.

Aufgabe 1 – Drei Fehler abfangen

int("abc")
10 / 0
zahlen = [1, 2, 3]; zahlen[5]

Sage für jede Zeile voraus, welchen Fehlertyp Python meldet. Fange dann jeden Fehler mit dem passenden except ab und gib eine eigene Meldung aus.

else und finally

  • else wird ausgeführt, wenn kein Fehler aufgetreten ist.
  • finally wird immer ausgeführt, egal ob ein Fehler auftrat oder nicht. Praktisch zum Aufräumen.
try:
    zahl = int(input("Zahl: "))
except ValueError:
    print("Keine Zahl.")
else:
    print("Alles gut, du hast", zahl, "eingegeben.")
finally:
    print("Danke für die Eingabe.")

Selbst einen Fehler auslösen: raise

Mit raise löst du selbst einen Fehler mit eigenem Text aus, zum Beispiel wenn eine Eingabe zwar eine Zahl, aber unsinnig ist.

try:
    x = int(input("Alter: "))
    if x < 0:
        raise ValueError("Das Alter darf nicht negativ sein.")
except ValueError as e:
    print("Ungültig:", e)

Aufgabe 2 – Alter prüfen

Frage nach dem Alter (Ganzzahl). Bei Text soll eine Meldung erscheinen. Bei einer negativen Zahl löst du mit raise selbst einen ValueError aus und fängst ihn ab.

Muster: So lange fragen, bis es passt

while True:
    try:
        zahl = int(input("Zahl: "))
        break                      # gültige Eingabe: Schleife verlassen
    except ValueError:
        print("Bitte eine ganze Zahl eingeben.")

String-Formatierung mit f-Strings

Aus dem 1. Jahr kennst du die format()-Methode mit Platzhaltern {}:

preis = 49
txt = "Der Preis liegt bei {:.2f} Euro"
print(txt.format(preis))

Kürzer und lesbarer geht es mit f-Strings: Ein f vor dem Text, die Variablen stehen direkt in den geschweiften Klammern.

name = "Lina"
preis = 4.5
print(f"{name} zahlt {preis:.2f} Euro")
print(f"Doppelter Preis: {preis * 2:.2f} Euro")   # auch Berechnungen sind möglich

Formatangaben

Nach einem Doppelpunkt steht die Formatangabe:

  • {preis:.2f} zwei Nachkommastellen
  • {name:<12} linksbündig in 12 Zeichen
  • {preis:>8.2f} rechtsbündig in 8 Zeichen, zwei Nachkommastellen
  • {nummer:03d} mit führenden Nullen auffüllen (007)
artikel = "Brezel"
preis = 1.2
nummer = 7
print(f"{nummer:03d} {artikel:<10}{preis:>8.2f} EUR")
# 007 Brezel        1.20 EUR

Eine Sammlung weiterer Formatierungen findest du unter learnpython.com.

Aufgabe 3 – Kassenbon (Teil 1)

warenkorb = {
    "Brezel": 1.20,
    "Vollkornbrot": 4.50,
    "Butterhörnchen": 0.95,
    "Kaffee": 2.80,
}

Gib jeden Artikel in einer Zeile aus. Die Namen stehen linksbündig, die Preise rechtsbündig untereinander, zum Beispiel „Brezel 1.20 EUR“.

Iteratoren (Kurzform)

Dieses Thema ist nicht prüfungsrelevant. Es hilft dir aber zu verstehen, was eine for-Schleife eigentlich macht.

  • Ein Iterable ist alles, was man mit einer Schleife durchlaufen kann: Listen, Strings, Dictionaries, range(), Dateien.
  • Ein Iterator liefert die Elemente eines Iterables nacheinander. Mit iter() erzeugst du ihn, mit next() holst du das nächste Element.
  • Ist nichts mehr übrig, löst next() den Fehler StopIteration aus.
wort = "Katze"
iterator = iter(wort)
print(next(iterator))   # K
print(next(iterator))   # a
print(next(iterator))   # t
print(next(iterator))   # z
print(next(iterator))   # e
print(next(iterator))   # StopIteration

Eine for-Schleife macht genau das: Sie ruft iter() auf, holt Element für Element mit next() und hört bei StopIteration auf, ohne dass du es siehst.

Aufgabe 4 – Das Wort „Katze“

Erzeuge mit iter() einen Iterator für „Katze“ und rufe next() sechsmal auf. Was passiert beim sechsten Aufruf?

Abschlussaufgaben

Jetzt wird es anspruchsvoller. Hier kombinierst du mehrere Dinge und musst selbst überlegen. Nimm dir Zeit, es müssen nicht alle Aufgaben geschafft werden.

Aufgabe 5 – Der Taschenrechner, der nicht abstürzt

  1. Frage zwei Zahlen (auch Kommazahlen) und einen Operator (+, -, *, /) ab und gib das Ergebnis aus.
  2. Fange ab: keine Zahl eingegeben (ValueError), Division durch 0 (ZeroDivisionError) und einen unbekannten Operator. Bei Letzterem löst du mit raise selbst einen ValueError mit eigenem Text aus.
  3. Gib das Ergebnis nur bei fehlerfreier Rechnung aus (else) und am Ende immer „Rechnung beendet.“ (finally).

Aufgabe 6 – Frag so lange, bis es passt

Ein Anmeldeformular fragt das Alter ab. Erlaubt ist eine Ganzzahl von 1 bis 120.

  1. Frage in einer Endlosschleife (while True) nach dem Alter.
  2. Bei ungültiger Eingabe (Text, Kommazahl, leere Eingabe) gibst du eine Meldung aus und fragst erneut.
  3. Liegt die Zahl nicht zwischen 1 und 120, löse mit raise einen ValueError mit eigenem Text aus und fange ihn wie die anderen Fehler ab.
  4. Bei gültiger Eingabe beendest du die Schleife mit break und gibst aus: „Willkommen! Du bist 17 Jahre alt.“

Zusatz: Baue daraus eine Funktion frage_zahl(text, minimum, maximum), die du auch für andere Eingaben verwenden kannst.

Aufgabe 7 – Der komplette Kassenbon

Erweitere deinen Kassenbon aus Aufgabe 3:

  1. Gib vor jedem Artikel eine laufende Nummer aus (01, 02, …).
  2. Berechne die Summe und gib sie unter einer Trennlinie aus.
  3. Gib zusätzlich die enthaltene Mehrwertsteuer aus (19 % stecken im Endpreis: brutto / 1.19 * 0.19).
  4. Schreibe eine der f-String-Zeilen als format()-Aufruf um und prüfe, ob dasselbe herauskommt.

Zusatz: Gib eine Tabelle Celsius → Fahrenheit für 0 bis 100 Grad in 20er-Schritten mit sauber untereinander stehenden Spalten aus (Fahrenheit = Celsius * 9 / 5 + 32).

Aufgabe 8 – Die for-Schleife von innen

  1. Baue mit while True, next() und try / except StopIteration eine Schleife, die dasselbe macht wie for zeichen in wort: print(zeichen) (für das Wort „Katze“).
  2. Ist die Liste [1, 2, 3] ein Iterator oder ein Iterable? Teste next([1, 2, 3]) und next(iter([1, 2, 3])) und erkläre den Unterschied.

Bonus – Generator: Mit yield baust du dir einen eigenen Iterator. Schreibe einen Generator quadrate(ende), der die Quadratzahlen von 1 bis ende liefert, und einen Generator gerade_zahlen(liste), der aus einer Liste nur die geraden Zahlen liefert.

def zaehle_bis(ende):
    zahl = 1
    while zahl <= ende:
        yield zahl
        zahl += 1

for x in zaehle_bis(5):
    print(x)