Logga in
| 7 sidor teori |
| 14 Uppgifter - Nivå 1 - 3 |
| Varje lektion är menad motsvara 1-2 lektioner i klassrummet. |
För alla dessa värden, gör så här: ...
Fortsätt att göra ... tills ....
Dessa två typer av loopar beskrivs med for
- respektive while
-satser, och på denna sida kommer du att lära dig hur man konstruerar sådana loopar.
varde = 0
maxvarde = 100
while varde < maxvarde: print(varde) varde = varde + 5
Vad tror du att koden gör? Vad kommer att skrivas ut? Vad händer om du byter plats på rad 4 och 5?
I den här lektionen går vi igenom följande begrepp:
Om man har instruktioner som ska upprepas ett känt antal gånger, t.ex. för varje element i en lista med given längd, kan man använda en for
-sats. Dessa skrivs med kommandot for
följt av ett variabelnamn, kommandot in
och till sist en lista eller uppräkning, avslutat med ett kolon.
for element in ['hej', 'på', 'dig']: print(element)
>
hej
på
dig
För varje element i listan ['hej', 'på', 'dig']
. Det innebär att variabeln element
sätts till det första värdet i listan och sedan ändras för varje ny upprepning i loopen. Dessa upprepningar kallas iterationer, och i den första kommer alltså element
att vara lika med 'hej'
för sedan bytas till 'på'
i andra iterationen och 'dig'
i tredje.range()
är en funktion som skapar en uppräkning av heltal. Skriver man t.ex. range(5)
får man en uppräkning från 0 till 4. Argumentet man anger ingår alltså inte i uppräkningen. Dessa uppräkningar är av datatypen iterator och används ofta tillsammans med loopar.
for x in range(8): print(x)
>
0
1
2
3
4
5
6
7
Om man skriver två argument i funktionen kommer uppräkningen att ske från det första argumentet till, men inte med, det andra.
for x in range(3,8): print(x)
>
3
4
5
6
7
Lägger man till ytterligare ett argument kommer det att användas som steglängden i uppräkningen.
for x in range(3,8,2): print(x)
>
3
5
7
for
-sats för att skriva ut Party!tio gånger.
for x in range(10): print('Party!')
Vad ska räckvidden vara?
Vi börjar med att skriva en for
-sats som går igenom heltalen från 0 till och med 9 för en variabel x
. Det ger att instruktionerna inne i loopen upprepas 10 gånger.
for x in range(10):
Vi behöver egentligen inte värdet som finns i variabeln x
, bara att instruktionerna i loopen upprepas 10 gånger. För att skapa en for
-sats måste man dock skriva något mellan for
och in
, så vi skriver in ett variabelnamn som sedan aldrig används. Inne i loopen använder vi print()
för att skriva ut vårt meddelande.
for x in range(10): print('Party!')
>
Party!
Party!
Party!
Party!
Party!
Party!
Party!
Party!
Party!
Party!
while
-satser används för kodstycken som ska upprepas så länge ett visst villkor är uppfyllt. Det är användbart för loopar där man inte vet hur många upprepningar som krävs. För att skriva en sådan sats börjar man med ordet while
, alltså medan
, följt av ett villkor och ett kolon. Den kod som ska upprepas skrivs med ett indrag.
tal = 1
while tal < 20: print('Talet är', tal) tal = tal*2 + 1
>
Talet är 1
Talet är 3
Talet är 7
Talet är 15
I while
-satser måste man akta sig för oändliga loopar. I programmet nedan ändras aldrig värdet på x, och då är villkoret alltid sant. Programmet kommer då aldrig ur loopen och måste avbrytas manuellt. De flesta programmeringsmiljöer har en stoppknapp för detta.
x = 1
while x < 5: print(x**2)
while
-sats som summerar de positiva heltalen, 1, 2, 3…, tills summan är minst 100 och sedan skriver ut hur många tal som behövdes. summa = 0
tal = 0
while summa < 100: tal = tal + 1 summa = summa + tal
print(tal)
>
14
Skapa variabeln tal
som börjar på 0 utanför slingan, öka den sedan med 1 för varje iteration.
Först måste vi bestämma villkoret. Vi ska addera termer tills summan är 100 eller mer, och alltså har vi en process som pågår medan summan är mindre än 100. Villkorsraden kan därför skrivas så här.
while summa < 100:
Men programmet kan inte börja så, för jämförelsen kan inte göras innan variabeln summa
fått ett värde. Vi måste därför först skapa variabeln summa
, och från början är den 0. Eftersom 0 är mindre än 100 är villkoret sant från början och då kan programmet starta loopen.
summa = 0
while summa < 100:
Sedan måste vi få loopen att räkna upp heltalen. Vi skapar variabeln tal
som börjar på 0 utanför loopen, för att sedan öka med 1 för varje iteration.
summa = 0
tal = 0
while summa < 100: tal = tal + 1
Nu har vi en loop som räknar upp heltal. Varje iteration ska nu avslutas med att talet läggs till summan. Till slut blir då summan så stor att villkoret blir falskt och loopen avslutas.
summa = 0
tal = 0
while summa < 100: tal = tal + 1 summa = summa + tal
När programmet har kommit ut ur loopen finns det senaste talet kvar i variabeln tal
. Detta värde är också antalet tal som har adderats, vilket är vad vi är ute efter. Vi behöver alltså bara skriva ut det.
summa = 0
tal = 0
while summa < 100: tal = tal + 1 summa = summa + tal
print(tal)
>
14
break
används i en for
- eller while
-sats för att avbryta den. Det är t.ex. användbart när man söker igenom en lista efter en viss sorts element. I exemplet nedan avbryts sökningen med break
när ett tal mellan 61 och 67 har hittats.
lista = [44, 50, 55, 1, 62, 70, 94, 66, 56, 6]
for tal in lista: if 61 < tal < 67: print(tal) break
>
62
Vi skapar först ett program som använder sju termer och ser att kvoten verkligen blir 5,6. På så sätt kan vi se att programmet gör rätt, och därifrån är det ingen svår sak att utöka antalet termer till 100.
Här vill vi först beräkna summan 1+2+...+7 och sedan kvadrera den. Summan är en aritmetisk summa och kan beräknas med en formel. Men nu tränar vi på loopar. Vi skriver därför ett program som räknar ut summan en term i taget. Vi skriver då en for
-sats som räknar upp talen 1-7 med hjälp av funktionen range()
.
for tal in range(1, 8): print(tal)
> 1 2 3 4 5 6 7
Kom ihåg att den övre gränsen i range()
sätts till 1 större än det sista tal som ska ingå i uppräkningen. Vi kontrollerar att rätt tal räknas upp med en print()
-rad. Nu skapar vi summan. Det är en variabel som börjar på 0, och sedan för varje iteration i loopen ökar summan med värdet tal
. Vi kontrollerar resultatet genom att skriva ut summan efter loopen.
summa = 0 for tal in range(1, 8): summa = summa + tal print(summa)
> 28
Summan 1+2+...+7 blir mycket riktigt 28, så programmet räknar rätt. Nu måste vi bara komma ihåg att kvadrera resultatet. För tydlighetens skull lägger vi det värdet i en ny variabel, och vi passar på att kontrollera att det verkligen blir 784 som uppgiften säger.
summa = 0 for tal in range(1, 8): summa = summa + tal kvadrat_av_summa = summa**2 print(kvadrat_av_summa)
> 784
Nu vill vi beräkna och lägga ihop kvadraterna 1^2, 2^2 osv. Vi skapar en ny variabel för den summan som börjar på 0.
summa = 0 summa_av_kvadrater = 0 for tal in range(1, 8): summa = summa + tal kvadrat_av_summa = summa**2
Precis som i förra summan ska vi här använda talen 1-7. Dessa loopar vi redan igenom en gång, så det behövs ingen ny loop. Vi lägger till en rad i loopen som ökar summa_av_kvadrater
med tal**2
och kontrollerar sedan resultatet med print()
.
summa = 0 summa_av_kvadrater = 0 for tal in range(1, 8): summa = summa + tal summa_av_kvadrater = summa_av_kvadrater + tal**2 kvadrat_av_summa = summa**2 print(summa_av_kvadrater)
> 140
Nu är vi redo att beräkna kvoten. Tänk på att dela i rätt ordning: kvadrat_av_summa
delat med den andra.
summa = 0 summa_av_kvadrater = 0 for tal in range(1, 8): summa = summa + tal summa_av_kvadrater = summa_av_kvadrater + tal**2 kvadrat_av_summa = summa**2 print(kvadrat_av_summa / summa_av_kvadrater)
> 5.6
Svaret blev 5,6 precis som i uppgiften. Troligen fungerar då programmet som det ska, och vi är redo att bygga ut det till 100 termer. Vi flyttar då den övre gränsen i range()
till 101. range()
exkluderar alltid den övre gränsen så därför måste gränsen vara 1 större än det sista tal som ska räknas upp. Eftersom vi ska avrunda till närmasta heltal lägger vi även till round()
i print
-kommandot.
summa = 0 summa_av_kvadrater = 0 for tal in range(1, 101): summa = summa + tal summa_av_kvadrater = summa_av_kvadrater + tal**2 kvadrat_av_summa = summa**2 print(round(kvadrat_av_summa / summa_av_kvadrater))
> 75
Kvadraten av summan är alltså 75 gånger större än summan av kvadraterna, då 100 termer används.
Funktionen max()
bestämmer det största värdet i en lista. Skriv ett program som gör samma sak utan att använda max()
. Testa det på följande lista.
varden = [-38, -26, 68, -68, -31, 0, -82, 40, 42, -1]
Tänk på att programmet ska fungera oavsett vilka värden som finns i listan.
Om man känner sig osäker på hur man ska lösa ett problem med programmering kan det alltid vara en god idé att fundera över hur man skulle lösa problemet för hand och se om man kan överföra det tänkandet till programmet. I det här fallet kan vi t.ex. anta att vi har en lista med värden nedskrivna på ett papper.
Då skulle man förmodligen börja från vänster och gå igenom dem en och en. Det första talet man ser är ju det största hittills, så man kommer ihåg det.
Sedan fortsätter man igenom de andra talen och jämför sitt tal. Dyker något större tal upp kommer man ihåg det istället och fortsätter tills man har gått igenom alla tal. Då har man hittat det största.
Nu ska vi överföra detta till kod, och vi börjar med att skapa vår lista.
varden = [-38, -26, 68, -68, -31, 0, -82, 40, 42, -1]
Vi skapar sedan en variabel för att komma ihåg det hittills största värdet. För att ha något att börja med sätter vi den till det första värdet i listan, som ju är det största hittills.
varden = [-38, -26, 68, -68, -31, 0, -82, 40, 42, -1]
maxvarde = varden[0]
Vi använder sedan en for
-sats som loopar igenom alla värden i listan. Om man vill går det att undvika att det första värdet ingår i loopen, men det gör inget om man har med det.
varden = [-38, -26, 68, -68, -31, 0, -82, 40, 42, -1]
maxvarde = varden[0] for x in varden:
För varje värde som for
-satsen går igenom vill vi göra en jämförelse för att se om det är större än det som för tillfället är sparat i maxvarde
. Om det är större vill vi skriva över maxvarde
med den nya större värdet.
varden = [-38, -26, 68, -68, -31, 0, -82, 40, 42, -1]
maxvarde = varden[0] for x in varden: if x > maxvarde: maxvarde = x
När loopen är färdig har programmet gått igenom och jämfört alla värden, så det som finns sparat i maxvarde
måste vara det största värdet i listan. Då behöver vi bara skriva ut det.
varden = [-38, -26, 68, -68, -31, 0, -82, 40, 42, -1]
maxvarde = varden[0] for x in varden: if x > maxvarde: maxvarde = x print(maxvarde)
> 68
Reglerna för att hitta nästa tal i Fibonacciföljden är enkla: lägg ihop de två senaste. Programmet behöver därför "komma ihåg" talen som hittas. En lista är ett bra sätt att lagra information i ett program, så vi skapar en sådan att lägga följden i. Från början innehåller listan bara de givna talen 0 och 1.
fibonacci = [0, 1]
Vi ska försöka återskapa de Fibonaccital som ges i uppgiften, innan vi går upp till n = 100. För att hitta nästa behöver vi plocka ut och lägga ihop talen som har index 0 och 1 i listan. Vi hämtar ut värden ur listor genom att sätta värdenas index inom hakparenteser. Än så länge råkar värdena vara samma som deras index, men blanda inte ihop dem!
fibonacci = [0, 1] summa = fibonacci[0] + fibonacci[1] print(summa)
> 1
0+1 blir mycket riktigt 1. Nu vill vi lägga till summan som ett nytt värde i listan. Det görs med append()
.
fibonacci = [0, 1] summa = fibonacci[0] + fibonacci[1] fibonacci.append(summa) print(fibonacci)
> [0, 1, 1]
Talet lades till, så nu behöver vi bara upprepa detta. Vi inför nu n=5 som en övre gräns på vilka platsnummer som ska tas med. Med en for
-sats kan vi loopa igenom alla platsnummer fram till n, dvs. 2-5 eftersom plats 0 och 1 redan finns i listan.
n = 5 fibonacci = [0, 1] for tal in range(2, n+1):
För varje platsnummer tal
vill vi plocka de två senaste talen i listan, som då ligger på plats nummer tal-1
och tal-2
. Vi hämtar ut dessa ur listan och summerar som tidigare. Vi lägger också varje summa som ett nytt element i listan med append()
. Efter loopen skriver vi ut listan för att se vad det blev.
n = 5 fibonacci = [0, 1] for tal in range(2, n+1): summa = fibonacci[tal - 1] + fibonacci[tal - 2] fibonacci.append(summa) print(fibonacci)
> [0, 1, 1, 2, 3, 5]
Nu har vi återskapat precis de Fibonaccital som gavs i uppgiften. Det är tillräckligt för att vi ska våga lita på vårt program: Om det gör rätt fram tills n = 5 kan den säkert fortsätta göra rätt fram tills n = 100. Vi höjer då gränsen, men med hundra tal är det lite mycket att skriva ut alla. Vi ändrar därför utskriften så den bara skriver ut det sista talet i listan, dvs. det med index n.
n = 100 fibonacci = [0, 1] for tal in range(2, n+1): summa = fibonacci[tal - 1] + fibonacci[tal - 2] fibonacci.append(summa) print(fibonacci[n])
> 354224848179261915075
Det hundrade Fibonaccitalet är alltså 354 224 848 179 261 915 075.
Nackdelen med listor är att programmet måste hålla en massa saker i minnet. Programmet blir då långsammare, och kan även krascha ifall minnet tar slut. Därför visas här en version som undviker listor, men den kan verka lite svårare. Tanken är här att de enda tal som programmet borde behöva hålla reda på är de senaste två, och med dessa beräkna nästa.
forra = 0 nytt = 1 nasta = forra + nytt
Koden ovan använder de två senaste talen för att bilda nästa tal i följden, nasta
. Men för att kunna fortsätta hitta nya tal måste värdena i forra
och nya
uppdateras. När nästa tal hittats är det tal som nyss var "nytt" istället det förra
talet, och det som nyss var nästa
tal är nu det nya
.
forra = 0 nytt = 1 nasta = forra + nytt forra = nytt nytt = nasta
Nu är vi redo att loopa! De två första raderna får stå kvar utanför loopen eftersom de utgör startläget. De sista tre är generella och kan upprepas. För att se om vi tänkt rätt lägger vi in en printrad i loopen.
forra = 0 nytt = 1 for i in range(5): nasta = forra + nytt forra = nytt nytt = nasta
print(nytt)
> 1 2 3 5 8
Utskrifterna matchar talen som visades i början av uppgiften, så nu har vi ett program som kan rabbla Fibonacciföljden. Då återstår bara att få programmet att hålla räkningen. Vi ser att range(5)
gav a_6 = 8, dvs. det sjätte Fibonaccitalet. Argumentet i range()
ska alltså vara 1 mindre än det platsnummer vi letar efter.
n = 5
forra = 0 nytt = 1 for i in range(n - 1): nasta = forra + nytt forra = nytt nytt = nasta
print(nytt)
> 1 2 3 5
Genom range(n - 1)
slutar programmet att loopa så att det senaste talet i nytt
är precis Fibonaccital nr n. Jämför med exempeltalen i början av uppgiften för att kontrollera att det blir rätt. Som avslutning ändrar vi till n = 100
och flyttar ut printraden till efter for
-satsen, så skrivs bara det hundrade talet ut.
n = 100
forra = 0 nytt = 1 for i in range(n - 1): nasta = forra + nytt forra = nytt nytt = nasta print(nytt)
> 354224848179261915075
Det hundrade Fibonaccitalet är alltså 354 224 848 179 261 915 075.
Ronja har skrivit ett program som beräknar vilket element i en geometrisk talföljd som är det första som är större än 10000. Användaren anger startvarde
och kvot
för att definiera sin talföljd.
startvarde = 2
kvot = 4
element = startvarde
antal_element = 1
while element < 10000:
element = element*kvot
antal_element = antal_element + 1
print("Element {} är det första över 10000.".format(antal_element))
>
Element 8 är det första över 10000.
Det finns en bugg som i vissa fall kan ställa till problem. Hitta felet och rätta till det.
Vi första anblick verkar det som att programmet gör vad det ska. Om man kör det med de värden som finns angivna i uppgiften får man ut precis vad man väntar sig.
startvarde = 2 kvot = 4
element = startvarde antal_element = 1 while element < 10000: element = element*kvot antal_element = antal_element + 1 print("Element {} är det första över 10000.".format(antal_element))
> Element 8 är det första över 10000.
Det finns dock en while
-sats i programmet, och då finns det alltid en risk att man fastnar inne i loopen. Vi bör alltså undersöka om det finns någon situation där villkoret element < 10000
aldrig blir falskt. Variabeln element
sätts till startvärdet innan loopen och ändras sedan i början av varje iteration på följande sätt.
element = element*kvot
Variabeln element
multipliceras alltså med kvoten som finns lagrad i kvot
tills element
är större än 10 000. Men vad händer om man har en kvot som är ligger mellan 0 och 1? Då kommer ju element
inte att bli större.
startvarde = 2 kvot = 0.5
element = startvarde antal_element = 1 while element < 10000: element = element*kvot antal_element = antal_element + 1 print("Element {} är det första över 10000.".format(antal_element))
>
Programmet fortsätter räkna ut nya element men de blir bara mindre och mindre istället för större, så villkoret i while
-satsen blir aldrig falskt. Vi fastnar i loopen och måste avbryta programmet. Om startvärdet är större än 10 000 fungerar det, men det är inte ett så intressant fall.
startvarde = 50000 kvot = 0.5
element = startvarde antal_element = 1 while element < 10000: element = element*kvot antal_element = antal_element + 1 print("Element {} är det första över 10000.".format(antal_element))
> Element 1 är det första över 10000.
På samma sätt blir det problem om kvoten ligger mellan -1 och 0. Elementen kommer då att byta tecken fram och tillbaka, men det är ändå samma situation som tidigare, att elementen kommer närmare och närmare 0 snarare än 10 000. Det blir också problem om kvoten är 1 eller -1 eftersom det varken gör att elementen kommer närmare 0 eller 10 000.
startvarde = 2 kvot = -1
element = startvarde antal_element = 1 while element < 10000: element = element*kvot antal_element = antal_element + 1 print("Det behövs {} element för att komma över 10000.".format(antal_element))
>
Man kan lösa problemet genom att lägga till en if
-sats som undersöker värdet i kvot
och bara kör loopen om det är större än 1, mindre än -1 eller om startvärdet är större än 10 000.
startvarde = 2 kvot = -0.5
if kvot > 1 or kvot < -1 or startvarde > 10000: element = startvarde antal_element = 1 while element <= 10000: element = element*kvot antal_element = antal_element + 1 print("Element {} är det första över 10000.".format(antal_element)) else: print('Serien blir aldrig större än 10000!')
> Serien blir aldrig större än 10000!