Osa 2

Enkla loopar

Vi har nu undersökt if-satser som gör det möjligt för oss att skriva program där olika block körs i olika situationer (alternativ). Ett annat viktigt koncept inom programmering är repetition (eller iteration). Alternativ och repetition är två grundläggande konstruktioner som varje programmerare förväntas kunna. De är kontrollstrukturer – de ger dig möjlighet att påverka vilka kodrader som ska köras och när. Medan if-satser låter dig välja mellan olika delar av kod, används repetition för att köra delar av koden flera gånger. Programmet går alltså tillbaka till en viss rad i koden ett antal gånger.

När man pratar om repetition i programmeringssammanhang använder man ofta det engelska begreppet loop även om det finns ett svenskt begrepp (slinga, silmukka på finska). En iteration är en "runda" i loopen – det vill säga när koden körs från början till slutet en gång.

I den här delen presenterar vi en enkel while-loop. Dess struktur påminner om if-satsen. I nästa del dyker vi djupare in i de möjligheter som loopar ger.

Vi tar en titt på ett program som ber användaren att mata in ett tal som sedan skrivs ut upphöjt till två. Programmet körs tills användaren matar in -1:

while True:
    tal = int(input("Ge ett tal, -1 avslutar programmet: "))

    if tal == -1:
        break

    print(tal ** 2)

print("Tack och hej!")

Så här kan det se ut när programmet körs:

Exempelutskrift

Ge ett tal, -1 avslutar programmet: 2 4 Ge ett tal, -1 avslutar programmet: 4 16 Ge ett tal, -1 avslutar programmet: 10 100 Ge ett tal, -1 avslutar programmet: -1 Tack och hej!

Som du ser ovan, frågar programmet om ett tal flera gånger tack vare while-satsen. När användaren anger siffran -1 kommer break-instruktionen att köras. Den gör att loopen genast avbryts och programkörningen fortsätter efter while-blocket.

En av de viktigaste sakerna att komma ihåg när man jobbar med while-loopar är att man måste se till att loopen avslutas i något skede. Annars kan vi få evighetsmaskiner, där loopen fortsätter för evigt (eller ja, tills vi stänger av programmet). Vi ändrar lite på ovanstående exempel för att åstadkomma en sådan situation:

tal = int(input("Ge ett tal, -1 avslutar programmet: "))
while True:
    if tal == -1:
        break

    print(tal ** 2)

print("Tack och hej!")

I den här versionen frågar programmet användaren efter talet utanför loopen. Om användaren matar in något annat tal än -1 kommer loopen aldrig att avslutas. Vi har en oändlig loop vilket i princip betyder att koden körs oavbrutet, förevigt:

Exempelutskrift

Ge ett tal, -1 avslutar programmet: 2 4 4 4 4 4 4 4 4 (fortsätter oändligt...)

Följande program har en mycket liknande struktur jämfört med exemplet ovan, men för användaren ser det ganska annorlunda ut. Det här programmet låter användaren fortsätta endast då den korrekta pin-koden 1234 anges:

while True:
    kod = input("Ange pin-kod: ")
    if kod == "1234":
        break
    print("Fel! Försök igen")

print("Korrekt pin-kod")
Exempelutskrift

Ange pin-kod: 0000 Fel! Försök igen Ange pin-kod: 9999 Fel! Försök igen Ange pin-kod: 1234 Korrekt pin-kod

Loopar och hjälpvariabler

Vi gör nu pin-kodsexemplet en aning mer realistiskt. Det här exemplet tillåter användaren endast tre försök i att ge korrekt pin-kod.

Programmet består av två hjälpvariabler: forsok håller reda på hur många gånger användaren angett en pin-kod och lyckades är antingen True eller False beroende på om användaren har matat in den korrekta koden eller inte.

forsok = 0

while True:
    kod = input("Ange pin-kod: ")
    forsok += 1

    if kod == "1234":
        lyckades = True
        break

    if forsok == 3:
        lyckades = False
        break

    # vi kommer hit om pin-koden är fel OCH tre försök inte ännu gjorts
    print("Fel! Försök igen")

if lyckades:
    print("Korrekt pin-kod")
else:
    print("För många försök...")
Exempelutskrift

Ange pin-kod: 0000 Fel! Försök igen Ange pin-kod: 1234 Korrekt pin-kod

Exempelutskrift

Ange pin-kod: 0000 Fel! Försök igen Ange pin-kod: 9999 Fel! Försök igen Ange pin-kod: 4321 För många försök...

Loopen avslutas antingen då pin-koden är korrekt eller maxantalet försök har uppnåtts. Efterföljande if-sats kollar variabeln lyckades värde och skriver ut ett meddelande baserat på det.

Att introducera loopar i ett program ökar risken för buggar. Därför är det viktigt att senast nu börja vänja dig vid att utnyttja print-satser i debuggningssyfte – dem såg vi på i den första delen av denna modul.

Vi kikar på ett nästan identiskt program som i det föregående exemplet. Det finns dock en märkbar skillnad:

forsok = 0

while True:
    kod = input("Ange pin-kod: ")
    forsok += 1

    if forsok == 3:
        lyckades = False
        break

    if kod == "1234":
        lyckades = True
        break

    print("Fel! Försök igen")

if lyckades:
    print("Korrekt pin-kod")
else:
    print("För många försök...")

Den här versionen fungerar konstigt när användaren anger den korrekta koden på det tredje försöket:

Exempelutskrift

Ange pin-kod: 0000 Fel! Försök igen Ange pin-kod: 9999 Fel! Försök igen Ange pin-kod: 1234 För många försök...

Nu borde vi alltså reda ut det här problemet. Några print-satser borde hjälpa oss att debugga – så låt oss lägga till sådana i loopen:

while True:
    print("while-blocket inleds:")
    kod = input("Ange pin-kod: ")
    forsok += 1

    print("försök:", forsok)
    print("villkor 1:", forsok == 3)
    if forsok == 3:
        lyckades = False
        break

    print("kod:", kod)
    print("villkor 2:", kod == "1234")
    if kod == "1234":
        lyckades = True
        break

    print("Fel! Försök igen")
Exempelutskrift

while-blocket inleds: Ange pin-kod: 2233 försök: 1 villkor 1: False kod: 2233 villkor 2: False Fel! Försök igen while-blocket inleds: Ange pin-kod: 4545 försök: 2 villkor 1: False kod: 4545 villkor 2: False Fel! Försök igen while-blocket inleds: Ange pin-kod: 1234 försök: 3 villkor 1: True För många försök...

Från utskriften ovan märker vi att under den tredje iterationen kommer villkoret i den första if-satsen att vara sant och därmed hinner vi aldrig fram till den andra if-satsen i och med att loopen avslutas. Därmed kontrolleras koden aldrig:

  while True:
    # ....

    # det här blocket kommer för tidigt
    if forsok == 3:
        lyckades = False
        break

    # vi når inte hit på det tredje försöket
    if kod == "1234":
        lyckades = True
        break

Ordningen på if-satser eller grenar inom if-satser är vanliga orsaker till buggar – framför allt när man nästlar if-satser innanför loopar. Debuggning med hjälp av print-satser hjälper förvånansvärt ofta.

Kombinera strängar med +-operatorn

Exemplet ovan använde hjälpvariabeln forsok för att hålla koll på hur många gånger användaren skrivit in en pin-kod:

forsok = 0

while True:
    kod = input("Ange pin-kod: ")
    forsok += 1
    # ...

Variabeln tilldelas värdet noll utanför loopen och varje iteration ökar dess värde med ett.

Man kan också göra motsvarande sak med strängar. Programmet kan till exempel hålla koll på de pin-koder användaren angett:

koder = ""
forsok = 0

while True:
    kod = input("Ange pin-kod: ")
    forsok += 1
    koder += kod + ", "
    # ...

Hjälpvariabeln kan tilldelas värdet "" – det vill säga en tom sträng:

koder = ""

För varje iteration blir strängen längre i och med att koden användaren angett läggs till i slutet av strängen tillsammans med ett komma och ett mellanslag.

    kod = input("Ange pin-kod: ")
    koder += kod + ", "

Om användaren anger koderna 1111 2222 1234 kommer värdet på koder till slut att vara:

Exempelutskrift

1111, 2222, 1234,

Loading...
:
Loading...

Log in to view the quiz

Vänligen svara på en kort enkät som behandlar den här veckans material.

Loading...
:
Loading...

Log in to view the quiz

Du har nått slutet av den här delen!

Se dina poäng genom att klicka på cirkeln nere till höger av sidan.