0%

Hoe ga je verder? · oefening

Lees een compleet programma en pas het aan

Code lezen is een andere vaardigheid dan code schrijven. Een volledig onbekend programma kan ingewikkeld lijken, ook wanneer je elke afzonderlijke mogelijkheid kent.

Gebruik een herhaalbare leesvolgorde.

1. Vind de gegevens

Bekijk:

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

Dit is een lijst met dictionaryrecords met een consistente vorm. Voordat je een lus leest, weet je al hoe één item eruitziet.

2. Lees functieafspraken van buitenaf

def highest_score(scores):
    pass

De naam suggereert één geselecteerd resultaat. De enige parameter ontvangt de verzameling.

Bekijk daarna de return-instructies. Geeft de functie een record, een getal, een string of None terug?

3. Volg één kleine aanroep

Voor een selectielus:

best = None

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

Volg twee records:

RondeHuidig recordbest daarna
1Ari, 12Ari, 12
2Bo, 19Bo, 19

De voorwaarde best is None geeft het eerste record een startplek. Python controleert eerst de linkerkant van or. Wanneer die waar is, weet Python al dat de volledige voorwaarde waar is en slaat het de rechterkant over. In de eerste ronde betekent dit dat Python nooit probeert best["points"] te lezen terwijl best gelijk is aan None.

In latere rondes bevat best een record, dus is de linkerkant onwaar en evalueert Python de vergelijking rechts. Een later record vervangt best alleen wanneer het meer punten heeft. Dit van links naar rechts overslaan heet kortsluitevaluatie.

4. Volg de aanroepers

Als een opmaakfunctie highest_score aanroept, bepaal dan welke teruggegeven velden die gebruikt.

Dit maakt de keten van het programma zichtbaar:

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

Haal een bekende rapportgrens terug

Een opmaakfunctie kan haar complete regels in een lijst bewaren en ze als één string teruggeven:

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

Leg de aanroep aan jezelf uit voordat je verder leest. Waarom staat "\n" vóór .join(), waarom is lines het argument en welk soort waarde komt terug?

Dezelfde regel uit de les over herstructureren geldt hier: de string vóór de punt is het scheidingsteken, het argument levert een lijst met strings en het resultaat is één string. Voeg bij het uitbreiden van dit rapport nog een complete string toe aan lines en behoud die grens.

5. Leg het uitgangspunt vast voordat je bewerkt

Voer de startcode precies uit zoals die is. Noteer de huidige uitvoer.

Behoud bij een nieuwe eis dat uitgangspunt, tenzij de eis het expliciet verandert.

Maak de kleinste juiste uitbreiding

Stel dat het programma ook de laagste score moet rapporteren. Een gerichte uitbreiding is:

  • voeg een tweede selectiefunctie toe met dezelfde afspraak over het record;

  • roep beide selectiefuncties vanuit het rapport aan;

  • laat de bestaande string voor de hoogste score in lines ongewijzigd;

  • voeg één nieuwe string voor de laagste score toe voordat de lijst wordt samengevoegd.

Een volledige herschrijving is niet nodig. Nauwkeurig lezen laat je het kleinste verantwoordelijke deel aanpassen.

Wat is een nuttige vroege vraag wanneer je voor het eerst een onbekend programma leest dat records verwerkt?

Opdracht

Lees het volledige bezoekersrapportprogramma voordat je het bewerkt. Voer de startcode uit en bepaal:

  • de vorm van één dagrecord;

  • wat busiest_day(days) teruggeeft;

  • hoe format_report(days) de lijst met rapportstrings in één string verandert.

Maak daarna één gerichte uitbreiding:

  1. Voeg quietest_day(days) toe met dezelfde afspraak om een record terug te geven.

  2. Pas format_report(days) aan zodat de bestaande string voor de drukste dag behouden blijft en de string voor de rustigste dag aan lines wordt toegevoegd.

  3. Blijf het rapport teruggeven met "\n".join(lines).

  4. Behoud de voorbereide gegevens en de laatste afdrukinstructie.

De uiteindelijke uitvoer moet zijn:

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

Beide selectiefuncties moeten werken voor andere niet-lege lijsten met dagen, inclusief een lijst met één record. Behoud bij gelijke bezoekersaantallen het eerste overeenkomende record, zoals de bestaande vergelijking in busiest_day doet.