Tilbake
7.1

7.1 Løsningsoppskriften — hele programmeringskjeden

Oversikten over den faste fem-ledds-kjeden og en fullt gjennomarbeidet eksamenscase som binder alle leddene sammen med gjenbruk.

45 min
6 oppgaver
Løsningsoppskriftenhele programmeringskjeden
Din fremgang i kapitlet
0 / 6 oppgaver
Forkunnskaper — sist du var her

Del 7 bruker alt du har bygget opp så langt, så her er de tre grepene kjeden hviler på, ferdig oppfrisket. Kjenner du dem igjen, er du klar.

1. Fra fil til tabell (kap. 4.1) — rens linja, del den, legg raden i tabellen:

linje = 'Nordlysjegerne;1;96;120\n'
rad = linje.strip().split(';')
print(rad)

Utskrift:

['Nordlysjegerne', '1', '96', '120']

2. Fra tabell til teller (kap. 3.5) — ordboka som legger sammen per nøkkel:

solgt = {}
for navn in ['Under isen', 'Nordlysjegerne', 'Under isen']:
    solgt[navn] = solgt.get(navn, 0) + 1
print(solgt)

Utskrift:

{'Under isen': 2, 'Nordlysjegerne': 1}

3. Kolonnen funnet ved navn (kap. 3.2) — aldri et hardkodet tall:

overskrift = ['film', 'sal', 'solgt', 'plasser']
k = overskrift.index('solgt')
print(k)

Utskrift:

2

I tillegg bygger kapitlet direkte på kap. 2.2 — gjenbruk, hjelpefunksjoner og main som dispatcher.

Løkke 1 — den samme oppgaven i ny innpakning (~10 min)

Her er tre oppgavetekster. De er hentet fra tre forskjellige verdener, og på papiret ser de ut som tre forskjellige oppgaver:

- «Filen reisetider.txt inneholder én linje per busstur. Skriv et program som finner den treigeste ruta.»
- «Filen stemmer.txt inneholder én linje per valgkrets. Skriv et program som finner partiet i ledelse.»
- «Filen kast.txt inneholder én linje per terningkast. Skriv et program som finner spilleren med flest seksere.»

Les dem én gang til, og se bort fra substantivene. Alle tre sier: åpne en fil, gjør hver linje om til tall, gå gjennom radene, finn den største verdien, skriv den ut. Det er én oppgave, ikke tre.

Dette er den viktigste enkeltinnsikten i hele faget. Den som leser oppgaven som «en oppgave om terningkast» må finne på noe nytt hvert år. Den som leser den som «kjeden, denne gangen med terninger» har løst den før.

Innpakning og øvelse
Innpakningen er domenet oppgaven er kledd i: bussruter, stemmesedler, terningkast, matoppskrifter. Øvelsen er det programmet faktisk gjør.

I dette faget er innpakningen ny hvert år og øvelsen den samme. Innpakningen bestemmer bare tre ting: hva fila heter, hva feltene heter, og hva svaret skal kalles i utskriften.

Praktisk grep når du får settet: stryk under de tre–fire substantivene i oppgaveteksten og erstatt dem i hodet med «rad», «kolonne» og «verdi». Det som blir igjen, er oppskriften i løkke 2.

Deloppgavene a) til f)

Programmeringsoppgaven er nesten aldri én stor bestilling. Den er delt i deloppgaver a), b), c) …, og hver deloppgave ber om én funksjon.

Rekkefølgen på deloppgavene følger kjeden: a) leser fila, b) tolker eller omformer dataene, c) og d) analyserer, e) skriver ut eller lagrer, f) binder det hele sammen.

Hver deloppgave har sin egen prosentvekting, og hver av dem rettes for seg. Det betyr at deloppgave d) kan gi full pott selv om c) er tom.

Datastrukturvalget: tabell eller ordbok

Ledd 1 ender alltid i én av to strukturer, og valget styres av spørsmålet du skal svare på:

- 2D-liste (tabell) — når du skal gå gjennom alle radene og sammenligne dem: finn den beste, sortér, regn snitt. En 2D-liste er en liste der hvert element selv er en liste, altså en tabell med rader og kolonner.
- Ordbok — når du skal slå opp én bestemt nøkkel raskt, eller telle og gruppere per nøkkel: {filmnavn: antall}.

Sier oppgaven «finn ruta med lengst reisetid», er svaret tabell. Sier den «hvor mange billetter solgte hver film», er svaret ordbok. Sier den begge deler, leser du inn i en tabell og bygger ordboka av tabellen etterpå — som i casen i løkke 3.

✏️Eksempel 1: tre oppgavetekster, én øvelse

Sett de tre oppgavetekstene over ved siden av hverandre, og skriv opp hva hvert ledd i kjeden må gjøre i hver av dem. Hva er likt, og hva er forskjellig?

LeddBussruterValgkretserTerningkast
Les filaén rad per turén rad per kretsén rad per kast
Tolkreisetid til intstemmetall til intøyne til int
Analysérstørst reisetidstørst stemmesumflest seksere per spiller
Skriv utrutenavnetpartinavnetspillernavnet

Det eneste som skifter, er ordene i venstre kolonne av datafila og ordet i utskriften. Selve arbeidet — open, strip, split, int, én løkke, én sammenligning — er tegn for tegn det samme.
To av de tre trenger i tillegg en ordbok, fordi de spør «per krets» og «per spiller». Det er ikke en ny øvelse; det er telleren fra kap. 3.5 satt inn i ledd 3.
Slik ville sensor sett på det: ingen får poeng for å ha skjønt at oppgavene ligner. Poengene ligger i at gjenkjennelsen sparer deg for femten minutters panikk, slik at du bruker tiden på koden i stedet.
📝Oppgave 1

(Innstegsoppgave — les oppgaveteksten som en kjede.) Her er en oppgavetekst du ikke har sett før:

«Filen soppturer.txt har én linje per tur: navn på plukkeren, sopptype og antall kilo. Skriv (a) en funksjon som leser fila til en 2D-liste, (b) en funksjon som finner den største enkeltfangsten, og (c) en funksjon som skriver ut hvor mange kilo hver plukker har til sammen.»

a) Hvilket ledd i kjeden hører hver deloppgave til?

b) Hvilken datastruktur bør deloppgave c) bygge, og hvorfor?

Løkke 2 — løsningsoppskriften i fem ledd (~12 min)

Nå skal oppskriften stå fast. Den er lik hvert år, og du skal kunne skrive den ned på kladdearket før du skriver en eneste kodelinje.

📜Løsningsoppskriften — de fem leddene

Dette er mønsteret hele programmeringsdelen følger. Lær det som en oppskrift, ikke som en tekst.

1. Les fila — åpne, gå gjennom linje for linje, bygg en 2D-liste eller en ordbok, lukk. Én funksjon: les_inn(filnavn).
2. Tolk dataenestrip() før split(), int() eller float() på tallfeltene, tidsstrenger om til tall. Ofte samme funksjon som ledd 1, ellers en egen.
3. Analysér — gå gjennom strukturen og finn det oppgaven spør om: den beste raden, en telling, en gruppering, en sortert rangering. Her ligger tyngdepunktet av poengene, og som regel to–tre deloppgaver.
4. Ta imot brukervalginput() med validering, eller en menyløkke som lar brukeren velge hvilken analyse som skal kjøres.
5. Skriv ut eller lagre — pen kolonneutskrift, en rapportfil, eller lagring til binærfil.

Og limet: main leser fila én gang og sender strukturen videre til de andre funksjonene.

main(filnavn)
    tabell = les_inn(filnavn)          <- ledd 1 og 2
    valg   = input(...)                <- ledd 4
    svar   = analyser(tabell)          <- ledd 3
    skriv_ut(svar)                     <- ledd 5

Blokken over er en skisse, ikke kjørbar kode. Alle deloppgavene løses hver for seg, i den rekkefølgen som passer deg — men skriv dem i denne rekkefølgen første gang, for da får du dataene å teste med underveis.

Ledd 1 — innlesing
Sjanger E, altså «les fila og bygg datastrukturen». Én funksjon som tar imot et filnavn og returnerer en 2D-liste eller en ordbok.

Fast form: open, deretter readline() hvis fila har overskriftsrad, deretter for linje in f: med linje.strip().split(sep) og append, og til slutt close og return.

Leddet er verdt 5–10 % og står i hvert eneste sett. Det er også det leddet du kan øve deg til full uttelling på, fordi det ikke varierer. Drilles i kap. 7.2.

Ledd 2 — parsing
Sjanger F, altså å tolke rådataene og gjøre dem om til noe regnbart. Å parse betyr nettopp det: å tolke en tekst og hente ut verdiene den representerer.

Typiske jobber: int()/float() på tallfeltene, en tidsstreng som '2:01.65' om til sekunder, en tabell om til en oppslagsordbok, eller en linje med varierende antall mellomrom delt riktig.

Leddet er verdt 5–10 %, og glemmes det, virker ingenting etterpå: sammenligner du strenger i stedet for tall, får du feil svar uten at programmet krasjer. Drilles i kap. 7.3.

Ledd 3 — analysen
Sjanger G — tyngdepunktet. Her ligger som regel to–tre deloppgaver à 5–10 %, altså mer enn de fire andre leddene til sammen.

Fire analysetyper dekker nesten alt: finn den beste raden, tell forekomster, gruppér i en ordbok av lister, og rangér hele tabellen etter en kolonne.

Analysefunksjonene tar tabellen som parameter — de åpner aldri fila selv. Drilles i kap. 7.4 og kap. 7.5, og gjøres robust i kap. 7.6.

Ledd 4 — input og meny
Sjanger H. Enten en enkelt validert input() («hvilken film vil du se tall for?»), eller en hel menyløkke som lar brukeren velge analyse etter analyse til han skriver q.

Fast form: while True:, vis valgene, les valg = input(...), la if/elif fordele jobben, og avslutt med break i den siste grenen.

Leddet er med i omtrent halvparten av settene og er verdt 5–10 % når det er der. Drilles i kap. 7.7.

Ledd 5 — utskrift og lagring
Sjanger I. Svaret skal ut av programmet: som pen kolonneutskrift på skjermen, som en rapportfil, eller lagret på binærfil.

Fast form for utskrift: ljust/rjust for kolonnebredde, '{:.2f}'.format(x) for desimaler, ', '.join(liste) for en oppramsing. Den nyere f-strengen f'{x:.2f}' gir det samme (verifiser mot gjeldende pensum — varslet inn 2019); arkivet 2014–2019 bruker .format().

Leddet er verdt 5–10 % og glemmes ofte fordi tiden er ute. Legg merke til at det som regel er den enkleste deloppgaven i settet — den bør du ta før du polerer analysen. Drilles i kap. 7.7.

Signaturen oppgaven gir deg

Oppgaveteksten oppgir nesten alltid funksjonsnavnet og parameterne selv: «skriv funksjonen finn_beste(tabell, kolonne) som returnerer …».

Bruk den ordrett. Endrer du navnet eller rekkefølgen på parameterne, virker ikke de senere deloppgavene som skal kalle den, og du mister poeng du allerede hadde.

Sier oppgaven ingenting, velger du selv — norske og engelske navn er like gyldige. Fasitene i dette faget blander fritt, og denne boka bruker overveiende norske navn.

Gjenbruk mellom leddene

Senere funksjoner skal kalle de tidligere, ikke kopiere koden deres.

Skal deloppgave d) regne fyllingsgrad for den beste raden, og deloppgave b) allerede har en fyllingsgrad-funksjon, kaller d) den. Sensor belønner det eksplisitt: gjenbruk teller som riktig løsning, kopiert kode gjør ikke.

Det er også en forsikring. Har du en liten feil i fyllingsgrad, står den ett sted og trekker én gang — ikke fire steder og fire ganger.

`main` leser fila én gang
main åpner fila, får tabellen, og sender den samme tabellen videre til alle de andre funksjonene.

Motstykket — at hver analysefunksjon åpner fila på nytt selv — er et av de vanligste trekkene i dette faget. Det gjør funksjonene umulige å gjenbruke på andre data, og det gjør at et filnavn må hardkodes fem steder.

Regelen i én setning: fila leses ett sted, dataene sendes videre som parameter.

✏️Eksempel 2: skissér kjeden før du koder

En oppgave lyder: «Filen forestillinger.txt har en overskriftsrad og deretter én linje per kinoforestilling: filmtittel, sal, antall solgte billetter og antall plasser i salen, skilt med semikolon. Skriv et program som finner den best fylte forestillingen og viser hvor mange billetter hver film har solgt til sammen.»

Skissér kjeden — hvilke funksjoner trenger du, hva tar de imot, og hva returnerer de? Ikke skriv kode ennå.

Slik ser fila ut:

Innholdet i forestillinger.txt:

film;sal;solgt;plasser
Nordlysjegerne;1;96;120
Sommeren på Stord;2;41;60
Nordlysjegerne;2;58;60
Under isen;1;77;120
Sommeren på Stord;1;110;120

Skissen på kladdearket, ett ledd per linje:

FunksjonTar imotReturnererLedd
les_forestillinger(filnavn)filnavnet2D-liste med overskriftsrad, tallene konvertert1 og 2
fyllingsgrad(rad, k_solgt, k_plasser)én rad og to kolonneindekserprosenten som flyttall3
best_fylte(tabell)tabellenden beste raden og verdien dens3
solgt_per_film(tabell)tabellenordbok {film: sum}3
skriv_rapport(tabell)tabelleningenting — den skriver ut5
main(filnavn)filnavnetingenting — den binder sammenlimet

Tre ting er verdt å legge merke til i skissen, og alle tre gir uttelling:
- fyllingsgrad er skilt ut som egen hjelpefunksjon selv om den bare er én linje. Da kan best_fylte kalle den i stedet for å gjenta regnestykket.
- best_fylte og solgt_per_film tar tabellen som parameter, ikke filnavnet. De leser aldri fila selv.
- Ingen av funksjonene får kolonnenummeret oppgitt utenfra. De finner det selv fra overskriftsraden, og da spiller det ingen rolle om kolonnene kommer i en annen rekkefølge neste år.
Denne skissen tar tre minutter og gjør resten av oppgaven til utfylling.

📝Oppgave 2
Eksamensnivå
«Filen panteautomat.txt har én linje per innlevering: butikknavn, dato og antall flasker, skilt med semikolon. Skriv et program som viser hvilken butikk som har tatt imot flest flasker til sammen, og hvor mange innleveringer hver butikk har hatt.»

Sett opp skissen som en tabell med kolonnene funksjon, parameter, returverdi og ledd. Skriv ingen kode — men skriv hvilken datastruktur hver analysefunksjon bygger.

Løkke 3 — hele casen, funksjon for funksjon (~15 min)

Nå fyller vi ut skissen fra eksempel 2. Hver funksjon står i sin egen blokk, akkurat som deloppgavene på et eksamenssett — og hver av dem kunne vært levert alene og fått sine poeng.

— naturlig pausepunkt før denne løkka —

✏️Eksempel 3: kinorapporten, hele kjeden (eksamensnivå)

Skriv programmet fra skissen i eksempel 2. Fila forestillinger.txt er den samme. Programmet skal skrive ut den best fylte forestillingen med fyllingsgraden i prosent, og deretter en oversikt over solgte billetter per film.

Deloppgave a) — innlesing (ledd 1 og 2). Overskriftsraden leses med readline() før løkka, og blir rad 0 i tabellen slik at kolonnene kan finnes ved navn senere.

def les_forestillinger(filnavn):
    f = open(filnavn, 'r')
    overskrift = f.readline().strip().split(';')
    tabell = [overskrift]
    for linje in f:
        felt = linje.strip().split(';')
        felt[2] = int(felt[2])
        felt[3] = int(felt[3])
        tabell.append(felt)
    f.close()
    return tabell

Kolonne 2 og 3 konverteres med int() under innlesingen. Gjør du det her, slipper du å huske på det i hver eneste analysefunksjon etterpå.

Deloppgave b) — hjelpefunksjonen (ledd 3). Én linje, men den er verdt å skille ut:

def fyllingsgrad(rad, k_solgt, k_plasser):
    return 100 * rad[k_solgt] / rad[k_plasser]

Legg merke til 100 * foran: skriver du rad[k_solgt] / rad[k_plasser] * 100, får du det samme, men skriver du rad[k_solgt] // rad[k_plasser] * 100, får du 0 for alt annet enn en helt full sal. Heltallsdelingen // runder nedover.

Deloppgave c) — finn den beste (ledd 3). Mønsteret med None som startverdi:

def best_fylte(tabell):
    k_solgt = tabell[0].index('solgt')
    k_plasser = tabell[0].index('plasser')
    beste = None
    beste_verdi = None
    for rad in tabell[1:]:
        v = fyllingsgrad(rad, k_solgt, k_plasser)
        if beste_verdi is None or v > beste_verdi:
            beste = rad
            beste_verdi = v
    return beste, beste_verdi

Fire ting gir uttelling her, hver for seg: kolonnene funnet med .index(...), beste_verdi startet på None og ikke på 0, tabell[1:] som hopper over overskriftsraden, og gjenbruket av fyllingsgrad.

Deloppgave d) — tell per film (ledd 3). Telleren fra kap. 3.5, med flasketallet lagt til i stedet for 1:

def solgt_per_film(tabell):
    k_film = tabell[0].index('film')
    k_solgt = tabell[0].index('solgt')
    per_film = {}
    for rad in tabell[1:]:
        navn = rad[k_film]
        per_film[navn] = per_film.get(navn, 0) + rad[k_solgt]
    return per_film

Deloppgave e) — utskriften (ledd 5). Den kaller de to analysefunksjonene i stedet for å regne selv:

def skriv_rapport(tabell):
    beste, grad = best_fylte(tabell)
    print('Best fylte forestilling:', beste[0], '- sal', beste[1])
    print('Fyllingsgrad:', '{:.1f}'.format(grad), 'prosent')
    print()
    print('Solgte billetter per film:')
    per_film = solgt_per_film(tabell)
    for navn in sorted(per_film):
        print(navn.ljust(20) + str(per_film[navn]).rjust(4))

Utskrift: ingen — blokken definerer bare funksjonen. Den skriver først når main kaller den.

Deloppgave f) — main (limet). Tre linjer, og fila leses ett eneste sted:

def main(filnavn):
    tabell = les_forestillinger(filnavn)
    skriv_rapport(tabell)

Kaller du main('forestillinger.txt') etter at de seks funksjonene over er definert, skriver programmet dette:

Utskrift:

Best fylte forestilling: Nordlysjegerne - sal 2
Fyllingsgrad: 96.7 prosent

Solgte billetter per film:
Nordlysjegerne       154
Sommeren på Stord    151
Under isen            77

Slik ville sensor sett på det, deloppgave for deloppgave:

DeloppgaveVektHva som gir uttelling
a) innlesing20 %open/close, strip().split(';'), int(), header hoppet over
b) hjelpefunksjon10 %riktig regnestykke, / og ikke //
c) finn beste25 %None som start, kolonne funnet ved navn, gjenbruk av b)
d) tell per film25 %ordbok med get-default, summering og ikke telling
e) utskrift10 %leselig format, kaller c) og d) i stedet for å regne selv
f) main10 %leser fila én gang, sender tabellen videre

Flere korrekte løsninger. Deloppgave c) kunne vært løst med max(tabell[1:], key=lambda rad: fyllingsgrad(rad, k_solgt, k_plasser)), deloppgave d) med .count. Begge gir full pott — sensor er ute etter riktig idé, ikke én bestemt formulering.
Og en trøst: hadde best_fylte returnert bare raden og ikke verdien, ville skriv_rapport krasjet. Det ville kostet noen få poeng på e), ikke på c). Deloppgavene rettes hver for seg.
📝Oppgave 3
Eksamensnivå, sjanger G

Bygg videre på kjeden i eksempel 3. Skriv funksjonen tomme_plasser(tabell) som returnerer det totale antallet usolgte plasser i alle forestillingene til sammen.

Funksjonen skal finne kolonnene ved navn, og den skal ikke åpne fila selv.

📝Oppgave 4
Eksamensnivå, sjanger G

Fortsatt samme kjede. Skriv dårligst_fylte(tabell) som returnerer raden med lavest fyllingsgrad.

Løs den ved å gjenbruke fyllingsgrad fra eksempel 3, og forklar med én setning hva du måtte endre fra best_fylte.

Løkke 4 — poengene: vekting, uavhengighet og antakelser (~8 min)

De siste poengene i programmeringsdelen hentes ikke i koden, men i hvordan du disponerer de fire timene.

Tidsbudsjett fra prosentvektingen

Prosentvektingen står trykt på settet, deloppgave for deloppgave. Den er ikke pynt — den er tidsplanen din.

Regnestykket: eksamen er 240 minutter. Er programmeringsdelen 55 %, er den verdt omtrent 130 minutter. Er én deloppgave 10 % av settet, er den verdt omtrent 24 minutter — og har du brukt 40, skal du videre uansett hvor nær du føler deg.

Skriv de tre tallene øverst på kladdearket før du begynner: klokkeslettet du skal være ferdig med teoridelen, med kodeforståelsen, og med hver programmeringsdeloppgave.

Uavhengige deloppgaver

Deloppgavene rettes hver for seg. Får du ikke til b), kan du fortsatt få full pott på c), d) og e).

Praktisk betyr det: står du fast på en deloppgave, skriv én setning om hva funksjonen skulle ha gjort, anta at den finnes, kall den i de neste deloppgavene, og gå videre. Du får poengene for de neste.

Det motsatte — å bli sittende på deloppgave b) til tiden er ute — er den dyreste enkeltfeilen i dette faget, fordi analysedeloppgavene som står igjen er de tyngste av alle.

Antakelse skrevet ned

Er oppgaveteksten uklar — kan to forestillinger ha samme fyllingsgrad? kan fila være tom? — velger du selv, og skriver én setning om valget.

«Antar at det bare finnes én best fylte forestilling; ved lik grad returneres den første» er nok. Det tar femten sekunder, og det er forskjellen mellom «feil» og «riktig gitt en dokumentert antakelse».

Sensorregelen som gjelder her, er den samme som for teorisvarene: svar kort og klart. Er svaret uklart eller lengre enn nødvendig, trekker det ned.

Delpoeng for riktig struktur

En løsning med riktig overordnet struktur og en indeksfeil gir god uttelling. En løsning uten struktur, men uten syntaksfeil, gir lite.

Det betyr at rekkefølgen du jobber i, bør være: få kjeden på plass først — funksjonene, parameterne, returverdiene — og finpuss kantene etterpå hvis det er tid.

Det betyr også at du aldri skal levere blankt på en deloppgave. Skriver du bare def best_fylte(tabell): med en løkke som går gjennom radene, har du allerede noe å få poeng for.

✏️Eksempel 4: to besvarelser på samme deloppgave

To studenter har levert deloppgave c) fra eksempel 3 — «finn den best fylte forestillingen». Hvilken uttelling får hver av dem, og hva skiller dem?

Besvarelse 1 — solid midtnivå (ville fått en god C, kanskje B):

def best_fylte(tabell):
    beste = tabell[1]
    beste_verdi = 100 * tabell[1][2] / tabell[1][3]
    for rad in tabell[1:]:
        v = 100 * rad[2] / rad[3]
        if v > beste_verdi:
            beste = rad
            beste_verdi = v
    return beste

tabell = [['film', 'sal', 'solgt', 'plasser'],
          ['Nordlysjegerne', '1', 96, 120],
          ['Sommeren på Stord', '1', 110, 120]]
print(best_fylte(tabell))

Utskrift:

['Sommeren på Stord', '1', 110, 120]

Denne koden virker på dataene i oppgaven, og den har riktig struktur: én løkke, én sammenligning, riktig returverdi. Det gir god uttelling.

To ting skiller den likevel fra toppen. Kolonnene 2 og 3 er hardkodet — kommer kolonnene i en annen rekkefølge, svarer funksjonen feil uten å si fra (felle #4). Og tabell[1] som startverdi krasjer på en tom tabell, altså en tabell som bare har overskriftsraden. Regnestykket er dessuten skrevet to ganger, så en feil i det må rettes to steder.

Besvarelse 2 — toppnivå: koden i eksempel 3. Forskjellen er tre grep, ikke tre sider: kolonnene funnet med .index(...), None som startverdi, og regnestykket i en egen funksjon som kalles begge steder.

Poenget for deg: avstanden fra midt til topp er liten og helt konkret. Det er de tre grepene i kap. 7.6 — dynamisk kolonne, tomtilfelle og ingen duplikater — og du kan lære dem på en kveld.

📝Oppgave 5
Eksamensnivå

Et sett har denne programmeringsoppgaven, og du har 130 minutter igjen når du begynner på den:

a) les_data(filnavn) — 10 %
b) tid_til_sekunder(tekst) — 10 %
c) raskeste(tabell) — 20 %
d) antall_per_klubb(tabell) — 20 %
e) skriv_resultatliste(tabell) — 15 %

Du står bom fast på b) etter 25 minutter. Hva gjør du, og hvor mange minutter har du igjen til hver av de tre siste?

Svar kort — dette er ikke et kodespørsmål.

📝Oppgave 6
Eksamensnivå, sjanger E…
«Filen soppturer.txt har én linje per tur uten overskriftsrad: plukkerens navn, sopptype og antall kilo, skilt med semikolon. Skriv (a) les_turer(filnavn) som returnerer en 2D-liste med kiloene som flyttall, (b) kilo_per_plukker(tabell) som returnerer en ordbok, og (c) beste_plukker(tabell) som returnerer navnet på den som har plukket mest til sammen. Deloppgave c) skal gjenbruke b).»

Skriv alle tre funksjonene. Du trenger ikke skrive main.

API- og konstruksjonsliste

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.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Norges teknisk-naturvitenskapelige universitet. Dette er ikke offisielt studiemateriell. Les mer.