Een projectafspraak onderscheiden van wat Python toevallig kan lezen.
Tekstvelden gecontroleerd normaliseren en omzetten.
Een complete registratie zonder bronmutatie opbouwen.
Een vrijwilligersvereniging ontvangt registraties van gewerkte minuten. Het eindprogramma moet daar een urenrapport van maken, maar een overtuigende som zegt weinig wanneer een onbekend team of een verkeerde datum al ongemerkt is binnengelaten. Daarom begin je het eindproject met afspraken over invoer.
Eerst afspreken wat een registratie betekent
Ons invoercontract beschrijft drie tekstvelden: datum, team en minuten. Een datum is een bestaande kalenderdag in de schrijfwijze JJJJ-MM-DD; een team is balie, bouw of groen; een duur ligt tussen één en 1440 minuten. Een herhaalde registratie blijft later gewoon meetellen.
Deze regels zijn keuzes van dit project. Een andere toepassing kan andere namen of een duur van meerdere dagen toestaan. Door de keuzes nu precies te benoemen, kun je straks uitleggen waarom een regel wordt geaccepteerd of geweigerd.
Een datum is meer dan tekst met streepjes
De klasse date uit datetime vertegenwoordigt een kalenderdag. Zij kan bijvoorbeeld controleren of 29 februari in een bepaald jaar bestaat. Daardoor hoef je de kalenderregels niet zelf met tekenposities na te bouwen.
Een datum heeft een vaste schrijfwijze
from datetime import date
received = ' 2024-02-29 '
parsed = date.fromisoformat(received.strip())
print(type(parsed).__name__)
print(parsed.isoformat())
print(parsed.day)
Verwachte uitvoer
date
2024-02-29
29
Het voorbeeld verwijdert alleen de buitenste witruimte en laat zien welk type de omzetting oplevert. Binnen het programma kun je daarna met een datumwaarde werken. Met isoformat() krijg je weer de vaste datumtekst voor een rapport.
Een bibliotheek kan ruimhartiger zijn dan jouw afspraak: fromisoformat kent ook andere ISO-schrijfwijzen. Vergelijk daarom de vaste teruggeschreven datum met de ontvangen tekst. Een geldige dag in een ongewenste notatie is voor dit project nog steeds ongeldige invoer.
Normaliseren zonder informatie te verzinnen
Met normaliseren maak je toegestane verschillen gelijk. Een team met buitenste spaties of hoofdletters krijgt na strip en casefold één vaste naam. Een spatie midden in bo uw verdwijnt niet: daarvoor hebben we geen alternatieve spelling afgesproken.
Een onbekende naam wordt ook niet automatisch bouw. Zo'n standaard lijkt behulpzaam, maar het rapport zou werk aan het verkeerde team toeschrijven. Gebruik de meegeleverde InputError om duidelijk te melden dat de registratie eerst moet worden gecorrigeerd.
Minuten beginnen als een CSV-veld
CSV levert tekst, ook wanneer een veld op een getal lijkt. Controleer daarom eerst het type en de toegestane tekens. Pas daarna maak je een geheel getal en controleer je de inclusieve grenzen.
Cijfers herkennen is nog geen projectbesluit
for text in ['45', '٤٥', '+45']:
print(repr(text), text.isdecimal(), text.isascii())
Verwachte uitvoer
'45' True True
'٤٥' True False
'+45' False True
Het voorbeeld onderscheidt decimale cijfers van ASCII-tekens. Beide eigenschappen zijn relevant: ons uitwisselformaat gebruikt uitsluitend de cijfers nul tot en met negen. Een plusteken of breuk past daar evenmin bij.
Voorloopnullen veranderen de waarde niet en zijn wel toegestaan. Verwijder ze voordat je een mogelijk zeer lang veld naar int omzet. Een significante tekenreeks met meer dan vier cijfers kan al geen geldig minuutgetal opleveren.
Veelgemaakte fout: alleen int aanroepen
int(text) kan een bruikbaar getal geven voor tekst die ons contract verbiedt. Ook bewijst een geslaagde conversie niet dat de duur positief of klein genoeg is. Laat de eigenschappen van de bibliotheek dus niet ongemerkt jouw projecteisen vervangen.
Van losse velden naar één model
Het meegeleverde Session-model bewaart een datum, teamnaam en minuutgetal bij elkaar. Jouw parse_record controleert eerst of de rij precies drie velden bevat en gebruikt daarna de drie parsers. Je hoeft de oorspronkelijke lijst daarvoor niet leeg te maken of aan te passen.
Iedere parser geeft een bruikbare waarde of een InputError. Een half ingevuld model en een verzonnen standaardwaarde zijn geen succes. De volgende lessen verbinden deze zuivere omzetting met modulegrenzen, echte CSV-invoer en rapportuitvoer.
AAN DE SLAG 0/4
1
Een kalenderdatum volgens afspraak
Maak parse_day(text). Accepteer tekst, verwijder buitenste witruimte en geef een date terug voor exact JJJJ-MM-DD. Compacte ISO- en weekdatums zijn buiten dit contract. Gebruik InputError("datum moet tekst zijn") bij andere typen; bij een ongeldige datum of schrijfwijze InputError("gebruik een bestaande datum als JJJJ-MM-DD").
2
Eén naam voor ieder team
Maak parse_team(text). Geef na strip en casefold alleen balie, bouw of groen terug. Andere typen geven InputError("team moet tekst zijn"); onbekende waarden geven InputError("onbekend team"). Interne witruimte is geen alternatieve spelling.
3
Minuten met duidelijke grenzen
Maak parse_minutes(text). Alleen tekst met na strip uitsluitend ASCII-cijfers mag naar een int van 1 tot en met 1440. Voorloopnullen mogen, ook veel. Andere typen geven InputError("minuten moeten tekst zijn"), verkeerde tekens InputError("minuten moeten uit cijfers 0 tot en met 9 bestaan"), buiten het bereik InputError("minuten moeten tussen 1 en 1440 liggen").
4
Een complete registratie maken
Maak parse_record(fields) voor een lijst met drie tekstvelden: datum, team, minuten. Gebruik je drie parsers en geef een Session terug; wijzig de lijst niet. Een ander aantal velden geeft InputError("verwacht drie velden: date, team, minutes"). De eerste veldfout gaat ongewijzigd door.
Samenvatting
Een contract bepaalt de toegestane invoer; een bibliotheek kan meer accepteren.
Normaliseer alleen verschillen die de afspraak werkelijk toestaat.
Zet drie gecontroleerde velden samen zonder de ontvangen rij te veranderen.