Åpen og lukket sløyfe, enkel PID-regulering og automatisering.
Prosjektarbeid med programmering
Gjennom denne seksjonen har du lært variablar, kontrollstrukturar, funksjonar, lister, filhandtering og visualisering. No er det tid for å setje alt saman i eit prosjektarbeid.
Eit programmeringsprosjekt er meir enn berre koding – det handlar òg om å planleggje, teste, feilsøke og dokumentere arbeidet ditt. Desse ferdigheitene er sentrale i teknologi og forskingslære, og dei speglar korleis profesjonelle utviklarar og forskarar arbeider.
I dette kapittelet lærer du:
- Korleis du planlegg eit prosjekt med pseudokode og flytskjema
- Teknikkar for testing og debugging (feilsøking)
- Korleis du dokumenterer koden din med kommentarar og docstrings
- Korleis du strukturerer eit større program med funksjonar og modular
Etter dette kapittelet vil du ha verktøya du treng for å gjennomføre eit sjølvstendig programmeringsprosjekt frå start til slutt.
Døme – pseudokode for eit 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 filEit flytskjema er ei visuell framstilling av programflyten med standardiserte symbol:
- Oval: Start/slutt
- Rektangel: Prosess (handling)
- Diamant (rombe): Avgjerd (if/else)
- Parallellogram: Inndata/utdata
Fordelar med planlegging:
- Du oppdagar logiske feil før du byrjar å kode
- Det er lettare å dele opp arbeidet i funksjonar
- Andre kan forstå planen din og gi tilbakemelding
- Du slepp å skrive om store delar av koden undervegs
Dei fire fasane i eit programmeringsprosjekt
Eit godt prosjekt følgjer desse fasane:
1. Planlegging (20 % av tida)
- Definer problemet tydeleg: Kva skal programmet gjere?
- Skisser løysinga med pseudokode eller flytskjema
- Identifiser kva for funksjonar du treng
- Bestem kva for bibliotek som er nyttige (csv, matplotlib, math)
2. Koding (40 % av tida)
- Skriv éin funksjon om gongen
- Test kvar funksjon for seg (einingstesting)
- Bruk skildrande variabelnamn og kommentarar
- Følg Python-konvensjonar (snake_case, innrykk med 4 mellomrom)
3. Testing (25 % av tida)
- Test med kjende data der du veit svaret
- Test grensetilfelle (tom liste, null, negative tal)
- Test med ugyldig inndata (tekst der det blir venta tal)
- Rett feil (debugging) og test på nytt
4. Dokumentasjon (15 % av tida)
- Skriv ei kort skildring av programmet
- Kommenter vanskelege delar av koden
- Lag ei brukarrettleiing dersom programmet har brukarinteraksjon
- Dokumenter kjelder (data, formlar, bibliotek)
Lat oss følgje prosessen for eit 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 funksjonar:
- les_data(filnavn) – les CSV og returnerer lister
- beregn_statistikk(temperaturer) – returnerer gjennomsnitt, min, maks
- lag_graf(datoer, temperaturer) – lagar og viser grafen
- skriv_rapport(statistikk, filnavn) – skriv 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 hovudprogrammet på slutten er svært lesbart – kvar linje skildrar eitt steg i analysen.
Kva for fase av eit programmeringsprosjekt bør du bruke mest tid på?
Tre typar testar:
1. Test med kjende data: Bruk inndata der du veit 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 grensetilfelle: Sjekk at programmet handterer spesielle verdiar.
# Test med tom liste
# Test med ett element
# Test med negative tall
# Test med veldig store tall3. Test med ugyldig inndata: Sjekk at programmet ikkje krasjar.
# 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-teknikkar:
- Print-debugging: Legg til print() for å sjå verdiar undervegs
- Les feilmeldinga nøye: Python fortel deg type feil og linjenummer
- Kommenter ut kode: Isoler problemet ved å deaktivere delar av koden
- Gummiand-metoden: Forklar koden høgt for ei «gummiand» (eller ein medstudent)
Vanlege feil og korleis du fiksar dei
Her er dei vanlegaste feila nybegynnarar 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 finst ikkje
# 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 heile feilmeldinga. Ho fortel deg type feil, linjenummer og ofte kva som gjekk gale.
Her testar vi ein funksjon som reknar ut 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 brukar abs(resultat - forventet) < 0.01 for å samanlikne desimaltal – direkte samanlikning med == kan gi feil på grunn av avrunding.
Kva er ein docstring i Python?
Dokumentasjon av kode
God dokumentasjon gjer koden din forståeleg for andre – og for deg sjølv om nokre veker!
Kommentarar forklarar kvifor du gjer noko (ikkje kva – det ser ein 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 funksjonar:
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)Filhovud – ein kommentar øvst i fila som skildrar programmet:
"""
Temperaturanalyse – Prosjektoppgave ToF 1
Programmet leser temperaturdata fra en CSV-fil,
beregner statistikk og lager visualiseringer.
Forfatter: Kari Nordmann
Dato: 2024-03-15
"""Hugs: Kode blir lesen mykje oftare enn han blir skriven. God dokumentasjon er ei investering i framtidig leseforståing.
Her er eit 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 elementa i eit godt prosjekt: filhovud, docstrings, feilhandtering, modulær oppbygging med funksjonar, og ein tydeleg hovudprogramdel.
Oppsummering
I dette kapittelet har du lært å:
- Planleggje eit programmeringsprosjekt med pseudokode og flytskjema
- Følgje dei fire fasane: planlegging, koding, testing og dokumentasjon
- Teste program systematisk med kjende data, grensetilfelle og ugyldig inndata
- Debugge vanlege Python-feil: SyntaxError, IndentationError, NameError, TypeError og IndexError
- Dokumentere kode med kommentarar, docstrings og filhovud
- Strukturere eit program med funksjonar som har tydeleg ansvar
Nøkkelprinsipp for gode prosjekt:
- Planlegg før du kodar – det sparar tid til slutt
- Skriv og test éin funksjon om gongen
- Les feilmeldingar nøye – dei fortel deg kva som er gale
- Dokumenter koden din – framtidas deg vil takke deg
- Hald funksjonar små og med eitt tydeleg formål
Med ferdigheitene frå heile seksjon 5 – variablar, kontrollstrukturar, funksjonar, lister, filhandtering, visualisering og prosjektarbeid – har du eit solid grunnlag for å bruke programmering som verktøy i teknologi og forskingslære.
Skriv pseudokode for eit program som les inn poengsummar frå ei prøve, reknar ut gjennomsnitt og median, og avgjer om snittet er greidd (over 50 %). Oversett deretter pseudokoden til Python-kode med minst to funksjonar.
Gjennomfør eit miniprosjekt: Lag eit Python-program som fungerer som ein «vêrstasjon». Programmet skal: a) Lese inn daglege målingar (temperatur, nedbør) i ei veke (7 dagar). b) Rekne ut og vise statistikk (gjennomsnitt, min, maks for begge). c) Lage to grafar med subplots: temperatur over veka og nedbør som stolpediagram. d) Lagre ein rapport til ei tekstfil. Kravliste: minst 3 funksjonar, docstrings på alle funksjonar, feilhandtering for ugyldig inndata, og eit filhovud.
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.