Lektion 35 von 35Python
Python · Lektion 35 · 60 Minuten
Boss-Level: Die Messdaten-Pipeline
Das lernst du
- Generatoren, Decorators und Type Hints zusammen einsetzen
- Fehlerhafte Daten robust überspringen
- Professionellen, gut lesbaren Code schreiben
Der letzte Boss
Du hast die Profi-Stufe fast geschafft: Generatoren, Decorators, Type Hints, async. Im letzten Boss-Level baust du eine Daten-Pipeline – so heißt eine Kette von Verarbeitungsschritten, wie sie in Wissenschaft und Industrie ständig vorkommt: Rohdaten rein, saubere Ergebnisse raus.
Baustein 1: Generator mit Filter
def nur_gerade(zahlen):
for z in zahlen:
if z % 2 == 0:
yield z
print(list(nur_gerade(range(10))))Ein Generator rechnet bei Bedarf – auch bei Millionen von Messwerten braucht er kaum Speicher.
Baustein 2: Decorator mit Gedächtnis
Funktionen sind Objekte – man kann ihnen sogar Attribute geben:
import functools
def laut(funktion):
@functools.wraps(funktion)
def huelle(*args):
print("→ Aufruf von", funktion.__name__)
return funktion(*args)
return huelle
@laut
def doppelt(x: int) -> int:
return 2 * x
print(doppelt(21))
print(doppelt.__name__) # dank functools.wraps nicht „huelle“Baustein 3: Robust bleiben
Echte Daten sind nie perfekt. Statt abzustürzen, überspringt gute Software kaputte Einträge – und zählt sie vielleicht mit:
eingaben = ["3", "drei", "4"]
for e in eingaben:
try:
print(int(e) * 10)
except ValueError:
print("übersprungen:", repr(e))Geschafft? Dann hast du alle drei Stufen gemeistert – Respekt! Als Nächstes: Nimm dir ein eigenes Projekt vor. Die Spielwiese ist dein Labor. 🎓
Deine Aufgabe
Jetzt bist du dran
Ein Sensor liefert Messwerte als Texte – manche sind kaputt ("Fehler", ""). Schreib den Generator messwerte(zeilen), der nur die gültigen Werte als float liefert (kaputte überspringen, mit try/except). Schreib den Decorator zaehle_aufrufe, der in funktion.aufrufe mitzählt, wie oft die Funktion aufgerufen wurde. Dekoriere damit mittelwert(werte: list[float]) -> float, der den Durchschnitt zurückgibt.
def messwerte(zeilen):
pass
def zaehle_aufrufe(funktion):
pass
def mittelwert(werte):
pass
daten = ["21.5", "Fehler", "22.0", "", "23.5"]
werte = list(messwerte(daten))
print(werte)
print(mittelwert(werte))- Denkanstoß
Ein Generator liefert Werte mit
yieldstatt sie alle mitreturnzurückzugeben. - Welcher Befehl hilft?
float("x")löst einenValueErroraus. Fang ihn mittry/exceptab und mach mitcontinueweiter.Die Hüll-Funktion im Decorator erhöht
huelle.aufrufeum 1 und ruft dann die echte Funktion auf. Setzhuelle.aufrufe=0, bevor du huelle zurückgibst – und schreib@zaehle_aufrufeüber mittelwert.Schreib die Typen dazu:
defmittelwert(werte: list[float])->float: – und benutzefunctools.wrapsim Decorator, damit sie erhalten bleiben. - Lückencode – ergänze die ___
___ def messwerte(zeilen): for zeile in ___: try: ___ except ValueError: continue def zaehle_aufrufe(funktion): ___ def huelle(*args, **kwargs): huelle.aufrufe += ___ return ___ huelle.aufrufe = ___ return ___ ___ def mittelwert(werte: list[float]) -> float: return ___ daten = ["21.5", "Fehler", "22.0", "", "23.5"] werte = list(messwerte(daten)) print(werte) print(mittelwert(werte))
Ohne Hinweise gelöst gibt es einen ⭐ auf deiner Fortschrittsseite.
Lösung anzeigen🔒 Erst nach allen Hinweisen oder 2 Prüf-Versuchen
Versuch es erst selbst – aus Fehlern lernt man am meisten. Hier ist eine mögliche Lösung:
import functools
def messwerte(zeilen):
for zeile in zeilen:
try:
yield float(zeile)
except ValueError:
continue
def zaehle_aufrufe(funktion):
@functools.wraps(funktion)
def huelle(*args, **kwargs):
huelle.aufrufe += 1
return funktion(*args, **kwargs)
huelle.aufrufe = 0
return huelle
@zaehle_aufrufe
def mittelwert(werte: list[float]) -> float:
return sum(werte) / len(werte)
daten = ["21.5", "Fehler", "22.0", "", "23.5"]
werte = list(messwerte(daten))
print(werte)
print(mittelwert(werte))