4. Moment04 - Iterationer och listor

Info

Till detta moment finns en sida med lösningsförslag och videoklipp.

Iteration

Iteration är ett annat ord för upprepning. Inom matematiken och i programmering handlar detta om att en funktion eller process åstadkommer något genom att upprepa beräkningar eller andra operationer tills ett önskat resultat uppnåtts.
https://sv.wikipedia.org/wiki/Iteration (avläst 2018-11-04)

Det finns flera olika strukturer när vi skapar iterationer inom programmeringen, de är bra på olika saker så för att få den mest effektiva koden behöver du kunna använda flera olika typer. När det gäller Python så finns det två olika typer av iterationer som vi behöver kunna.

4.1 for-loopen

For-loopen är den mest styrda loopen, här ligger fokus på att en operation genomförs x antal gånger. Vi börjar med ett exempel.

Kodexempel: enkel for-loop, bestämt slutvärde

for i in range (5):
    print(i)

for-kommandot innebär att det är en for-loop vi vill köra. i får värdet som iteratorn (räknaren) har i varje varv. Och in range (5) innebär att vi skall räkna från början, vilket är 0 eftersom det lägsta talet inom programmering är 0, och köra vår loop 5 gånger. För bättre tydlighet skulle vi kunna skriva koden på följande sätt;

Kodexempel: enkel for-loop, bestämt start- och slutvärde

for i in range (0, 5):
    print(i)

Alltså: Kör en loop, börja med att i får värdet 0 och kör loopen 5 gånger (egentligen kör mot 5 men stanna innan 5 körs). Utskrifterna skulle i bägge fallen bli.

Utskrift

0
1
2
3
4

Att kunna utföra en viss operation flera gånger är något som ofta används inom programmeringen. Just nu kör vi en loop ganska få gånger men vid statistiska beräkningar så kan loopen bestå av enormt stora datamängder. Vi skall senare kika lite på hur vi kan loopa igenom en lista istället för att följa en talserie.

Men om vi nu vill följa en dataserie men inte använda alla tal i vår beräkning så kan vi på ett enkelt sätt ta större steg än 1 i vår loop.

Kodexempel: enkel for-loop, bestämda steg

for i in range (0, 15, 3):
    print(i)

Utskriften blir då.

Utskrift

0
3
6
9
12

När vi kör vår for-loop så finns det ett kommando som körs när loopen har kört färdigt och innan skriptet fortsätter utanför loopen och det är kommandot else. OBS: Blanda nu inte ihop det med else som används vid selektioner.

Kodexempel: for-loop med else

summa = 0
for i in range (0, 15, 3):
    print(i)
    summa += i
else:
    print("Summan av alla talen är", summa)

Utskriften blir då.

Utskrift

0
3
6
9
12
Summan av alla talen är 30

I detta fallet så hade vi fått samma resultat och utskrift om vi hade skrivit koden på följande sätt;

Kodexempel: for-loop utan else

summa = 0
for i in range (0, 15, 3):
    print(i)
    summa += i

print("Summan av alla talen är", summa)

Återigen ett exempel på hur vi kan skriva kod på olika sätt för att få fram samma resultat. Lägg här märke till rad 6 där koden inte har någon indentering och därför inte tillhör loopen. Det finns tillfällen då else är extra intressant och det kikar vi på senare.

Vi har sett att det finns tre olika parametrar till vår for-loop och hittills har vi bara räknat uppåt. Det går naturligtvis också att räkna nedåt, det viktigaste då är att vi ser till att vi har ett korrekt startvärde och slutvärde så att det går att loopa mellan dessa tal. Går det inte att loopa så kommer inte loopen att köras.

Kodexempel: for-loop räknar nedåt

summa = 0
for i in range (10, 3, -3):
    print(i)
    summa += i

print("Summan av alla talen är", summa)

Vi kör vår loop från talet 10 till talet 3 där varje steg minskas med 3. Utskriften blir då.

Utskrift

10
7
4
Summan av alla talen är 21

Testa vad som händer om du byter plats på parameter 1 och 2 eller gör parameter 3 till positiv.

Uppgift: m04u01

Skriv ut alla tal från 1 till 10, i steg om 2, med hjälp av en for-loop.

Multiplicera sedan värdet på alla dessa tal och skriv ut svaret.

Vidareutveckling: kodkalendern 2021, lucka 1

Med m04u01 som grund så går det att bygga vidare för att lösa Unga programmerares kodkalender lucka 1 år 2021. Så det blir uppgiften, hitta den sexsiffriga pinkoden.

Uppgift: m04u02

Ulf har satt in 10 000kr på ett konto med 3 % årlig ränta, hur mycket pengar finns på kontot efter 15 år? Inga fler insättningar görs.
Välj själv hur du vill skriva ut svaret, med en enda rad efter färdig uträkning eller en rad för varje år.

Tips1: Under utveckling är det smart att skriva ut på varje rad för att se att du har tänkt, och beräknat, allt rätt.

Tips2: Om du inte vet hur du skall ställa upp din for-loop så fundera på hur du skulle lösa denna uppgiften på en matematiklektion utan miniräknare.

Fördjupning m04u02a [klicka för att visa]

Bygg ut applikationen så att sparbelopp, antal år och räntan går att mata in till systemet. Räntan vill jag ange som ett decimaltal.

Fördjupning m04u02b [klicka för att visa]

För att utveckla applikationen ytterligare och skapa en sparsimulator så skulle jag vilja att du fixar möjlighet att spara nya pengar varje år. Om Ulf sätter in 0kr på kontot från början, nysparar 15000kr/år (barn-/studiebidraget) till 6.5% ränta i 18 år så har han 486151kr på kontot. Detta utgår ifrån att han inte får ränta på detta års insatta pengar, men på alla pengar som fanns där när året började.

4.1.1 Nästlade iterationer

Genomgång [klicka för att visa]

Vi har tidigare kikat på hur vi kan nästla selektioner vilket innebär en, eller flera, selektioner i en annan selektion. På samma sätt kan vi göra med kontrollstrukturen iterationer. Vi kan dessutom blanda hur vi vill nästla selektioner och iterationer, allt beror på uppgiften vi skall lösa.

Här kommer ett exempel på hur man kan nästla iterationer.

Kodexempel: 6:an och 7:ans multiplikationstabeller

# 6:an & 7:ans multiplikationstabeller
# Den yttre loopen tar hand om första talet, 6:ans tabell, 7:ans tabell
for i in range(6, 8):
    # Den inre loopen tar hand om alla tal mellan 0 och 10
    for j in range(0, 11):
        print(f"{i} * {j} = {i*j}")

    print()     # Skapar tomrad mellan de olika "tabellerna"

Det som behöver fokuseras främst på är kommenterat i koden ovan. Utskriften av programmet kommer här.

Utskrift

6 * 0 = 0
6 * 1 = 6
6 * 2 = 12
6 * 3 = 18

//
// bortklippta rader
//

7 * 8 = 56
7 * 9 = 63
7 * 10 = 70

Här kommer ett exempel på en selektion i en iteration där vi loopar från 10 till 20 men istället för att ta tre steg så väljer vi att skriva ut vart tredje tal med summan som alla tal skapar. Om vi kör tre steg i loopen så missar vi ju att summera de tal som inte stegas igenom vilket gör att resultatet blir felaktigt.

Kodexempel: for-loop räknar nedåt

# Deklarerar variabler
summa = 0
start = 10
stopp = 20
print("\nVi loopar från {} till {}.".format(start, stopp))
# Loopar från start till stopp
for i in range (start, stopp+1):
    summa += i
    # Om i är jämnt delbart med 3 skriver vi ut en delberäkning
    if i % 3 == 0:
        print("När i är {} så är totalsumman {}".format(i, summa))
# else som tillhör loopen och körs när loopen har körts färdigt
else:
    print("När vi loopat färdigt så är summan {}".format(summa))

Det som behöver fokuseras främst på är kommenterat i koden ovan. Utskriften av programmet kommer här.

Utskrift

Vi loopar från 10 till 20.
När i är 12 så är totalsumman 33
När i är 15 så är totalsumman 75
När i är 18 så är totalsumman 126
När vi loopat färdigt så är summan 165

Kodexempel: for-loop räknar nedåt

# Deklarerar variabler
summa = 0
start = 10
stopp = 20
print("\nVi loopar från {} till {}.".format(start, stopp))
# Loopar från start till stopp
for i in range (start, stopp+1):
    summa += i
    # Om i är jämnt delbart med 3 skriver vi ut en delberäkning
    if i % 3 == 0:
        print("När i är {} så är totalsumman {}".format(i, summa))
# else som tillhör loopen och körs när loopen har körts färdigt
else:
    print("När vi loopat färdigt så är summan {}".format(summa))

Det som behöver fokuseras främst på är kommenterat i koden ovan. Utskriften av programmet kommer här.

Utskrift

Vi loopar från 10 till 20.
När i är 12 så är totalsumman 33
När i är 15 så är totalsumman 75
När i är 18 så är totalsumman 126
När vi loopat färdigt så är summan 165

Uppgift: m04u03

Skapa en multiplikationstabell som ritar ut alla tal upp till tians multiplikationstabell. Viktigt här är att göra en bra formatering så att alla siffror inte flyter ihop. Se gärna exempelutskrift nedan.

Utbyggnad 1:Låt användaren mata in valfritt heltal för att bygga sin egen multiplikationstabell.

Utbyggnad 2: Hitta ett sätt så att multiplikationstabellen inte kan vara större än 15x15. Fundera på om det finns olika sätt att göra detta?

Utbyggnad 3: Om användaren matar in ett negativt heltal så ritas ingen multiplikationstabell ut, fundera på vilka alternativa lösningar som kan användas för att ändå rita ut. abs() kan vara ett alternativ? Vilka andra finns?

Utbyggnad 4: Det är så enkelt att göra en multiplikationstabell som är 5x5, 10x10 eller 12x12, men hur skulle du göra om användaren vill ha en multiplikationstabell som är tex 12x6?

Utskrift

Multiplikationstabell
   1   2   3   4   5   6   7   8   9  10
   2   4   6   8  10  12  14  16  18  20
   3   6   9  12  15  18  21  24  27  30
   4   8  12  16  20  24  28  32  36  40
   5  10  15  20  25  30  35  40  45  50
   6  12  18  24  30  36  42  48  54  60
   7  14  21  28  35  42  49  56  63  70
   8  16  24  32  40  48  56  64  72  80
   9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100

4.1.2 Iteration som testmetod

Jag har tidigare nämnt att iteration ofta kan vara ett bra sätt att använda när vi kör tester på våra program. Vi skall kika på hur vi kan testa en uppgift som vi jobbade med i moment03. Uppgiften M03U04 handlade om att vi skulle hämta ett klockslag från datorn och sedan jämföra värdet på timmen för att se om det är före skoldag, efter skoldag eller om skoldagen pågår. Genom att skapa en iteration från 0 till 23 så är det lätt att se om vårt program fungerar som det är tänkt.

Kodexempel: for-loop för att testa applikation

# Loopar från klockan 0 till 23
for timme in range (0, 24):
    # Skriver ut vad klockan är men utan radbrytning
    print("Klockan är {}, ".format(timme), end="")
    if timme < 8:
        print("skoldagen har inte börjat.")
    elif timme > 16:
        print("skoldagen är slut.")
    else:
        print("skoldagen pågår.")

Utskriften blir då.

Utskrift

Klockan är 0, skoldagen har inte börjat.
Klockan är 1, skoldagen har inte börjat.
// bortklippt //
Klockan är 7, skoldagen har inte börjat.
Klockan är 8, skoldagen pågår
// bortklippt //
Klockan är 16, skoldagen pågår
Klockan är 17, skoldagen är slut.
// bortklippt //
Klockan är 22, skoldagen är slut.
Klockan är 23, skoldagen är slut.

Den största fördelen här är att det nu är möjligt att testa hela applikationen utan att göra en manuell inmatning 24 ggr. Dessutom är det enkelt att testa de gränser som är intressanta för oss. I exemplet ovan så är det ju timvärden 7, 8, 16, 17 som vi är mest intresserade av att testa.

Uppgift: m04u03b

Bygg vidare på multiplikationstabellen som vi gjorde tidigare. Det talet som användaren matar in är det antal multiplikationstabeller som skall skrivas ut. Om användaren skriver in 3 så skall fört multiplikationstabellen för 1x1 skrivas ut, sedan för 2x2 och slutligen för 3x3.

Utskrift [klicka för att visa]

Ange vilken multiplikationstabell: 3

Multiplikationstabell upp till 1x1
   1

Multiplikationstabell upp till 2x2
   1   2
   2   4

Multiplikationstabell upp till 3x3
   1   2   3
   2   4   6
   3   6   9

4.2 while-loopen

Genomgång [klicka för att visa]

Den andra typen av loop som vi skall gå igenom är while-loopen. Här är det villkoret som är det styrande för hur länge loopen skall köras.

Kodexempel: while-loop

tal = 1

while tal < 5:
    print(tal)
    tal += 1

I exemplet så ser vi att uttrycket är tal < 5 och så länge detta gäller så kommer loopen att köras ett varv till. När vi jobbar med while-loopen så måste vi se till att det värde som finns i uttrycket måste förändras, vilket sker på rad 5, annars kommer loopen att bli oändlig. Utskriften i vårt exempel blir då.

Utskrift

1
2
3
4

Svårare än så är inte while-loopen och det viktigaste är att hålla koll på uttrycket eftersom det avgör om loopen skall köras en gång till. På samma sätt kan vi använda else för att göra något när villkoret inte längre ger värdet True och loopen avbryts.

Kodexempel: while-loop med else

tal = 1

while tal < 5:
    print(tal)
    tal += 1
else:
    print("När vi har loopat klart så har tal värdet {}".format(tal))

Utskrift

1
2
3
4
När vi har loopat klart så har tal värdet 5

Använd else när det behövs.

Uppgift: m04u04

Skriv ut alla tal från 10 till 1 med hjälp av en while-loop.

Multiplicera sedan värdet på alla dessa tal och skriv ut svaret.

Uppgift: m04u05

Antalet råttor i en stad är 100 stycken, varje månad dubblas populationen av råttor, hur många månader dröjer det innan det finns en miljon råttor i staden? Lös uppgiften med en while-loop.

Tips: Under utveckling är det smart att skriva ut på varje rad för att se att du har tänkt, och beräknat, allt rätt.

Uppgift: Kodkalendern lucka 5

Testa nu att göra kodkalendern lucka nr5 från 2021.

Uppgift: m04e01 [klicka för att visa]

En "e"-uppgift?

Vad hände här? m04e01? Jo så här dags i kursen brukar det finnas elever som tycker loopar är lite lurigt och några som snabbare får koll på det. Uppgifterna som är namngivna e är sådana uppgifter som jag tidigare har givit elever som vill ha fler uppgifter att träna på. De kan vara av blandad nivå, ibland är de svåra, ibland är det typ samma uppgift som vi redan har löst fast på ett annat sätt.

Gör uppgiften om du vill, den finns där för att ge alla elever möjlighet att skaffa, och vässa, så många verktyg som möjligt.

Dessa uppgifter brukar inte ha någon lösning på hjälpsidan....

Bygg om m04u02 (Ulfs sparade pengar) så att den uppgiften körs med en whileloop.

4.2.1 Continue

Genomgång [klicka för att visa]

Ibland kan det vara så att vi vill använda en loop men av någon anledning inte genomföra en viss process ifall något uttryck gäller. Då kan vi använda kommandot continue som kommer hoppa över allt som kommer efter det kommandot i loopen och börja om loopen igen. Ett exempel;

Kodexempel: continue

tal = 0
while tal < 10:                 # kör så länge tal är mindre än 10
    tal += 1                    # öka tal med 1
    if tal % 2 == 0:            # om tal är jämnt delbart med 2 ..
      continue                  # .. starta om loopen
    print("Talet är", tal)     # skriv ut talet

print("Utanför loopen")

Utskrift

Talet är 1
Talet är 3
Talet är 5
Talet är 7
Talet är 9
Utanför loopen

Continue kan användas i både for-loopar och while-loopar.

Det finns ingen specifik uppgift för continue utan det kommer en efter avsnitt 4.2.3.

4.2.2 Break

Genomgång [klicka för att visa]

Kommandot break används på liknande sätt som continue fast istället för att börja om på nästa varv i loopen så avbryts loopen och programmet fortsätter efter loopen. Samma exempel som för continue fast med break.

Kodexempel: break

tal = 0
while tal < 10:                 # kör så länge tal är mindre än 10
    tal += 1                    # öka tal med 1
    if tal % 2 == 0:            # om tal är jämnt delbart med 2 ..
      break                     # .. avbryt loopen
    print("Talet är", tal)     # skriv ut talet

print("Utanför loopen")

Utskrift

Talet är 1
Utanför loopen

Uppgift: m04e02 [klicka för att visa]

Bygg om m04u05 (råttorna) så att den uppgiften körs med en for-loop.

Uppgift: m04e03 [klicka för att visa]

OBS: Denna uppgift kan upplevas lite klurig, kika på min punktlista nedan för att bygga ut/om uppgiften steg för steg.

Bygg ut uppgift m04u04 så att du;

  • Skriver ut talet och produkten för varje tal.
  • Bara multiplicerar jämna tal (använder continue).
  • Bryter (break) när produkten är över 500.

Hade detta gått att göra detta utan break & continue?

4.2.3 Aktivitetsdiagram och pseduokod för loopar

Genomgång [klicka för att visa]

AktivitetsdiagramI förra momentet lärde vi oss att skriva pseudokod och aktivitetsdiagram i sekvens och selektion. Nu har det blivit dags att lägga till iterationer (loopar). Egentligen är det uttrycket vi är intresserade av och sedan visar vi att det är en loop med hjälp av pilar. Jag visar med ett exempel och det är kodexempel: continue ovan som jag kommer använda som exempel.

Om vi skall skriva pseudokod för samma uppgift så kan den se ut så här.

  • Ge tal värdet 0
  • Om tal är mindre än 10
    • Öka talet med 1
    • Om tal inte är jämnt delbart med 2
      • Skriv ut talet
    • Annars kör ett varv till
  • Annars skriv ut att vi är utanför loopen

Som du ser är den lik aktivitetsdiagrammet, men man skulle också kunna skriva den på ett mer generellt sätt så att varje utvecklare själv kan välja vilken typ av loop som skall/kan användas. Då kan det se ut så här.

  • Loopa igenom alla tal från 1 till 10
  • Om talet inte är jämnt delbart med 2
    • Skriv ut talet
  • Skriv ut att vi är utanför loopen

Här finns inget rätt eller fel även om du i det första exemplet troligtvis styrs till att använda while-loopen och i det andra själv får välja vilken iteration du vill använda för att lösa uppgiften.

Avancerade algoritmer med flera eller djupa iterationer känns ofta lättare att följa med ett aktivitetsdiagram än med pseudokod.

Uppgift: m04u06

Denna uppgift kan kännas lite klurig men lös punkt för punkt nedan så går det lättare.

Låt användaren mata in följande tal;

  • Ett tal som loopen skall börja med.
  • Ett tal som loopen skall avsluta med.
  • Ett tal som inte skall skrivas ut.
  • Ett tal som skall avbryta loopen.

Bygg sedan detta program med en while-loop så att det fungerar enligt instruktionerna ovan.

Planera gärna uppgiften med aktivitetsdiagram eller pseudokod.

4.2.4 Felhantering, körtidsfel

Genomgång [klicka för att visa]

Tidigare har vi pratat om att syntaxfel är de fel som vi skriver i koden som gör att våra skript inte går att köra utan ger ett, eller flera, fel när vi försöker köra applikationen.

Nästa feltyp vi behöver lära oss ta hand om är körtidsfel och de är fel som kraschar en applikation medan den körs. Vi har stött på detta när vi matar in någonting annat än vad vår applikation förväntar sig. Ofta blir det fel när vi skall mata in ett heltal och matar in någonting som inte kan konverteras till ett heltal.

Det som löser detta problem för oss är en kontrollstruktur som egentligen är en variant av selektion och som passar väldigt bra ihop med iterationer. Strukturen är en try-except (try-catch i många andra programmeringsspråk) och den provar att göra någonting, om det fungerar så är allt frid och fröjd och applikationen kan fortsätta, fungerar det inte så har vi möjlighet att skriva kod som talar om vad vi vill skall hända då. En felaktig inmatning, eller en felaktig inläsning från en fil, gör ju att vår applikation kraschar lite senare och det vill vi ju inte, då är det bättre att ta kontroll på inmatningen så att den går rätt till. Vi kör ett exempel.

Kodexempel: try-except

# loopen kommer "alltid" köras eftersom uttrycket är True
while True:
    try:        # detta block är det som testas, blir det fel här...
        tal = int(input("Ange ett heltal: "))
        break   # avbryter loopen
    except:     # ... hamnar vi här istället
        print("Det blev fel, försök igen")
# Utanför loopen sker utskriften
print("Det korrekt inmatade talet är {}".format(tal))

Utskrift

Ange ett heltal: tre
Det blev fel, försök igen
Ange ett heltal: 3.2
Det blev fel, försök igen
Ange ett heltal: 3,2
Det blev fel, försök igen
Ange ett heltal: 3
Det korrekt inmatade talet är 3

Koden och kommentarerna borde räcka för att förklara vad som händer. Detta är ett smidigt sätt att undvika krascher i våra applikationer.

Uppgift: m04u07 (svårare)

Bygg vidare på m04u06 så att användaren inte kan mata in felaktiga värden. Kolla både att datatypen är rätt men också att de inmatade värdena är korrekta i förhållande till varandra, alltså att stoppvärdet är större än startvärdet (annars måste vi förändra steglängden så att den blir negativ) och att tal som skall hoppas över och avbryta loopen måste finnas inom intervallet mellan start- och stoppvärdet.

4.3 Listtyper

Genomgång [klicka för att visa]

Olika typer av listor är vanliga i de flesta programmeringsspråk. Orsaken till detta är att vi ofta behöver bearbeta en stor mängd data och då är det inte praktiskt att skapa variabler för all denna data. Tänk att en klass har genomfört ett prov och du nu skall göra ett antal beräkningar av denna data. Då är det inte vettigt att skapa en variabel för varje resultat; res1 = 14, res2 = 19 osv. För detta ändamål används någon form av lista. I python har vi fyra olika listtyper; list, tuple, set och dictionary. Det är främst de två första som vi kommer kika på och det är list som vi kommer lägga mest tid på att använda.

4.3.1 List

Genomgång [klicka för att visa]

En lista kan du se som en variabel med flera fack (element), i varje element kan det lagras ett värde. Om vi går tillbaka till exemplet om att samla provresultat så kommer varje resultat hamna i var sitt element i den listan som du har skapat. I de flesta listtyper kommer varje element ha ett id som gör att vi kan hålla ordning på i vilket element ett visst värde finns.

4.3.1.1 Skapa

Att skapa en lista är enkelt, du skapar en variabel men anger värden med hjälp av klammer och separerar värden med kommatecken.

Kodexempel: skapa list

resultat = [12, 19, 22, 4, 0]

På detta sättet skapar vi en lista med fem resultat.

4.3.1.2 Skriv ut hela

Om vi vill skriva ut vår lista så går det att skriva ut variabelns värde vilket kommer se ut på precis samma sätt som vi skrev in den.

Kodexempel: skriv ut list

resultat = [12, 19, 22, 4, 0]
print(resultat)

Utskrift

[12, 19, 22, 4, 0]

Det går också att skriva ut varje element för sig genom att loopa igenom listan.

Kodexempel: skriv ut list individuellt

resultat = [12, 19, 22, 4, 0]

# Loopar igenom resultat med en for-loop
for r in resultat:    # Låt r lagra nästa element i listan resultat
    print(r)

Utskrift

12
19
22
4
0

Det är också möjligt att lagra olika datatyper i en list.

Kodexempel: list med olika datatyper

data = [21, "Programmering01", [2, 3, 4, 5], False, 3.14]
print("Skriv ut innehållet:", data)
print("\nSkriv ut datatyperna i listan")
for d in data:
    print(d, "är av typen", type(d))

Utskrift

Skriv ut innehållet: [21, 'Programmering01', [2, 3, 4, 5], False, 3.14]

Skriv ut datatyperna i listan
21 är av typen <class 'int'>
Programmering01 är av typen <class 'str'>
[2, 3, 4, 5] är av typen <class 'list'>
False är av typen <class 'bool'>
3.14 är av typen <class 'float'>

I exemplet så skapar jag en lista med fem värden. Värt att notera är att list är en datatyp vilket gör det möjligt att lagra en lista i en lista.

4.3.1.3 Enskilt element

För att kunna anropa ett enskilt element i en lista så behöver dessa identifieras på något sätt. I en list så identifieras de med ett index och det kan vi använda om vi vill skriva ut ett särskilt värde. Indexen i en list börjar numreras från 0.

Kodexempel: list och index

cities = ["Göteborg", "Alingsås", "Borås"]
print("Pelle bor i", cities[1])
cities[1] = "Vårgårda"
print(cities)

Utskrift

Pelle bor i Alingsås
['Göteborg', 'Vårgårda', 'Borås']

Här visar jag hur du kan skriva ut värdet för index 1 (position 2) i cities och sedan ändra värdet på detta index.

Ibland kan det vara bra att kunna skriva ut både index och värdet. En sådan enkelt utskrift som nedan är inget vi vill ha i en färdig applikation men det kan vara skönt att göra utskriften under utveckling.

Kodexempel: värde och index i en list

cities = ["Göteborg", "Alingsås", "Borås"]
for index, value in enumerate(cities):
    print(index, value)

Utskrift

0 Göteborg
1 Alingsås
2 Borås

Enumerate() är en inbyggd funktion som skapar en räknare till den datatyp som vi itererar igenom.

Ofta vill vi göra något mer än att bara hämta index och värden från en lista. Då är det viktigt att förstå hur vi ändrar värdet som vi hämtat och hur vi ändrar värdet som finns lagrat i listan.

Kodexempel: förändra data i en lista

cities = ["Göteborg", "Alingsås", "Borås"]
for index, value in enumerate(cities):
    if value == "Borås":
        cities[index] = "Borås i listan"
        value = "Borås i loopen"
    print(index, value)

print(cities)

Utskrift

0 Göteborg
1 Alingsås
2 Borås i loopen
['Göteborg', 'Alingsås', 'Borås i listan']

4.3.1.4 Skriv ut del av list

Ibland kanske vi inte vill skriva ut hela listan utan bara en del.

Kodexempel: skriv ut list

resultat = [12, 19, 22, 4, 0]

print(resultat[0:3])    # Skriv ut de tre första elementens värden, starta på index 0, gå mot index 3.
print(resultat[-1])     # Skriv ut det sista värdet i listan
print(resultat[::-1])   # Vänd listan

Utskrift

[12, 19, 22]
0
[0, 4, 22, 19, 12]

När vi anger [-1] för det sista indexet så frågar vi efter ett specifikt värde och därför så returneras ingen lista utan endast ett värde.

4.3.1.5 Lägg till och ta bort

Hittills har vi bara kikat på listor som får alla sina värden när listan skapas. Det går bra att lägga till, eller ta bort, element efter att listan är skapad. Här kommer ett exempel på både hur man lägger till och tar bort ett element.

Kodexempel: lägg till och ta bort element i en list

cities = ["Göteborg", "Alingsås", "Borås"]
print(cities)

# append lägger till ett element sist i vår list
cities.append("Vårgårda")
print(cities)

# insert lägger till ett element på den plats vi vill i listan.
# Angivet index är där vi petar in vårt element
cities.insert(1, "Mölnlycke")
print(cities)

# Vi kan fråga efter index om vi känner till värdet
index_borås = cities.index("Borås")
cities.pop(index_borås)     # pop tar bort det index som anges
print(cities)

Utskrift

['Göteborg', 'Alingsås', 'Borås']
['Göteborg', 'Alingsås', 'Borås', 'Vårgårda']
['Göteborg', 'Mölnlycke', 'Alingsås', 'Borås', 'Vårgårda']
['Göteborg', 'Mölnlycke', 'Alingsås', 'Vårgårda']

Om vi skall kunna lägga till element från inmatning eller på något annat sätt så behöver vi kunna deklarera en variabel som list även om den är tom.

Kodexempel: deklarera en tom list

cities = []
print(cities)

cities.append("Alingsås")
print(cities)

Utskrift

[]
['Alingsås']

4.3.1.6 Funktioner

Python är synnerligen välbyggt för att jobba med datahantering och listor, därför finns det en hel mängd inbyggda funktioner.

Kodexempel: funktioner för list

resultat = [12, 19, 22, 4, 19, 13, 21, 18]

# Maxvärdet i list
print(max(resultat))

# Minvärdet i list
print(min(resultat))

# Summan av alla värden
print(sum(resultat))

# Antal element i vår list
print(len(resultat))

# Sortera vår list
resultat.sort()
print(resultat)

# Sorterar listan omvänt
resultat.sort(reverse=True)
print(resultat)

# Antal element med ett visst värde
print(resultat.count(19))

# Tömmer list
resultat.clear()
print(resultat)

Utskrift

22
4
128
8
[4, 12, 13, 18, 19, 19, 21, 22]
[22, 21, 19, 19, 18, 13, 12, 4]
2
[]

Uppgift: m04u08

Fyll en lista med heltal tills användaren matar in 0, då stoppas inmatningen. Skriv sedan ut summan av alla tal i listan, leta efter högsta och lägsta talet. Detta skall beräknas! Skriv sedan ut det du har beräknat och jämför med inbyggd funktion.

Tycker du att denna uppgift är svår, eller har svårt att komma igång med, så har jag delat upp den i två delar, lösningen skall bli den samma när du är klar.

Första delen

Skapa en lista med 5 heltal. Loopa igenom denna lista och beräkna summan av alla tal samt ta fram lägsta och högsta värdet. Detta skall beräknas! Skriv sedan ut det du har beräknat och jämför med inbyggd funktion.

Hjälp [klicka för att visa]

Att ge dina variabler min och max var sitt startvärde kan man göra på olika sätt. I vissa programmeringsspråk så finns det ett tydligt min och maxvärde för en viss datatyp men eftersom python automatiskt gör om en int till en long (longint) ifall värdet blir större än sitt max, eller mindre än sitt min-värde, så går det inte att använda denna tekniken.

Det säkraste sättet är att sätta första talet i listan till min- och max-värdet när vi börjar så att vi har korrekta värden att utgå ifrån.

Tips

Det är inte så dumt att skapa en pseudokod först för att planera din lösning innan du kodar den.

Andra delen

Låt nu användaren mata in tal till din lista, ta bort de tal du skapat tidigare, tills användaren matar in talet 0, då är användaren klar med inmatningen.

Se till att alla beräkningar från a-delen fortfarande fungerar.

Hjälp [klicka för att visa]

Skapa lämplig loop som avbryts på lämpligt sätt när användaren matar in talet 0. Detta värde (0) skall inte lagras i listan.

Uppgift: m04u09

Äntligen dags att ta fram tärningen och göra en sådan övning. Fråga användaren om hur många tärningsslag hen vill göra. Vi använder en vanlig tärning med värden 1-6. Simulera sedan dessa slag och lagra dem i en lista. Skriv sedan ut hur många slag det blev av varje värde, skriv ut detta på ett snyggt sätt.

Kodexempel: Slumptal

# Importera randint som gör att vi slumpa heltal
from random import randint
# Skriv ut ett slumpat tal mellan 1 och 100
print(randint(1, 100))

Utskrift

Slumpat tal mellan 1 och 100: 91

Uppgift: Kodkalendern (svårare)

När du nu kan använda listor så finns det oändliga möjligheter att lösa olika problem där listor och loopar är grunden för att hitta lösningen. I kodkalendern 2021 finns följande uppgifer som kan vara lämpliga att lösa;

  • lucka 6 (Beräkningar av tal i lista)
  • lucka 9 (Beräkningar av tal i lista)
  • lucka 10 (Stega igenom en lista beroende på värdet av talet)
  • lucka 12 (Tips: hantera strängen som en lista, loopa igenom alla index)
  • lucka 13 (Tips: Här kan du använda break/else för att avsluta ett test som är felaktigt)
  • lucka 16 (Palindrom, vända på en sträng som du hanterar som en lista)
Tänkt på att det finns svar att få och även en video där han går igenom hur han löser uppgiften.

Uppgift: m04e04

Här kommer en extrauppgift som du har möjlighet att bygga på hur långt du vill. Yatzy är ett klassiskt spel med fem tärningar, klassisk tärning 1-6, där det gäller att samla poäng genom att samla på olika serier av tärningsslag.

Börja med att att skapa fem slumpade tärningar i en lista. Skriv sedan ut din hand på valfritt sätt.

Första uppgiften är att kolla om det finns minst ett par bland dina fem tärningar. Använd gärna aktivitetsdiagram och/eller pseudokod för att planera hur du skall lösa detta.

  • Kan du visa vilket värde som blivit yatzy (1:or, 2:or osv..).
  • Kan du se om det är flera par?
  • Kan du se om det blivit någon triss?

Alla som har spelat yatzy vet att det är en hel del olika typer av slag som kan ge olika antal poäng. Att bygga upp hela detta spelet tar en stund och är väl omfattande för denna kursen. Hur hittar vi då en förenklad version av yatzy? Vi går naturligtvis till barnspelen och kikar på hur barn- och bamse-yatzy fungerar. Utifrån dessa regler så är det enklare att bygga fullt fungerande varianter av yatzy.

Barnyatzy [klicka för regler]

Bamseyatzy [klicka för regler]

4.3.2 Tuple

Genomgång [klicka för att visa]

Denna filmen är ingen ren genomgång av det som står i detta avsnitt om Tuple utan är mer byggd som exempel och förklaring på vad en Tuple är och hur den kan användas. Använd gärna filmen ihop med det som är skriveti avsnittet.

Tuple är nästa typ av lista som vi skall kika på. Det som är speciellt med en Tuple är att den får sina värden när den skapas och sedan kan den inte ändras på något sätt. Försöker vi ge ett element ett nytt värde så kommer du få error av typen;

Error

TypeError: 'tuple' object does not support item assignment

4.3.2.1 Skapa en tuple

Skillnaden på att skapa en tuple istället för en lista är att när vi skapar en tuple så skall den skapas med parentes istället för klammer.

Kodexempel: skapa tuple

weekdays = ("måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag", "söndag")

4.3.2.2 Skriva ut hela eller delar

Att skriva ut en tuple sker på samma sätt som med en list.

Kodexempel: skapa tuple

weekdays = ("måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag", "söndag")
print(weekdays)        # Hela tupeln
print(weekdays[0])     # Tupeln med index 0 (position 1)
print("\nEn dag på varje rad")
for w in weekdays:
    print(w)

Utskrift

('måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag', 'söndag')
måndag

En dag på varje rad
måndag
tisdag
onsdag
torsdag
fredag
lördag
söndag

4.3.2.3 Funktioner

Några funktioner som kan användas när vi jobbar med en tuple.

Kodexempel: skapa tuple

weekdays = ("måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag", "söndag")

# Hur många element det finns med ett visst värde
print(weekdays.count("tisdag"))

# Vilket index ett visst värde har
print(weekdays.index("tisdag"))

# storleken på en tuple
print(len(weekdays))

# ta bort en tuple
del weekdays

# Det går nu inte att skriva ut innehållet i vår tuple,
# den är helt borttagen och inte tömd som en list
# Istället får vi ett error "NameError: name 'weekdays' is not defined"
# print(weekdays)

Utskrift

1
1
7

Uppgift

Till denna del finns det ingen uppgift, allt du kan göra med en tuple kan du göra med en list, däremot kan det finnas tillfälle då den är användbar. Kanske skulle du kunna lagra de olika alternativen om du gör ett barn- eller Bamseyatzy. Låta en tuple hålla alla alternativa värden som färger eller figurer.

4.3.3 Set

Genomgång [klicka för att visa]

Denna filmen är ingen ren genomgång av det som står i detta avsnitt om Set utan är mer byggd som exempel och förklaring på vad en Set är och hur den kan användas. Använd gärna filmen ihop med det som är skriveti avsnittet.

Set är den tredje listtypen som vi pratar om. Det som är speciellt med den är att det inte får finnas dubbletter och att listan är osorterad (det är dock en sanning med modifikation, matar du in tal så sorteras den, men inte med strängar). Eftersom det inte finns några unika index i denna lista så kan vi inte skriva ut ett specifikt element ur vårt set. Kika på exemplet för att förstå hur det fungerar.

Kodexempel: set

orter = {"Vårgårda", "Alingsås", "Göteborg", "Lerum"}
print(orter)           # slumpvis utskrift, eftersom sets är osorterad
print(len(orter))      # Hur många orter finns i set

# Kolla om ett värde finns i vårt set
if("Alingsås" in orter):
    print("Ja, Alingsås finns i vårt set")

tomt_set = set()        # Skapar ett tomt set
tal = {4, 3, 1}         # Skapar ett set
print(tal)

tal.add(2)              # Lägger till värdet 2
print(tal)

# Lägger till värdet 2 igen, denna lagras inte eftersom talet 2 redan finns
tal.add(2)

for t in tal:           # Utskrift mha for-loopen
    print(t)

tal.remove(2)           # Ta bort talet 2, ger error om 2 inte finns
tal.discard(2)          # Tar också bort talet 2, ger inget error om det ej finns
print(tal)

tal.clear()             # Tar bort allt innehåll i vårt set
print(tal)

del tal                 # Tar bort set

# Kan inte skriva ut ett borttaget set (NameError: name 'tal' is not defined)
# print(tal)

Jag visar exempel på vad man kan göra med ett set i detta fallet men flera koder fungerar även på andra listtyper som tex if("Alingsås" in orter) vilket är användbart om vi skall kolla om ett värde skall finnas, eller inte får finnas.

Utskrift

{'Lerum', 'Alingsås', 'Vårgårda', 'Göteborg'}
4
Ja, Alingsås finns i vårt set
{1, 3, 4}
{1, 2, 3, 4}
1
2
3
4
{1, 3, 4}
set()

Så funkar ett set, fokus här är att inte få dubbletter och att det inte är viktigt i vilken ordning saker skapas. Skulle kunna användas för att kolla mailadresser, användarnamn eller andra saker som behöver vara unika.

Kodexempel: set, ett praktiskt användningsområde

# En lista med ett antal värden
l1 = [1, 6, 2, 3, 2, 5, 2, 1, 3, 1, 4, 5, 1, 4, 5, 6]
print(f"Antal tal: {len(l1)}, lista: {l1}")

# Gör om till ett set
s1 = set(l1)
print(f"Antal tal: {len(s1)}, set: {s1}")

# Gör om till lista
l2 = list(s1)
print(f"Antal tal: {len(l2)}, lista: {l2}")

Här använder jag set för att få fram unika siffor i min lista.

Utskrift

Antal tal: 16, lista: [1, 6, 2, 3, 2, 5, 2, 1, 3, 1, 4, 5, 1, 4, 5, 6]
Antal tal: 6, set: {1, 2, 3, 4, 5, 6}
Antal tal: 6, lista: [1, 2, 3, 4, 5, 6]

Uppgift: m04u10

Låt användaren mata in ett antal orter. Om orten redan finns lagrad så skall orten inte lagras igen. Skriv sedan ut samtliga orter, i bokstavsordning, som användaren matat in och hur många inmatningar användaren har gjort. Matar man in Alingsås två ggr så skall det räknas som två inmatningar, även om Alingsås endast lagras en gång.

4.3.4 Dictionary

Genomgång [klicka för att visa]

Denna filmen är ingen ren genomgång av det som står i detta avsnitt om Dictionary utan är mer byggd som exempel och förklaring på vad en Dictionary är och hur den kan användas. Använd gärna filmen ihop med det som är skriveti avsnittet.

Dictionary har en stark koppling mellan index, som du själv sätter, och det värde som är kopplat till index. Detta är en lämplig konstruktion för olika typer av uppslag.

Kodexempel: dictionary

points = {'A':20, 'B':17.5, 'C':15, 'D':12.5, 'E':10}
grade = input("Vilket betyg har du fått på kursen? ")
print("Du har angivit betyget {} som räknas om till poängen {}".format(grade, points[grade]))

# Nu kan vi lägga till F
points['F'] = 0

# Skriv ut hela dictionary, med både index och värde
print("\nOmvandlingslista")
for key, value in points.items():
    print("Betyget {} ger {:3.1f} poäng".format(key, value))

# Skriv ut endast värde
print("\nAlla värden")
for value in points.values():
  print(value)

# Skriv ut endast index
print("\nAlla index")
for key in points.keys():
  print(key)

# Ta bort ett element
points.pop('A')
# del points['A']   # Funkar på samma sätt

points.clear()      # Tömmer dictionary
print(points)       # Skriver ut tomt

del points          # Tar bort hela dictionary
# print(points)     # Ger error eftersom dictionary är borttaget

Utskrift

Vilket betyg har du fått på kursen? A
Du har angivit betyget A som räknas om till poängen 20

Omvandlingslista
Betyget A ger 20.0 poäng
Betyget B ger 17.5 poäng
Betyget C ger 15.0 poäng
Betyget D ger 12.5 poäng
Betyget E ger 10.0 poäng
Betyget F ger 0.0 poäng

Alla värden
20
17.5
15
12.5
10
0

Alla index
A
B
C
D
E
F
{}

Kodexempel: dictionary lagras i en lista

l_users = []                            # Listan där alla dict skall lagras

while True:
    print("\nNu skall du mata in en ny användare, avbryt inmatning genom att mata in tom sträng.")
    user = input("Mata in användarnamn: ")
    if len(user) < 1:                   # Om tom inmatning...
        break                           # ... avbryt inmatning
    pwd = input("Mata in lösenord: ")
    if len(pwd) < 1:
        break
    d = {'user': user, 'password': pwd}
    l_users.append(d)                   # Lägg till dict i listan

print("\nDu har avbrutit inmatningen.")
print(f"Här är listan med alla användare: {l_users}")

Utskrift

Nu skall du mata in en ny användare, avbryt inmatning genom att mata in tom sträng.
Mata in användarnamn: Anna
Mata in lösenord: qwerty

Nu skall du mata in en ny användare, avbryt inmatning genom att mata in tom sträng.
Mata in användarnamn: Bosse
Mata in lösenord: abc123

Nu skall du mata in en ny användare, avbryt inmatning genom att mata in tom sträng.
Mata in användarnamn: Cilla
Mata in lösenord: 12345678

Nu skall du mata in en ny användare, avbryt inmatning genom att mata in tom sträng.
Mata in användarnamn: 

Du har avbrutit inmatningen.
Här är listan med alla användare: [{'user': 'Anna', 'password': 'qwerty'}, {'user': 'Bosse', 'password': 'abc123'}, {'user': 'Cilla', 'password': '12345678'}]

Uppgift: m04u11 (svårare)

Mata in kurser och betyg i en lista, mha dictionary. Beräkna sedan ditt meritvärde utfrån dictionary points som finns i Kodexempel: dictionary.
Tips: Skapa dictionary för varje kurs med kopplat betyg och lägg dessa i en lista.

4.3.5 En cheat sheet på listor

OperationList (lista)Set (mängd)Tuple (tupel)Dictionary (ordlista)
Skapa en tom listamylist = []myset = set()mytuple = ()mydict = {}
Skapa en lista med två elementmylist = [1, 2]myset = {1, 2}mytuple = (1, 2)mydict={1:'a', 2:'b'}
Lägga till element i listamylist.append(3)myset.add(3)Inte möjligtmydict[3] = 'c'
Ta bort element ur listamylist.remove(1) eller del mylist[0]myset.remove(1) eller myset.discard(1)Inte möjligtdel mydict[1]
Uppdatera element i listanmylist[0] = 'ny'Inte direkt tillämpligtInte möjligtmydict[1] = 'ny'
Töm listamylist.clear()myset.clear()Inte möjligtmydict.clear()
Ta bort listadel mylistdel mysetdel mytupledel mydict
Skriva ut listan som den ser utprint(mylist)print(myset)print(mytuple)print(mydict)
Skriva ut ett element i listanprint(mylist[0])Inte direkt möjligtprint(mytuple[0])print(mydict[1])
Skriva ut alla element i listan genom en loopfor e in mylist: print(e)

e står för element

for e in myset: print(e)

Kom ihåg att elementen i ett set inte är i någon specifik ordning

for e in mytuple: print(e)

För att skriva ut varje nyckel-värdepar:

for k, v in mydict.items(): print(f"K: {k}, V: {v}")

Eller bara värden:

for value in mydict.values(): print(value)

Eller bara nycklarna:

for key in mydict.keys(): print(key)

I inlägget Användning av listor finns det lite fler exempel på hur man kan använda olika typer av listor för att analysera data.

4.4 Inlämningsuppgift

Genomgång [klicka för att visa]

Denna uppgift byggs på i flera delar. Du löser så många delar du kan och lämnar in den sista fungerande lösningen. I denna övning kommer jag testa dig på tekniker från detta och tidigare moment men framförallt testas du på problemlösning. Ta hand om en del i taget, klura ut vad jag vill att du gör, dela upp uppgiften i mindre delar och när du är helt klar med den delen så går du vidare till nästa. Du kommer inte vinna på att kika på flera delar åt gången. I de tidigare delarna så får du lite extra hjälp att komma igång medan de senare delarna kräver en del egen problemlösning för att få det att fungera. I varje del så får du se hur min utskrift ser ut när jag har löst programmet, du måste inte härma mig men det kan vara en vägledning för att du skall förstå uppgiften.

I uppgift a ligger fokus på iteration och selektion, i uppgift b ligger fokus på fler iterationer och även listor. Jag vill att du klarar av dessa två innan inlämning för att visa på kunskaper inom de delar som ingår i momentet.

Inlämningsinstruktioner

Innan du lämnar in uppgiften kolla att följande saker är gjorda;

  • Filen med källkod har rätt namn, klass_namn_moment04.py.
  • Lämna endast in den svåraste uppgiften som du har löst.
  • Applikationen körs utan error. Koden är rensad från testdata och ser ok ut att lämna in.
  • Källkoden är kommenterad. För din egen del se till att du kommenterar koden eftersom den hela tiden byggs på.
  • Skapa ett huvud i källkoden där du som en kommentar skriver ditt namn och klass, vilken uppgift som du har löst och sedan en kort utvärdering av lösningen/ditt arbete. Jag är extra intresserad över hur du har tänkt när du fått ta olika beslut. I denna uppgift så finns det i del b-e en fråga som jag vill att du besvarar. Gör detta i kodhuvudet.
  • Är du godkänd på aktivitetsdiagram och pseudokod sedan tidigare så behöver du inte göra det på denna uppgiften. Har du inte lämnat in sedan tidigare, eller inte är godkänd, så är det lämpligt att skapa sådana för någon vald algoritm. Tala om vilken algoritm du har avgränsat och lämnat in lösning för. Lämna in i textformat, bildformat eller pdf och namnge filen med ditt namn och momentets namn.

Exempel på kodhuvud

# Anders Andersson, 18TEx
# Moment04, uppgift d
# Det var en utmanade uppgift och jag klarade inte av sista tillägget.
# Det som var mest utmanande var hur jag skulle konvertera det som matades in...
# ....

Inlämningsuppgift moment04

Uppgiften är att bygga en applikation som beräknar olika saker kring en rektangel och ett rätblock. Den matematiska delen skall inte vara svår utan fokus ligger på problemlösning, iterationer och användning av listor.

Läs och lös en uppgift i taget.

Uppgift a [klicka för att visa]

Be användaren ange rektangelns två sidor, vi använder endast heltal. Skriv ut arean på rektangeln och skriv också ut ett meddelande ifall rektangeln är en kvadrat. Slutligen skall du på lämpligt sätt beräkna och skriva ut volymen på rätblock med den angivna rektangeln som bas och alla heltalshöjder mellan 1 och 10. Enhet behöver du inte ange, vill du göra det så går le, ae och ve bra (längdenhet, areaenhet, volymenhet).

Hjälp [klicka för att visa]

Här får du hjälp i form av pseudokod. Använd den gärna som exempel för kommentarer och skriv koden under.

# Be användaren mata in rektangelns två sidor
# Beräkna och skriv ut arean på rektangeln
# Om bägge sidorna är lika långa...
  # ... tala om att det är en kvadrat
# Loopa höjden från 1 till 10
  # Beräkna volymen och skriv ut den

Utskrift

Så här kan resultatet se ut när jag kör mitt program. Du måste inte göra exakt likadant.

Denna applikation gör ett antal beräkningar på en rektangel/rätblock.
Ange rektangelns ena sida: 5
Ange rektangelns andra sida: 5

Rektangeln har sidorna 5 och 5 vilket gör att arean är 25
Eftersom bägge sidorna är lika långa så är denna rektangel en kvadrat.

Höjden | Volymen
-----------------
     1 |      25
     2 |      50
     3 |      75
     4 |     100
     5 |     125
     6 |     150
     7 |     175
     8 |     200
     9 |     225
    10 |     250

Uppgift b [klicka för att visa]

När du har ett fungerande program från uppgift a så vill jag att detta program skall köras om och om igen tills användaren på något sätt, som du väljer, inte vill köra fler beräkningar.

Varje gång du har utfört en areaberäkning vill jag att du i en lista lagrar info om rektangelns sidor, area och ifall det är en kvadrat.

När användaren har valt att inte göra fler beräkningar skall alla beräkningar visas upp innan programmet avslutas.

Berätta i kodhuvudet hur du har löst den stora programloopen (den som styr hur länge användaren vill köra applikationen) och motivera ditt val.

Hjälp [klicka för att visa]

Här får du hjälp i form av pseudokod. Använd den gärna som exempel för kommentarer och skriv koden under.

# Skapa en loop som bryter när användaren inte vill göra fler beräkningar
  # Be användaren mata in rektangelns två sidor
  # Beräkna och skriv ut arean på rektangeln samt lagra i listan
  # Om bägge sidorna är lika långa...
    # ... tala om att det är en kvadrat och skriv detta i listan
  # Loopa höjden från 1 till 10
    # Beräkna volymen och skriv ut den
  # Fråga användaren om hen vill göra fler beräkningar
    # Om inte avryt loopen
# Skriv ut alla beräkningar

Utskrift

Så här kan resultatet se ut när jag kör mitt program. Du måste inte göra exakt likadant.

Denna applikation gör ett antal beräkningar på en rektangel/rätblock.
Ange rektangelns ena sida: 5
Ange rektangelns andra sida: 5

Rektangeln har sidorna 5 och 5 vilket gör att arean är 25
Eftersom bägge sidorna är lika långa så är denna rektangel en kvadrat.

Höjden | Volymen
-----------------
     1 |      25
###### bortklippt ######
    10 |     250
Vill du göra en beräkning till (J/N)? J

Ange rektangelns ena sida: 6
Ange rektangelns andra sida: 4

Rektangeln har sidorna 6 och 4 vilket gör att arean är 24

Höjden | Volymen
-----------------
     1 |      24
###### bortklippt ######
    10 |     240
Vill du göra en beräkning till (J/N)? N

Rektangeln har sidorna 5 och 5 vilket gör att arean är 25, rektangeln är en kvadrat.
Rektangeln har sidorna 6 och 4 vilket gör att arean är 24

Hjälp: Hur skall applikationen fungera? [klicka för att visa]

I denna film så visar jag hur mitt program fungerar och ger även lite tips på vad ni skall tänka på. Det som tillkommer i uppgift b, jämfört med uppgift a, är att det skall till en programloop (oändlig) som skall avbrytas när användaren matar in n på frågan om hen vill köra programmet en gång till. Dessutom skall en lista läggas till där alla svar skall samlas upp för att sedan skrivas ut. Nyckeln här är att INTE skapa listan inne i programloopen, då kommer den att nollställas varje gång programloopen kör ett varv till.

Hjälp: Johan kodar en liknande uppgift. [klicka för att visa]

Då flera elever tyckte att det var lite lurigt att få ihop inlämningsuppgiftens olika delar så har jag spelat in en film där jag löser en annan uppgift men där alla olika delar (programloop, körtidsfelshantering, inre loopar, listhantering mm) finns med. Genom att följa denna uppgift så har du sedan troligtvis de verktyg som du behöver för att få till inlämningsuppgift B.

Uppgift c [klicka för att visa]

Bygg vidare på uppgift b. Denna gång skall du låta användaren mata in vilka höjder som skall visas i volymuträkningen. Om användaren matar in 5 så skall volymen för alla höjder 1-5 visas. Du skall också hjälpa användaren att göra rätt genom att;

  • Om användaren matar in något annat än ett heltal så skall användaren få chansen igen.
  • Om användaren matar in ett negativt tal skall höjden sättas till 1
  • Om användaren matar in ett större tal än 10 så skall höjden sättas till 10.

Du behöver fortfarande inte ha denna säkerhet/logik kring inmatning av rektangelns två sidor.

Berätta i kodhuvudet hur du har tagit hand om, och hjälpt, användaren med inmatningen och motivera ditt val.

Hjälp [klicka för att visa]

För att mata in korrekta siffor för höjden på rätblocket så har du fått tre regler. Nu behöver du fundera på hur du skall hantera dessa regler. Tips från coachen är att du behöver använda dig av en teknik för att ta hand om eventuella körtidsfel. MEN alla tre reglerna går inte att lösa på detta sättet...

Här är det möjligt att du kan få hjälp med lösningen genom att använda dig av någon teknik för att skissa/rita fram en bra lösning med aktivitetsdiagram eller pseudokod.

Utskrift

Så här kan resultatet se ut när jag kör mitt program. Du måste inte göra exakt likadant.

Denna applikation gör ett antal beräkningar på en rektangel/rätblock.
Ange rektangelns ena sida: 5
Ange rektangelns andra sida: 5
Ange rätblockets höjd: tre
Du har gjort en felaktig inmatning, ange ett heltal
Ange rätblockets höjd: -3

Rektangeln har sidorna 5 och 5 vilket gör att arean är 25
Eftersom bägge sidorna är lika långa så är denna rektangel en kvadrat.

Höjden | Volymen
-----------------
     1 |      25
Vill du göra en beräkning till (J/N)? N
Rektangeln har sidorna 5 och 5 vilket gör att arean är 25, rektangeln är en kvadrat.

Tänk på att höjden -3 skulle sättas till 1.

Uppgift d [klicka för att visa]

Nu är det dags att bygga om applikationen en hel del, kan vara läge att spara en kopia av del c ifall du behöver backa och göra om. Ingen ny funktionalitet skall läggas till men nu vill jag att du i en, eller flera, listor lagrar rektangelns två sidor och den höjden du skall räkna upp till för varje rätblock. Se till att du får inmatningarna på det sätt som du vill. När användaren har matat in sina värden för ett önskat antal rätblock så skall alla uträkningar skrivas ut på samma sätt som förut.

Berätta i kodhuvudet hur du valt att lagra värden för sidorna och höjden samt motivera ditt val.

Utskrift

Utskrifterna kan i princip se ut på samma sätt som tidigare.

Uppgift e [klicka för att visa]

Dags för den sista delen som också är en liten blick in i nästa moment. Vi skall kika på funktioner och hur man kan skapa sina egna funktioner.

En egengjord funktion bygger man av kod som antingen är tydligt avgränsad (för beräkningar av area, omkrets, volym etc) eller för att det är en kodsnutt som återanvänds flera gånger (t.ex. kontroller för inmatning av flera tal). Inom programmeringen, och matematiken, pratar vi om en algoritm som är en begränsad uppsättning instruktioner för att lösa en uppgift. Fokus här är att lösa en uppgift, skall det utföras två uppgifter, beräkna area och omkrets, så kan/bör det skapas två funktioner.

Kodexempel: funktioner

# funktion omkrets
# inparameter: sida1 & sida2
# returvärde inget
def omkrets(s1, s2):
    print("Omkretsen av en rektangel med sidorna {} och {} är {}"
           .format(s1, s2, 2*(s1+s2)))

# funktion omkrets_retur
# inparameter: sida1 & sida2
# returvärde: omkretsen
def omkrets_retur(s1, s2):
    return 2*(s1+s2)

sida1 = 5
sida2 = 5

# ta emot det returnerade värdet
o = omkrets_retur(sida1, sida2)

# Anropar funktionen omkrets för utskrift
omkrets(sida1, sida2)

# Anropar funktionen omkrets_retur i utskriften
print("Omkretsen av en rektangel med sidorna {} och {} är {}"
       .format(sida1, sida2, omkrets_retur(sida1, sida2)))

Infoga en eller flera funktioner i din applikation på lämplig algoritm, några exempel finns i presentationstexten för funktioner.

Berätta i kodhuvudet hur du valt att använda funktioner hur det har fungerat.

Innan inlämning, se till att du har fungerande kod, att du har följt inlämningsinstruktionerna och att du har döpt alla filer på rätt sätt.