Project: KNMI

Inleiding

Je bent aangekomen bij het laatste hoofdstuk. In dit hoofdstuk ga je aan de slag met een project, waarin veel van wat je hebt geleerd in voorgaande hoofdstukken nodig is om het project tot een goed einde te brengen. In het project ga je aan de slag met gegevens van het KNMI (Koninklijk Nederlands Meteorologisch Instituut).

De data bevat maand- en jaarwaarden van het meetstation in De Bilt. Het doel is een aantal vragen te beantwoorden over deze gegevens. In verschillende deelopdrachten werk je naar een eindresultaat toe.

Leerdoelen

Aan het einde van dit hoofdstuk:

  • Kun je een project plannen

  • Kun je een project structureren

  • Kun je de juiste oplossing voor de problemen vinden

Het project: KNMI

Doel

Het doel van het project is een aantal vragen over de KNMI-gegevens te beantwoorden. Om die vragen te beantwoorden ga je een programma schrijven, zodat je niet alle antwoorden handmatig hoeft op te sporen in de data.

Plan

Download eerst de gegevens als txt bestand. Inspecteer de data zodat je een gevoel bij de gegevens krijgt.

De data is te verkrijgen via de website van het KNMI.

Deze gegevens ga je gebruiken om de volgende vragen te beantwoorden:

Opdracht 1

Wat was voor de jaren 1901, 2000 en 2023 gemiddeld de warmste maand? Wat was de gemiddelde temperatuur van de betreffende maand? Geef voor elk jaar het resultaat als volgt op: "Maand, temperatuur". Bijvoorbeeld: "Mei, 13.3".

Opdracht 2

Maak twee groepen aan: de eerste groep bevat alle maanden die door de jaren heen ooit een hoogste gemiddelde temperatuur hadden. De tweede groep bevat alle maanden die door de jaren heen ooit een laagste temperatuur hadden.

Maak twee groepen aan. De eerste groep bevat alle maanden die ooit in een jaar de hoogste gemiddelde temperatuur hadden. Als juni in 1910 bijvoorbeeld de warmste maand was, dan komt juni in deze groep.

De tweede groep bevat alle maanden die ooit in een jaar de laagste gemiddelde temperatuur hadden. Als maart in 1960 de koudste maand was, dan komt maart in deze groep.

Zijn er maanden die in beide groepen voorkomen?

Opdracht 3

Verkrijg het jaar met de warmste maand en het jaar met de koudste maand.

Opdracht 4

Maak een lijst met de vijf hoogste jaargemiddelden en een lijst met de vijf laagste jaargemiddelden. Maak vervolgens een lijst met alle jaren die één van die 10 temperaturen heeft.

Uit hoeveel jaren bestaat de lijst?

Opdracht 1: Plan

Maak een plan voor jezelf. Neem hierin op wat je denkt nodig te hebben, hoe je projectindeling er ongeveer uit gaat zien, welke stappen je als eerst gaat zetten, etc.

Het hoeft niet tot in detail te kloppen en het is niet erg als er gaandeweg zaken wijzigen. Het gaat erom dat je actief nadenkt over het eindresultaat en hoe je denkt daar te komen.

Klik om het antwoord te tonen

Een mogelijk plan is als volgt.

Stap 1: Data opschonen

De data ziet er vrij gestructureerd uit, maar moet nog wel worden opgeschoond. De help-tekst die erboven staat is niet nodig. Verder is het nu een `txt`-bestand, maar om de gegevens te analyseren is het handig om het om te zetten naar een `CSV`-bestand.

Stap 2: Structuur bepalen

Kijkend naar de gegevens en naar de vragen, kun je al een beetje voorspellen hoe de structuur er van je project uit gaat zien. Zo wil je de data opschonen. Ook heb je verschillende berekeningen nodig, die je in functies kunt zetten. Misschien zijn er voor elke berekening ook wel een paar vaste handelingen nodig, die in een eigen functie kunnen. De belangrijkste functies wil je misschien wel testen. Tot slot wil je misschien een main.py gebruiken om de rest aan te roepen. Een mogelijke indeling kan dus iets zijn als:

knmi/
├─ calculations.py  # De berekeningen om de vragen te beantwoorden
├─ contstants.py    # Eventuele constanten
├─ data.csv         # Opgeschoonde data
├─ data.txt         # Ruwe data
├─ main.py          # Hoofdbestand
├─ services.py      # Functies die in meerdere berekeningen nodig zijn
├─ tests.py         # Unit testen

Stap 3: Data opschonen

Schrijf een functie om de data op te schonen.

Stap 4: Berekeningen schrijven

Aan de slag met het schrijven van de code om de berekeningen te schrijven. Als je merkt dat je in herhaling valt, kun je de herhalende code in een functie in services.py plaatsen. De belangrijkste functies kun je testen of ze tot het juiste resultaat leiden in tests.py.

Stap 5: Samenvoegen

Voeg alles samen in main.py.

Data opschonen

Om te werken met de data moet het nog worden opgeschoond. Open de url, kopieer alle tekst en plak dit in een bestandje data.txt. Plaats dit bestandje in je projectmap, bijvoorbeeld knmi.

Het doel is de data op te schonen en om te zetten naar een CSV-bestand. CSV staat voor Comma-separated values en is een tekstbestand dat komma’s (of andere tekens) gebruikt om waarden te scheiden. Met een CSV-bestand kun je tabelgegevens opslaan en lezen. Neem bijvoorbeeld onderstaande tabel:

Kolom A

Kolom B

Kolom C

1

A

3

10

X

5

In CSV-formaat zou dit er zo uit zien:

Kolom A,Kolom B,KolomC
1,A,3
10,X,5

De eerste regel bestaat uit de (optionele) koppen van de kolommen.Daarna bevat elke regel de rij met waarden, gescheiden door een komma.Na elke komma begint dus een nieuwe kolom.Een CSV-bestand sla je op als voorbeeld.csv.

Opdracht 2: Data opschonen

Schrijf nu code dat data.txt neemt, het opschoont en omzet naar data.csv. Tips:

  • Verwijder alle spaties tussen de kolommen.

  • Verwijder de help-tekst en de lege regel tussen de koppen en de rest van de gegevens.

Klik om het antwoord te tonen

Een uitwerking is als volgt. Sla deze code bijvoorbeeld op in services.py en roep het aan in main.py:

# services.py
def clean_data(name):
    """
    Read in the raw data (txt) and clean it up. Remove help text,
    spaces and empty lines. Store as CSV.
    """

    text_file = f"{name}.txt"
    csv_file = f"{name}.csv"

    try:
        # Open the raw data
        with open(text_file, "r", encoding="utf-8") as file:

            # Loop over every line. If it is the header (starts with "STN,YYYY")
            # or starts with 260, we want to keep it.
            # Remove spaces
            lines = []
            for line in file:
                if line.startswith("STN,YYYY") or line.startswith("260"):
                    lines.append(line.replace(" ", ""))

        # Write the cleaned lines to a new CSV-file.
        with open(csv_file, "w", encoding="utf-8") as file:
            file.writelines(lines)

    except OSError as e:
        print("Could not open file.", e)

# main.py
from services import clean_data


if __name__ == "__main__":
    clean_data("data")

De opdrachten

Met de opgeschoonde data kun je nu de code gaan schrijven om de opdrachten op te lossen.Werk de opdrachten één voor één af.Merk je dat je code herhaalt: plaats het dan in een aparte functie, zodat je het eenvoudig kunt hergebruiken.Schrijf tijdens het schrijven van de code ook tests, om na te gaan of je de gewenste resultaten verkrijgt.

Verder enkele tips:

  • Gebruik de module csv uit de standaard bibliotheek om het CSV-bestand in te lezen.

  • Schrijf als eerst de functie om de data in te lezen

  • Schrijf veelvuldig commentaren bij je code.Laat je het even liggen om later verder te werken, dan kun je teruglezen wat je aan het doen was.

  • Maak voor de testen nep-gegevens aan die lijken op de echte data, maar dan veel beperkter.Zo kun je eenvoudig nagaan of je functies het gewenste resultaat opleveren.

  • Probeer te itereren.Schrijf een eerste versie die je testen doen slagen.Probeer daarna je code eenvoudiger of duidelijker te maken.

  • Kom je er niet uit, gebruik dan print-statements om te kijken wat er gebeurt in je code.

  • Alles is op te lossen met alles wat je geleerd hebt in deze opleiding. Er zijn geen externe tools of andere packages uit de standaard bibliotheek nodig, behalve csv.

Opdracht 1

Wat was voor de jaren 1901, 2000 en 2023 gemiddeld de warmste maand? Wat was de gemiddelde temperatuur van de betreffende maand? Geef voor elk jaar het resultaat als volgt op: "Maand, temperatuur". Bijvoorbeeld: "Mei, 13.3".

Opdracht 2

Maak twee groepen aan: de eerste groep bevat alle maanden die door de jaren heen ooit een hoogste gemiddelde temperatuur hadden. De tweede groep bevat alle maanden die door de jaren heen ooit een laagste temperatuur hadden.

Maak twee groepen aan. De eerste groep bevat alle maanden die ooit in een jaar de hoogste gemiddelde temperatuur hadden. Als juni in 1910 bijvoorbeeld de warmste maand was, dan komt juni in deze groep.

De tweede groep bevat alle maanden die ooit in een jaar de laagste gemiddelde temperatuur hadden. Als maart in 1960 de koudste maand was, dan komt maart in deze groep.

Zijn er maanden die in beide groepen voorkomen?

Opdracht 3

Verkrijg het jaar met de warmste maand en het jaar met de koudste maand.

Opdracht 4

Maak een lijst met de vijf hoogste jaargemiddelden en een lijst met de vijf laagste jaargemiddelden. Maak vervolgens een lijst met alle jaren die één van die 10 temperaturen heeft.

Uit hoeveel jaren bestaat de lijst?