Programme planen, bauen und testen · Übung
Lies Code, bevor du ihn änderst
Du wirst oft Code ändern, den du nicht heute geschrieben hast. Er kann von einer anderen Person, von deinem früheren Ich, aus einer Dokumentation oder aus einem Projekt stammen, das du vor mehreren Lektionen begonnen hast.
Diese Lektion verlässt bewusst das Quizprogramm, damit du die Vorgehensweise auf etwas anderes überträgst. Wenn eine Arbeitsweise nur bei Code hilft, den du bereits kennst, taugt sie noch nicht besonders viel. Hier begegnest du einer kleinen Zusammenfassung von Bewertungen, als wäre sie heute Morgen auf deinem Schreibtisch gelandet.
Schreibe den Code nicht gleich in deinem bevorzugten Stil neu. Entwickle zuerst eine brauchbare Vorstellung davon, was er tut.
Lies von außen nach innen
Beginne an den Grenzen, an denen die Funktion auf den Rest des Programms trifft:
beim Funktionsnamen und den Parametern;
beim Rückgabewert oder der sichtbaren Ausgabe;
bei einem kleinen Beispielaufruf.
Sobald diese Teile verständlich sind, untersuche den Funktionskörper. Diese Reihenfolge gibt den Details einen Zusammenhang.
Betrachte:
def summarize_distances(distances):
total = 0
for distance in distances:
total += distance
return {
"count": len(distances),
"total": total,
}
Von außen betrachtet erhält die Funktion eine Liste und gibt ein Dictionary zurück. Das Dictionary hat zwei Felder.
Im Inneren wird jede Strecke zu einer laufenden Summe addiert. Du kannst [3, 5] nachverfolgen:
| Zeitpunkt | total |
|---|---|
| vor der Schleife | 0 |
| nach 3 | 3 |
| nach 5 | 8 |
Das zurückgegebene Dictionary ist daher {"count": 2, "total": 8}.
Bestätige das aktuelle Verhalten
Führe den Code aus, bevor du ihn bearbeitest. Füge bei Bedarf einen vorübergehenden Aufruf oder eine Zusicherung hinzu.
So erhältst du einen Ausgangspunkt:
assert summarize_distances([3, 5]) == {
"count": 2,
"total": 8,
}
Wenn diese Ausgangsprüfung bereits fehlschlägt, beginnst du nicht mit dem Verhalten, von dem du ausgegangen bist.
Finde die kleinste Änderung
Angenommen, die neue Anforderung fügt ein Feld "average" hinzu. Frage dich:
Welcher Wert ist bereits verfügbar?
Welche neue Berechnung wird gebraucht?
Was passiert bei einer leeren Liste?
Welche vorhandenen Felder müssen unverändert bleiben?
Vielleicht brauchst du nur wenige Zeilen. Bei einer vollständigen Neufassung musst du mehr Verhalten erneut prüfen.
Bewahre den alten Vertrag, während du ihn erweiterst
Füge Prüfungen für das neue Feld hinzu, behalte aber die Prüfungen für "count" und "total" bei. Eine neue Funktionalität ist nicht fertig, wenn sie stillschweigend Verhalten beschädigt, auf das Aufrufer bereits vertrauen.
Das Lesen unbekannten Codes ist kein Wettbewerb im Schnelllesen. Das Ziel ist eine präzise Änderung, deren Richtigkeit du belegen kannst.
Was ist der beste erste Schritt, bevor du eine unbekannte Funktion änderst?
Aufgabe
Lies die vorgegebene Funktion summarize_ratings(ratings), bevor du sie änderst. Sie gibt derzeit die Anzahl, die Summe und den Durchschnitt für eine nicht leere Liste zurück.
Erweitere den Vertrag:
Füge
"highest"mit der höchsten Bewertung hinzu.Gib für eine leere Liste die Anzahl
0, die Summe0, den DurchschnittNoneund als höchsten WertNonezurück.Bewahre alle vorhandenen Felder und Verhaltensweisen.
Ersetze das zurückgegebene Dictionary nicht durch ausgegebenen Text. Behalte den vorbereiteten Aufruf und die Ausgabe bei.
Das ausgegebene Dictionary muss diese Felder und Werte enthalten; die Reihenfolge der Felder darf abweichen:
{'count': 4, 'total': 14, 'average': 3.5, 'highest': 5}