Villkor och loopar

By . Latest revision .

Vi har nu bra koll på variabler och datatyper i python. Vi känner till stränger, heltal, flyttal och boolska värden (sant eller falskt). Vi ska i denna övning titta på hur data flödar igenom våra program. Vi kommer titta på villkors-satsen if och på två olika sätt, for och while, för att upprepa delar av koden.

Vi rekommenderar att du kodar med i denna övning så du själv får känna på hur det är att skriva Python-kod.

#Villkor

Ofta vill vi ta reda på om våra variabler uppfyller vissa krav. Det kan vara om en heltalsvariabel är större än 10 eller om en strängvariabel är lika med en annan sträng. För att undersöka om våra variabler uppfyller dessa krav kan vi använda oss av en if-sats. Låt oss titta på hur en if-sats ser ut i Python.

number_of_apples = 13

if number_of_apples > 10:
    print("Du har mer än 10 äpplen")

# skriver ut: Du har mer än 10 äpplen

I kodexemplet ovan definierar vi först en variabel number_of_apples och sätter den lika med heltalet 13. Vi gör sedan en jämförelse mellan vår variabel number_of_apples och heltalet 10. Om vi läser ut raden, där vi gör jämförelsen, blir det ungefär “om antalet äpplen är större än 10 skriver vi ut ‘Du har mer än 10 äpplen’”.

Som vi ser ovan är raden som skriver ut ‘Du har mer än 10 äpplen’ inflyttat ett snäpp. Detta kallas för indentering. I Python används indentering som ett sätt att avgränsa det som hör till if-satsen. I exemplet nedan ser vi hur vi kan ‘avsluta’ if-satsen genom att flytta ut koden längst till vänster.

number_of_apples = 13

if number_of_apples > 10:
    print("Du har mer än 10 äpplen")

print("Nu är vi klara med if-satsen")

# skriver ut:
# Du har mer än 10 äpplen
# Nu är vi klara med if-satsen

I kodexemplet ovan skrivs det inte ut nått från if-satsen om vi har 10 eller färre äpplen, men det vore ju trevligt om vårt program även skrev ut ett meddelande till de med få äpplen. Så låt oss äta 4 äpplen och titta på nedanstående exempel.

number_of_apples = 9

if number_of_apples > 10:
    print("Du har mer än 10 äpplen")
else:
    print("Du har nog varit hungrig och ätit upp dina äpplen")

print("Nu är vi klara med if-satsen")

# skriver ut:
# Du har nog varit hungrig och ätit upp dina äpplen
# Nu är vi klara med if-satsen

Om vi läser upp ovanstående exempel blir det ungefär: “om antalet äpplen är större än 10 skriver vi ut ‘Du har mer än 10 äpplen’, annars skriver vi ut ‘Du har nog varit hungrig och ätit upp dina äpplen’”. Om vi istället vill kolla att antalet äpplen ligger inom ett intervall kan vi använda ytterligare ett villkor i vår if-sats. Detta gör vi genom att använda konstruktionen elif.

number_of_apples = 9

if number_of_apples > 10:
    print("Du har mer än 10 äpplen")
elif 5 < number_of_apples <= 10:
    print("Du blev snabbt mätt och åt bara upp några av dina äpplen")
else:
    print("Du har nog varit hungrig och ätit upp dina äpplen")

print("Nu är vi klara med if-satsen")

# skriver ut:
# Du blev snabbt mätt och åt bara upp några av dina äpplen
# Nu är vi klara med if-satsen

Notera 5 < number_of_apples <= 10, i många andra programmeringsspråk funkar inte det. Då behöver man istället använda and, number_of_apples > 5 and number_of_apples <= 10

Vi har även möjligheten att kombinera villkor för att få ett mer avancerat flöde i våra program. Om vi nu också vill kolla vilken sorts frukt vi har kan det se ut på följande sätt.

type_of_fruit = "päron"
number_of_fruits = 13

if number_of_fruits > 10:
    if type_of_fruit == "äpple":
        print("Du har mer än 10 äpplen")
    else:
        print("Du har mer än 10 frukter")

    print("Nu är vi klara med den inre if-satsen")

print("Nu är vi klara med den yttre if-satsen")

# skriver ut:
# Du har mer än 10 frukter
# Nu är vi klara med den inre if-satsen
# Nu är vi klara med den yttre if-satsen

Vi har nu tittat på hur en if-sats kan se ut i python och hur det kan styra flödet av data i våra program. Ett sätt att få en överblick över flödet är att rita så kallade flödesdiagram (flow charts). Det enklaste sättet är att rita på ett blankt papper och det ger en bra möjlighet för att tänka över det problem, som vi löser med Python-kod. Ett exempel på flödesdiagram för ett kodexempel syns nedan.

number_of_apples = 9

if number_of_apples > 10:
    print("Du har mer än 10 äpplen")
else:
    print("Du har nog varit hungrig och ätit upp dina äpplen")

print("Nu är vi klara med if-satsen")

# skriver ut:
# Du har nog varit hungrig och ätit upp dina äpplen
# Nu är vi klara med if-satsen
Flödesdiagram för en if-sats.

Flödesdiagram för en if-sats.

Ytterligare ett bra sätt att förstå hur en if-sats exekveras är att använda vi rekommenderade i kmom01. Nedan finns exemplet i visualiseringsverktyget.

Exemplet i fullskärm.

Andreas visar hur if-else exekveras.

#For-loop

Nu har vi tittat på hur vi kan styra flödet av data genom våra program med villkor och programmeringskonstruktionen if-satser. I detta avsnitt ska vi kolla på hur vi kan upprepa delar av koden med hjälp av konstruktionerna for, range och in. En for-loop är en konstruktion för att upprepa en del av koden ett bestämt antal gånger. Så vet vi till exempel att vi vill skriva ut en text 10 gånger är for-loopen ett perfekt verktyg istället för att manuellt använda print() 10 gånger.

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

print("Jag är klar med loopen")

# skriver ut:
# siffrorna 0-9 i följd
# Jag är klar med loopen

Vi noterar att vi skriver ut siffrorna 0-9 och kanske inte som väntat 1-10. I Python och många andra programmeringsspråk är talföljder och liknande konstruktioner 0-indexerade. Det viktigaste är att vi vet om det och vi kommer senare under kursens gång titta mer på detta. Vi ser även att vi här, precis som med if-satser, använder indentering för att avgränsa det som hör till for-loopen.

Vi har alltså nu en konstruktion som upprepar det som finns inuti for-loopen ett bestämt antal gånger. Om vi kombinerar detta med det vi lärde oss om if-satser kan vi redan nu skapa avancerade flöden i våra program. Om vi anger två siffror till range() får vi siffrorna däremellan till svar. Här räknas number_of_apples-variabeln upp från 3 till 15 och med hjälp av if-satsen skriver vi ut olika meddelanden.

for number_of_apples in range(3, 15):
    if number_of_apples > 10:
        print("Du har mer än 10 äpplen")
    elif 5 < number_of_apples <= 10:
        print("Du blev snabbt mätt och åt bara upp några av dina äpplen")
    else:
        print("Du har nog varit hungrig och ätit upp dina äpplen")

Exemplet i fullskärm.

Om vi bara vill göra något ett bestämt antal gånger utan att bry oss om index i kan vi använda oss av _ istället för i enligt nedan. Detta gör att vi inte behöver skapa en variabel som tar plats i minnet på datorn och som förvirrar personer som läser koden.

for _ in range(5):
    print("Python är ett spännande programmeringsspråk")

# skriver ut:
# Python är ett spännande programmeringsspråk 5 gånger

Vi kan även loopa över annat än talföljder och vi kommer senare i kursen lära oss många olika konstruktioner som vi kan loopa över. I nedanstående exempel loopar vi igenom en sträng bokstav för bokstav med hjälp av samma in konstruktion som vi använde för talföljderna.

for letter in "räksmörgås":
    if letter in "åäö":
        print(letter)

#skriver ut:
# ä
# ö
# å

Notera att vi använder in konstruktionen även i en if-sats för att kolla om bokstaven finns i en annan sträng. in kan alltså användas på olika sätt tillsammans med både villkor och loopar. Vi kommer under kursens gång tillbaka till in flertalet gånger och ser många användningsområden. Så om det känns lite magiskt nu kommer det att sätta sig under kursens gång.

För att kolla om ett värde inte finns kan vi använda nyckelordet not tillsammans med in.

non_letters = ""
for letter in "räksmörgås":
    if letter not in "åäö":
        non_letters += letter
print(non_letters)

#skriver ut:
# rksmrgs

Andreas visar hur for-loopar exekveras.

#For-loop med input

Försök själv att skriva ett program som gör följande. Be användaren skriva en ett ord, skapa en ny sträng som innehåller ordet användaren skrev in fast med en punkt efter varje bokstav och skriv sen ut den nya strängen. T.ex. om användaren skriver in “apa” ska programmet skriva ut “a.p.a.”.

Om du undrar hur man kan lösa den eller har fastnat kan du kolla på videon där Andreas löser uppgiften.

Andreas löser problemställningen.

#For-loop med enumerate

Vi kan med for-loopen iterera över en sträng för att få ett tecken i taget.

result = ""
string = "Python"
print("The letters in " + string + " are: ")
for character in string:
    result += character + ","    
print(result)

#ger utskriften P, y, t, h, o, n,

Ibland vill vi, i samband med att vi itererar över ex-vis en sträng, även hålla ordning på vilken iteration i ordningen det är. För att lösa detta finns funktionen enumerate(). Denna funktion lägger till en räknare och ger som resultatet ett sk. uppräkningsbart objekt (eng enumerated object), dvs ett objekt som innehåller två delar ett heltal (räknaren) och elementet (i en sträng blir det ett tecken).

...
for counter, element in enumerate(the_string)
    pass

# counter kommer att ges värdet 0 och räknas upp med 1 för varje iteration
# element kommer att ges ett tecken i taget med start på det första (som finns på position/index 0)

Fundera över vilken utskrift vi får om vi exekverar

the_string = "abc"
result = ""
for counter, element in enumerate(the_string):
    result += str(counter) + "," + element + "\n"
print(result)

Svaret är:
0,a
1,b
2,c

Anta att vi har behov av att bestämma och presentera de positioner/index där det finns mellanslag dvs ’ ‘, i en sträng. Då kan vi t.ex lösa detta genom att använda enumerate()-funktionen i samband med for-loopen.

result = ""
string = "This is an example of using enumerate"
for index, character in enumerate(string):
    if character == ' ':
        result += str(index) + " "
print(result)

#ger utskriften 4 7 10 18 21 27 

Lös uppgiften att givet ett inmatat lösenord bestämma vilka positioner/index som det finns något av specialtecknen @, £, $, #, %, &, ?, !, *. Du ska skapa en sträng som innehåller varje special-tecken tillsammans med dess index.
Ex-vis om lösenordet är “&df3#!bj6!” ska den resulterande strängen vara “&:0 #:4 !:5 !:9 “

Betty visar hur man hittar specialtecken i lösenord

#While-loop

Vi använde for-loopen för att upprepa delar av ett program ett bestämt antal gånger. Om vi inte på förhand vet exakt hur många gånger vi vill upprepa kan vi använda oss av en while-loop. Vi måste dock ha ett villkor som är sant så länge vi vill upprepa den specifika delen av programmet. I nedanstående kodexempel loopar vi så länge number är mindre än 20 och varje gång vi fortsätter loopen dubblerar vi number.

number = 2

while number < 20:
    print(number)
    number = number + number

# skriver ut: 2 4 8 16

Det viktiga med en while-loop är att vi någon gång avslutar loopen för annars kommer den fortsätta i all oändlighet eller tills datorn stängs av. Vi avslutar loopen genom att ändra så att villkoret är falskt. I exemplet ovan avslutar vi alltså loopen när number blir 20 eller större.

while-loopar kan även användas för att ta emot indata från användaren. Om vi vill ta emot indata tills användaren skriver in ett specifikt värde kan vi använda break när användaren skriver in detta värde.

Andreas visar hur while-loopar fungerar.

Vi har tidigare sett hur vi använder input och hur vi konverterar data från en sträng till ett heltal. I while-loopen bryter vi mot regeln ovan att vi skulle ha ett villkor som någon gång avslutas. Villkoret True blir aldrig falskt och då avslutas while-loopen aldrig, men vi använder konstruktionen break för att avsluta. Inne i loopen är det första vi gör att kolla om användaren har skrivit in värdet för avslut (q), om användaren har gjort det avslutar vi programmet. Annars skriver vi ut ett meddelande baserat på de if-satser vi har sett tidigare.

while True:
    user_input = input("Skriv in antal äpplen (eller q för avslut): ")
    if user_input == "q":
        print("Du är nu klar med att äta äpplen.")
        print("Hej då!")
        break
    else:
        number_of_apples = int(user_input)
        if number_of_apples > 10:
            print("Du har mer än 10 äpplen")
        elif 5 < number_of_apples <= 10:
            print("Du blev snabbt mätt och åt bara upp några av dina äpplen")
        else:
            print("Du har nog varit hungrig och ätit upp dina äpplen")

På rad 8 i koden ovan gör vi om variabeln user_input från en sträng till ett heltal med hjälp av int(). Då data som finns i variabeln kommer från en användare kan vi inte lita på att variabeln innehåller ett heltal. Om vi skriver in något annat än ett heltal (till exempel bokstaven ‘g’) får vi följande fel i python.

Traceback (most recent call last):
  File "while.py", line 23, in <module>
    number_of_apples = int(user_input)
ValueError: invalid literal for int() with base 10: 'g'

I python finns en konstruktion som kan rädda oss från såna fel. Konstruktionen heter try-except och fungerar så att vi har två delar ungefär som en if-sats. En del när allt går som vanligt och en del för när det går åt skogen.

try:
    number_of_apples = int(user_input)
except ValueError:
    print("Oj! Du skrev inte in en siffra.")

I koden ovan försöker vi omvandla user_input till ett heltal, om detta inte går får vi ett ValueError som vi såg i felmeddelandet. I except skriver vi bara ut att det blev fel och fortsätter. Ett uppdaterat kodexempel med felhantering ses nedan. Notera att vi använder continue för att hoppa till nästa upprepning i while-loopen. Vi har tidigare sett break som avslutar hela loopen, continue avslutar bara den nuvarande upprepning och fortsätter sedan med nästa upprepning.

while True:
    user_input = input("Skriv in antal äpplen (eller q för avslut): ")
    if user_input == "q":
        print("Du är nu klar med att äta äpplen.")
        print("Hej då!")
        break
    else:
        try:
            number_of_apples = int(user_input)
        except ValueError:
            print("Oj! Du skrev inte in en siffra.")
            continue

        if number_of_apples > 10:
            print("Du har mer än 10 äpplen")
        elif 5 < number_of_apples <= 10:
            print("Du blev snabbt mätt och åt bara upp några av dina äpplen")
        else:
            print("Du har nog varit hungrig och ätit upp dina äpplen")

Exemplet i fullskärm.

#Ett simpelt tärningsspel

Skapa ett litet program som slår två tärningar och skriver ut dess värden, tills användaren säger till programmet att sluta. Du kan använda dig av modulen random för att representera tärningarna. Du kan slumpa fram ett värde mellan 1 och 6 på fölajnde sätt.

import random

MIN = 1
MAX = 6

dice_value1 = random.randint(MIN, MAX)
print(dice_value1)

Första raden inkluderar färdig kod för att slumpa värden. random.randint(MIN, MAX) anropar funktionen randint som ligger i random modulen, den returnerar ett slumpmässigttal mellan de två heltalen som skickas in till funktionen. I vårt fall 1 och 6.

Gör detta två gången i en loop och skriv ut de slumpade värdena fram tills användaren indikerar att programmet ska avslutas.

Om du fastnar eller bara vill se en lösning kan du kolla på videon nedanför där Andreas skriver koden för programmet.

Andreas visar hur man kan skapa ett simpelt tärningsspel.

#Avslutningsvis

Vi har i denna övning tittat på konstruktioner i python som låter oss styra flödet av data i våra program. Vi använder if för att jämföra värden och beroende på utfallet av jämförelsen körs olika delar av programmet. for-loopen används för att upprepa en del av koden ett bestämt antal gånger och vi kan loopa genom talföljder och strängar. while-loopen används för att loopa tills ett villkor går från sant till falskt. När villkoret är falskt avslutas upprepningen. Vi har även tittat på hur vi kontinuerligt kan ta emot indata från användaren tills användaren skriver in ett bestämt värde och då bryta loopen med hjälp av break.

if, for och while konstruktioner finns i de flesta programmeringsspråken. Dessa konstruktioner används för att styra flödet av data och utgör stora delar av de program vi kommer skriva i resten av kursen och vidare fram i programmet.

Alla kodexempel från denna övningen finns i kursrepot för python-kursen.

#Revision history

  • 2020-09-09: (C, aar) Uppdatera villkor med and till pythonic kod.
  • 2020-05-12: (B, aar) Uppdaterad inför H20.
  • 2017-05-29: (A, efo) Första utgåvan inför kursen python H17.

Document source.

Category: python.