Åpen og lukket sløyfe, enkel PID-regulering og automatisering.
Prosjektarbeid med programmering
Gjennom denne seksjonen har du lært variabler, kontrollstrukturer, funksjoner, lister, filhåndtering og visualisering. Nå er det tid for å sette alt sammen i et prosjektarbeid.
Et programmeringsprosjekt er mer enn bare koding – det handler også om å planlegge, teste, feilsøke og dokumentere arbeidet ditt. Disse ferdighetene er sentrale i teknologi og forskningslære, og de gjenspeiler hvordan profesjonelle utviklere og forskere arbeider.
I dette kapittelet lærer du:
- Hvordan du planlegger et prosjekt med pseudokode og flytskjema
- Teknikker for testing og debugging (feilsøking)
- Hvordan du dokumenterer koden din med kommentarer og docstrings
- Hvordan du strukturerer et større program med funksjoner og moduler
Etter dette kapittelet vil du ha verktøyene du trenger for å gjennomføre et selvstendig programmeringsprosjekt fra start til slutt.
Eksempel – pseudokode for et analyseprogram:
LES data fra fil
FOR hver måling i data:
LEGG TIL måling i liste
BEREGN gjennomsnitt
BEREGN standardavvik
HVIS gjennomsnitt > grenseverdi:
SKRIV advarsel
LAG graf av målingene
LAGRE rapport til filEt flytskjema er en visuell fremstilling av programflyten med standardiserte symboler:
- Oval: Start/slutt
- Rektangel: Prosess (handling)
- Diamant (rombe): Beslutning (if/else)
- Parallellogram: Inndata/utdata
Fordeler med planlegging:
- Du oppdager logiske feil før du begynner å kode
- Det er lettere å dele opp arbeidet i funksjoner
- Andre kan forstå planen din og gi tilbakemelding
- Du slipper å skrive om store deler av koden underveis
De fire fasene i et programmeringsprosjekt
Et godt prosjekt følger disse fasene:
1. Planlegging (20 % av tiden)
- Definer problemet tydelig: Hva skal programmet gjøre?
- Skisser løsningen med pseudokode eller flytskjema
- Identifiser hvilke funksjoner du trenger
- Bestem hvilke biblioteker som er nyttige (csv, matplotlib, math)
2. Koding (40 % av tiden)
- Skriv én funksjon om gangen
- Test hver funksjon for seg (enhetstesting)
- Bruk beskrivende variabelnavn og kommentarer
- Følg Python-konvensjoner (snake_case, innrykk med 4 mellomrom)
3. Testing (25 % av tiden)
- Test med kjente data der du vet svaret
- Test grensetilfeller (tom liste, null, negative tall)
- Test med ugyldig inndata (tekst der det forventes tall)
- Rett feil (debugging) og test på nytt
4. Dokumentasjon (15 % av tiden)
- Skriv en kort beskrivelse av programmet
- Kommenter vanskelige deler av koden
- Lag en brukerveiledning hvis programmet har brukerinteraksjon
- Dokumenter kilder (data, formler, biblioteker)
La oss følge prosessen for et program som analyserer temperaturdata:
Steg 1 – Pseudokode:
LES temperaturer fra CSV-fil
BEREGN gjennomsnitt, min, maks
TELL dager med frost (under 0)
LAG linjediagram av temperaturene
LAGRE rapport til tekstfilSteg 2 – Identifiser funksjoner:
- les_data(filnavn) – leser CSV og returnerer lister
- beregn_statistikk(temperaturer) – returnerer gjennomsnitt, min, maks
- lag_graf(datoer, temperaturer) – lager og viser grafen
- skriv_rapport(statistikk, filnavn) – skriver rapport til fil
Steg 3 – Kode:
import csv
import matplotlib.pyplot as plt
def les_data(filnavn):
"""Leser temperaturdata fra en CSV-fil."""
datoer = []
temperaturer = []
with open(filnavn, "r") as fil:
leser = csv.reader(fil)
next(leser) # Hopp over overskrift
for rad in leser:
datoer.append(rad[0])
temperaturer.append(float(rad[1]))
return datoer, temperaturer
def beregn_statistikk(temperaturer):
"""Beregner og returnerer statistikk som en dictionary."""
return {
"antall": len(temperaturer),
"gjennomsnitt": sum(temperaturer) / len(temperaturer),
"maks": max(temperaturer),
"min": min(temperaturer),
"frost": sum(1 for t in temperaturer if t < 0),
}
def lag_graf(datoer, temperaturer):
"""Lager et linjediagram av temperaturene."""
plt.figure(figsize=(12, 5))
plt.plot(temperaturer, "b-", linewidth=1.5)
plt.axhline(y=0, color="red", linestyle="--", alpha=0.5)
plt.xlabel("Dag nr.")
plt.ylabel("Temperatur (°C)")
plt.title("Daglige temperaturer")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig("temperaturgraf.png", dpi=150)
plt.show()
def skriv_rapport(statistikk, filnavn):
"""Skriver en rapport med statistikk til fil."""
with open(filnavn, "w") as fil:
print("TEMPERATURRAPPORT", file=fil)
print("=" * 30, file=fil)
for nokkel, verdi in statistikk.items():
if isinstance(verdi, float):
print(f"{nokkel:15s}: {verdi:8.1f}", file=fil)
else:
print(f"{nokkel:15s}: {verdi:8d}", file=fil)
# Hovedprogram
datoer, temperaturer = les_data("temperaturer.csv")
statistikk = beregn_statistikk(temperaturer)
lag_graf(datoer, temperaturer)
skriv_rapport(statistikk, "temperaturrapport.txt")
print("Analyse fullført!")Legg merke til at hovedprogrammet på slutten er svært lesbart – hver linje beskriver ett steg i analysen.
Hvilken fase av et programmeringsprosjekt bør du bruke mest tid på?
Tre typer tester:
1. Test med kjente data: Bruk inndata der du vet svaret.
# Test: gjennomsnitt av [2, 4, 6] skal gi 4.0
resultat = beregn_gjennomsnitt([2, 4, 6])
print(f"Forventet: 4.0, Fikk: {resultat}")2. Test grensetilfeller: Sjekk at programmet håndterer spesielle verdier.
# Test med tom liste
# Test med ett element
# Test med negative tall
# Test med veldig store tall3. Test med ugyldig inndata: Sjekk at programmet ikke krasjer.
# Hva skjer hvis brukeren skriver "abc" i stedet for et tall?
try:
tall = float(input("Tall: "))
except ValueError:
print("Ugyldig inndata – skriv inn et tall.")Debugging-teknikker:
- Print-debugging: Legg til print() for å se verdier underveis
- Les feilmeldingen nøye: Python forteller deg type feil og linjenummer
- Kommenter ut kode: Isoler problemet ved å deaktivere deler av koden
- Gummiand-metoden: Forklar koden høyt for en «gummiand» (eller en medstudent)
Vanlige feil og hvordan du fikser dem
Her er de vanligste feilene nybegynnere møter i Python:
1. SyntaxError – skrivefeil i koden
# Feil: mangler kolon
if x > 5
print("Stor")
# Riktig:
if x > 5:
print("Stor")2. IndentationError – feil innrykk
# Feil: blander mellomrom og tab
def funksjon():
print("a")
print("b") # For mye innrykk!
# Riktig: konsekvent innrykk med 4 mellomrom
def funksjon():
print("a")
print("b")3. NameError – variabelen finnes ikke
# Feil: skrivefeil i variabelnavn
temperatur = 22.5
print(tempratur) # NameError!
# Riktig:
print(temperatur)4. TypeError – feil datatype
# Feil: kan ikke legge sammen streng og tall
alder = "17"
neste_ar = alder + 1 # TypeError!
# Riktig:
neste_ar = int(alder) + 15. IndexError – ugyldig indeks
# Feil: listen har bare 3 elementer (indeks 0–2)
tall = [10, 20, 30]
print(tall[3]) # IndexError!
# Riktig:
print(tall[2]) # Siste elementTips: Les alltid hele feilmeldingen. Den forteller deg type feil, linjenummer og ofte hva som gikk galt.
Her tester vi en funksjon som beregner karaktergjennomsnitt:
def beregn_snitt(karakterer):
"""Beregner gjennomsnittet av en liste med karakterer (1-6)."""
if len(karakterer) == 0:
return 0.0
return sum(karakterer) / len(karakterer)
# === TESTER ===
# Test 1: Vanlig tilfelle
resultat = beregn_snitt([4, 5, 3, 6, 4])
forventet = 4.4
print(f"Test 1: {resultat} == {forventet}? {'OK' if abs(resultat - forventet) < 0.01 else 'FEIL'}")
# Test 2: Alle like
resultat = beregn_snitt([5, 5, 5])
forventet = 5.0
print(f"Test 2: {resultat} == {forventet}? {'OK' if abs(resultat - forventet) < 0.01 else 'FEIL'}")
# Test 3: Bare én karakter
resultat = beregn_snitt([6])
forventet = 6.0
print(f"Test 3: {resultat} == {forventet}? {'OK' if abs(resultat - forventet) < 0.01 else 'FEIL'}")
# Test 4: Tom liste (grensetilfelle)
resultat = beregn_snitt([])
forventet = 0.0
print(f"Test 4: {resultat} == {forventet}? {'OK' if abs(resultat - forventet) < 0.01 else 'FEIL'}")Utskrift:
Test 1: 4.4 == 4.4? OK
Test 2: 5.0 == 5.0? OK
Test 3: 6.0 == 6.0? OK
Test 4: 0.0 == 0.0? OKLegg merke til at vi bruker abs(resultat - forventet) < 0.01 for å sammenligne desimaltall – direkte sammenligning med == kan gi feil på grunn av avrunding.
Hva er en docstring i Python?
Dokumentasjon av kode
God dokumentasjon gjør koden din forståelig for andre – og for deg selv om noen uker!
Kommentarer forklarer hvorfor du gjør noe (ikke hva – det ser man av koden):
# Dårlig kommentar (sier hva koden gjør – det ser vi allerede):
x = x + 1 # Øker x med 1
# God kommentar (sier hvorfor):
x = x + 1 # Kompenser for 0-indeksering i utskriftenDocstrings dokumenterer funksjoner:
def beregn_bmi(vekt_kg, hoyde_m):
"""
Beregner Body Mass Index (BMI).
Parametre:
vekt_kg (float): Vekt i kilogram
hoyde_m (float): Høyde i meter
Returnerer:
float: BMI-verdien
"""
return vekt_kg / (hoyde_m ** 2)Filhode – en kommentar øverst i filen som beskriver programmet:
"""
Temperaturanalyse – Prosjektoppgave ToF 1
Programmet leser temperaturdata fra en CSV-fil,
beregner statistikk og lager visualiseringer.
Forfatter: Kari Nordmann
Dato: 2024-03-15
"""Husk: Kode leses mye oftere enn den skrives. God dokumentasjon er en investering i fremtidig leseforståelse.
Her er et komplett miniprosjekt med god struktur og dokumentasjon:
"""
BMI-kalkulator med statistikk
Programmet lar brukeren registrere BMI for flere personer,
beregner statistikk og lager et stolpediagram.
Forfatter: Elev Elevesen
Dato: 2024-03-20
"""
import matplotlib.pyplot as plt
def beregn_bmi(vekt_kg, hoyde_m):
"""Beregner BMI basert på vekt (kg) og høyde (m)."""
return vekt_kg / (hoyde_m ** 2)
def bmi_kategori(bmi):
"""Returnerer BMI-kategori som tekst."""
if bmi < 18.5:
return "Undervekt"
elif bmi < 25:
return "Normalvekt"
elif bmi < 30:
return "Overvekt"
else:
return "Fedme"
def les_inn_data():
"""Leser inn navn, vekt og høyde for flere personer."""
navn_liste = []
bmi_liste = []
print("BMI-kalkulator (skriv 'ferdig' for å avslutte)")
while True:
navn = input("Navn: ")
if navn.lower() == "ferdig":
break
try:
vekt = float(input("Vekt (kg): "))
hoyde = float(input("Høyde (m): "))
bmi = beregn_bmi(vekt, hoyde)
navn_liste.append(navn)
bmi_liste.append(bmi)
print(f" BMI: {bmi:.1f} ({bmi_kategori(bmi)})")
except ValueError:
print(" Ugyldig input – prøv igjen.")
return navn_liste, bmi_liste
def vis_statistikk(navn_liste, bmi_liste):
"""Skriver ut en oppsummering av BMI-dataene."""
print("\nOPPSUMMERING")
print("=" * 35)
for navn, bmi in zip(navn_liste, bmi_liste):
print(f" {navn:15s} BMI: {bmi:5.1f} ({bmi_kategori(bmi)})")
print("-" * 35)
print(f" Gjennomsnitt: {sum(bmi_liste) / len(bmi_liste):.1f}")
def lag_diagram(navn_liste, bmi_liste):
"""Lager et stolpediagram over BMI-verdiene."""
farger = ["green" if 18.5 <= b < 25 else "orange" for b in bmi_liste]
plt.figure(figsize=(8, 5))
plt.bar(navn_liste, bmi_liste, color=farger)
plt.axhline(y=18.5, color="gray", linestyle="--", alpha=0.5)
plt.axhline(y=25, color="gray", linestyle="--", alpha=0.5)
plt.ylabel("BMI")
plt.title("BMI-oversikt")
plt.tight_layout()
plt.savefig("bmi_oversikt.png", dpi=150)
plt.show()
# === HOVEDPROGRAM ===
navn, bmi = les_inn_data()
if len(navn) > 0:
vis_statistikk(navn, bmi)
lag_diagram(navn, bmi)
else:
print("Ingen data registrert.")Programmet viser alle elementene i et godt prosjekt: filhode, docstrings, feilhåndtering, modulær oppbygging med funksjoner, og en tydelig hovedprogramdel.
Oppsummering
I dette kapittelet har du lært å:
- Planlegge et programmeringsprosjekt med pseudokode og flytskjema
- Følge de fire fasene: planlegging, koding, testing og dokumentasjon
- Teste programmer systematisk med kjente data, grensetilfeller og ugyldig inndata
- Debugge vanlige Python-feil: SyntaxError, IndentationError, NameError, TypeError og IndexError
- Dokumentere kode med kommentarer, docstrings og filhoder
- Strukturere et program med funksjoner som har tydelig ansvar
Nøkkelprinsipper for gode prosjekter:
- Planlegg før du koder – det sparer tid til slutt
- Skriv og test én funksjon om gangen
- Les feilmeldinger nøye – de forteller deg hva som er galt
- Dokumenter koden din – fremtidens deg vil takke deg
- Hold funksjoner små og med ett tydelig formål
Med ferdighetene fra hele seksjon 5 – variabler, kontrollstrukturer, funksjoner, lister, filhåndtering, visualisering og prosjektarbeid – har du et solid grunnlag for å bruke programmering som verktøy i teknologi og forskningslære.
Skriv pseudokode for et program som leser inn poengsummer fra en prøve, beregner gjennomsnitt og median, og avgjør om snittet er bestått (over 50 %). Oversett deretter pseudokoden til Python-kode med minst to funksjoner.
Gjennomfør et miniprosjekt: Lag et Python-program som fungerer som en «værstasjon». Programmet skal: a) Lese inn daglige målinger (temperatur, nedbør) i en uke (7 dager). b) Beregne og vise statistikk (gjennomsnitt, min, maks for begge). c) Lage to grafer med subplots: temperatur over uken og nedbør som stolpediagram. d) Lagre en rapport til en tekstfil. Kravliste: minst 3 funksjoner, docstrings på alle funksjoner, feilhåndtering for ugyldig inndata, og et filhode.
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.