Pythonuppgifter 5 - Iteration med fördefinierat antal repetitioner — for-loopen
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 ett fördefinierat antal upprepningar kan implementeras med hjälp av
for
-loopen. - Förstå hur sekvenser kan bearbetas iterativt.
Man kan få max 150 poäng och för att få godkänt krävs 105 poäng (135 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.
Uppgift 5.1 (5p)
Skriv en funktion create_ten_list_for()
vars uppgift är att returnera en lista som innehåller heltalen 0
-10
i ordning, dvs listan [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
. Uppgiften ska lösas med en for
-loop.
Tips 1
Skapa en tom lista med t.ex. result = []
som du sedan lägger till värden till.
Tips 2
Hur använder man range
för att få ut de värden man vill ha?
Tips 3
Lägg till innehåll till en lista genom att använda operatorn +
.
|
|
Ovanstående kod kommer att resultera i att new_list
innehåller ["hej", "då"]
. Exemplet visar också hur det ser ut när man lägger till ett hårdkodat värde till en lista och hur det ser ut när man lägger till ett värde från en variabel till en lista.
Uppgift 5.2 (5p)
Skriv funktionen create_zero_to_number_list_for(number)
. Funktionen ska ta in ett heltal som argument (number
) och returnera en lista som innehåller siffrorna från 0 till number
. Uppgiften ska lösas med en for
-loop.
Anropet create_zero_to_number_list_for(3)
ska alltså returnera listan [0, 1, 2, 3]
.
Uppgift 5.3 (5p)
Skriv funktionen create_number_to_number_list_for(start_number, end_number)
. Funktionen ska skapa och returnera en lista som innehåller siffror från start_number
till och med end_number
. Både start_number
och end_number
är heltal. start_number
kommer också alltid att vara mindre än eller lika med end_number
.
Funktionen create_number_to_number_list_for(number)
ska implementeras med en for
-loop.
Anropet create_number_to_number_list_***(5, 9)
ska alltså returnera listan [5, 6, 7, 8, 9]
Uppgift 5.4
5.4.1 (5p)
Funktionen get_max_for(integer_list)
ska iterera över listans index med hjälp av en for
-loop.
Ledtråd Hur fungerade funktionen len
och hur kan man använda den för att loopa “rätt” antal gånger?
5.4.2 (5p)
Funktionen get_max_for(integer_list)
får inte använda range
eller len
men ska använda en for
-loop.
Reflektion
Vad var skillnaden mellan get_max_for_by_index
och get_max_for
? Vilken lösning känns mest naturlig och enklast att förstå?
När vi använder for
-loopar vill vi oftast låta själva for
-raden, blockets header, göra så mycket som möjligt av arbetet så att loopvariabeln innehåller det värde vi faktiskt vill använda i varje iteration (varje upprepning). Det gör koden enklare att förstå när koden ska läsas. Varför kan vi fortfarande kan säga att for
-loopen gör ett fördefinierat antal upprepningar?
Uppgift 5.5
5.5.1 (5p)
Skriv funktionen get_five_first(value_list)
som tar in en lista som alltid kommer vara längre än 5 element. Funktionen ska returnera en lista som bara innehåller de fem första elementen i value_list
. Använd en loop och inte “slice”-notationen som introducerades i Laboration 1.
Exempel
|
|
5.5.2 (5p)
Skriv funktionen get_nfirst(value_list, n)
som tar in en sekvens, seq
som alltid är längre än heltalsargumentet n
. Funktionen ska returnera en tupel som innehåller de n
första elementen i seq
. Du får återigen inte använda “slice” för att lösa uppgiften.
Exempel
|
|
5.5.3 (5p)
Skriv funktionen get_all_less_than(values, cutoff)
som returnerar en lista med alla värden från argumentet values
som är mindre än cutoff
. Alla värden i values
och värdet i cutoff
är flyttal.
Exempel
|
|
5.5.4 (5p)
Skriv funktionen get_all_even(values)
som returnerar en lista med alla jämna värden från argumentet values
, som kan vara en lista eller en tupel.
Exempel
|
|
5.5.5 (5p)
Skriv funktionen get_all_divisible(values, divisor)
som returnerar en lista med alla värden från argumentet values
som är delbara med divisor
.
Anropet get_all_divisible([4, 10, 7, 8], 4)
ska alltså returnera listan [4, 8]
.
Uppgift 5.6 (15p)
Skriv funktionen insert_at_asc_place(values, new_value)
som tar emot en tupel av tal ordnade från minsta till största värde samt ett nytt tal. Funktionen ska returnera en ny tupel med new_value
insatt bland värdena i values
så att den nya tupeln också är ordnad från minsta till största värde.
Funktionen sorted
får inte användas.
Kuriosa Om man vill använda en mer effektiv algoritm för att hitta rätt position att sätta in new_value
på så kan man använda en så kallad binärsökning. Då undersöker man värdet i mitten av sekvensen. Är det värdet större än new_val
kan man eliminera den övre halvan av sekvensen, är värdet mindre än new_val
kan man eliminera den lägre halvan av sekvensen. Man undersöker sedan det mittersta elementet i den halva av sekvensen som är kvar, och upprepar samma procedur, osv.
Exempel
|
|
Uppgift 5.7 (10p)
Skriv funktionen insertionsort_asc(values)
som returnerar en sorterad version av tupeln values
. Du får inte använda någon redan existerande sorteringsalgoritm, t.ex. med funktionen sorted
. Använd insert_at_asc_place
som implementerades i förra uppgiften.
Exempel
|
|
Uppgift 5.8 (5p)
Skriv funktionen word_in_list_for(words, word)
. Funktionen får in en lista av strängar(argumentet words
) samt en enskild sträng (argumentet word
). Funktionen ska returnera True
om strängen word
finns i listan words
. False
ska returneras om word
inte finns i listan words
.
Den inbyggda operatorn in
får inte användas, använd en for
-loop för att undersöka orden i words
. OBS! Förekomsten av in
i for
-loopskonstruktionen är inte den inbyggda operatorn in
utan hänger ihop med nyckelordet for
. Se stycket nedan.
Om man inte vill att loopen ska fortsätta när man väl hittat att ordet finns kan man använda nyckelordet break
för att avbryta. Det går även bra att returnera i loopen.
Förväxlingar
Det är viktigt att notera att nyckelordet in
i en for
-loop inte är samma in
som operatorn in
som används för att undersöka ifall ett visst värde finns i en samling. Dessa två förekomster av in
fyller olika syften och kan aldrig förekomma i samma kontext, så det råder sällan någon risk för förväxling. Med det sagt hade det kanske varit mer pedagogiskt ifall Guido hade valt
|
|
eller kanske
|
|
istället för att använda in
i båda dessa fall.
Dock innehåller alla programmeringsspråk designval som av vissa programmerare upplevs som olämpliga. Detta är en av flera orsaker till att nya programmeringsspråk uppstår så gott som dagligen.
När vi ändå är inne på förväxlingar är det också viktigt att veta for
inte bara används i for
-loopen utan också i så kallade generatoruttryck (eng. generator expressions), oftast i så kallade listbyggare (eng. list comprehensions). Dessa är att betrakta som överkurs.
Uppgift 5.9 (5p)
Skriv funktionen count_integers_for(value_list)
. Funktionen ska returnera antalet heltal i argumentet value_list
.
Använd funktionen type()
som returnerar vilken datatypen hos ett värde. Till exempel type(4)
returnerar int
, så jämförelsen type(4) == int
kommer att vara True
(OBS! att int
inte är omgiven av några citat-tecken).
Uppgiften ska lösas med en for
-loop.
Tips
Hur sparar du antalet heltal och vad händer när du hittar en?
Uppgift 5.10 (5p)
Skriv funktion average_for(values)
. Funktionen ska returnera genomsnittet av alla värden i argumentet values
som kommer vara en lista av flyttal. Funktionen ska summera ihop värdena med en for
-loop och sedan dela summan med antalet värden i listan values
.
Den inbyggda funktionen sum
(eller statistics.mean
) får inte användas.
Exempel:
|
|
Uppgift 5.11 (5p)
I samband med vissa psykologiska experiment vill vi använda sensorer för att mäta vitalparametrar som puls, kroppstemperatur, blodtryck, pupillvidgning, osv. hos försöksdeltagarna. Tyvärr mäter inte alla sådana sensorer med samma frekvens (lika ofta). Vissa ger ett mätvärde varje sekund, andra varannan sekund, vissa var femte sekund, osv.
Oftast vill vi dock kunna matcha upp olika parametrar med varandra. Det betyder att om sensor A mätte var fjärde sekund och sensor B mätte varje sekund så vill vi matcha varje mätning från sensor A med var fjärde mätning från sensor B.
Skriv en funktion every_nth_measurement(values, n)
som använder en for
-loop för att hämta ut vart “n:te” (vart annat, vart tredje, vart fjärde, osv.) värde ur en lista values
. Vi antar att det första värdet alltid ingår (se exempel nedan).
Tips: Ett annat sätt att säga att ett värde är ett av vart n:te värde är att dess index är jämnt delbart med n
.
Tips: Man kan testa om ett index är delbart med n
genom att testa ifall index % n == 0
.
Exempel
För att göra exemplen tydliga låter vi values
vara en lista av alla heltal från 1 till och med 10 i ordning. I verkligheten kan det ju såklart vara helt andra värden.
|
|
Uppgift 5.12 (10p)
I funktionen every_nth_measurement
skulle vi hämta ut vart “n:te” element ur en lista. Detta är ett exempel på ett mer generellt mönster av att hämta ut vart n:te element ur vilken sekvens som helst.
Skriv en funktion every_nth_element(seq, n)
som hämtar ut vart “n:te” element ur en sekvens seq
. Det returnerade värdet ska vara av samma datatyp som seq
men funktionen får inte explicit kontrollera värdet av seq
(t.ex. med hjälp av type
eller isinstance
)
Tips: Eftersom vi inte vet vilken datatyp seq
har från början kan vi inte vara säkra på hur ett enskilt element från sekvensen ska kombineras ihop med de element vi redan hämtat ut. Om vi däremot hämtar ut delsekvenser av längden 1 istället för enskilda element…
Exempel
I det tredje exemplet nedan använder vi en tupel. Tupler fungerar ungefär på samma sätt som listor och vi kommer in på skillnaderna mellan dem längre fram i kursen.
|
|
Uppgift 5.13 (10p)
Skriv en funktion reverse_sequence_for(seq)
som tar en sekvens och returnerar en sekvens av samma typ i omvänd ordning från seq
. Funktionen ska använda en loop för att lösa problemet, seq[::-1]
är alltså inte godkänt.
Tips Var ska man börja för att enkelt kunna skapa den sekvensen? Hur ser man till att ackumulatorvariabeln blir av rätt typ?
Exempel
|
|
Uppgift 5.14 (5p)
Skriv en funktion replace_periods_with_newlines(string_value)
som använder en loop för att gå igenom en sträng och byta ut alla .
-tecken (punkter) mot radbrytningar. Resulterande sträng returneras av funktionen.
Använd en loop för att göra detta, inte strängmetoden str.replace()
. (Vi kommer till metoder längre fram i kursen.)
Tips!
I Python kan man inte byta ut enskilda tecken i en sträng. Hur kan du då få en nästintill identisk sträng med hjälp av en loop?
När du stöter på en punkt, spara undan radbryttecknet \n
istället.
Exempel
|
|
Uppgift 5.15 (10p)
Skriv funktionen replace_char_in_string(original_string, original_char, new_character)
som ska gå igenom strängen original_string
och byta ut alla förekomster av tecknet original_char
mot tecknet new_char
. Använd en loop för att göra detta, inte strängmetoden str.replace()
. (Vi kommer till metoder längre fram i kursen.)
Exempel
|
|
Tips Börja med en tom sträng och lägg tecken för tecken från original_string
till den tomma strängen, förrutom när original_char
påträffas, lägg då istället till new_char
.
Uppgift 5.16 (5p)
Skriv funktionen list_replace(lst, original_value, new_value)
som ska gå igenom listan lst
och byta ut alla förekomster av värdet original_value
mot värdet new_value
. Använd en loop för att göra detta.
Exempel
|
|
Uppgift 5.17 (5p)
Skriv funktionen sum_of_ints(value_list)
som tar in en lista med värden som
argument. Funktionen ska returnera summan av alla heltal som finns i listan.
Uppgift 5.18 (10p)
Födelsedagsproblemet: Skriv funktionen birthday(n)
, som beräknar sannolikheten $p(n)$, med hjälp av en loop, för att bland $n$ personer åtminstone 2 har samma födelsedag. Vi bortser från skottår.
Uppgiften skall lösas med hjälp av iteration.
Tips: Formeln för sannolikheten är $p(n)=1 - 365/365 \cdot 364/365 \cdot 363/365 \ldots (366-n)/365$. Hur kan man upprepa detta för ett givet $n$?
Sidansvarig: Johan Falkenjack
Senast uppdaterad: 2025-08-05