Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
  1. Hjem
  2. Informasjonsteknologi
  3. IT 2 – Python
  4. Løsning Høst 2023
VG3

Løsningsforslag Informasjonsteknologi IT 2 – PythonHøst 2023

Se eksamensoppgaven
Vår 2024Nyere
Om løsningsforslaget: Dette er et veiledende løsningsforslag laget av eksamenssett.no for REA3049-PY Høst 2023. Vi gir korrekte svar på flervalgsoppgavene med begrunnelse, fullstendig kode for programmeringsoppgavene (5, 11, 12), og eksempelsvar på drøftingsoppgavene om finanssektoren og personvern (10). Husk at det finnes flere gode måter å løse de åpne oppgavene på.

Løsningsforslag – IT 2 Python Høst 2023

Eksamen: REA3049-PY | Semester: Høst 2023 | Tema: Pseudokode-grunnlag, OOP-prinsipper, billettsystem-flytdiagram, nest-størst-algoritme, IoT-personvern, YouTube-datasett, Manic Mansion-spill

Oppgave 1 – Hva kjennetegner IKKE pseudokode?

Oppgaven: Hvilket alternativ er ikke typisk for pseudokode?
Riktig svar: Den kan kjøres direkte på en datamaskin.

Pseudokode er nettopp ikke kjørbar — den ligner på menneskespråk, har uformell syntaks og brukes i planleggingsfasen. Datamaskinen forstår bare et formelt programmeringsspråk. Pseudokoden må «oversettes» til Python, JavaScript e.l. for å kjøre.

Oppgave 2 – For- og while-løkker

Oppgaven: Hvilken påstand om for- og while-løkker er riktig?
Riktig svar: en for-løkke er best egnet når du vet hvor mange ganger du vil at løkken skal kjøre

For-løkker passer for kjente, faste antall iterasjoner (over en sekvens, eller med teller). While-løkker passer når avslutningsbetingelsen er dynamisk eller ukjent på forhånd. De andre påstandene er feil: for-løkker kan iterere over alle iterables (ikke bare tall), while-løkker har ikke fast antall, og while-løkker kan absolutt bruke en teller.

Oppgave 3 – Hovedprinsippet bak OOP

Oppgaven: Hva er hovedprinsippet bak objektorientert programmering?
Riktig svar: å representere data og funksjoner som objekter

OOP samler data (felter) og oppførsel (metoder) i objekter, slik at programmet modellerer virkeligheten i form av selvstendige enheter som kan kommunisere. Det er motpolen til prosedural/funksjonell programmering der data og funksjoner er adskilt.

Oppgave 4 – Pseudokode som skriver ut 1–5

Oppgaven: Hvilke pseudokode-sekvenser skriver ut 1, 2, 3, 4, 5? (flere svar kan være riktige)
Riktige svar: Alternativ 1 og Alternativ 3
Alt.PseudokodeSkriver utRiktig?
1SET i TO 1; FOR i ≤ 5: PRINT i1, 2, 3, 4, 5✅
2SET i TO 1; WHILE i < 5: PRINT i; INCREMENT i1, 2, 3, 4 (mangler 5)❌
3SET i TO 0; FOR i ≤ 4: PRINT i+11, 2, 3, 4, 5✅
4SET i TO 1; WHILE i ≤ 5: PRINT i; INCREMENT i BY 21, 3, 5 (kun oddetall)❌

Oppgave 5 – Flytdiagram for billettpris

Oppgaven: Lag flytdiagram for et program som tar inn alder og skriver ut billettpris: barn (≤15) 30 kr, voksen (16–66) 50 kr, pensjonist (≥67) 35 kr.
  ┌──────────┐
  │  START   │
  └────┬─────┘
       ▼
  ┌──────────────┐
  │ LES alder    │
  └────┬─────────┘
       ▼
   ╱──────────╲
  ╱ alder ≤ 15? ╲────Ja──▶ DISPLAY "Barnebillett: 30 kr" ──┐
   ╲──────────╱                                              │
        Nei                                                  │
       ▼                                                     │
   ╱──────────╲                                              │
  ╱ alder ≥ 67? ╲────Ja──▶ DISPLAY "Pensjonistbillett: 35 kr"─┤
   ╲──────────╱                                              │
        Nei                                                  │
       ▼                                                     │
  DISPLAY "Voksenbillett: 50 kr"                             │
       │                                                     │
       └──────────────────┬──────────────────────────────────┘
                          ▼
                    ┌──────────┐
                    │  SLUTT   │
                    └──────────┘

Tilsvarende pseudokode:

READ alder
IF alder <= 15
  DISPLAY "Barnebillett: 30 kr"
ELSE IF alder >= 67
  DISPLAY "Pensjonistbillett: 35 kr"
ELSE
  DISPLAY "Voksenbillett: 50 kr"
ENDIF

Test pensjonist-grensen først hvis du tester etter «alder ≥ 16» (ellers vil en 80-åring matche voksen-grenen). Den enkleste rekkefølgen er barn → pensjonist → voksen (else).

Oppgave 6 – Nest-største tall

Oppgave 6a – Hvilke to løsninger er riktige?

Riktige svar: Alternativ 2 og Alternativ 4
Alt.StrategiKorrekt?Hvorfor
1Finn størst, fjern den, finn nest-størst❌Hvis flere har samme maks-verdi (f.eks. [9, 9, 5]), vil «fjern størst» bare fjerne én 9-er, og 9 returneres som «nest størst» — i strid med kravet.
2Initialiser med to første verdier, oppdater nøye✅Sjekken tall NOT EQUAL TO størst sikrer at duplikater av maks ikke regnes som nest-størst.
3Kun én løkke, oppdater størst og nest-størst❌Mangler sjekk på likhet — hvis listen er [9, 9, 5], setter den nest-størst = 9.
4Sorter synkende, finn første som er ulik forrige✅Etter sortering [9, 9, 5] er svaret elementet etter alle 9-erne — altså 5. Krav om «ingen av maks regnes» er oppfylt.

Oppgave 6b – Sammenligning av løsning 2 og 4

Tidskompleksitet: Løsning 2 er O(n) — den traverserer listen én gang. Løsning 4 er O(n log n) på grunn av sorteringen. For store lister er løsning 2 betydelig raskere.

Plasskompleksitet: Løsning 2 bruker konstant ekstra plass (to variabler). Løsning 4 trenger plass til den sorterte listen, eller endrer originalen — som kan være uønsket.

Lesbarhet: Løsning 4 er enklere å forstå og kortere å skrive — sortering er en velkjent operasjon. Løsning 2 har mer betingelseslogikk (initialisering, swap, doble sjekker) og er lettere å gjøre feil i.

Konklusjon: Løsning 4 vinner på lesbarhet og kompakthet. Løsning 2 vinner på effektivitet, særlig når listen er stor eller man ikke ønsker å endre den. For en typisk skoleeksempel med få elementer er forskjellen i ytelse uvesentlig, og løsning 4 er den jeg ville valgt for tydelig kode.

Oppgave 7c – Implementasjon av valgt nest-størst-algoritme

# nest_storst.py — to løsninger som finner nest-største unike verdi
from typing import Sequence


def nest_storst_lineaer(tall: Sequence[float]) -> float | None:
    """Løsning 2 — én pass, O(n)."""
    if len(tall) < 2:
        return None

    storst = nest_storst = float("-inf")
    for t in tall:
        if t > storst:
            nest_storst = storst
            storst = t
        elif t < storst and t > nest_storst:
            nest_storst = t
    return nest_storst if nest_storst != float("-inf") else None


def nest_storst_sortert(tall: Sequence[float]) -> float | None:
    """Løsning 4 — sorter og hopp over duplikater, O(n log n)."""
    if len(tall) < 2:
        return None
    sortert = sorted(tall, reverse=True)
    storst = sortert[0]
    for t in sortert[1:]:
        if t != storst:
            return t
    return None  # alle elementene var like


if __name__ == "__main__":
    eksempler = [
        [9, 9, 5, 3],     # forventet: 5
        [1, 2, 3, 4, 5],   # forventet: 4
        [7],              # forventet: None
        [3, 3, 3],        # forventet: None (alle like)
    ]
    for e in eksempler:
        print(f"{e!s:<18} → lineær={nest_storst_lineaer(e)}, sortert={nest_storst_sortert(e)}")

Oppgave 9 – IoT-risikovurdering

Oppgaven: Hvorfor bør forsikringsselskaper risikovurdere IoT-leverandører?
Riktig svar: for å forsikre seg om at produktene er trygge og overholder personvernregelverket

IoT-enheter samler ofte sensitive opplysninger (helse, lokasjon, vaner). Brudd på personvernregelverket kan føre til store bøter etter GDPR (opp til 4 % av global omsetning) og omdømmetap. Et forsikringsselskap som inngår samarbeid uten risikovurdering, eksponeres for betydelig juridisk og økonomisk risiko.

Oppgave 10 – Endring i finanssektoren + personverndilemma

Oppgave 10a – Endring forårsaket av IT

Endring: Den mest gjennomgripende endringen i finanssektoren det siste tiåret er overgangen til digitale betalingsløsninger — Vipps, BankID, mobilbank — som har erstattet både fysisk kontant og papirgiro for de aller fleste hverdagstransaksjoner. Norge er i dag blant verdens mest «kontantløse» økonomier; under 3 % av betalingene skjer med kontanter (Norges Bank, 2023).

Endringen er drevet av flere IT-trender: smarttelefonens utbredelse, sikker autentisering med BankID, åpne API-er gjennom PSD2-direktivet, og maskinlæringsbaserte system for svindeldeteksjon. Tradisjonelle banker har gått fra fysiske filialer til app-styrt selvbetjening, og nye fintech-aktører (Klarna, Revolut, Wise) konkurrerer direkte med etablerte banker.

Oppgave 10b – Personverndilemma

Dilemmaet: Når alle transaksjoner er digitale, etterlater hver kjøp en datasti — hva, hvor, når og hvor mye. Bankene ser dermed ikke bare hvilke varer du kjøper, men kan også slutte seg til helsetilstand (apotek-kjøp), politisk engasjement (donasjoner), forhold (hotell-kjøp utenfor hjemstedet) og hele livsstilen din.

Spenning: Disse dataene er nyttige — de gjør det mulig å avsløre svindel, tilby personlige råd og forebygge gambling-avhengighet. Men de er også svært sensitive. Hvis dataene lekker, selges, eller kobles med andre datasett, kan profileringen brukes til diskriminering (kredittavslag basert på «livsstil»), målrettet manipulasjon (mikrotargetert reklame som utnytter sårbarheter), eller statlig overvåkning.

GDPR og dataminimering: Personvernforordningen krever at banker bare lagrer det de trenger til avtalt formål — men «svindeldeteksjon» og «kunderelasjon» er bredt nok til at lite effektivt begrenses i praksis. Dataportabilitet (PSD2) gir kunden rett til å overføre data til andre tilbydere, men gjør samtidig at flere aktører får tilgang til transaksjonshistorikken.

Vurdering: Den kontantløse økonomiens bekvemmelighet kommer med en pris i form av redusert anonymitet. Et velregulert system med streng tilsynsmyndighet (Datatilsynet, Finanstilsynet) kan dempe risikoen, men aldri fjerne den. Som forbruker er det viktig å være bevisst om at hver Vipps-betaling tilfører en datapost som potensielt eksisterer for alltid.

Oppgave 11 – YouTube-statistikk

Oppgaven: Datasett over YouTube-kanaler globalt. (a) De 10 landene med flest kanaler. (b) Gjennomsnittlig antall abonnenter og videovisninger per kanal for hvert av disse landene.
# oppgave11.py — analyse av YouTube-datasett
"""Forberedelse av datasettet:
- Datasettet er kodet med ukjent tegnsett. Vi prøver utf-8, deretter latin-1.
- Numeriske felter er kodet som tekst i CSV; vi konverterer der det kreves.
- Tomme/feilede land-felter ignoreres."""

import csv
from collections import Counter, defaultdict
from pathlib import Path

DATAFIL = Path("youtube.csv")


def les_data(filsti: Path = DATAFIL) -> list[dict]:
    for enc in ("utf-8", "utf-8-sig", "latin-1"):
        try:
            with filsti.open(encoding=enc) as f:
                return list(csv.DictReader(f, delimiter=","))
        except UnicodeDecodeError:
            continue
    raise RuntimeError("Klarte ikke å lese filen i kjente tegnsett.")


def til_int(s: str) -> int:
    try:
        return int(float(s.replace(",", "").strip()))
    except (ValueError, AttributeError):
        return 0


def topp_ti_land(data: list[dict]) -> list[tuple[str, int]]:
    teller: Counter[str] = Counter()
    for r in data:
        land = (r.get("Country") or r.get("country") or "").strip()
        if land and land.lower() != "nan":
            teller[land] += 1
    return teller.most_common(10)


def snitt_per_land(data: list[dict], land: list[str]) -> dict[str, tuple[float, float]]:
    sum_abo: defaultdict[str, int] = defaultdict(int)
    sum_views: defaultdict[str, int] = defaultdict(int)
    antall: defaultdict[str, int] = defaultdict(int)

    landset = set(land)
    for r in data:
        l = (r.get("Country") or r.get("country") or "").strip()
        if l in landset:
            sum_abo[l] += til_int(r.get("subscribers", "0"))
            sum_views[l] += til_int(r.get("video views", "0"))
            antall[l] += 1

    return {
        l: (sum_abo[l] / antall[l] if antall[l] else 0,
            sum_views[l] / antall[l] if antall[l] else 0)
        for l in land
    }


def main() -> None:
    data = les_data()
    topp = topp_ti_land(data)
    print("\nTopp 10 land etter antall YouTube-kanaler:")
    print(f"{'Rang':<6}{'Land':<20}{'Kanaler':>10}")
    for i, (land, antall) in enumerate(topp, start=1):
        print(f"{i:<6}{land:<20}{antall:>10}")

    snitt = snitt_per_land(data, [l for l, _ in topp])
    print("\nGjennomsnitt per kanal i topp 10:")
    print(f"{'Land':<20}{'Snitt abonnenter':>20}{'Snitt visninger':>20}")
    for land, _ in topp:
        abo, views = snitt[land]
        print(f"{land:<20}{abo:>20,.0f}{views:>20,.0f}".replace(",", " "))


if __name__ == "__main__":
    main()

Oppgave 12 – Manic Mansion

Oppgaven: Lag et 2D-spill der mennesket henter sauer mens spøkelser sirkler tilfeldig og hindringer blokkerer. Kollisjon med spøkelse stopper spillet; én sau om gangen kan bæres, sauen drar ned hastigheten.

Oppgave 12a – Forklaring av modellen

En naturlig OO-modell består av en abstrakt Spillobjekt-klasse med posisjon og størrelse, og fire spesialiseringer:

  • Menneske — styres av piltaster, blokkeres av hindringer/kanter, har variabel hastighet (faller når sau bæres).
  • Spokelse — beveger seg konstant i en tilfeldig retning, reflekteres ved kanter og frisone-grenser, ignorerer hindringer.
  • Hindring — statisk objekt, blokkerer Menneske men ikke Spokelse.
  • Sau — statisk inntil bæres; kontaktes Menneske → fjernes/festes.

I tillegg har vi en Spillebrett-klasse som holder rede på alle objekter, oppdager kollisjoner, håndterer venstre/høyre frisone, og kjører spilløkken med poengtelling. Modellen viser polymorfisme (hver subklasse implementerer egen tegn() og oppdater()) og innkapsling (objektene eksponerer kun det grensesnittet spillebrettet trenger).

Oppgave 12b – Implementasjon

# manic_mansion.py — Pygame-implementasjon
# pip install pygame
from __future__ import annotations
import random
import pygame

# --- Konstanter ---
BREDDE, HOEYDE = 800, 600
FRISONE = 80            # bredde på frisonene venstre/høyre
FPS = 60
MENNESKE_FART = 4.0
SAU_BREMSEFAKTOR = 0.5
SPOKELSE_FART = 3.0
START_SPOKELSER = 1
START_HINDRINGER = 3
START_SAUER = 3


class Spillobjekt:
    def __init__(self, x: float, y: float, storrelse: int, farge: tuple) -> None:
        self.x, self.y = x, y
        self.storrelse = storrelse
        self.farge = farge

    def rect(self) -> pygame.Rect:
        s = self.storrelse
        return pygame.Rect(int(self.x - s / 2), int(self.y - s / 2), s, s)

    def tegn(self, skjerm) -> None:
        pygame.draw.rect(skjerm, self.farge, self.rect())


class Menneske(Spillobjekt):
    def __init__(self, x: float, y: float) -> None:
        super().__init__(x, y, 28, (26, 43, 74))   # mørk blå
        self.bærer_sau = False
        self.poeng = 0
        self.dx, self.dy = 0.0, 0.0

    def fart(self) -> float:
        return MENNESKE_FART * (SAU_BREMSEFAKTOR if self.bærer_sau else 1.0)

    def oppdater(self, taster, hindringer: list[Spillobjekt]) -> None:
        f = self.fart()
        nx, ny = self.x, self.y
        if taster[pygame.K_LEFT] or taster[pygame.K_a]:  nx -= f
        if taster[pygame.K_RIGHT] or taster[pygame.K_d]: nx += f
        if taster[pygame.K_UP] or taster[pygame.K_w]:    ny -= f
        if taster[pygame.K_DOWN] or taster[pygame.K_s]:  ny += f

        # Begrens innenfor spillebrett
        s = self.storrelse / 2
        nx = max(s, min(BREDDE - s, nx))
        ny = max(s, min(HOEYDE - s, ny))

        # Hindringskollisjon — beveg én akse av gangen for «glide»-følelse
        forrige_x, forrige_y = self.x, self.y
        self.x = nx
        if any(self.rect().colliderect(h.rect()) for h in hindringer):
            self.x = forrige_x
        self.y = ny
        if any(self.rect().colliderect(h.rect()) for h in hindringer):
            self.y = forrige_y


class Spokelse(Spillobjekt):
    def __init__(self, x: float, y: float) -> None:
        super().__init__(x, y, 24, (229, 115, 115))
        vinkel = random.uniform(0, 2 * 3.14159)
        import math
        self.dx = math.cos(vinkel) * SPOKELSE_FART
        self.dy = math.sin(vinkel) * SPOKELSE_FART

    def oppdater(self) -> None:
        self.x += self.dx
        self.y += self.dy

        # Reflekter på kanter av brett
        if self.x < self.storrelse / 2 or self.x > BREDDE - self.storrelse / 2:
            self.dx = -self.dx
        if self.y < self.storrelse / 2 or self.y > HOEYDE - self.storrelse / 2:
            self.dy = -self.dy

        # Reflekter på frisone-grensene (spøkelser holdes ute av frisonene)
        if self.x < FRISONE + self.storrelse / 2:
            self.dx = abs(self.dx)
        if self.x > BREDDE - FRISONE - self.storrelse / 2:
            self.dx = -abs(self.dx)


class Hindring(Spillobjekt):
    def __init__(self, x: float, y: float) -> None:
        super().__init__(x, y, 36, (120, 100, 80))


class Sau(Spillobjekt):
    def __init__(self, x: float, y: float) -> None:
        super().__init__(x, y, 22, (240, 240, 230))


class Spill:
    def __init__(self) -> None:
        pygame.init()
        self.skjerm = pygame.display.set_mode((BREDDE, HOEYDE))
        pygame.display.set_caption("Manic Mansion")
        self.klokke = pygame.time.Clock()
        self.font = pygame.font.SysFont("Helvetica", 20)

        self.menneske = Menneske(40, HOEYDE / 2)
        self.spokelser: list[Spokelse] = []
        self.hindringer: list[Hindring] = []
        self.sauer: list[Sau] = []
        for _ in range(START_SPOKELSER): self._ny_spokelse()
        for _ in range(START_HINDRINGER): self._ny_hindring()
        for _ in range(START_SAUER): self._ny_sau()
        self.tapt = False

    def _tilfeldig_midten(self) -> tuple[int, int]:
        return random.randint(FRISONE + 30, BREDDE - FRISONE - 30), random.randint(30, HOEYDE - 30)

    def _ny_spokelse(self) -> None:
        x, y = self._tilfeldig_midten()
        self.spokelser.append(Spokelse(x, y))

    def _ny_hindring(self) -> None:
        x, y = self._tilfeldig_midten()
        self.hindringer.append(Hindring(x, y))

    def _ny_sau(self) -> None:
        x = random.randint(BREDDE - FRISONE + 10, BREDDE - 20)
        y = random.randint(20, HOEYDE - 20)
        self.sauer.append(Sau(x, y))

    def _handter_kollisjoner(self) -> None:
        m_rect = self.menneske.rect()
        # Spøkelse → tap
        if any(m_rect.colliderect(s.rect()) for s in self.spokelser):
            self.tapt = True
            return
        # Sau → plukke opp
        if not self.menneske.bærer_sau:
            for sau in list(self.sauer):
                if m_rect.colliderect(sau.rect()):
                    self.sauer.remove(sau)
                    self.menneske.bærer_sau = True
                    break
        # Tilbake i venstre frisone med sau → poeng
        if self.menneske.bærer_sau and self.menneske.x < FRISONE:
            self.menneske.bærer_sau = False
            self.menneske.poeng += 1
            self._ny_sau()
            self._ny_spokelse()
            self._ny_hindring()
        # Treff annen sau mens man bærer en → tap
        if self.menneske.bærer_sau and any(m_rect.colliderect(s.rect()) for s in self.sauer):
            self.tapt = True

    def kjor(self) -> None:
        kjorer = True
        while kjorer:
            for e in pygame.event.get():
                if e.type == pygame.QUIT:
                    kjorer = False

            if not self.tapt:
                taster = pygame.key.get_pressed()
                self.menneske.oppdater(taster, self.hindringer)
                for sp in self.spokelser:
                    sp.oppdater()
                self._handter_kollisjoner()

            self.skjerm.fill((232, 215, 185))
            pygame.draw.rect(self.skjerm, (200, 220, 200), (0, 0, FRISONE, HOEYDE))
            pygame.draw.rect(self.skjerm, (200, 220, 200), (BREDDE - FRISONE, 0, FRISONE, HOEYDE))
            for obj in [*self.hindringer, *self.sauer, *self.spokelser, self.menneske]:
                obj.tegn(self.skjerm)

            tekst = f"Poeng: {self.menneske.poeng}"
            if self.tapt:
                tekst += "  —  TAPT! Trykk på krysset for å avslutte."
            self.skjerm.blit(self.font.render(tekst, True, (0, 0, 0)), (10, 10))

            pygame.display.flip()
            self.klokke.tick(FPS)

        pygame.quit()


if __name__ == "__main__":
    Spill().kjor()
Designvalg for sensor:
  • Polymorfisme via arv: Alle objekter arver fra Spillobjekt og overstyrer tegn() ved behov. Spill-klassen kan iterere over en blandet liste og kalle tegn(self.skjerm) uten å bry seg om type.
  • Aksevis kollisjonshåndtering for menneske: Vi flytter først x, sjekker, evt. ruller tilbake; deretter y. Dette gir naturlig «glide langs vegg» i stedet for å stoppe helt opp.
  • Frisoner er enkle x-grenser; spøkelser reflekteres når de prøver å gå inn, mennesket har lov til å gå inn.
  • Tap-tilstand stopper bare bevegelse — vinduet kan fortsatt lukkes via X-knappen.
  • Krav om at ingen objekter starter oppå hverandre kan styrkes ved å sjekke kollisjon i _tilfeldig_midten og prøve på nytt — utelatt for kortere kode.

Oppgave 13 – Innlevering

123456/
├── oppgave5/billettpris_flytdiagram.pdf
├── oppgave7c/nest_storst.py
├── oppgave11/
│   ├── oppgave11.py
│   └── youtube.csv
├── oppgave12/manic_mansion.py
└── README.md   (krev: pip install pygame)
Nyere løsning
Vår 2024

Alle løsningsforslag for IT 2 – Python

Vår 2025Høst 2024Vår 2024Høst 2023
Se eksamensoppgaven
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS