Problemdekomponering, grådige algoritmer og backtracking.
Databehandling og filhandtering
I den verkelege verda ligg data sjeldan ferdig i ei Python-liste. Data blir lagra i filer, databasar og på nettet. For å bruke desse dataene må du kunne lese dei inn, behandle dei og ofte lagre resultata tilbake.
I dette kapittelet skal du lære:
- Lese og skrive tekstfiler i Python
- Jobbe med CSV-filer (kommaseparerte verdiar)
- Lese og skrive JSON-data
- Grunnleggjande datareinsking
- Introduksjon til pandas for dataanalyse
Desse ferdigheitene er essensielle for alle som jobbar med data, anten det er vitskapleg forsking, webutvikling eller dataanalyse.
Grunnleggjande konsept:
Opne ei fil:
fil = open("filnavn.txt", modus)Modusar:
| Modus | Skildring |
|---|---|
"r" | Lese (read) - standard |
"w" | Skrive (write) - overskriv fila |
"a" | Leggje til (append) - legg til på slutten |
"x" | Opprett ny fil - feil viss fila finst |
Viktig: Bruk
with-blokk!# Anbefalt: with lukkar fila automatisk
with open("data.txt", "r") as fil:
innhold = fil.read()
# Filen er nå lukket automatisk
# IKKE anbefalt: Må huske å lukke selv
fil = open("data.txt", "r")
innhold = fil.read()
fil.close() # Lett å glemme!Teiknsett (encoding):For norske teikn (æ, ø, å), bruk UTF-8:
with open("norsk.txt", "r", encoding="utf-8") as fil:
innhold = fil.read()# Skrive tekst til fil
with open("dagbok.txt", "w", encoding="utf-8") as fil:
fil.write("Dag 1: Lærte om filhåndtering\n")
fil.write("Dag 2: Lærte om CSV-filer\n")
fil.write("Dag 3: Lærte om JSON\n")
# Legge til mer tekst
with open("dagbok.txt", "a", encoding="utf-8") as fil:
fil.write("Dag 4: Lærte om pandas\n")Lese frå fil:
# Les hele filen som én streng
with open("dagbok.txt", "r", encoding="utf-8") as fil:
innhold = fil.read()
print(innhold)
# Les linje for linje
with open("dagbok.txt", "r", encoding="utf-8") as fil:
for linje in fil:
print(linje.strip()) # strip() fjerner \n
# Les alle linjer til en liste
with open("dagbok.txt", "r", encoding="utf-8") as fil:
linjer = fil.readlines()
print(linjer)
# ['Dag 1: ...\n', 'Dag 2: ...\n', ...]Praktisk eksempel: Behandle ei loggfil
def analyser_logg(filnavn):
"""Analyserer en loggfil og teller feilmeldinger"""
feil_teller = 0
advarsel_teller = 0
with open(filnavn, "r", encoding="utf-8") as fil:
for linje in fil:
if "ERROR" in linje:
feil_teller += 1
elif "WARNING" in linje:
advarsel_teller += 1
print(f"Feil: {feil_teller}")
print(f"Advarsler: {advarsel_teller}")
# Lagre rapport
def lagre_rapport(filnavn, data):
"""Lagrer en rapport til fil"""
with open(filnavn, "w", encoding="utf-8") as fil:
fil.write("=== Rapport ===\n\n")
for nøkkel, verdi in data.items():
fil.write(f"{nøkkel}: {verdi}\n")
print(f"Rapport lagret til {filnavn}")
rapport = {"Antall brukere": 150, "Aktive i dag": 42, "Nye i uka": 12}
lagre_rapport("rapport.txt", rapport)Kva skriv denne koden til fila "tall.txt"?
with open("tall.txt", "w") as fil:
for i in range(1, 4):
fil.write(str(i * 10) + "\n")
with open("tall.txt", "a") as fil:
fil.write("Ferdig!")Eksempel på CSV-fil (elever.csv):
navn,alder,karakter
Anna,17,5
Bob,18,4
Charlie,17,6Kvifor CSV?
- Enkelt og lesbart format
- Kan opnast i Excel, Google Sheets, etc.
- Lett å eksportere frå databasar
- Standard format for datautveksling
Pythons csv-modul:
import csvViktige funksjonar:
- csv.reader() - Les CSV som lister
- csv.DictReader() - Les CSV som ordbøker
- csv.writer() - Skriv lister til CSV
- csv.DictWriter() - Skriv ordbøker til CSV
Vanlege problem:
- Norske filer bruker ofte semikolon (;) som separator
- Teiknsett: Bruk UTF-8 for norske teikn
- Desimaltal: Norsk format bruker komma (3,14) vs punkt (3.14)
import csv
with open("elever.csv", "r", encoding="utf-8") as fil:
leser = csv.reader(fil)
overskrift = next(leser) # Hopp over overskriftsraden
print(f"Kolonner: {overskrift}")
for rad in leser:
navn, alder, karakter = rad
print(f"{navn} er {alder} år og har karakter {karakter}")Lese CSV med DictReader (anbefalt):
import csv
with open("elever.csv", "r", encoding="utf-8") as fil:
leser = csv.DictReader(fil)
for elev in leser:
print(f"{elev['navn']}: karakter {elev['karakter']}")DictReader bruker første rad som nøklar, så du kan referere til kolonnar med namn.
Skrive CSV:
import csv
elever = [
{"navn": "Diana", "alder": 18, "karakter": 5},
{"navn": "Erik", "alder": 17, "karakter": 4},
{"navn": "Fiona", "alder": 18, "karakter": 6}
]
with open("nye_elever.csv", "w", encoding="utf-8", newline="") as fil:
felter = ["navn", "alder", "karakter"]
skriver = csv.DictWriter(fil, fieldnames=felter)
skriver.writeheader() # Skriv overskriftsrad
for elev in elever:
skriver.writerow(elev)Norsk CSV med semikolon:
import csv
# Les norsk CSV med semikolon
with open("norsk_data.csv", "r", encoding="utf-8") as fil:
leser = csv.reader(fil, delimiter=";")
for rad in leser:
print(rad)Praktisk eksempel: Berekne gjennomsnitt frå CSV
import csv
def beregn_snitt(filnavn, kolonne):
"""Beregner gjennomsnittet av en numerisk kolonne i CSV"""
verdier = []
with open(filnavn, "r", encoding="utf-8") as fil:
leser = csv.DictReader(fil)
for rad in leser:
verdier.append(float(rad[kolonne]))
snitt = sum(verdier) / len(verdier)
return round(snitt, 2)
snitt_karakter = beregn_snitt("elever.csv", "karakter")
print(f"Gjennomsnittskarakter: {snitt_karakter}")Du har ei CSV-fil "temperaturer.csv" med dette innhaldet:
by,temperatur
Oslo,5.2
Bergen,8.1
Tromsø,-3.4
Trondheim,4.7Skriv kode som les fila og finn byen med høgast temperatur.
JSON-format:
{
"navn": "Anna",
"alder": 17,
"fag": ["matte", "norsk", "engelsk"],
"aktiv": true,
"adresse": {
"gate": "Storgata 1",
"by": "Oslo"
}
}JSON vs Python:
| JSON | Python |
|---|---|
object {} | dict |
array [] | list |
string "" | str |
| number | int/float |
| true/false | True/False |
| null | None |
Pythons json-modul:
import jsonViktige funksjonar:-
json.load(fil) - Les JSON frå fil-
json.loads(streng) - Les JSON frå streng-
json.dump(data, fil) - Skriv JSON til fil-
json.dumps(data) - Konverter til JSON-strengFordelar med JSON:
- Lesbart for menneske
- Støttar nesta strukturar
- Standard format for web-APIar
- Blir støtta av nesten alle programmeringsspråk
import json
elever = [
{
"navn": "Anna",
"alder": 17,
"fag": ["matte", "norsk", "IT"],
"karakterer": {"matte": 5, "norsk": 4, "IT": 6}
},
{
"navn": "Bob",
"alder": 18,
"fag": ["matte", "engelsk"],
"karakterer": {"matte": 4, "engelsk": 5}
}
]
# Skriv til fil
with open("elever.json", "w", encoding="utf-8") as fil:
json.dump(elever, fil, indent=2, ensure_ascii=False)
# indent=2 gjør filen lesbar
# ensure_ascii=False bevarer norske tegnLese JSON frå fil:
import json
with open("elever.json", "r", encoding="utf-8") as fil:
elever = json.load(fil)
for elev in elever:
print(f"{elev['navn']} tar {len(elev['fag'])} fag")
for fag, karakter in elev['karakterer'].items():
print(f" {fag}: {karakter}")JSON frå streng (f.eks. frå web-API):
import json
json_streng = '{"by": "Oslo", "temperatur": 5.2, "nedbør": true}'
data = json.loads(json_streng)
print(data["by"]) # Oslo
print(data["temperatur"]) # 5.2
# Tilbake til streng
ny_streng = json.dumps(data, ensure_ascii=False)
print(ny_streng)Praktisk eksempel: Konfigurasjonsfil
import json
def les_konfig(filnavn="config.json"):
"""Leser konfigurasjon fra JSON-fil"""
try:
with open(filnavn, "r", encoding="utf-8") as fil:
return json.load(fil)
except FileNotFoundError:
# Returner standardverdier
return {"tema": "lys", "språk": "nb", "font_størrelse": 14}
def lagre_konfig(konfig, filnavn="config.json"):
"""Lagrer konfigurasjon til JSON-fil"""
with open(filnavn, "w", encoding="utf-8") as fil:
json.dump(konfig, fil, indent=2, ensure_ascii=False)
# Bruk
konfig = les_konfig()
konfig["tema"] = "mørk"
lagre_konfig(konfig)Kva for ein påstand om CSV og JSON er riktig?
Vanlege problem i reelle data:
| Problem | Eksempel | Løysing |
|---|---|---|
| Manglande verdiar | tom celle, "N/A" | Fjerne rad eller fylle inn |
| Feil datatype | "atten" i staden for 18 | Konvertere eller fjerne |
| Duplikat | Same rad to gonger | Fjerne duplikat |
| Inkonsistent format | "Oslo", "oslo", "OSLO" | Standardisere |
| Whitespace | " Oslo " | strip() |
| Uteliggjarar | Alder: 999 | Vurdere og eventuelt fjerne |
Steg i datareinsking:
1. Inspiser: Sjå på dataene, finn problem
2. Valider: Sjekk datatypar, verdiar og format
3. Reins: Fiks problem systematisk
4. Verifiser: Sjekk at reinskinga var vellukka
Tommelregel: Du bruker ofte 80% av tida på datareinsking og berre 20% på sjølve analysen!
Lat oss reinske eit datasett med elevar som har diverse problem:
import csv
def les_og_rens(filnavn):
"""Leser CSV og renser dataene"""
renset_data = []
forkastet = 0
with open(filnavn, "r", encoding="utf-8") as fil:
leser = csv.DictReader(fil)
for rad in leser:
# 1. Fjern whitespace fra alle verdier
renset = {k: v.strip() for k, v in rad.items()}
# 2. Standardiser navn (stor forbokstav)
renset["navn"] = renset["navn"].title()
# 3. Sjekk manglende verdier
if not renset["navn"] or not renset["alder"]:
forkastet += 1
continue
# 4. Konverter og valider alder
try:
alder = int(renset["alder"])
if alder < 15 or alder > 20:
forkastet += 1
continue
renset["alder"] = alder
except ValueError:
forkastet += 1
continue
# 5. Konverter og valider karakter
try:
karakter = int(renset["karakter"])
if karakter < 1 or karakter > 6:
forkastet += 1
continue
renset["karakter"] = karakter
except ValueError:
renset["karakter"] = None # Manglende karakter OK
renset_data.append(renset)
print(f"Beholdt {len(renset_data)} rader, forkastet {forkastet}")
return renset_data
# Fjerne duplikater
def fjern_duplikater(data, nøkkel="navn"):
"""Fjerner duplikater basert på en nøkkel"""
sett = set()
unik = []
for rad in data:
if rad[nøkkel] not in sett:
sett.add(rad[nøkkel])
unik.append(rad)
return unikVanlege reinskefunksjonar:
# Standardisere tekst
def rens_tekst(tekst):
"""Renser og standardiserer tekst"""
tekst = tekst.strip() # Fjern whitespace
tekst = tekst.lower() # Til lowercase
tekst = " ".join(tekst.split()) # Fjern ekstra mellomrom
return tekst
# Håndtere manglende verdier
def fyll_manglende(data, kolonne, standardverdi):
"""Fyller inn manglende verdier"""
for rad in data:
if rad[kolonne] is None or rad[kolonne] == "":
rad[kolonne] = standardverdi
return data
# Konvertere datoformat
def standardiser_dato(dato_tekst):
"""Konverterer ulike datoformater til standard"""
from datetime import datetime
formater = ["%d.%m.%Y", "%d/%m/%Y", "%Y-%m-%d"]
for fmt in formater:
try:
return datetime.strptime(dato_tekst, fmt).strftime("%Y-%m-%d")
except ValueError:
continue
return NoneDu har denne lista med data:
data = [
{"navn": " Anna ", "alder": "17", "karakter": "5"},
{"navn": "bob", "alder": "atten", "karakter": "4"},
{"navn": "Charlie", "alder": "18", "karakter": ""},
{"navn": "Anna", "alder": "17", "karakter": "5"},
{"navn": "Diana", "alder": "200", "karakter": "3"}
]Kva for rader bør forkastast og kvifor?
Hovudkonsept:
DataFrame: Ein tabell med rader og kolonnar (som eit rekneark)
import pandas as pd
df = pd.DataFrame({
"navn": ["Anna", "Bob", "Charlie"],
"alder": [17, 18, 17],
"karakter": [5, 4, 6]
})Series: Ein enkelt kolonne (som ei liste med indeks)
alder = df["alder"] # SeriesKvifor pandas?
- Raskare enn løkker for store datasett
- Innebygde funksjonar for datareinsking
- Enkel fillesing (CSV, JSON, Excel, etc.)
- Kraftig filtrering og gruppering
- Statistiske funksjonar innebygd
Installasjon:
pip install pandasImport-konvensjon:
import pandas as pdimport pandas as pd
# Les fra CSV
df = pd.read_csv("elever.csv", encoding="utf-8")
# Les fra JSON
df = pd.read_json("elever.json", encoding="utf-8")
# Les norsk CSV med semikolon
df = pd.read_csv("norsk_data.csv", sep=";", encoding="utf-8")Inspeksjon av data:
import pandas as pd
df = pd.read_csv("elever.csv")
print(df.head()) # Første 5 rader
print(df.info()) # Kolonnetyper og manglende verdier
print(df.describe()) # Statistikk for numeriske kolonner
print(df.shape) # (antall_rader, antall_kolonner)
print(df.columns.tolist()) # KolonnenavnVelje data:
# Velg kolonne
navn = df["navn"]
# Velg flere kolonner
utvalg = df[["navn", "karakter"]]
# Filtrere rader
voksne = df[df["alder"] >= 18]
flinke = df[df["karakter"] >= 5]
# Kombinert filter
flinke_voksne = df[(df["alder"] >= 18) & (df["karakter"] >= 5)]Berekningar:
# Statistikk
print(df["karakter"].mean()) # Gjennomsnitt
print(df["karakter"].median()) # Median
print(df["karakter"].max()) # Maks
print(df["karakter"].min()) # Min
print(df["karakter"].std()) # Standardavvik
# Gruppering
per_alder = df.groupby("alder")["karakter"].mean()
print(per_alder)Datareinsking med pandas:
# Fjern rader med manglende verdier
df_ren = df.dropna()
# Fyll inn manglende verdier
df["karakter"] = df["karakter"].fillna(df["karakter"].mean())
# Fjern duplikater
df_unik = df.drop_duplicates()
# Endre datatype
df["alder"] = df["alder"].astype(int)
# Standardiser tekst
df["navn"] = df["navn"].str.strip().str.title()Lagre resultat:
df.to_csv("resultat.csv", index=False, encoding="utf-8")
df.to_json("resultat.json", orient="records", force_ascii=False)Gitt denne DataFrame:
import pandas as pd
df = pd.DataFrame({
"navn": ["Anna", "Bob", "Charlie", "Diana", "Erik"],
"fag": ["matte", "norsk", "matte", "norsk", "matte"],
"karakter": [5, 4, 6, 5, 3]
})Kva gir df.groupby("fag")["karakter"].mean()?
Oppsummering
Filhandtering:
- Bruk alltid with open(...) as fil: for automatisk lukking
- Modusar: "r" (les), "w" (skriv), "a" (legg til)
- Bruk encoding="utf-8" for norske teikn
CSV-filer:
- Tabellformat med rader og kolonnar
- Bruk csv.DictReader() for enkel lesing
- Bruk csv.DictWriter() for skriving
- Hugs delimiter=";" for norske filer
JSON:
- Støttar nesta strukturar (objekt og lister)
- json.load() / json.dump() for filer
- json.loads() / json.dumps() for strengar
- Bruk indent=2 for lesbarheit
Datareinsking:
- Fjern whitespace: strip()
- Standardiser: lower(), title()
- Valider datatypar: try/except med int(), float()
- Handter manglande verdiar
- Fjern duplikat
pandas:
- pd.read_csv() / pd.read_json() for innlesing
- df.head(), df.info(), df.describe() for inspeksjon
- Filtrering: df[df["kolonne"] > verdi]
- Gruppering: df.groupby("kolonne").mean()
- Reinsking: dropna(), fillna(), drop_duplicates()
Filformat-samanlikning:
| Format | Struktur | Bruksområde | Lesbarheit |
|---|---|---|---|
| TXT | Ustrukturert | Loggar, notat | God |
| CSV | Flat tabell | Rekneark, enkel data | God |
| JSON | Nesta objekt | APIar, konfigurasjon | God |
Samleoppgåver
Oppgåver som kombinerer filhandtering, datareinsking og analyse:
Du har ei CSV-fil "salg.csv" med desse kolonnane: produkt, antal, pris, dato.
Skildre stega for ein komplett databehandlingspipeline som:
1. Les inn dataene
2. Reinskar dataene (handterer manglande verdiar og feil)
3. Bereknar total omsetnad per produkt
4. Lagrar resultatet som JSON
For kvart scenario, vel riktig filformat (TXT, CSV eller JSON) og grunngi valet:
A) Lagre ei liste med 1000 temperaturar med tidspunkt og stad
B) Lagre brukarinnstillingar for ein app (tema, språk, varsel, favorittar)
C) Lagre ei loggfil med hendingar som skjer i eit program
D) Eksportere data frå ein database som skal opnast i Excel
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.