Filer och kontexthanterare
Skriv lösningarna till uppgifterna i en och samma fil och testa koden själv innan du använder rättningsskriptet. Att kunna testa sin kod är en viktig del av att programmera!
Att lära dig från uppgifterna
- Förstå hur filer öppnas och stängs för läsning och skrivning.
- Förstå hur kontexthanterare fungerar för filhantering
Man kan få max 95 poäng och för att få godkänt krävs 65 poäng (85 för väl godkänt). Försök dock att lösa alla uppgifter då inte alla fel upptäcks av rättningsskriptet. Om ni har lite marginal kan ni kanske bli godkända även om assistenten som rättar hittar något sådant fel.
Förberedelser
Två datafiler behövs för att lösa många av uppgifterna nedan. Börja därför med att kopiera dem från kurskatalogen. Du hittar filerna firstnames
och lastnames
i katalogen /courses/729G46/kursmaterial/tema2
.
Filen firstnames
innehåller förnamn och filen lastnames
innehåller efternamn.
Filer att hämta via webben istället för via kurskatalogen:
Högerklicka på länkarna och välj “Spara som…”.
Uppgift 8.1
8.1.1 (5p)
Skriv en funktion print_lines(path)
som tar sökvägen till en fil representerat som en sträng som argument. Funktionen skall skriva ut alla rader i filen.
Exempel
|
|
Tips 1: Innan vi kan läsa från en fil, så måste vi öppna filen för läsning med hjälp av funktionen open()
. Ett filobjekt måste stängas när man är färdig med det.
Tips 2: När vi har öppnat en fil så läser vi den med hjälp av metoden readlines()
. Du kan läsa pythondokumentationen för readlines() översiktligt. Du behöver inte förstå allt, men du får exempel på den terminologi som används. Vissa termer kommer kanske att vara nya. Vad betyder t.ex. EOF?
8.1.2 (5p)
Skriv en funktion save_strings(path, lst)
som tar en sökväg och en lista av strängar och skriver strängarna till filen, en sträng per rad. Om filen redan existerar ska innehållet skrivas över. Använd file.write
för att skriva varje sträng i lst
till filen.
Tips: Kom ihåg att tecknet för en radbrytning är '\n'
.
Exempel
|
|
Innehållet i stringfile.txt
efter båda anropen ovan:
rad 4
rad 5
rad 6
8.1.3 (5p)
Skriv en funktion save_more_strings(path, lst)
som tar en sökväg och en lista av strängar och skriver strängarna till filen, en sträng per rad. Om filen redan existerar ska innehållet läggas till i slutet av filen. Använd file.writelines
för att skriva hela listan till filen i ett anrop.
Exempel
|
|
Innehållet i stringfile.txt
efter båda anropen ovan:
rad 1
rad 2
rad 3
rad 4
rad 5
rad 6
Förberedelser
Två datafiler behövs för att lösa många av uppgifterna nedan. Börja därför med att kopiera dem från kurskatalogen. Du hittar filerna firstnames
och lastnames
i katalogen /courses/729G46/kursmaterial/tema2
.
Filen firstnames
innehåller förnamn och filen lastnames
innehåller efternamn.
Filer att hämta via webben istället för via kurskatalogen:
Högerklicka på länkarna och välj “Spara som…”.
Uppgift 8.2 (5p)
Skriv en funktion count_lines(path)
som returnerar antalet rader i en fil.
Använd kontexthanteraren för filobjekt med hjälp av with
för att slippa att manuellt stänga filen.
Exempel
|
|
Uppgift 8.3 (5p)
Skriv funktionen get_names_starting_with(path, letter)
som läser in en fil med namn och returnerar en lista på alla namn som börjar på bokstaven letter
. Det ska inte spela någon roll ifall letter
är gemen eller versal.
Tips: För att slippa anropa str.strip
eller str.rstrip
på varje element för att bli av med radbrytningstecknen kan man istället för att läsa in raderna med file.readlines
använda file.read
, som returnerar hela filen som en sträng, och sedan strängmetoden str.splitlines
(eller str.split('\n')
), för att dela upp den strängen i rader. Sätter man ihop det blir det t.ex. f.read().splitlines()
.
Exempel
|
|
Uppgift 8.4 (10p)
Skriv funktionen find_in_file(path, search_str)
som tar en sökväg och en söksträng. Filen skall returnera en tupel med två element, radnumret (numrerat från 1) på den första raden som innehåller search_str
samt en sträng som representerar hela raden (utom radbrytningen). Om ingen rad i filen innehåller search_str
skall funktionen returnera None
.
Exempel
|
|
Uppgift 8.5 (5p)
Skriv funktionen find_all_in_file(path, search_str)
som tar en sökväg och en söksträng. Filen skall returnera en lista av tupler med två element*. Varje tupel skall innehålla radnumret (numrerat från 1) på den rad som innehåller search_str
samt en sträng som representerar hela raden (utom radbrytningen). Om ingen rad i filen innehåller search_str
skall funktionen returnera en tom lista.
* Detta är ett exempel på en så kallad nästlad datastruktur. Vi kommer titta mer på dessa längre fram i kursen.
Exempel
|
|
Uppgift 8.6 (10p)
Skriv en funktion get_random_name(firstnames_path, lastnames_path)
som skapar slumpmässiga namn genom att använda för- och efternamn från de angivna filerna. För- och efternamn får inte komma från samma rad i båda filerna, dvs. det slumpade namnet skall inte vara ett av de riktiga namnen.
Tips: För att garanterat välja två olika slumpmässiga tal kan man använda random.sample(range(lowest, highest+1), k=2)
.
Uppgift 8.7 (10p)
Skriv funktionen combine_lines(input_path1, input_path2, sep)
som tar två sökvägar och en separator sep
som argument. Funktionen skall läsa de båda filerna (som alltså måste existera) och returnera en lista med strängar som skapats genom att slå ihop rad 1 (exklusive radbrytningar) från båda filerna med sep
mellan dem, rad 2 från båda filerna med sep
mellan, osv.
Exempel
|
|
Uppgift 8.8 (5p)
Skriv funktionen combine_and_save_names(firstnames_path, lastnames_path, output_path)
som tar tre sökvägar som argument. Funktionen skall läsa de båda första filerna (som förväntas innehålla förnamn respektive efternamn på personer) och skapa en lista med strängar genom att slå ihop rad 1 (exklusive radbrytningar) från båda filerna, rad 2 från båda filerna, osv. enligt mönstret nedan. Dessa strängar skall sedan skrivas till filen output_path
. Om filen output_path
redan existerar skall dess innehåll skrivas över.
Använd funktioner från uppgifterna ovan för att lösa problemet, det är inte tillåtet att anropa open
direkt från combine_and_save_names
.
Exempel
|
|
Innehåll i scientists.csv
efter att ha kört raden ovan:
Marie,Curie
Ida,Noddack
Maria,Goeppert-Mayer
Sofia,Vasiljevna Kovalevskaja
Rosalind,Franklin
Cecilia,Payne-Gaposchkin
Jocelyn,Bell Burnell
Dorothy,Crowfoot Hodgkin
Ada,Lovelace
Barbara,McClintock
Grace,Hopper
Uppgift 8.9 (10p)
Skriv funktionen get_first_name(path, lastname)
som tar in ett efternamn och en sökväg som argument. Sökvägen ska gå till en fil som matchar formatet i scientists.csv
, dvs en CSV-fil med förnamn i första kolumnen och efternamn i andra kolumnen. Funktionen ska returnera det första förnamnet på den första personen med det angivna efternamnet i den angivna filen. Använd scientists.csv
som exempel.
Tips: Strängmetoden str.split
är användbar för att separera för- och efternamn. Kom ihåg att efternamn kan ha mellanslag!
Uppgift 8.10 (5p)
Skriv en funktion get_names_of_length(path, length)
som returnerar en lista av alla namn av längden length
i en fil med sökvägen path
.
Uppgift 8.11 (5p)
Skriv en funktion get_longest_name(path)
som plockar fram det längsta namnet i den angivna filen.
Uppgift 8.12 (10p)
Skriv en funktion get_palindromes(path)
som returnerar en lista med alla namn som är palindrom från en given fil. Det räcker att ett namn är ett palindrom när alla bokstäver konverterats till gemener. (Ett palindrom är en sekvens tecken som blir samma oavsett om den läses framifrån eller bakifrån, t.ex. “kajak”, “apa” eller “tillit”.)
Exempel
|
|
Sidansvarig: Johan Falkenjack
Senast uppdaterad: 2025-08-05