Lab10

Forberedelser
Innlevering og automatisk retting


Repetisjon: oppgave 1

Del A

I filen uke_10_oppg_1.py skriv funksjonen at_least_two(word, c) som har et ord og en bokstav som parametre, og som returnerer True dersom bokstaven c forekommer minst to ganger i ordet word.

print("Tester at_least_two... ", end="")
assert(at_least_two('assessment', 's'))
assert(at_least_two('eksamen', 'e'))
assert(not at_least_two('gradering', 'd'))
assert(at_least_two('grunnleggende', 'e'))
assert(not at_least_two('midterm', 'x'))
print("OK")

Del B

I filen uke_10_oppg_1.py skriv funksjonen at_least_two_in_list(wordlist, c) som har en liste med ord samt en bokstav som parametre, og som returnerer i hvor mange ord bokstaven forekommer minst to ganger.

print("Tester at_least_two_in_list... ", end="")
words = ['exam', 'christmas', 'assessment', 'test', 'paper', 'class']
assert(3 == at_least_two_in_list(words, 's'))
assert(1 == at_least_two_in_list(words, 'e'))
assert(0 == at_least_two_in_list(words, 'a'))
print("OK")

Del C

I filen uke_10_oppg_1.py skriv funksjonen at_least_two_in_file(path, c) som har en filsti (til en fil som inneholder ett ord på hver linje) samt en bokstav som parametre, og som returnerer i hvor mange ord i filen bokstaven forekommer minst to ganger. Last ned wordlist.txt for å bruke testen under.

print("Tester at_least_two_in_file... ", end="")
assert(4==at_least_two_in_file('wordlist.txt', 's'))
assert(1==at_least_two_in_file('wordlist.txt', 'e'))
assert(0==at_least_two_in_file('wordlist.txt', 'a'))
print("OK")
Repetisjon: oppgave 2

I filen uke_10_oppg_2.py skriv funksjonen num_pairwise_diff_gt10(a) som har en liste med tall a som input og som returnerer hvor mange ganger den absolutte forskjellen mellom to etterfølgende tall er større enn 10.

print("Tester num_pairwise_diff_gt10... ", end="")
a =[9, 3, 12, 0,- 3, 2, -9]  # Forskjellen er større: 12 -> 0 og 2 -> -9
assert(2 == num_pairwise_diff_gt10(a))
a =[10, 2, 12, 0, 1, 2, 11]
assert(1 == num_pairwise_diff_gt10(a))
a= [1, 14, 0, 12, 1, 20, 8]
assert(6 == num_pairwise_diff_gt10(a))
print("OK")

  • For å sammenligne elementet på posisjon i med elementet på posisjon i+1, regn ut differansen mellom verdiene a[i] og a[i+1] og ta absolutt-verdien av dette.

  • Bruk en løkke over indekser.

  • Bruk en tellevariabel som initielt er 0 før løkken begynner. Oppdaterer denne i løkken når du finner to etterfølgende tall med gitt egenskap.

Repetisjon: oppgave 3

I filen uke_10_oppg_3.py, skriv en ikke-destruktiv funksjon filter_words(words, must_include, must_exclude) som har en liste med ord samt to mengder (set) med bokstaver som parametre, og som returnerer en ny liste med alle ordene som

Ordene skal være i samme rekkefølge i den returnerte listen som de er i den opprinnelige listen.

print("Tester filter_words... ", end="")
word_list = ["kattepus", "hundevofs", "kosebamse", "kanintuss", "slangesvin"]
must_include = {"a", "s"}
must_exclude = {"m", "v"}
expected_value = ["kattepus", "kanintuss"]
assert(expected_value == filter_words(word_list, must_include, must_exclude))

word_list = ["abc", "abd", "adc", "dbc", "abcx", "abyc", "azbc", "dcba"]
must_include = {"a", "b", "c"}
must_exclude = {"x", "y", "z"}
expected_value = ["abc", "dcba"]
assert(expected_value == filter_words(word_list, must_include, must_exclude))
print("OK")

Det kan være lurt å dele denne oppgaven inn i mindre biter/hjelpefunksjoner som kan feilsøkes og testes hver for seg. For eksempel:

  • En hjelpefunksjon word_includes_all(single_word, must_include) som returnerer True dersom single_word inkluderer alle bokstavene i must_include, og False ellers.
  • En hjelpefunksjon word_excludes_all(single_word, must_exclude) som returnerer True dersom single_word ikke inneholder noen av bokstavene i must_exclude, og False ellers.
  • En hjelpefunksjon words_that_include(words, must_include) som returnerer en liste med de ordene som tilfredsstiller kravet om at alle bokstavene i must_include er inkludert. Denne funksjonen kan kalle på word_includes_all i en løkke over ordene i words.
  • En hjelpefunksjon words_that_exclude(words, must_exclude) som returnerer en liste med de ordene som tilfredsstiller kravet om at ingen av bokstavene i must_exclude er inkludert. Denne funksjonen kan kalle på word_excludes_all i en løkke over ordene i words.
  • I filter_words gjenstår det kun å kalle på words_that_include og words_that_exclude. For eksempel, kall først på words_that_include, og kall deretter på words_that_exclude med returverdien fra det tidligere kallet som argument.

Repetisjon: oppgave 4

I filen uke_10_oppg_4.py skriv en funksjon people_with_age(path, age) som tar inn filnavn path som inneholder navn på folk og deres alder samt en alder age, og returnerer en mengde (set) men navnet til alle personene med den alderen. Vi kan anta at navnet ikke inneholder mellomrom. Filen har følgende format.

Navn1 alder1
Navn2 alder2
Navn3 alder3
...

Bruk namesages.txt for å teste

assert(people_with_age('namesages.txt', 18) == {'Odin', 'Trym'})
assert(people_with_age('namesages.txt', 19) == {'Brage', 'Embla', 'Idun',
                                                'Astrid', 'Gro'})
assert(people_with_age('namesages.txt', 20) == {'Alf', 'Frøya', 'Edda'})
assert(people_with_age('namesages.txt', 21) == {'Thor'})
assert(people_with_age('namesages.txt', 22) == {'Geir'})
assert(people_with_age('namesages.txt', 23) == set())

  • Les inn filen som en streng: kursnotater om strenger.

  • Opprett en tom mengde og legge elementer til i en mengde: kursnotater om mengder.

  • Løkke over linjene i strengen: kursnotater om strenger.

  • Klippe opp en streng i biter: kursnotater om lister.

  • Konvertere fra streng til int: kursnotater kom i gang.


Oppgave 5: egen modul

I denne oppgaven skal vi lage vår egen modul statistical_averages i filen statistical_averages.py, samt et eksempel-program i filen uke_10_oppg_5.py. La innholdet i filen uke_10_oppg_5.py være nøyaktig:

import statistical_averages

data = [3, 1, 7, -3, 5, 9, 1, 5, 9, 7, -3, 7]

a = statistical_averages.mean(data)
b = statistical_averages.median(data)
c = statistical_averages.mode(data)

print(a, b, c)

Utskrift til terminal når filen uke_10_oppg_5.py kjøres skal være nøyaktig:

4.0 5.0 7.0

Oppgaven går ut på å skrive modulen statistical_averages slik at funksjonskallene over fungerer. I tillegg til at modulen skal kunne importeres uten at det blir noen utskrift til skjermen, skal det også være mulig å kjøre statistical_averages.py direkte for å få en interaktiv modus hvor brukeren kan skrive inn tallene selv.

En eksempelkjøring av statistical_averages.py (fet/grønn tekst skrevet av brukeren):

Regn ut statistiske gjennomsnitt for en liste.
Oppgi tallene du vil regne ut gjennomsnitt for, separert av mellomrom:
3 1 7 -3 5 9 1 5 9 7 -3 7

Gjennomsnitt: 4.0
Median:       5.0
Typetall:     7.0

Ytterligere krav:

Del A: mean

def almost_equals(a, b):
   return abs(a - b) < 0.00000001

assert(almost_equals(2.75, mean([2, 5, 3, 1])))

Du kan legge til assert’en over (og almost_equals-funksjonen) i statistical_averages.py. Vi legger ikke til print-setninger som skriver ut «Tester mean… OK» før og etter assert’en siden vi ikke skal ha andre utskrifter enn dem som er spesifisert over; men selve assert-setningen kan vi beholde i kildekoden likevel. (I virkeligheten har man ofte slike tester i egne filer i stedet for å ha dem liggende i selve kildekoden, men i INF100 klarer vi oss med å ha asserter liggende i samme fil som funksjonen som testes).

Del B: median

assert(almost_equals(5.0, median([4, 12, 3, 9, 5])))
assert(almost_equals(6.0, median([4, 12, 3, 9, 5, 7])))

Del C: mode

assert(almost_equals(4.0, mode([3, 4, 22, 7, 4, 15, 4, 7, 1])))

a = [3, 22, 7, 7, 7, 22.0, 3, 22.0] # Tricky case: både 22 og 22.0
assert(almost_equals(22.0, mode(a)))

# Sjekk at a ikke er mutert
for i, v in enumerate([3, 22, 7, 7, 7, 22.0, 3, 22.0]):
   assert(a[i] == v), f"Feil verdi: a[{i}]={a[i]}, men forventet {v}"
   assert(type(a[i]) == type(v)), f"Feil type: type(a[{i}])={type(a[i])}"

Alternativ A (tregt, men korrekt)

  • Opprett en hjelpefunksjon number_of_occurrences(a, x) som tar som input en liste a og en verdi x og returnerer hvor mange ganger x opptrer i a. For eksempel:
assert(2 == number_of_occurrences([1, 4.0, 4, 3, 3, 3], 4))
  • Opprett en hjelpefunksjon number_of_occurences_in_a_for_values_b(a, b) som tar som input to lister a og b og returnerer en liste c som er like lang som b. Verdien c[i] skal være antall ganger verdien b[i] opptrer i a (bruk hjelpefunksjonen number_of_occurrences for å regne ut dette).
assert([2, 2, 3] == number_of_occurences_in_a_for_values_b(
   [1, 4.0, 4, 9, 9, 9], [4, 4, 9]
))
  • Observer at max(number_of_occurences_in_a_for_values_b(a, a)) returnerer antall opptredener for den mest vanlige verdien i a (hvorfor?)
  • Til slutt, gå gjennom alle verdiene i a. Første gang vi ser en verdi der number_of_occurrences av denne verdien er lik antall opptredener for mest vanlige verdi, returner verdien (konvertert til flyttal om nødvendig).

Alternativ B (effektivt og korrekt)

  • Bruk et oppslagsverk for å telle hvor mange ganger du har sett en verdi i listen. La nøklene i oppslagsverket være verdiene i listen, og la verdiene i oppslagsverket være «tellere» som sier oss hvor mange ganger den korresponderende nøkkelen opptrer som en verdi i listen. I utgangspunktet kan oppslagsverket være tomt.

  • Bruk en løkke over verdiene i listen; dersom verdien i listen vi ser på i en gitt iterasjon ikke finnes som en nøkkel i oppslagsverket vårt, opprett den som en ny nøkkel i oppslagsverket og gi den verdien 1 (fordi vi nå har sett denne nøkkelen som en verdi i listen 1 gang). Hvis ikke, øk telleren for denne nøkkelen i oppslagsverket med én (fordi vi nå har sett denne nøkkelen som en verdi i listen én gang til).

  • TIPS FOR TRICKY CASE: Konverter til flyttall (rett) før du bruker et tall som nøkkel i oppslagsverket (det kan være fristende å mutere listen, men unngå det).

  • Når vi er ferdig med å telle hvor mange ganger hver verdi opptrer i listen, kan vi finne maks-verdien i oppslagsverket sine verdier (les kursnotatene om oppslagsverk for å se hvordan vi ser gjennom verdiene). Dette tallet sier hvor mange ganger den mest vanlige verdien opptrer.

  • Til slutt, gå igjennom listen med tall én gang til. Første gang du er ved en verdi hvor telleren er lik antallet for mest vanlige verdi, returner denne verdien.

Del D: Interaktivt program

Opprett en funksjon cmd_main() uten parametre som skriver ut teksten som vist i begynnelsen av oppgaven, leser inn input fra brukeren, konverterer til en liste og bruker funksjonene fra de forrige deloppgavene for å regne ut riktig svar. Gjør et kall til denne funksjonen dersom filen statistical_averages.py kjøres direkte, men ikke dersom statistical_averages blir importert som en modul.

Kursnotater om moduler

Oppgave 6: finn neste fredag 13.

I filen uke_10_oppg_6.py skriv en funksjon first_friday_13th_after(date) som har som parameter et datetime -objekt. Funksjonenen returnerer et nytt datetime-objekt, som befinneer seg på første fredag den 13. etter den gitte datoen. Dersom input-datoen selv er på en fredag den 13., er det neste datoen som skal returneres.

Denne oppgaven skal løses ved hjelp av datetime -modulen fra python sitt standardbibliotek.

print("Tester first_friday_13th_after... ", end="")
# Test 1
result = first_friday_13th_after(datetime(2022, 10, 24))
assert((2023, 1, 13) == (result.year, result.month, result.day))
# Test 2
result = first_friday_13th_after(datetime(2023, 1, 13))
assert((2023, 10, 13) == (result.year, result.month, result.day))
# Test 3
result = first_friday_13th_after(datetime(1950, 1, 1))
assert((1950, 1, 13) == (result.year, result.month, result.day))
print("OK")

  • Se eksempel på bruk av datetime i kursnotater om standardbibliotektet og se eventuelt også den offisielle dokumentasjonen for datetime.

  • Kan være lurt å ha en hjelpefunksjon som sjekker om et gitt tidspunkt er på en fredag den trettende.

  • Forsøk å øke datoen med én dag helt til du treffer en dag som er på en fredag den trettende.

Oppgave 7: beregn π med tilfeldige tall

I denne oppgaven skal vi bruke modulen random fra python sitt standardbibliotek for å beregne verdien av π. Selvfølgelig finnes en tilnærming for denne verdien allerede (f. eks. math.pi), men la oss forestille oss at vi nå ikke hadde denne beregningen fra før.1

π er definert som en sirkels omkrets delt på sin diameter. Uten å vite nøyaktig hvilken verdi π har, kan matematikere bevise at denne verdien, om vi en vakker dag skulle få vite hva den er, kan brukes for å regne ut en sirkel sitt areal:

$$ A = \pi \cdot r^2 $$

I formelen over er \(r\) er sirkelens radius.

Tenk deg nå at vi har en sirkel med sentrum i (0, 0) og radius \(r = 1\). Vi har også et kvadrat med sidelengde \(s = 2\), som går mellom punktene (-1, -1) og (1, 1), som illustrert i bildet under.

Illustrasjon av sirkel i rektangel

Vi legger verdiene for r og s inn i formelene for areal av henholdsvis sirkler og kvadrat, og får følgende:

$$A_{\bigcirc} = \pi \cdot r^2 = \pi \cdot 1^2 = \pi$$ $$A_{\square} = s^2 = 2^2 = 4$$

Siden arealet av sirkelen tydelig er mindre enn arealet av kvadratet, vet vi allerede nå at π må være mindre enn 4. Men vi kan gjøre en bedre tilnærming enn som så.

Dersom vi velger et helt tilfeldig punkt inne i kvadratet, vil punktet med viss sannsynlighet \(p\) havne inne i sirkelen. Merk at denne sannsynligheten \(p\) er gitt ved forholdet mellom arealet av sirkelen og kvadratet:

$$ p = \frac{A_{\bigcirc}}{A_{\square}} = \frac{\pi}{4}$$

Det følger at hvis vi klarer å beregne hva \(p\) er for noe, kan vi bare gange tallet med 4 for å finne π. Det leder oss til følgende algoritme:

  1. Gjett et tilfeldig punkt mellom (-1, -1) og (1, 1)
  2. Sjekk om punktet er innenfor eller utenfor sirkelen
  3. Gjenta steg 1-2 tilstrekkelig mange ganger, og tell opp hvor ofte det tilfeldige tallet havnet inne i eller utenfor sirkelen. Da bli forholdet mellom antall treff i sirkel og totalt antall genererte punkter tilnærmet lik \(p\).
  4. Gang opp \(p\) med 4 for å finne en tilnærmet verdi for π.

Del A

I uke_10_oppg_7.py skriv en funksjon find_pi(n) med en parameter n som angir hvor mange tilfeldige punkter som skal genereres. La funksjonen beregne π ved å generere n tilfeldige koordinater mellom (-1, -1) og (1, 1) og telle opp hvor mange av dem som havnet innefor sirkelen og hvor mange som havnet utenfor.

For å finne et tilfeldig verdi mellom -1 og 1:

  • random.random() gir oss et tilfeldig flyttall mellom 0 og 1

  • gang tallet med 2 og trekk fra 1; da får vi et tilfeldig tall mellom -1 og 1. For å finne ut om et punkt er inne i en sirkel, holder det å sjekke om avstanden mellom punktet og sirkelens sentrum er større enn sirkelens radius. Til dette kan vi bruke pytagoras. Se oppgave 5b i lab1 og tilhørende løsningsforslag.

Del B (frivillig)

Gjør oppgaven grafisk med uib_inf100_graphics slik at vi visuliserer resultatatet etter hvert som vi legger til flere og flere tilfeldige punkter. Space for å legge til et punkt, a for å skifte til automodus legge til punkter automatisk, r for å resette.

Modellen kan bruke variabler:

  • app.points, en list med tupler, der hver tuple er et punkt (x, y) med x og y flyttall mellom -1 og 1.
  • app.automode, en boolsk verdi som slår av og på automatisk generering av nye punkter

Kontrollen:

  • key_pressed, hvis brukeren trykker på a slås automode av/på, hvis brukeren trykker på r blir listen app.points tømt, og hvis brukeren trykker på Space kalles funksjonen som legger til et tilfeldig nytt punkt
  • timer_fired, hvis app.automode er aktivt kaller denne på en funksjon som legger til et tilfeldig nytt punkt
  • add_random_new_point, en funksjon som genererer et tilfeldig punkt og legger det til i app.points.

Visningen:

  • redraw_all, ansvarlig for å kalle de andre funksjonene i visningen

  • draw_summary, ansvarlig for å tegne teksten.

  • count_points_inside, en funksjon som teller hvor mange av punktene som er innenfor sirkelen. Bruker pytagoras for å regne ut avstanden til origo for hvert punkt, og sammenligner dette med sirkelens radius for å avgjøre om punktet er innenfor sirkelen eller ikke.

  • draw_simulation, ansvarlig for å tegne den store firkanten, den store sirkelen, og oppå der, tegne hver av de små prikkene. Trenger å gjøre noen beregninger for å tegne punktene riktig i forhold til pikselkoordinatene hvor alt skal tegnes. Se f. eks. eksempelet med pandemisimulering fra forelesningen uke 9.

Oppgave 8: last ned dagens værmelding

I filen uke_10_oppg_8.py skriv en funksjon wheather_in_bergen_next_hour uten parametre som returnerer en streng som sammenfatter været i Bergen den neste timen. Funksjonen skal hente vær-data fra meterologisk instutt, og bruke informasjon fra feltet «symbol_code» om den nærmeste timen.

Eksempelkjøring: print("Været i Bergen neste time:", wheather_in_bergen_next_hour())

Været i Bergen neste time: cloudy

For å løse denne oppgaven, skal vi

  1. Finne ut hvilken url vi kan bruke for å få informasjon om været fra meterologisk institutt
  2. Bruke requests -pakken for å laste ned informasjonen fra meterlogisk institutt inn i python-programmet
  3. Bruke json -pakken for å konvertere den nedlastede informasjonen til et oppslagsverk, og til slutt
  4. Slå opp på riktig sted i oppslagsverket og returnere denne informasjonen.

Steg A: nettadresse fra meterologisk institutt

Meterologisk instutt tilbyr massevis av vær-informasjon gratis (under lisensen CC-BY 4.0) fra sine nettsider. Slå opp på nettsiden https://api.met.no/weatherapi/locationforecast/2.0/ og les om GET /compact under data.

For å finne breddegrad og lengdegrad for et gitt sted, kan du på til https://maps.google.com og trykke på kartet. Da vil koordinatene til det gitte stedet vises.

Steg B: bruk requests for å laste ned informasjon

Bruk nettadressen vi fant i forrige steg som url. Merk at vilkårene til Meterologisk institutt sier at vi må identifisere hvem vi er i User-Agent -feltet i «header». Det er tilstrekkelig å bruke "inf100.ii.uib.no <ditt uib-brukernavn>" som verdi for dette feltet. Se eksempel i kursnotater om eksterne pakker.

Steg C: bruk JSON for å konvertere til oppslagsverk

Se eksempel i kursnotater om moduler

Steg D: returner verdien knyttet til nøkkelen «symbol code» i oppslagsverket

Det gjelder å holde tungen rett i munnen når du skal slå opp i oppslagsverket. En strategi kan være å begynne med å returnere d["properties"] og så spesifisere videre ved å returnere d["properties"]["timeseries"] og så videre, helt til riktig verdi blir returnert.

Det er ikke nødvendig å finne nøyaktig riktig time for å få oppgaven godkjent, det holder å returnere den første timen du får informasjon om (selv om den var i fortiden)

Steg E (frivillig): finn nøyaktig riktig time å rapportere for

For å rapportere for nøyaktig riktig time, må du matche den timen du får fra meterologisk instiutt med tiden akkurat nå. Les deg opp på datetime -modulen og se om du kan bruke informasjonen fra meterologisk institutt for å finne den nærmeste timen å rapportere fra.

Steg F (frivillig): mer omfattende værmelding

Kan du finne mer informasjon å rapportere? Nedbørsmengder? Vind? Sannsynlighet for nedbør (nå må du over på GET /complete hos meterologisk institutt)?

Oppgave 9: kombinere CSV-filer

I denne oppgaven skal vi kombinere flere CSV-filer som ligger i en mappe til én stor CSV-fil. Hver av CSV-filene har det samme formatet, som også er det formatet den kombinerte CSV-filen skal ha:

uibid,karakter,kommentar
abc101,A,"Veldig bra, fra start til slutt"
abc102,B,"Denne kandidaten kan sin INF100, men bommer litt i oppgave 2 og 3"
abc103,C,"Denne kandidaten valgte å kun svare på partallsoppgavene"

I uke_10_oppg_9.py skriv en funksjon combine_csv_in_dir(dirpath, result_path) som har to parametre:

For å teste funksjonen kan du laste ned samples.zip og pakke ut innholdet i samme mappe hvor du også finner uke_10_oppg_9.py. Innholdet skal ligge i en mappe som heter samples. Du kan så teste funksjonen din med denne koden:

print("Tester combine_csv_in_dir... ", end="")
# Mappen samples må ligge i samme mappe som denne filen
dirpath = os.path.join(os.path.dirname(__file__), "samples")
combine_csv_in_dir(dirpath, "combined_table.csv")
with open("combined_table.csv", "rt", encoding='utf-8') as f:
   content = f.read()
   assert("""\
uibid,karakter,kommentar
abc104,C,hei
abc105,D,"med komma, her er jeg"
abc106,E,tittit
abc101,A,Her er min kommentar
abc102,B,"Jeg er glad, men her er komma"
abc103,C,Katching
""" == content or """\
uibid,karakter,kommentar
abc101,A,Her er min kommentar
abc102,B,"Jeg er glad, men her er komma"
abc103,C,Katching
abc104,C,hei
abc105,D,"med komma, her er jeg"
abc106,E,tittit
""" == content)
print("OK")

Merk: csv-biblioteket sin standard oppførsel når du lagrer 2D-lister som CSV er at det kun benyttes hermetegn dersom det er nødvendig. Det er nødvendig med hermetegn dersom en celle inneholder skilletegn (komma), linjeskift eller hermetegn. Dersom cellen ikke inneholder noen av de tre tegnene, vil det ikke inkluderes hermetegn i filen. Denne oppførselen kan endres ved å kalle på write_csv_file -funksjonen i kursnotatene med argumentene quoting=csv.QUOTE_NONNUMERIC eller quoting=csv.QUOTE_ALL (se også offisiell dokumentasjon).

Dette betyr at selv om det kanskje er hermetegn i input-filen, vil disse ikke nødvendigvis bli med i resultat-filen. Assert-setningene over viser resultatet slik det blir med standard-innstillingene til csv-biblioteket.

  • CSV-filene i dette eksempelet er best lest med csv-biblioteket. Det blir fort komplisert å tolke dem selv, siden det kan være komma-tegn i kommentar-feltet. Bruk gjerne funksjonene fra kursnotatene om csv-modulen i notater om standardbiblioteket.

  • Les om os -modulen i kursnotater om standardbiblioteket, og legg spesielt merke til os.walk -funksjonen.

  • Bruk gjerne en hjelpefunksjon merge_table_into(master_table, new_table) som tar som input en 2D-liste master_table som skal muteres, og en 2D-liste new_table som inneholder det nye innholdet som skal legges til. For hver rad i new_table (bortsett fra første rad), kopier raden inn i master_table.

  • Opprett først en 2D-liste for resultat-tabellen vår, som initielt inneholder én rad (overskriftene). På slutten skal vi konvertere denne listen til CSV.

  • Bruk os.walk eller os.listdir for å gå igjennom alle filene i mappen gitt ved dirpath (os.walk vil også gå inn i undermapper, og du trenger en nøstet løkke inne i os.walk for å gå gjennom listen med filer; ellers fungerer de nokså likt). For hver fil som ender på .csv (bruk f. eks. .endswith -metoden på strenger).

  • Husk å bruke os.path.join -funksjonen for å omgjøre filnavn til filstier. Se eksempler fra kursnotatene.

  • For hver .csv -fil du finner, omgjør den til en 2D-liste, og legg til radene i resultat-tabellen (bruk hjelpefunksjonen beskrevet over).


  1. Den beste tilnærmingen vi har til π i skrivende stund inneholder over \(10^{12}\) siffer. I python er tilnærmingen av gitt ved math.pi begrenset til de første 15 siffrene av pi, men det finnes også andre moduler som gir en bedre tilnærming; men da må vi slutte å bruke float, og heller bruke en annen datatype som er i stand til å gi oss høyere presisjon. ↩︎