0%

Wie es weitergeht · Übung

Lies ein vollständiges Programm und passe es an

Code zu lesen ist eine andere Fähigkeit, als ihn zu schreiben. Ein vollständiges, unbekanntes Programm kann unübersichtlich wirken, auch wenn dir jede einzelne verwendete Technik vertraut ist.

Verwende eine Lesereihenfolge, die du wiederholen kannst.

1. Suche die Daten

Betrachte:

scores = [
    {"name": "Ari", "points": 12},
    {"name": "Bo", "points": 19},
]

Dies ist eine Liste einheitlich aufgebauter Dictionary-Datensätze. Noch bevor du eine Schleife liest, weißt du, wie ein einzelnes Element aussieht.

2. Lies Funktionsverträge von außen

def highest_score(scores):
    pass

Der Name deutet auf ein einzelnes ausgewähltes Ergebnis hin. Der einzige Parameter erhält die Sammlung.

Sieh dir als Nächstes die Rückgabeanweisungen an. Gibt die Funktion einen Datensatz, eine Zahl, einen String oder None zurück?

3. Verfolge einen kleinen Aufruf

Bei einer Auswahlschleife:

best = None

for score in scores:
    if best is None or score["points"] > best["points"]:
        best = score

Verfolge zwei Datensätze:

SchleifendurchlaufAktueller Datensatzbest danach
1Ari, 12Ari, 12
2Bo, 19Bo, 19

Die Bedingung best is None gibt dem ersten Datensatz einen Ausgangspunkt. Python prüft zuerst die linke Seite von or. Wenn sie wahr ist, weiß Python bereits, dass die gesamte Bedingung wahr ist, und überspringt die rechte Seite. Im ersten Durchlauf versucht es deshalb nie, best["points"] zu lesen, solange best den Wert None hat.

In späteren Durchläufen enthält best einen Datensatz. Dann ist die linke Seite falsch, und Python wertet den Vergleich auf der rechten Seite aus. Ein späterer Datensatz ersetzt best nur, wenn seine Punktzahl größer ist. Dieses Überspringen von links nach rechts heißt Kurzschlussauswertung.

4. Verfolge den aufrufenden Code

Wenn eine Formatierungsfunktion highest_score aufruft, ermittle, welche zurückgegebenen Felder sie verwendet.

So wird die Verarbeitungskette des Programms sichtbar:

records -> selection function -> selected record -> formatted report

Rufe einen vertrauten Aufbau für Berichte ab

Eine Formatierungsfunktion kann ihre vollständigen Zeilen in einer Liste speichern und sie als einen String zurückgeben:

lines = [f"Busiest: {busiest['name']}"]
return "\n".join(lines)

Erkläre dir den Aufruf, bevor du weiterliest. Warum steht "\n" vor .join(), warum ist lines das Argument, und welche Art von Wert kommt zurück?

Hier gilt dieselbe Regel wie in der Lektion zum Refactoring: Der String vor dem Punkt ist das Trennzeichen, das Argument liefert eine Liste von Strings, und das Ergebnis ist ein String. Wenn du diesen Bericht erweiterst, ergänze einen weiteren vollständigen String in lines und behalte diese Trennung zwischen Zeilenaufbau und Zusammenfügen bei.

5. Halte vor Änderungen den Ausgangszustand fest

Führe den Startcode genau so aus, wie er ist. Halte seine aktuelle Ausgabe fest.

Wenn eine neue Anforderung hinzukommt, erhalte diesen Ausgangszustand, sofern die Anforderung ihn nicht ausdrücklich ändert.

Ergänze so wenig wie nötig und so genau wie nötig

Angenommen, das Programm soll auch die niedrigste Punktzahl melden. Eine gezielte Erweiterung besteht darin:

  • eine zweite Auswahlfunktion mit demselben Vertrag für die Datensätze hinzuzufügen;

  • beide Auswahlfunktionen im Bericht aufzurufen;

  • den vorhandenen String für den Höchstwert in lines unverändert zu lassen;

  • vor dem Zusammenfügen der Liste einen neuen String für den Tiefstwert hinzuzufügen.

Ein vollständiges Neuschreiben ist unnötig. Genaues Lesen ermöglicht dir, den kleinsten zuständigen Bereich zu verändern.

Welche Frage ist früh beim ersten Lesen eines unbekannten Programms zur Verarbeitung von Datensätzen hilfreich?

Aufgabe

Lies das vollständige Programm für den Besucherbericht, bevor du es bearbeitest. Führe den Startcode aus und ermittle:

  • den Aufbau eines Tagesdatensatzes;

  • was busiest_day(days) zurückgibt;

  • wie format_report(days) seine Liste von Berichtsstrings in einen String umwandelt.

Nimm dann eine gezielte Erweiterung vor:

  1. Ergänze quietest_day(days) mit demselben Vertrag, der einen Datensatz als Rückgabewert vorsieht.

  2. Passe format_report(days) so an, dass die Funktion den vorhandenen String für den besucherstärksten Tag beibehält und den String für den besucherschwächsten Tag zu lines hinzufügt.

  3. Gib den Bericht weiterhin mit "\n".join(lines) zurück.

  4. Behalte die vorbereiteten Daten und die abschließende Ausgabe bei.

Die endgültige Ausgabe muss so aussehen:

Busiest: Saturday (42)
Quietest: Monday (12)

Beide Auswahlfunktionen müssen auch mit anderen nicht leeren Tageslisten funktionieren, einschließlich einer Liste mit nur einem Datensatz. Behalte bei gleicher Besucherzahl den ersten passenden Datensatz bei, so wie es der vorhandene Vergleich in busiest_day tut.