0%

JSON en CSV · oefening

De CSV-structuur lezen

Een CSV-rij met de hand bij elke komma splitsen zou het product met de naam "Dice, Set of 6" stukmaken. De module csv kent de regels voor aanhalingstekens al. Gebruik die kennis in plaats van een deel van CSV opnieuw te bouwen met stringmethoden.

Laat de kop elke cel benoemen

csv.reader geeft elke rij terug als een lijst. csv.DictReader gaat één stap verder: die gebruikt de eerste rij als sleutels voor elke volgende rij.

with open("catalog.csv", newline="", encoding="utf-8") as handle:
    reader = csv.DictReader(handle, strict=True)
    for row in reader:
        print(row["sku"], row["name"])

newline="" laat de CSV-parser zelf CSV-newlines afhandelen. De expliciete codering en contextmanager zetten het bestandscontract uit hoofdstuk 5 voort. strict=True zorgt dat onjuiste CSV-aanhalingstekens een csv.Error opwerpen in plaats van een beschadigd record stilletjes te accepteren.

De teruggegeven rij is nog steeds een dictionary van tekst:

{
    "sku": "BK-101",
    "name": "Python Field Notes",
    "quantity": "4",
    "unit_price": "12.50",
    "in_stock": "true",
}

Valideer de vorm vóór de waarden

reader.fieldnames is de koprij. Die moet precies gelijk zijn aan FIELDNAMES, inclusief de volgorde. Een anders geordende of extra kop afwijzen maakt onbedoelde bestandswijzigingen zichtbaar in plaats van stilletjes de betekenis van een kolom te veranderen.

Ook de breedte van rijen moet worden gecontroleerd. DictReader gebruikt de sleutel None voor extra cellen en de waarde None voor ontbrekende cellen. Wijs beide af voordat je rijen teruggeeft. Zo kan de volgende les op één eerlijke aanname bouwen: elke teruggegeven dictionary heeft precies de vijf afgesproken tekstcellen.

Nu jij

Implementeer validate_headers(fieldnames) en read_csv_rows(path) in catalog.py.

  • Een correcte kop keert normaal terug; elke andere waarde werpt een ValueError op met een melding die de verwachte kop noemt.

  • Open path met het hierboven getoonde bestandscontract uit hoofdstuk 5.

  • Maak een csv.DictReader met strict=True.

  • Valideer de kop voordat je gegevensrijen leest.

  • Wijs een rij met een extra of ontbrekende cel af en vermeld het CSV-rijnummer, geteld vanaf één, in de foutmelding.

  • Geef een lijst met onbewerkte rijdictionaries terug. Zet nog geen waarden om.

“Rijnummer” betekent hier het logische CSV-recordnummer: de kop is rij 1 en het eerste gegevensrecord is rij 2. Een cel tussen aanhalingstekens kan een newline bevatten zonder een tweede record te worden.

Je hoeft het voorbeeld niet regel voor regel te volgen. Het gaat erom dat een goede kop rijen oplevert, een anders geordende kop een fout opwerpt en een rij met het verkeerde aantal cellen een fout met zijn rijnummer opwerpt. Probeer elk geval in een tijdelijke kopie van catalog.csv en geef het pad van die kopie aan read_csv_rows. Houd de oorspronkelijke catalog.csv met drie rijen ongewijzigd voor het inleveren.

DictReader geeft een rij de sleutel None of de waarde None. Wat is er gebeurd?

Opdracht

Implementeer validate_headers(fieldnames) en read_csv_rows(path).

Geef elke onbewerkte rijdictionary uit catalog.csv terug en behoud de komma in Dice, Set of 6. Wijs een verkeerde kop en elke rij met te veel of te weinig cellen af. Laat elke cel tekst blijven voor de volgende les.