Hoofdstuk 10
Een programma over bestanden verdelen
Waarom een werkend programma opsplitsen
Met dit hoofdstuk verandert er iets, nog voordat je een regel schrijft.
Tot nu toe gaf elke les je één editor met één programma. Dit hoofdstuk geeft je een project: een verzameling bestanden die van de ene les naar de volgende behouden blijven. Wat je in les 2 schrijft staat er in les 8 nog steeds, en via het bestandenpaneel naast de editor wissel je ertussen.
Het project bevat al één bestand. Open main.py en lees het.
Wat je voor je hebt
Dit hoofdstuk begint met een nieuwe, kleinere quiz met bekende verantwoordelijkheden: een Question die het eigen antwoord kent, een Quiz die vragen bewaart, een Attempt die antwoorden beoordeelt, een functie die een poging omzet in rapportregels en een main die ze met elkaar verbindt.
Het behoudt één tekstvraagtype en een lopende score, zodat je je kunt richten op het verplaatsen van verantwoordelijkheden tussen bestanden. Het vervangt de uitgebreidere familie uit hoofdstuk 9 of de bijbehorende validatieregels niet. Behoud gedurende het hoofdstuk het gedrag van dit gegeven programma.
Met ongeveer zestig regels past het nog makkelijk in één bestand. We oefenen de grenzen die nuttig worden als het programma groeit.
Wat één bestand kost
Programma’s worden niet moeilijk om mee te werken doordat ze lang zijn. Ze worden moeilijk doordat alles erin overal bij kan.
Dingen vinden. report_lines staat zonder enige reden tussen Attempt en build_quiz. In een bestand van duizend regels wordt ‘waar is de scoreregel?’ een zoekopdracht in plaats van een plek.
Lezen. Om Attempt te begrijpen scrol je langs Question en Quiz. Niets vertelt van welke daarvan Attempt echt afhangt, omdat het antwoord in één bestand altijd ‘alles kan’ is.
Wijzigen. Twee mensen die dit bestand bewerken, bewerken hetzelfde bestand. Hun wijzigingen botsen zelfs als het werk niet overlapt.
Hergebruiken. Een ander programma kan Question importeren uit dit bestand met een uitvoercontrole, maar laadt dan ook definities voor rapportopmaak en het bouwen van de quiz. Een gerichte module maakt de kleinere afhankelijkheid duidelijk.
Testen. Hoofdstuk 13 schrijft echte tests. Alleen Question testen is veel makkelijker als Question ergens afzonderlijk staat.
Welke van deze redenen is het sterkst om dit programma in modules op te splitsen?
Waar we naartoe werken
Aan het einde van het hoofdstuk ziet main.py er ongeveer zo uit:
from models import Question, Quiz
from report import report_lines
def main():
...
Dit is de tussentijdse vlakke indeling; les 7 voegt het packagevoorvoegsel quizapp toe. De importregels tonen de afhankelijkheden. Iedereen die dit bestand opent leert in drie seconden dat het programma een domein en een rapportagelaag heeft en dat het startpunt beide gebruikt. Die zin staat nergens in commentaar; die zit in de structuur.
Het hoofdstuk werkt daar stap voor stap naartoe:
Lessen 2 en 3 maken je eerste module en importeren daaruit.
Les 4 bekijkt wat er echt gebeurt als Python een import uitvoert.
Les 5 maakt van
main.pyeen startpunt in plaats van een verzamelplek.Les 6 trekt de grens tussen regels en presentatie, ditmaal in bestanden.
Les 7 groepeert modules in een package en behandelt het importprobleem waar beginners tegenaan lopen.
Les 8 rondt de splitsing af.
Over de werkruimte
Omdat de bestanden behouden blijven, blijft een fout dat ook. Als een latere les zich vreemd gedraagt, kan de oorzaak in een eerder geschreven bestand zitten. Dat is precies de situatie waarin dit hoofdstuk je leert werken.
Run voert altijd main.py uit, ook als er een ander bestand openstaat. Submit controleert de bestanden die de huidige les vereist.
De knop Reset herstelt het project naar de begintoestand. Die wist je hoofdstukbestanden, maar behoudt de vinkjes voor voltooiing. Latere oefeningen kunnen daardoor vereisen dat je eerder werk opnieuw opbouwt. Gebruik de knop alleen als je het project opnieuw wilt beginnen.