Dataclasses en waardeobjecten · eindproject
Eindproject: Project: modelleer resultaatregistraties en configuratie
Het hele betoog van dit hoofdstuk past in één zin: laat Python de code schrijven die al door je attributenlijst wordt bepaald en blijf zelf de code schrijven die een beslissing uitdrukt.
Het project is een klein resultatensysteem waarin elke keuze uit het hoofdstuk één keer voorkomt.
Wat je bouwt
QuizConfig how a quiz runs changeable, has defaults
Points an amount frozen value
Question a question frozen value, built several ways
ResultRecord one finished result frozen value
Gradebook the collection entity, changes as results arrive
Drie bevroren waarden, één veranderbare configuratie en één entiteit die bestaat om te groeien.
De beslissingen om bij stil te staan
Waarom ResultRecord bevroren is. Een afgerond resultaat is een gegeven over iets dat al is gebeurd. Niets hoort de score van vorige week te kunnen aanpassen, en bevriezen legt dat vast op een manier die commentaar niet kan.
Waarom Gradebook dat niet is. Het bestaat om resultaten te verzamelen. Bevriezen zou betekenen dat je bij elk resultaat de hele resultatenlijst opnieuw moet opbouwen. eq=False behoudt ook de entiteitsidentiteit: twee afzonderlijke resultatenlijsten worden niet hetzelfde object alleen omdat hun huidige registraties overeenkomen.
Waarom Gradebook een lijst bevat die per object wordt gemaakt. Les 4 en les 8 toonden dezelfde fout via verschillende routes: een veranderbare standaardwaarde en een veranderbaar klasseattribuut. Eén Gradebook per programma is het gebruikelijke geval, en precies daarom zou een gedeelde lijst tussen twee exemplaren lang onopgemerkt blijven.
Waarom is ResultRecord bevroren en Gradebook niet?
De methoden die geen boilerplate zijn
@dataclass schrijft de constructors, reprs en vergelijkingen. Wat overblijft is van jou en daar besteedt de beoordelaar de meeste aandacht aan:
Question.from_dictenQuestion.simple, twee extra ingangen;Question.normalize, de hulpmethode die bij vragen hoort;Question.is_correctenpoints_for, de regels die een vraag beheert;ResultRecord.percentageenpassed_under, gegevens over een resultaat;Gradebook.record,bestenaverage, die genormaliseerde percentages vergelijken zodat resultaten met verschillende totalen betekenisvol blijven.
Geen enkele ervan had kunnen worden gegenereerd, omdat elke methode een beslissing is die iemand heeft genomen.
Afronden
Tel de regels die je niet hoefde te schrijven. Lees daarna de regels die je wel schreef en controleer of elke regel iets zegt dat niet uit de lijst met attributen erboven had kunnen worden afgeleid.
Voeg twee resultaten met verschillende totalen toe, zoals 9/100 en 8/10, en druk het beste resultaat plus het gemiddelde percentage af. Die laatste uitvoering bewijst dat de resultatenlijst resultaten modelleert in plaats van alleen de gegeven voorbeelden te doorstaan.
Opdracht
Bouw de vijf klassen en gebruik het gegenereerde werk voor alles wat daardoor wordt afgedekt.
Points is een bevroren waarde met een positieve amount, waarbij plus(other) een nieuwe Points teruggeeft.
Question is een bevroren, gevalideerde waarde met een niet-lege prompt en answer, en points met standaardwaarde Points(1).
QuizConfig is een veranderbare dataclass: een verplichte niet-lege title, pass_mark met standaardwaarde 0.6 en een beperking tot boven 0 en maximaal 1, en tags die per configuratie als een nieuwe lege lijst begint.
ResultRecord is een bevroren waarde met een niet-lege learner, een niet-negatieve total en een score van 0 tot en met total, met percentage en een methode passed_under(config).
Gradebook is een veranderbare entiteit met een niet-lege title en één interne lijst _records. Gebruik eq=False. De klasse krijgt record(result), records() dat een veilige kopie teruggeeft, best() en average().
Maak de methoden af die in de startcode worden genoemd:
Question.from_dict(record)leestprompt,answeren eenPoints-waarde uitpoints;simple(prompt, answer)gebruiktPoints(1). Beide zijn klassemethoden die viaclseen object maken. Weiger een puntenargument dat geenPointsis metTypeError.Question.normalize(text)is een statische methode die witruimte aan de uiteinden verwijdert en tekst omzet naar kleine letters. Gebruik die aan beide kanten inis_correct.points_forgeeft de gehele hoeveelheid terug voor een juist antwoord en anders0.QuizConfig.practice(title)enfinal_exam(title)zijn klassemethoden die respectievelijk slaaggrenzen van0.5en0.8kiezen; tags beginnen nog steeds leeg.ResultRecord.percentageis de verhoudingscore / total, of0.0bij een totaal van nul.passed_under(config)rekent een resultaat precies op de slaaggrens van de configuratie ook als geslaagd.Gradebook.recordaccepteert alleenResultRecord-waarden en gooit andersTypeErrorop.best()vergelijkt percentages en geeft een hoogste resultaat terug, ofNoneals er geen resultaten zijn.average()is het gemiddelde van de geregistreerde percentages, of0.0als er geen resultaten zijn.
Gebruik ValueError voor de hierboven beschreven ongeldige veldwaarden. Houd de geschiedenis van de resultatenlijst buiten constructorargumenten en de gegenereerde repr met init=False, repr=False, zoals in les 7. Geen enkele klasse drukt iets af.