IN1000 høst2024
Introduksjon til objektorientert programmering (Python)
05.01: Lesing fra fil
Filnavn: les_fil.py og navn.txt
a) Opprett en tekstfil kalt navn.txt, som du legger i samme mappe som les_fil.py. Tekstfilen skal inneholde navnene under:
Anne
Bjarne
Carina
David
Elise
Frode
b) Bruk open()
for å åpne navn.txt i pythonprogrammet.
c) Opprett en tom liste med navn navn_liste
d) Skriv en løkke som går gjennom filen, linje for linje, og legger linjene inn i listen.
NB: Husk å lukke filen når du er ferdig
e) Skriv ut listen til terminal.
b)
fil = open("navn.txt", "r")
c)
navn_liste = []
d)
for linje in fil:
navn_liste.append(linje)
fil.close()
e)
print(navn_liste)
05.05 Enkle tabulære filer
I denne øvelsen skal du skrive flere funksjoner som kan lese tabulære filer, dvs. som har data organisert i rader og kolonner, og lagre innholdet i forskjellige samlinger.
Del 1
Filnavn: bil.txt, bil.py
a) Opprett en tekstfil kalt bil.txt, som inneholder følgende tekst og legger i samme mappe som bil.py:
brand:Ford
model:Mustang
year:1964
b) Skriv en funksjon, les_bil(filnavn)
, i bil.py som kan lese bil.txt. Funksjonen skal...
- ... lage en tom ordbok, resultatet
- ... gå gjennom filen og dele hver linje i to kolonner etter ":" (kolon).
Sørg også for at linjeskift er fjernet.
- ... for hver linje lagre den første kolonnen som ordboknøklen, og den andre kolonnen som ordbokverdien.
- ... returnere ordboken
c) Skriv ut resultatet
Del 2
Filnavn: song_contest.txt, song_contest.py
a) Opprett en tekstfil song_contest.txt som inneholder følgende teskt:
2016 Ukrania
2017 Portugal
2018 Israel
2019 Nederland
2020 avlyst
2021 Italia
b) Skriv en funksjon, les_song_contest(filnavn)
i song_contest.py som kan lese song_contest.txt. Funksjonen skal...
- ... opprette to lister, årene
og landene
- ... gå gjennom filen og dele hver linje i to kolonner etter mellomrom.
Sørg også for at linjeskift er fjernet.
- ... lagre den første verdien i listen årene
og den andre verdien i listen landene
.
- ... opprette en ordbok song_contest
som inneholder nøkkelen år
med listen av årene som verdi og nøkkelen land
med listen av landene som verdi.
- ... returnere ordboken
c) Skriv ut resultatet
Del 3
Filnavn: poeng.txt, poeng.py
a) Opprett en tekstfil poeng.txt som inneholder følgende teskt:
Mari:3,5,3,6
Erik:2,4,5,3
Silje:3,5,4,6
Ola:2,5,4,5
b) Skriv en funksjon, les_poeng(filnavn)
i poeng.py som kan lese poeng.txt. Funksjonen skal...
- ... opprette en tom ordbok poeng
- ... gå gjennom filen og dele hver linje i to kolonner etter ":" (kolon).
Sørg også for at linjeskift er fjernet.
- ... dele opp strengen av antall poeng på "," (komma). Dette resulterer i en liste.
- ... sette dataen i ordboken poeng
der navn er nøkkelen og listen av poeng til personen er tilhørende verdi.
- ... returnere ordboken
c) Skriv ut resultatet
Utfordring: Skriv om funksjonen i Del 3 slik at verdiene i ordboken poeng
er et heltall som er summen av alle tall i listen i stedet for listen selv.
Del 1
def les_bil(filnavn):
# oppretter ordboken
resultatet = {}
for linje in open(filnavn):
linje = linje.strip()
kolonner = linje.split(":")
noekkel = kolonner[0]
verdi = kolonner[1]
# sette data i ordboken
resultatet[noekkel] = verdi
return resultatet
print(les_bil("bil.txt"))
Del 2
def les_song_contest(filnavn):
årene = []
landene = []
for linje in open(filnavn):
linje = linje.strip()
kolonner = linje.split()
årene.append(kolonner[0])
landene.append(kolonner[1])
song_contest = {"år": årene, "land": landene}
return song_contest
print(les_song_contest("song_contest.txt"))
Alternativ løsning:
def les_song_contest(filnavn):
årene = []
landene = []
for linje in open(filnavn):
linje = linje.strip()
år, land = linje.split()
årene.append(år)
landene.append(land)
song_contest = {"år": årene, "land": landene}
return song_contest
print(les_song_contest("song_contest.txt"))
Del 3
def les_poeng(filnavn):
resultatet = {}
for linje in open(filnavn):
linje = linje.strip()
kolonner = linje.split(":")
navn = kolonner[0]
poeng = kolonner[1].split(",")
resultatet[navn] = poeng
return resultatet
print(les_poeng("poeng.txt"))
c) - utfordring
def les_poeng(filnavn):
resultatet = {}
for linje in open(filnavn):
linje = linje.strip()
kolonner = linje.split(":")
navn = kolonner[0]
poeng = kolonner[1].split(",")
total = 0
for p in poeng: # må kastes om til et heltall
total += int(p)
resultatet[navn] = total
return resultatet
print(les_poeng("poeng.txt"))
05.06 Skriv til filer
a) Lag en prosedyre skriv_dna()
som skriver ut følgende linjer:
O---o
O-o
O
o-O
o---O
Hint
Du kan bruke print()
flere ganger, eller kalle print()
bare 1 gang og bruke linjeskift tegn "\n"
b) Endre prosedyren skriv_dna()
slik at den tar inn et filnavn som parameter og skriver strengen til filen i stedet for å skrive den ut til terminalen. Husk å lukke filen.
c) Kall prosedyren skriv_dna()
tre ganger med samme filnavn som argumentet. Hvordan ser den resulterende filen ut? Ser den ut som forventet?
d) Bonus: Les documentasjonen om mode-argumentet her. Endre prosedyren skriv_dna()
slik at den bruker 'append mode' i stedet for 'write mode' for å løse problemet fra c), og kjør programmet igjen.
a)
def skriv_dna():
print("O---o")
print(" O-o")
print(" O")
print(" o-O")
print("o---O")
eller
def skriv_dna():
print("O---o\n O-o\n O\n o-O\no---O")
b)
def skriv_dna(filnavn):
fil = open(filnavn, "w")
fil.write("O---o\n")
fil.write(" O-o \n")
fil.write(" O \n")
fil.write(" o-O \n")
fil.write("o---O\n")
fil.close()
eller
def skriv_dna(filnavn):
fil = open(filnavn, "w")
fil.write("O---o\n O-o\n O\n o-O\no---O\n")
fil.close()
c) Den resulterende filen inneholder stringen én gang, ikke tre ganger selv om prosedyren er kalt 3 ganger.
d) Bruk mode "a" (append) i stedet for "w" (write)
def skriv_dna(filnavn):
fil = open(filnavn, "a")
fil.write("O---o\n O-o\n O\n o-O\no---O\n")
fil.close()
skriv_dna("dna_fil.txt")
skriv_dna("dna_fil.txt")
skriv_dna("dna_fil.txt")
05.07 Maks ord per linje
I denne oppgave skal du lage et program som tar inn en tekst og skriver den ut til en fil. I utdatafilen er det et maksimalt antall ord som er tillatt per linje.
a) Lag en prosedyre format_text()
som tar inn en string tekst
, en string filnavn
og et heltall maks_ord
.
- tekst
er det som skrives til fil
- filnavn
er navnet på utdatafilen
- maks_ord
er maksimalt antall ord per linje
Prosedyren skal...
- ... dele stringen tekst
i ord
- ... skrive hvert ord til filen
- ... passe på at ikke flere ord enn maks_ord
skrives på hver linje
Du kan bruke en tellervariabel for å holde oversikt over hvor mange ord du har skrevet til filen. Hver gang maks_ord
er nådd for linjen, skriv en linjeskrift-karater ("\n") til filen.
b) Test programmet med følgende verdier og sjekk at filen "test.out" opprettes og inneholder det som forventes:
- Teksten: "I denne oppgave skal du lage et program som tar inn en tekst og skriver den ut til en fil. I utdatafilen er det maksimalt antall ord som er tillatt per linje."
- Filnavn: "test.out"
- Maks antall ord per linje: 5
Forventet resultat:
I denne oppgave skal du
lage et program som tar
inn en tekst og skriver
den ut til en fil.
I utdatafilen er det maksimalt
antall ord som er tillatt
per linje.
Husk å åpne og lukke filen!
def format_text(tekst, filnavn, maks_ord):
ordene = tekst.split()
fil = open(filnavn, "w")
teller = 0
for min_ord in ordene:
teller += 1
fil.write(min_ord)
fil.write(" ") # inkluder mellomrom mellom ordene.
# kan også bruke "if teller % maks_ord == 0"
if teller == maks_ord:
teller = 0
fil.write("\n")
fil.close()
tekst = "I denne oppgave skal du lage et program som tar inn en tekst og skriver den ut til en fil. I utdatafilen er det maksimalt antall ord som er tillatt per linje."
format_text(tekst, "test.out", 5)
05.08 Linjefilter
I denne oppgaven skal du skrive en prosedyre som skriver ut alle linjene i en gitt tekstfil som ikke inneholder 'NA' til en ny fil.
I tabulær filer brukes verdien 'NA' (“not available”) for å betegne manglende informasjon. Vurder følgende tabulær fil med NA-verdier:
Name,Sex,Age,Height(in),Weight(lbs)
Alex,M,41,74,NA
Bert,M,NA,68,166
Carl,M,32,70,155
Dave,M,NA,72,167
Elly,F,30,66,124
Fran,F,33,NA,115
Gwen,F,26,64,121
Hank,M,30,71,158
Ivan,M,53,NA,175
Jake,M,32,69,143
Kate,F,47,69,139
Luke,M,34,72,163
Myra,F,NA,62,98
Neil,M,36,75,160
Omar,M,38,70,145
Page,F,31,67,NA
Quin,M,29,71,176
Ruth,F,28,65,131
Lagre teksten over i en .csv-fil kalt input_med_na.csv
a) Skriv prosedyren fil_na_filter()
som tar inn to strenger som parameter: et inputfilnavn og et outputfilnavn.
b) Åpne filene og lagre dem i variablene input_fil
og output_fil
c) For hver linje i input_fil
skal den skrives til output_fil
hvis linjen ikke inneholder verdien 'NA'.
Hint
Bruk in
d) Kall prosedyren med "input_med_na.csv" som inputfil og "output_uten_na.csv" som outputfil. Inspiser at outputfilen opprettes og inneholder det som forventes.
def fil_na_filter(input_filnavn, output_filnavn):
input_fil = open(input_filnavn, "r")
output_fil = open(output_filnavn, "w")
for linje in input_fil:
if "NA" not in linje:
output_fil.write(linje)
# Har du husket å lukke filene?
input_fil.close()
output_fil.close()
fil_na_filter("input_med_na.csv", "output_uten_na.csv")
Forventet resultat:
Name,Sex,Age,Height(in),Weight(lbs)
Carl,M,32,70,155
Elly,F,30,66,124
Gwen,F,26,64,121
Hank,M,30,71,158
Jake,M,32,69,143
Kate,F,47,69,139
Luke,M,34,72,163
Neil,M,36,75,160
Omar,M,38,70,145
Quin,M,29,71,176
Ruth,F,28,65,131
05.09 Skriv ut første/siste antall linjer
a) Skriv en prosedyre opprett_filen()
som oppretter en fil test.in og skriver 10 linjer til filen. Linjene kan inneholde hva som helst men de bør ikke være helt like.
b) Skriv en prosedyre skriv_ut_foerste_linjer()
som tar inn to parametre: en streng filnavn
og et heltall antall_linjer
. Prosedyren skal lese de første antall_linjer
linjene i filen og skrive dem ut til terminalen.
Hint
For å ikke skrive ut to linjeskift, bruk strip()
eller print(sep="")
for å fjerne linjeskift.
c) Skriv en ny prosedyre skriv_ut_siste_linjer()
som har de samme parametre som prosedyren i b), men som skriver ut de siste antall_linjer
linjene til terminalen
Hint
Du må først lese inn hele filen.
d) Kall prosedyrene for å opprette filen "test.in" og skrive ut de første og siste 5 linjer. Skriv gjerne en tom linje mellom prosedyrekallene for å dele opp resultatene
a)
def opprett_filen():
fil = open("test.in", "w")
for i in range(10):
linje = "linje " + str(i + 1)
fil.write(linje)
fil.write("\n")
fil.close()
b)
def skriv_ut_foerste_linjer(filnavn, antall_linjer):
fil = open(filnavn, "r")
idx = 0
for linje in fil:
if idx < antall_linjer:
print(linje.strip())
idx += 1
fil.close()
c)
def skriv_ut_siste_linjer(filnavn, antall_linjer):
fil = open(filnavn, "r")
linjene = []
for linje in fil:
linjene.append(linje.strip())
fil.close()
indeks = len(linjene) - antall_linjer
for linje in linjene[indeks:]:
print(linje)
d)
opprett_filen()
skriv_ut_foerste_linjer("test.in", 5)
print()
skriv_ut_siste_linjer("test.in", 5)
05.10: Sorter hund og person
Navn: sorter_navnefil.py, navn.txt
Teksten under er en liste over navn til personer og hunder. Linjene som starter med P inneholder et navn til en person, mens linjene som starter med H er for en hund. Kopier over listen til en fil du kaller navn.txt.
P Martin
H Trofast
H Tapper
H Rex
P Simen
P Elin
H Tara
P Svein
Skriv et program som leser inn navn.txt og sorterer navnene i to lister: personer
og hunder
. Til slutt skal listene skrives ut.
Det finnes mange måter å løse denne oppgaven på.
Løsning med split()
:
NB: Merk at dette ikke vil fungere hvis et navn inneholder et mellomrom
personer = []
hunder = []
fil = open("navn.txt", "r")
for linje in fil:
kolonner = linje.split()
if kolonner[0] == "H":
hunder.append(kolonner[1])
elif kolonner[0] == "P":
personer.append(kolonner[1])
else:
print("Feil i linjeformat:\n", linje)
fil.close()
print("Personer")
print(personer)
print("\nHunder")
print(hunder)
Løsning med slicing:
Husk at du kan bruke slicing til å ta utdrag fra en tekststreng. F.eks:
navn = "Ole Petter!"
print(navn[4:-1])
gir utskriften
Petter
Tallet 4 indikerer startposisjonen i strengen og -1 indikerer den nest-siste posisjonen (her er det indeks 9).
personer = []
hunder = []
fil = open("navn.txt", "r")
for linje in fil :
if linje[0] == "H":
hunder.append(linje[2:-1])
elif linje[0] == "P":
personer.append(linje[2:-1])
else:
print("Feil i linjeformat:\n", linje)
fil.close()
print("Personer")
print(personer)
print("\nHunder")
print(hunder)
05.11 En tabulær fil med karakterer
Filnavn: karakter.csv, sorter_etter_karakter.py
I denne øvelsen skal du lage et program som leser en fil med studentnavn og sine karakterer. Filen heter karakter.csv og er en tabulær fil med to kolonner som skal se slik ut:
Anna,C
Joakim,E
Louise,A
Lasse,F
Gry,B
Odd,D
Sven,D
Kaja,F
Ola,F
Ine,E
Vegard,A
Paal,C
a) Lag en funksjon sorter_etter_karakter()
som tar inn parameter filnavn
og leser hver linje i filen. Funksjonen skal:
- opprette en ordbok for å lagre informasjon over studentene og karakterene
- hente navn og karakter fra hver linje (uten linjeskrift-karakter) og lagre dem i ordbøken som bruker karakteren som nøkkelverdi og har en liste med navn som innholdsverdi.
- Hver gang du finner en karakter som ikke er en nøkkel i ordboken ennå, kan du legge det til. Hvis den allerede er i ordboken, legg til navnet i listen.
- returnere ordboken som ser slik ut:
{'C': ['Anna', 'Paal'], 'E': ['Joakim', 'Ine'], 'A': ['Louise', 'Vegard'], 'F': ['Lasse', 'Kaja', 'Ola'], 'B': ['Gry'], 'D': ['Odd', 'Sven']}
b) Lag en prosedyre skriv_ut_sortert()
som tar inn ordbøken laget av sorter_etter_karakter()
og skriver ut denne ordbøken sortert:
A : ['Louise', 'Vegard']
B : ['Gry']
C : ['Anna', 'Paal']
D : ['Odd', 'Sven']
E : ['Joakim', 'Ine']
F : ['Lasse', 'Kaja', 'Ola']
c) Lag en funksjon hent_vanligste_karakter()
som tar inn ordbøken og returnerer karakteren som de fleste studenter fikk. (Hint: bruk funksjonen len()
for å se hvor mange studenter fikk karakteren).
d) Kall hver funksjon og prosedyre for å sjekke at de fungerer.
a)
def sorter_etter_karakter(filnavn):
karakter_ordbok = {}
fil = open(filnavn, "r")
for linje in fil:
navn, karakter = linje.strip().split(",")
if karakter in karakter_ordbok:
karakter_ordbok[karakter].append(navn)
else:
karakter_ordbok[karakter] = [navn]
# Husk å lukke filen
fil.close()
return karakter_ordbok
b)
def skriv_ut_sortert(karakter_ordbok):
for karakter in sorted(karakter_ordbok.keys()):
print(karakter, ": ", karakter_ordbok[karakter])
c)
def hent_vanligste_karakter(karakter_ordbok):
vanligste_karakter = ""
antall_studenter = 0
for karakter in sorted(karakter_ordbok.keys()):
if len(karakter_ordbok[karakter]) > antall_studenter:
antall_studenter = len(karakter_ordbok[karakter])
vanligste_karakter = karakter
return vanligste_karakter
d) Husk å lagre karakter.csv i samme mappe som sorter_etter_karakter.py
karakter_ordbok = sorter_etter_karakter("karakter.csv")
skriv_ut_sortert(karakter_ordbok)
print("Vanligste karakter:", hent_vanligste_karakter(karakter_ordbok))
05.13 Maks tegn per linje
Filnavn: maks_tegn_per_linje.py
Dette er en fortsettelse av oppgave 05.07. Hvis du ikke har løst oppgave 05.07 ennå, kan du prøve det først.
I denne oppgaven skal du skrive en prosedyre som tar inn en tekst (string), et utdatafilnavn (string) og et maksimalt antall tegn (heltall) per linje. Prosedyren skal skrive teksten til utdatafilen slik at hver linje ikke inneholder mer enn det maksimale antallet tegn. I tillegg skal prosedyren passe på at ordene ikke deles på flere linjer, dvs. at et ord flyttes til en ny linje i stedet for å deles over to linjer. Bruk koden du skrev for oppgave 05.07 som utgangspunkt.
Hint
Denne gangen bør du ikke holde oversikt over antall skrevne ord, men antall skrevne tegn for en linje.
Eksempel:
- Teksten: "I denne oppgave skal du lage et program som tar inn en tekst og skriver den ut til en fil. I utdatafilen er det maksimalt antall ord som er tillatt per linje."
- Filnavn: "test.out"
- Maks antall tegn per linje: 20
Forventet resultat: test.out
I denne oppgave skal
du lage et program
som tar inn en tekst
og skriver den ut til
en fil. I utdatafilen
er det maksimalt
antall ord som er
tillatt per setning.
def format_text(tekst, filnavn, maks_tegn):
ordene = tekst.split()
fil = open(filnavn, "w")
teller = 0
for min_ord in ordene:
if teller + len(min_ord) > maks_tegn:
# Må starte ny linje
fil.write("\n")
teller = len(min_ord)
else:
# Husk at mellomrom også er et tegn
teller += len(min_ord) + 1
fil.write(min_ord)
fil.write(" ")
# Husk å lukke filen!
fil.close()
tekst = "I denne oppgave skal du lage et program som tar inn en tekst og skriver den ut til en fil. I utdatafilen er det maksimalt antall ord som er tillatt per setning."
format_text(tekst, "test.out", 20)
05.14 Omvendt rekkefølge
Filnavn: input.txt, omvendt_fil.py
Lagre følgende dikt i en fil som heter input.txt:
Once upon a time
Alice left me in the wonderland
I shall never forget
Dreams can come true
There is no way that
Fairy tales are deceiving and disappointing
I am sure that
Reality
Is only a hiding place from
Fantasy
‘Humans have a chance to fly’
I will shout to the world and object to the following line
Peter pan is a liar
In fact
The world spins around love instead of money
It is not true that
Cinderella loves the prince just for his money
I would rather believe
There is true love on earth
And I will never believe that
There is no happy ending in real life
Skriv en funksjon omvendt_fil()
som skriver linjene til en fil i omvendt rekkefølge til en annen fil. Funksjonen skal ta inn to parametre: input_filnavn
og output_filnavn
. Pass på at de to filnavnene er ikke like.
Hint
Det er mange forskjellige måter å løse denne øvelsen på, men det er nyttig å lagre fillinjene i en liste.
def omvendt_fil(input_filnavn, output_filnavn):
linjene = []
input_fil = open(input_filnavn, "r")
for linje in input_fil:
linjene.append(linje)
# Husk å lukke filen!
input_fil.close()
omvendte_linjene = linjene[::-1]
output_fil = open(output_filnavn, "w")
for linje in omvendte_linjene:
output_fil.write(linje)
# Husk å lukke filen!
output_fil.close()
omvendt_fil("input.txt", "output.txt")
05.15 Timelister
I denne oppgave skal du lage et system for å holde styr på timelister. Dette er en utfordrende oppgave som omhandler fillesing, filskriving, og ordbøker.
Vi har flere timeliste filer som ser slik ut:
- Den første linjen i filen er en overskrift som inneholder navn
- Resten av filen er 5 linjer som inneholder antall arbeidstimer for hver dag i arbeidsuken.
timeliste1.txt:
Louise,Sven,Kaja,Anna
8,6,7,6
8,6,7,7
4,6,0,0
8,6,4,0
8,6,0,0
timeliste2.txt:
Anna,Odd,Paal
0,4,8
0,4,8
6,5,8
8,5,8
6,5,0
a) Skriv en funksjon som leser inn en timelistefil og returnerer resultatet som en ordbok. Funksjonen skal returnere følgende gitt fil 1:
{'Louise': [8, 8, 4, 8, 8], 'Sven': [6, 6, 6, 6, 6], 'Kaja': [7, 7, 0, 4, 0], 'Anna': [6, 7, 0, 0, 0]}
NB: Ikke glem å konvertere tallene til heltall!
Hint
Du bør finne en måte å holde oversikt over:
- om du leser den første linjen fra filen, eller eventuelle påfølgende linjer
- hvilken indeks hvert av navnene vises for å matche timene til riktig person.
b) Skriv en funksjon som slår sammen to timelisteordbøker. Hvis et navn vises i begge ordbøkene, bør tidsoppføringene summeres sammen.
Resultatet skal se slik ut:
{'Louise': [8, 8, 4, 8, 8], 'Sven': [6, 6, 6, 6, 6], 'Kaja': [7, 7, 0, 4, 0], 'Anna': [6, 7, 6, 8, 6], 'Odd': [4, 4, 5, 5, 5], 'Paal': [8, 8, 8, 8, 0]}
c) Skriv en prosedyre som tar en timelisteordbok og skriver den til en fil på den samme formaten som de andre filene. Den skal ha to parametre: en timelisteordbok og et utdatafilnavn. Bruk denne prosedyren til å skrive den kombinerte timelisteordbok en fil.
a)
def les_timeliste(filnavn):
fil = open(filnavn, "r")
er_foerste_linje = True
for linje in fil:
if er_foerste_linje:
overskrift_navn = linje.strip().split(",")
timeliste_ordbok = {}
for navn in overskrift_navn:
timeliste_ordbok[navn] = []
er_foerste_linje = False
else:
timer = linje.strip().split(",")
for i in range(len(overskrift_navner)):
navn = overskrift_navner[i]
time = int(timer[i])
timeliste_ordbok[navn].append(time)
# Husk å lukke filen!
fil.close()
return timeliste_ordbok
b)
def slaa_sammen(ordbok1, ordbok2):
ny_ordbok = {}
for noekkel in ordbok1.keys():
ny_ordbok[noekkel] = ordbok1[noekkel]
for noekkel in ordbok2.keys():
if noekkel in ny_ordbok.keys():
for i in range(5):
ny_ordbok[noekkel][i] += ordbok2[noekkel][i]
else:
ny_ordbok[noekkel] = ordbok2[noekkel]
return ny_ordbok
c)
def skriv_timeliste_fil(ordbok, filnavn):
fil = open(filnavn, "w")
overskrift_navner = list(ordbok.keys())
fil.write(",".join(overskrift_navner) + "\n")
for i in range(5):
linje = []
for navn in overskrift_navner:
linje.append(str(ordbok[navn][i]))
fil.write(",".join(linje) + "\n")
# Husk å lukke filen!
fil.close()
timeliste1 = les_timeliste("timeliste1.txt")
timeliste2 = les_timeliste("timeliste2.txt")
timeliste = slaa_sammen(timeliste1, timeliste2)
skriv_timeliste_fil(timeliste, "timeliste.txt")
06.05: Finne flest forekomster i en liste
Navn: forekomst_av_tall.py, tall.txt
a) Skriv en funksjon les_tall_fra_fil()
som tar et filnavn som parameter, leser inn innholdet og returnerer en liste av tallene i filen. Filen skal har et tall på hver linje og ser slik ut:
15
7
34
3
2
2
34
5
15
19
2
Lagre linjene over i en fil kalt tall.py i samme mappe som programmet.
b) Skriv en funksjon antall_forekomster()
som tar imot en liste og et heltall som parameter. Funksjonen skal finne ut hvor mange ganger tallet forekommer i listen og returnere antall forekomster.
c) Skriv en funksjon flest_forekomster()
som tar imot en liste og returnerer det tallet som forekommer flest. Du trenger ikke å ta høyde for at flere tall kan forekomme like mange ganger.
d) Skriv et hovedprogram som tester funksjonene dine.
a)
def les_tall_fra_fil(filnavn):
tallene = []
fil = open(filnavn, "r")
for linje in fil:
tallene.append(int(linje))
fil.close()
return tallene
b)
def antall_forekomster(liste, heltall):
ant = 0
for verdi in liste:
if heltall == verdi:
ant += 1
return ant
c)
def flest_forekomster(liste):
verdi_med_flest_forekomster = liste[0]
teller = antall_forekomster(liste, liste[0])
for verdi in liste:
if antall_forekomster(liste, verdi) > teller:
verdi_med_flest_forekomster = verdi
teller = antall_forekomster(liste, verdi)
return verdi_med_flest_forekomster
d)
def testprogram():
mine_tall = les_tall_fra_fil("tall.txt")
print("Tallet 34 forekommer", antall_forekomster(mine_tall, 34), "ganger")
print("Det er flest forekomster av tallet", flest_forekomster(mine_tall))
testprogram()
06.06: Middagskalender
Filnavn: matkalender.py, matretter.txt
I denne oppgaven skal vi lage et program som leser inn en fil med matretter. Vi ønsker å lage en matkalender da det alltid er frustrerende å komme opp med forslag til middagsretter.
Strukturen på data ser slik ut:
MATRETT SOM KAN HA MELLOMROM,ANTALLMINUTTER
For eksempel: matretter.txt
Nykål med varmrøkt laks,30
Grillet torsk med ramsløkpoteter,30
Grillet paprika med biff,30
Kremet finnbiff med potetmos,40
Glasert ribbe på toast,20
Eggerøre med gressløk,20
Chili- og hvitløksmarinerte kyllingspyd,40
Grillet søtpotet med urtesmør,80
Tacosalat med kylling,40
Asiatisk kyllingsalat,30
Stekt uerfilet med gul paprikasaus,80
Pasta Carbonara med squash og løk,30
Pizza med ruccola og strandaskinke,30
Thaisuppe med kylling og sukkererter,25
I denne oppgaven kan du selv velge hvilken datastruktur du ønsker å bruke for å løse oppgaven.
a) Lag en funksjon lesInnMatFil()
som tar inn et filnavn som parameter, leser innholdet, og returnerer informasjonen i din valgte datastruktur.
b) Lag en funksjon velgMatretter()
som tar inn to argumenter: et tall, n
, og en liste av matretter og returner n
tilfeldige matretter fra listen.
Hint: random
random
er en innebygd modul for å generere tilfeldige tall og har noen funksjoner som kan være nyttige her:
random.randint(start, slutt)
som returnerer et tilfeldig heltall mellom start- og sluttverdien.random.choice(liste)
som returnerer et tilfeldige element fraliste
random.sample(liste, n)
som returnerer en liste som inneholdern
tilfeldige elementer fraliste
c) Lag en funksjon skrivMatretterTilFil()
som tar inn et utdatafilnavn og en matplan som argument og skriver matrettene til filen.
a)
def lesInnMatFil(filnavn):
matretter = []
fil = open(filnavn, "r")
for linje in fil:
info = linje.split(",")
matretter.append(info[0])
fil.close()
return matretter
b) med random.randint()
from random import randint
def velgMatretter(matretter, n):
valgt_mat = []
for i in range(n):
r = randint(0, len(matretter))
valgt_mat.append(matretter[r])
return valgt_mat
med random.choice()
from random import choice
def velgMatretter(matretter, n):
valgt_mat = []
for i in range(n):
valgt_mat.append(choice(matretter))
return valgt_mat
med random.sample()
from random import sample
def velgMatretter(matretter, n):
return sample(matretter, n)
c)
def skrivMatretterTilFil(filnavn, matretter):
fil = open(filnavn, "w")
for mat in matretter:
fil.write(mat + "\n")
fil.close()
10.02 Nærmeste naboer
Denne oppgave er en fortsettelse av oppgave 10.01. Klassen Punkt
brukes i denne oppgaven. Du kan kopiere denne klassen fra løsningsforslaget til oppgave 10.01, eller skrive den selv.
Filnavn: test_punkt2.py, gruppe1.csv, gruppe2.csv
a) Skriv en funksjon som spør brukeren om en x-, y- og z-dimensjon og returnerer en instans av Punkt
-klassen med de gitte dimensjonene.
b) Skriv en annen funksjon som leser dimensjonene til flere Punkt
-objekter fra en fil og returnerer en liste med disse objektene.
Inndatafilen skal formateres som denne eksempelfilen:
1,2,3
5,3,1
4,5,6
Med filen ovenfor, bør den resulterende listen være lik følgende: [Punkt(1,2,3), Punkt(5,3,1), Punkt(4,5,6)]
c) Skriv et hovedprogram som skal bestemme hvilken gruppe av Punkt
-objekter et nytt Punkt
-objekt tilhører. Dette hovedprogrammet bør lese i de to filene nedenfor, som representerer to forskjellige grupper av punkter i 3D-rommet. Da bør den be brukeren om dimensjonene av et nytt Punkt
-objekt. Deretter bør det avgjøres om det nye Punkt
-objektet er nærmere den første gruppen eller den andre gruppen. For å bestemme dette, bør den se på det nærmeste punktet i hver av disse to gruppene. Til slutt skriv ut hvilken gruppe er nærmest, og avstandet til nærmeste punktet i denne gruppen.
gruppe1.csv, første gruppe av punkter i 3D-rommet:
1,1,5
2,2,5
1,5,4
1,3,3
1,1,6
1,3,5
3,4,6
1,6,5
1,2,3
gruppe2.csv, andre gruppe av punkter i 3D-rommet:
3,3,1
3,4,2
4,5,1
3,1,2
3,3,1
4,4,2
4,5,2
5,2,3
3,1,1
4,4,1
a)
def faaPunktFraBruker():
x = float(input("Dimension x: "))
y = float(input("Dimension y: "))
z = float(input("Dimension z: "))
nyttPunkt = Punkt(x, y, z)
return nyttPunkt
b)
def lesPunkterFraFil(filnavn):
punkter = []
fil = open(filnavn, "r")
for linje in fil:
tall = linje.split(",")
x = float(tall[0])
y = float(tall[1])
z = float(tall[2])
punkt = Punkt(x, y, z)
punkter.append(punkt)
fil.close()
return punkter
c) NB: Husk å lagre .csv-filen i samme mappen som test_punkt2.py og importere Punkt
-klassen
from punkt import Punkt
def hovedprogram():
gruppe1 = lesPunkterFraFil("gruppe1.csv")
gruppe2 = lesPunkterFraFil("gruppe2.csv")
punkt = faaPunktFraBruker()
naermestGruppe1 = punkt.faaNaermestePunkt(gruppe1)
naermestGruppe2 = punkt.faaNaermestePunkt(gruppe2)
avstandGruppe1 = punkt.faaAvstand(naermestGruppe1)
avstandGruppe2 = punkt.faaAvstand(naermestGruppe2)
if avstandGruppe1 < avstandGruppe2:
gruppe = 1
avstand = avstandGruppe1
else:
gruppe = 2
avstand = avstandGruppe2
print("Punktet", punkt, "er nærmere gruppe", gruppe)
print("Avstandet til nærmeste punkt i gruppe", gruppe, "er", avstand)
hovedprogram()
11.06: Personalia
Filnavn: person.py, test_person_informasjon.py
I denne oppgaven skal du lage en fil som inneholder personinformasjon. En slik fil vil se slik ut:
Navn
Addresse
Postnr. + poststed
Land
Tlfnummer
Twitter-brukernavn
Et eksempel på dette er:
Ola Nordmann
Norgesveien 24
1234 Oslo
Norge
91464883
@olanordmann
a) Skriv klassen Person
som tar inn dataen over som parametre i konstruktøren. En instans av Person
-klassen skal kunne opprettes slik:
ola_nordmann = Person("Ola Nordmann", "Norgesveien 24", "1234 Oslo", "Norge", "91464883", "@olanordmann")
b) Utvid Person
-klassen med følgende metoder:
skrivUtPerson()
som skriver ut informasjon om personen.- metoder som endrer en persons informasjon (f.eks.
endreNavn()
,endreAddresse()
, osv.) - metoder som returnerer de respektive variablene. (f.eks.
hentNavn()
,hentAddresse()
, osv.)
c) I test_person_informasjon.py skriv funksjonen lagrePerson()
som tar et Person
-objekt som parameter og skriver personinformasjonen til filen person.txt.
d) I test_person_informasjon.py skriv funksjonen lesInnPerson()
som tar inn et filnavn som parameter. Filen skal være på formatten som vises over. Funksjonen skal lese filinnholdet, opprette et Person
-objekt med informasjonen og returnere objektet til slutt.
a - b)
class Person:
def __init__(self, navn, adr, postadr, land, tlf, brukernavn):
self._navn = navn
self._adresse = adr
self._postadresse = postadr
self._land = land
self._telefon = tlf
self._brukernavn = brukernavn
def skrivUtPerson(self):
print("Navn: " + self._navn + "adresse: " + self._adresse + "postadresse: " + self._postadresse + "land: " + self._land + "telefon: " + self._telefon + "brukernavn: " + self._brukernavn)
def endreNavn(self, nyttNavn):
self._navn = nyttNavn
def endreAddresse(self, nyAdr, nyPostadr, nyttLand):
self._nyAdr = nyAdr
self._postadresse = nyPostadr
self._land = nyttLand
def endreTelefon(self, nyttTlf):
self._telefon = nyttTlf
def endreBrukernavn(self, nyBruker):
self._brukernavn = nyBruker
def hentNavn(self):
return self._navn
def hentAdresse(self):
return self._adresse
def hentPostAdresse(self):
return self._postadresse
def hentLand(self):
return self._land
def hentTelefon(self):
return self._telefon
def hentBruker(self):
return self._brukernavn
c) test_person_informasjon.py
def lagrePerson(person, filnavn):
fil = open(filnavn, "w")
fil.write(person.hentNavn() + "\n")
fil.write(person.hentAdresse() + "\n")
fil.write(person.hentPostAdresse() + "\n")
fil.write(person.hentLand() + "\n")
fil.write(person.hentTelefon() + "\n")
fil.write(person.hentBruker() + "\n")
fil.close()
d) test_person_informasjon.py
def lesInnPerson(filnavn):
fil = open(filnavn, "r")
#antar at hver fil har 1 person:
navn = fil.readline()
adresse = fil.readline()
postadresse = fil.readline()
land = fil.readline()
telefon = fil.readline()
bruker = fil.readline()
person = Person(navn, adresse, postadresse, land, telefon, bruker)
fil.close()
return person
NB: Husk å importere Person
-klassen øverst i hovedfilen!
from person import Person
11.07: Regn og atter regn...
Filnavn: dag.py, nedbør.py, Nedbørsmengder.txt
I denne oppgaven skal du jobbe med Nedbørsmengder.txt som inneholder nedbørmengder fra 1. mai 2017 til 30. april 2018 observert på Blindern. Filen er bygget opp slik: DD. MÅNED ÅÅÅÅ - NEDBØRTALL mm
30. april 2018 - 0,0 mm
29. april 2018 - 0,0 mm
28. april 2018 - 0,0 mm
...
a) Lag klassen Dag
som tar inn en dato (string) og et nedbørtall (flytall). Merk at den ikke skal være en streng så du må fjerne "mm" og erstatte "," med "." før det kan konverteres til et flytall. I tillegg skal du lage metoder for å hente ut datoen og nedbørtall.
I nedbør.py lag følgende funksjoner:
-
b)
lesInnFil()
som tar et filnavn som parameter. Funksjonen skal lese inn Nedbørsmengder.txt og opprette etDag
-objekt for hver linje i filen. Deretter skalDag
-objektene lagres i en liste. Til slutt skal listen avDag
-objektene returneres. -
c)
dagMaks()
som tar inn en liste med dager som parameter og returnerer datoen og nedbørsmengden (Dag
-objektet) til den dagen det regnet mest. -
d)
tilsammen()
som tar inn en liste med dager som parameter og returnerer den totale mengden nedbør av alle dagene.
e) Sjekk at alt fungerer som forventet. Opprett en dagliste fra Nedbørsmengder.txt og skrive ut dagen med mest regn, samt total mengde nedbør.
f) Utfordring besteMaaned()
som tar inn en liste med dager som parameter og returnerer den måneden med færrest nedbørsdager (ergo. nedbør == 0).
a)
class Dag:
def __init__(self, dato, nedbor):
self._dato = dato
self._nedbor = nedbor
def hentNedbor(self):
return self._nedbor
def hentDato(self):
return self._dato
def __str__(self):
return "Dato: " + self._dato + " - Nedbør: " + str(self._nedbor)
b)
def lesInnFil(filnavn):
fil = open(filnavn, "r")
dagListe = []
for line in fil:
elementer = line.split("-")
dato = elementer[0].strip()
nedbor = elementer[1].strip()
# Fjern 'mm'
nedbor = nedbor[:-2].strip()
# Erstatt ',' med '.'
nedbor = nedbor.replace(',', '.')
# Konverter til float
nedbor = float(nedbor)
# Lag ny Dag objekt
enDag = Dag(dato, nedbor)
dagListe.append(enDag)
fil.close()
return dagListe
c)
def dagMax(dagListe):
topDag = None
for dag in dagListe:
if (topDag == None):
topDag = dag
elif(dag.hentNedbor() >= topDag.hentNedbor()):
topDag = dag
return topDag
d)
def tilsammen(dagListe):
totalMengde = 0
for dag in dagListe:
totalMengde += dag.hentNedbor()
return totalMengde
e)
dagListe = lesInnFil("Nedbørsmengder.txt")
print(dagMax(dagListe))
print(tilsammen(dagListe))