- Kursmaterial
- Planering
- Arbete
- Kunskapsdokument
- Andra kurser
- Om Kursolle
3. Moment03 - Selektioner och operatorer
Info
Till detta moment finns en sida med lösningsförslag och videoklipp.
För de elever som vill utmanas ytterligare med fler och/eller svårare uppgifter hittar dessa här.
I alla programmeringsspråk så är selektioner ett centralt begrepp. Selektioner eller villkorssatser brukar vi kalla det på svenska, Control Structures heter det på engelska. Oavsett vad det kallas så handlar det om val och att tala om för programmet att göra olika saker beroende på ett specifikt villkor.
I detta moment kommer vi lära oss att förstå strukturen kring villkorssatser men också lära oss att skriva de villkor som styr dem.
3.1 if
Villkor låter oss styra vad programmet gör. En if-sats kör kod om uttrycket efter if är sant. I Python avgör kolon (:) och indentering (inryck) vilken kod som hör till villkoret.
Vi gör ett enkelt exempel;
Kodexempel: enkel if-sats
# Fråga efter ålder och lagra denna i variabeln age
age = int(input("Ange din ålder: "))
# Om age är större än 17 ...
if age > 17:
# ... Skriv ut meddelande
print("Du är myndig och får rösta")
# Skrivs ut oavsett om if-satsens villkor är rätt eller ej
print("Programmet avslutas")
Det uttryck som skrivs ihop med en if-sats skrivs alltid på ett sådant sätt att det ger ett svar som är sant eller falskt, true/false, och detta uttryck får datatypen boolean vilket vi snabbt nämnde i förra momentet. Mer om uttryck och operatorer kommer senare i detta moment.
Resultatet beror på vad du matar in, men här kommer två exempelutskrifter.
Utskrift
Ange din ålder: 16 Programmet avslutas
Utskrift
Ange din ålder: 22 Du är myndig och får rösta Programmet avslutas
Info om utskrifter
Det som skrivs in efter kolon (:) i mina exempel är det som användaren matar in i konsolen.
Kom ihåg
- Uttrycket efter
ifska kunna bli sant/falskt (t.ex.age > 17). - Koden som tillhör if-satsen är indenterad.
Som du ser på rad 5 i koden ovanför så bygger vi upp ett villkor med if
och sedan skrivs ett uttryck. Koden som tillhör if-satsen är indenterad (vanligtvis fyra mellanslag). Var konsekvent i hela filen. Du som har kodat i andra språk tidigare har säkerligen sett andra alternativ för hur man skriver selektioner men i Python är det kolon :
och indentering som avgör vad som tillhör en selektion eller inte.
3.1.1 Ett snarlikt exempel – med/utan indentering
Här kommer två exempel som ser väldigt lika ut men där utskriften blir annorlunda.
Kodexempel: Kodexempel A
# resultatet på ett matteprov
result = 14
# Mindre än 20 poäng var underkänt på provet
if result > 19:
print("Du är godkänd")
print("Grattis till ett bra resultat")
I detta fall ges ingen utskrift alls. Vi förändrar koden ytterst lite och tar bort indenteringen på rad sju vilket gör att koden ser ut på följande sätt...
Kodexempel: Kodexempel B
# resultatet på ett matteprov
result = 14
# Mindre än 20 poäng var underkänt på provet
if result > 19:
print("Du är godkänd")
print("Grattis till ett bra resultat")
... och ger detta resultatet.
Utskrift
Grattis till ett bra resultat
Små förändringar i indentering ändrar programflödet — var noggrann.
3.1.2 Tid i program – localtime
Vi kan läsa av datorns (lokala) tid. Funktionen localtime() ger ett paket med tidsfält (en struct_time, ungefär som en namngiven tupel). Med strftime() kan vi formatera tiden till en snygg sträng.
Kodexempel: localtime + strftime
from time import localtime, strftime
t = localtime() # t är en struct_time med fält som tm_hour, tm_min, ...
print(t) # visar alla fält (debug)
# Plocka ut delar
print("Timme:", t.tm_hour) # 0..23
print("Minut:", t.tm_min)
print("Sekund:", t.tm_sec)
# Formatera hela datum/tid som text
tidtext = strftime("%Y-%m-%d %H:%M:%S", t)
print("Nu är klockan:", tidtext)
Utskriften blir då på följande sätt.
Utskrift
time.struct_time(tm_year=2026, tm_mon=05, tm_mday=11, tm_hour=04, tm_min=32, tm_sec=51, tm_wday=1, tm_yday=130, tm_isdst=1) Timme: 04 Minut: 32 Sekund: 51 Nu är klockan: 2026-05-11 04:32:51
Vanliga formatkoder
%Y=år
%m=månad
%d=dag
%H=timme (00–23)
%M=minut
%S=sekund
struct_time (tupelliknande)
localtime() returnerar ett time.struct_time–objekt (som en namngiven tupel).
Du kan läsa fält som t.tm_hour, t.tm_min osv. Objektet är oföränderligt.
Övning 3.1
- Hämta timmen: Spara
t.tm_houri en variabeltimmeoch skriv utTimmen är: …
. - En enkel if: Skriv en if-sats som skriver
Eftermiddag
omtimme >= 12. - Format: Skriv ut
Idag är det YYYY-MM-DD
medstrftime().
Lösningsförslag
from time import localtime, strftime
t = localtime()
# Uppgift 1
timme = t.tm_hour # 0..23
print(f"Timmen är: {timme}")
# Uppgift 2
if timme >= 12:
print("Eftermiddag") # körs kl 12–23
# Uppgift 3
datumtext = strftime("%Y-%m-%d", t)
print(f"Idag är det {datumtext}")
Vill du läsa mer och lära dig mer om vilka formateringsmöjligheter som finns för datum och tid så kan du läsa det här.
localtime vs datetime
localtime() ger tillbaka ett time.struct_time – ungefär som en
namngiven tupel – med fält som tm_year, tm_mon, tm_mday, tm_hour osv.
Det är oföränderligt (du kan läsa värden men inte ändra dem). För enklare utskrifter och
“plocka ut fält” räcker detta långt.
Behöver du däremot skapa specifika datum/tider, göra beräkningar (lägga till dagar/timmar), eller jämföra tidpunkter, använd datetime. Det ger datum-/tidsobjekt som går att manipulera och formatera flexibelt.
Här kommer ett exempel på hur man kan använda datetime.
Kodexempel: datetime
from time import localtime, strftime # localtime() ger en time.struct_time
from datetime import datetime, date # datetime/date är muterbara objekt
t = localtime()
print("\nt: localtime")
print(t)
print(type(t))
d = datetime.now()
print("\nd: datetime")
print(d)
print(type(d))
d1 = date.fromisoformat("2012-06-24")
d2 = date.fromisoformat("2014-09-25")
print("\nd: Specifikt datum")
print(d1)
print(d1.strftime('%Y-%m-%d %H:%M:%S'))
print(type(d1))
print(d2 - d1)
Utskrift
t: localtime time.struct_time(tm_year=2026, tm_mon=05, tm_mday=11, tm_hour=04, tm_min=32, tm_sec=51, tm_wday=1, tm_yday=130, tm_isdst=1) <class 'time.struct_time'> d: datetime 2026-05-11 04:32:51.293 <class 'datetime.datetime'> d: Specifikt datum 2012-06-24 2012-06-24 00:00:00 <class 'datetime.date'> 823 days, 0:00:00
Uppgift: m03u01
Skapa variabeln timme med värdet från localtime().tm_hour (aktuell timme). Skriv en if-sats som kollar om timme > 16 – skriv då "Skoldagen är slut".
3.2 else
När vi har ett villkor men vill fånga alla andra fall också använder vi else. Tänk: Om (villkor) – annars …
. En else-gren har inget eget uttryck; den körs när villkoret i if är falskt.
Kodexempel: if-else-sats
# Fråga efter ett heltal
tal = int(input("Ange ett heltal: "))
if tal > 0:
print("Talet är positivt")
else:
print("Talet är noll eller negativt")
print("Klart!") # körs alltid
Kom ihåg
ifbehöver ett uttryck (t.ex.tal > 0),elseskall inte ha något uttryck.- Kolon (
:) + indentering avgör vilka rader som hör till respektive gren.
Övning 3.2
- Byt villkor: Ändra uttrycket i exemplet ovan till
tal % 2 == 0och skriv utjämnt
annarsudda
. - Förutsäg utfallet: Vad skrivs ut om
tal = 0? Varför? - Indenteringstest: Flytta sista
print("Klart!")in ielse. Vad händer?
Lösningsförslag
tal = int(input("Ange ett heltal: "))
# Uppgift 1
if tal % 2 == 0: # rest 0 => jämnt
print("jämnt")
else:
print("udda")
# Uppgift 2
# Utskrift: "jämnt"
# Förklaring: 0 % 2 == 0 (resten när 0 delas med 2 är 0),
# därför uppfylls villkoret för "jämnt".
# Uppgift 3
# if tal > 0:
# print("Talet är positivt")
# else:
# print("Talet är noll eller negativt")
# print("Klart!") # nu skrivs "Klart!" ENDAST när else grenen körs
3.2.1 Jämföra två tal – tvåvägsbeslut
Kodexempel: störst eller inte
a = float(input("Ange tal a: "))
b = float(input("Ange tal b: "))
if a >= b:
print(f"a ({a}) är störst eller lika stort som b ({b})")
else:
print(f"b ({b}) är större än a ({a})")
3.2.2 Feljakt
Här finns en kort kodsnutt med flera vanliga misstag kring if/else. Kopiera, kör och rätta tills programmet beter sig som texten säger.
Feljakt: vad är fel?
# Programmet ska fråga efter ålder och skriva
# "Myndig" om åldern är 18 eller mer, annars "Minderårig".
age = input("Ange din ålder: ") # ska vara ett heltal
if age = 18: # jämförelse, inte tilldelning
print("Myndig")
else
print("Minderårig")
print("Klar")
Ledtrådar
- Typkonvertering:
input()ger text – gör om tillint. - Operatorer:
=är tilldelning,==är jämförelse. - Gräns: Villkoret ska vara
>= 18, inte exakt 18. - Syntax: Kolon efter
if/else, konsekvent indentering.
En möjlig rättning
age = int(input("Ange din ålder: "))
if age >= 18:
print("Myndig")
else:
print("Minderårig")
print("Klar")
Uppgift: m03u02
Fråga användaren efter namn och ålder. Skriv sedan ut:
- En hälsning med namnet.
- Namnets första bokstav.
Myndig
om ålder är 18 eller mer, annarsMinderårig
.
Krav: namn ska tvättas innan utskrift: namn = namn.strip(). (Se Moment02 om stränghantering.)
Startkod (frivillig)
namn = input("Ange ditt namn: ").strip()
age = int(input("Ange din ålder: "))
print(f"Hej {namn}!")
print(f"Första bokstaven i ditt namn är: {namn[0]}")
if age >= 18:
print("Myndig")
else:
print("Minderårig")
Uppgift: m03u03
Bygg vidare på m03u01. Lägg till en else som skriver Skoldagen pågår
om klockan är mindre än 17. (I nästa uppgift förfinar vi detta till riktiga intervall.)
3.3 elif
När ett beslut har fler än två vägar använder vi elif (else + if). Du kan ha hur många elif-grenar som helst, men fortfarande bara en if och högst en else i samma kedja.
Kodexempel: intervall med elif
# Läs in ett heltal
poäng = int(input("Ange poäng (0–100): "))
if poäng >= 90:
print("Betyg: A")
elif poäng >= 80:
print("Betyg: B")
elif poäng >= 70:
print("Betyg: C")
elif poäng >= 60:
print("Betyg: D")
elif poäng >= 50:
print("Betyg: E")
else:
print("Betyg: F")
Ordningsregeln
Villkor testas uppifrån och ned. För överlappande villkor, lägg snävaste/största först. I exemplet ovan måste poäng >= 90 ligga före poäng >= 80, annars hinner inte A-fallet träffas.
Övning 3.3a
- Byt ordning felaktigt: Kika på kodexemplet ovan, om du flyttar upp
poäng >= 50överst. Vad händer för poäng 95? Varför? - Gränstest: Testa 49, 50, 59, 60, 69, 70, 79, 80, 89, 90. Får du rätt bokstav varje gång? Det är viktigt att testa
gränsvärden
.
Lösningsförslag
# Uppgift 1 # För poäng = 95 blir utskriften "E". # Varför? Kedjan testas uppifrån och ned. Villkoret (poäng >= 50) är sant # för 95, så programmet stannar där och senare villkor (>= 90, >= 80 …) # hinner aldrig testas. Ordningsregeln är alltså viktig. # Uppgift 2 # Ja, rätt svar på varje test. # Förväntat (A..F): 49:F 50:E 59:E 60:D 69:D 70:C 79:C 80:B 89:B 90:A
3.3.1 Vanlig fälla: överlapp & “döda grenar”
Exempel: överlapp
ålder = int(input("Ange ålder: "))
if ålder >= 18:
print("Vuxen")
elif ålder >= 65: # Denna gren är "död" – träffas aldrig
print("Senior")
else:
print("Minderårig")
Varför? Alla värden >= 65 matchar redan första villkoret. Lösning: byt ordning eller gör det första villkoret snävare.
Rättning
if ålder >= 65:
print("Senior")
elif ålder >= 18:
print("Vuxen")
else:
print("Minderårig")
3.3.2 Feljakt
Kopiera, kör och rätta programmet så att det kategoriserar temperatur korrekt:
Feljakt: temperatur
# Regler:
# temp < 0 → "Iskallt"
# 0–9 → "Kallt"
# 10–19 → "Svalt"
# 20–24 → "Lagom"
# 25–30 → "Varmt"
# > 30 → "Hett"
t = input("Ange temperatur i °C: ")
if t > 30:
print("Hett")
elif t >= 25:
print("Varmt")
elif t >= 20
print("Lagom")
elif t >= 0:
print("Kallt")
elif t >= 10:
print("Svalt")
else:
print("Iskallt")
Ledtrådar
- Typkonvertering:
input()→ text. Gör om tillintellerfloat. - Syntax: saknat kolon efter ett
elif. - Ordningsregel: Testa större gränser först (t.ex. 20 före 10 före 0) i en elif-kedja.
- Ordningskontroll: Stämmer konkurrenterna för >/>= över hela skalan?
- Gränstest: Prova −1, 0, 9, 10, 19, 20, 24, 25, 30, 31.
En möjlig rättning
t = float(input("Ange temperatur i °C: "))
if t > 30:
print("Hett")
elif t >= 25:
print("Varmt")
elif t >= 20:
print("Lagom")
elif t >= 10:
print("Svalt")
elif t >= 0:
print("Kallt")
else:
print("Iskallt")
Övning 3.3b
Skriv en elif-kedja som tolkar en statuskod:
Pellerp→Plockas
Sellers→Skickad
Lellerl→Levererad
- Annars →
Okänd status
Tips: normalisera inmatningen: kod = input(...).strip().upper().
Lösningsförslag
# mata in koden
kod = input("Ange statuskod: ").strip().upper()[0]
if kod == "P":
print("Plockas")
elif kod == "S":
print("Skickad")
elif kod == "L":
print("Levererad")
else:
print("Okänd status")
Uppgift: m03u04
Bygg vidare på dina klock-exempel med tre utskrifter beroende på timme:
- kl. 8–16 →
Skoldagen pågår
- kl. 0–7 →
Skoldagen har inte börjat
- kl. 17–23 →
Skoldagen är slut
Testa med manuella värden först. Återställ sedan så timmen hämtas via localtime() (se 3.1-exemplet).
3.4 Operatorer
I våra selektioner har vi skrivit uttryck som avgör vad programmet ska göra.
Alla sådana uttryck måste ge ett svar som är sant (True) eller falskt (False).
För att kunna bygga dessa uttryck behöver vi kunna använda olika operatorer.
3.4.1 Jämförelseoperatorer
Jämförelseoperatorer används när vi vill jämföra värden. De fungerar ungefär som i matematiken och returnerar alltid ett booleskt värde (True eller False).
| Operator | Betydelse | Exempel | Resultat |
|---|---|---|---|
== |
Lika med | x == 12 |
Sant om x är 12 |
!= |
Inte lika med | x != 12 |
Sant om x inte är 12 |
< |
Mindre än | x < 12 |
Sant om x är mindre än 12 |
> |
Större än | x > 12 |
Sant om x är större än 12 |
<= |
Mindre än eller lika med | x <= 12 |
Sant om x är 12 eller mindre |
>= |
Större än eller lika med | x >= 12 |
Sant om x är 12 eller större |
Kodexempel: jämförelser
x = 14 print(x == 12) # False print(x != 12) # True print(x < 12) # False print(x > 12) # True print(x <= 12) # False print(x >= 12) # True
Det går även att jämföra strängar alfabetiskt (lexikografiskt):
Kodexempel: strängar
print("apa" == "apa") # True
print("Apa" == "apa") # False (stor/liten bokstav skiljer)
print("apa" < "banan") # True (a kommer före b i alfabetet)
Övning 3.4a – Sant eller falskt?
Förutsäg resultatet innan du kör programmet:
Kodexempel: True / False
x = 10
y = 15
print(x > y)
print(x + 5 == y)
print("hej" != "Hej")
print("abc" < "abd")
Lösningsförslag
# x > y -> False # x + 5 == y -> True # "hej" != "Hej" -> True (stor/liten bokstav skiljer) # "abc" < "abd" -> True (alfabetiskt jämförs tecken för tecken)
3.4.2 Logiska operatorer
Logiska operatorer används för att kombinera flera uttryck i samma villkor. De fungerar så här:
| Operator | Namn | Exempel | Resultat |
|---|---|---|---|
and |
och | x > 5 and y < 10 |
Sant om båda villkoren är sanna |
or |
eller | x > 5 or y < 10 |
Sant om minst ett villkor är sant |
not |
inte (negerar) | not x > 5 |
Sant om uttrycket x > 5 är falskt |
Prioritet i logik
not har högst prioritet, sedan and, sist or. Sätt parenteser när du vill styra ordningen – och för läsbarhet.
Kodexempel: kombinera villkor
ålder = 17 har_tillstånd = True print(ålder > 18 and har_tillstånd) # False print(ålder > 18 or har_tillstånd) # True print(not har_tillstånd) # False
Övning 3.4b – Kombinera villkor
- Skriv ett program som frågar efter ålder och längd (cm).
- Om personen är minst 15 år och minst 160 cm, skriv ut
Du får åka!
. - Annars, skriv
Tyvärr, inte idag.
. - Testa olika värden för att se när villkoret blir sant/falskt.
Lösningsförslag
ålder = int(input("Ange ålder: "))
längd = int(input("Ange längd i cm: "))
if ålder >= 15 and längd >= 160:
print("Du får åka!")
else:
print("Tyvärr, inte idag.")
3.4.3 Sammansatta uttryck, parenteser & operatorprioritet
Python prioriterar and före or. Med parenteser kan vi styra ordningen. Samma variabler kan ge olika resultat beroende på hur vi grupperar uttrycken.
Kodexempel: Konsertinträde
# Regler (tänkta):
# - Man kommer in om man har biljett OCH dörren är öppen
# - ... ELLER om man står på gästlistan
har_biljett = False
dörr_öppen = True
på_gästlista = True
# A) Utan parenteser → AND prioriteras före OR
# Tolkning: (har_biljett AND dörr_öppen) OR på_gästlista
resA = har_biljett and dörr_öppen or på_gästlista
print("A:", resA) # True
# B) Parenteser runt AND-delen (samma som A enligt prioritet)
resB = (har_biljett and dörr_öppen) or på_gästlista
print("B:", resB) # True
# C) Parenteser på ett annat ställe
# Tolkning: har_biljett AND (dörr_öppen OR på_gästlista)
resC = har_biljett and (dörr_öppen or på_gästlista)
print("C:", resC) # False
Utskrift (med startvärdena ovan)
A: True B: True C: False
Varför blir det olika?
- A/B: Testar först
har_biljett and dörr_öppen. Eftersom det ärFalse, avgörpå_gästlistaviaor→True. - C: Kräver alltid
har_biljetteftersomandligger ytterst. Medhar_biljett = Falseblir alltFalse.
Övning 3.4d: Lek med sanningsvärden
- Fall 1: Sätt
har_biljett=True,dörr_öppen=False,på_gästlista=False. Förutsäg A/B/C innan du kör. Vad händer och varför? - Fall 2: Sätt
har_biljett=True,dörr_öppen=True,på_gästlista=False. Blir alla treTrue? Förklara. - Negation: Lägg till koden sist i programmet, gissa sedan när
resDblir sant.Kodexempel: Negation
resD = not (har_biljett and dörr_öppen or på_gästlista) print("D:", resD)
Lösningsförslag
# Negation (resD är True bara när varken "biljett & dörr" eller gästlista gäller)
har_biljett=False
dörr_öppen=False
på_gästlista=False
resD = not (har_biljett and dörr_öppen or på_gästlista) # not(False or False) -> True
print("Negation:", resD) # True
Kom ihåg
andprioriteras föreor.- Använd parenteser för att göra avsikten tydlig – och undvik överraskningar.
- Python utvärderar bara så mycket som behövs, vid
orräcker det att första delen är sann, och vidandräcker det att första delen är falsk. Detta kallasshort-circuit evaluation
, det finns ingen bra svensk översättning på uttrycket men ibland användstidig avbrytning av uttryck
elleravbruten utvärdering
.
Fördjupning – kortare skrivning
Python låter dig ibland skriva uttryck kortare.
Exempel: istället för age > 15 and age < 20 kan du skriva 15 < age < 20.
Det är fortfarande samma logik, bara mer kompakt.
3.4.4 Miniquiz – Sant eller falskt?
Testa om du har koll på logiska operatorer, parenteser och kedjade jämförelser. Försök gissa resultaten innan du öppnar facit!
Kodexempel: Quiz – förutsäg utskriften
# Fråga 1 print(5 > 3 and 2 < 4) # Fråga 2 print(5 > 3 or 2 > 8 and 4 < 1) # Fråga 3 print(not (7 <= 10 and 3 > 5)) # Fråga 4 ålder = 17 print(8 <= ålder < 18) # Fråga 5 biljett = False gästlista = False print(not (biljett or gästlista))
Facit och förklaringar (klicka för att visa)
# Fråga 1 # 5 > 3 (True) och 2 < 4 (True) → True and True → True # Fråga 2 # and prioriteras före or: # 2 > 8 and 4 < 1 → False and False → False # 5 > 3 or False → True → True # Fråga 3 # (7 <= 10 and 3 > 5) → True and False → False # not False → True # Fråga 4 # 8 <= 17 < 18 → True and True → True # (kedjad jämförelse kontrollerar båda delarna) # Fråga 5 # (biljett or gästlista) → False # not False → True # alltså: "Får inte komma in" → True betyder att uttrycket 'inte har biljett eller gästlista' stämmer
Tips
andtestas föreor– precis som multiplikation före addition i matematiken.notvänder sanningsvärdet.- Kedjade jämförelser (
8 <= x < 18) kontrollerar båda gränserna samtidigt. - Träna genom att ändra talen och se hur utfallet påverkas.
Uppgift: m03u05 – Klockan och skoldagen
Du ska bygga vidare på dina tidigare klockexempel. Programmet ska avgöra om skoldagen:
- inte har börjat
- pågår
- är slut
Del 1 – grundversion
Denna del har du redan gjort i uppgift m03u01, m03u02 och m03u04.
Skapa en variabel timme och sätt den till den aktuella timmen med hjälp av
localtime(). Skriv sedan en if-/elif-/else-struktur med följande logik:
kl. 8–16→ skrivSkoldagen pågår
kl. 0–7→ skrivSkoldagen har inte börjat
kl. 17–23→ skrivSkoldagen är slut
Del 2 – testa olika uttryck
Skriv om koden på minst tre olika sätt så att den gör samma sak. Du ska själv välja hur du formulerar villkoren:
- med
and/or - med intervall (
8 <= timme < 17) - med hjälp av negation (
not)
Del 3 – fördjupning (m03u05b)
Skolan börjar kl. 08:15 och slutar 15:45.
Ändra programmet så att det tar hänsyn till både timme och minut
(från localtime()).
Tips: jämför total tid i minuter (timme * 60 + minut),
då blir det enklare att testa intervall. Alternativt att du löser det med sammansatta uttryck.
Del 4 – utmaning (m03u05c)
Låt användaren själv mata in skolstart och skolslut (timme och minut). Programmet ska sedan meddela om skolan inte har börjat, pågår eller är slut.
Testa noggrant
Prova särskilt gränsvärden, t.ex. 07:59, 08:15, 15:45 och 16:00. Får du alltid rätt meddelande?
Uppgift: m03u06 – Filmklubben 2.0
En biograf har följande regler:
- Filmen har en viss åldersgräns.
- Medlemmar får gå in även om de är upp till 2 år yngre.
- Alla måste ha en biljett (ja/nej).
Skriv ett program som frågar efter:
- användarens ålder
- om personen är medlem (
ja/nej) - om personen har biljett (
ja/nej) - filmens åldersgräns
Programmet ska sedan avgöra om personen får komma in och skriva ut ett tydligt besked.
Tips
- Tvätta inmatningen:
.strip().lower() - Bygg upp ett logiskt uttryck som kontrollerar alla regler.
- Tänk på ordningen: kolla biljett först, sedan medlemskap/ålder.
3.5 Metoder för att underlätta problemlösning
Innan vi börjar skriva kod är det viktigt att planera och strukturera våra program. Det hjälper oss att förstå problemet bättre och undvika misstag senare. Ett vanligt verktyg för detta är pseudokod – ett sätt att beskriva hur programmet ska fungera med vanligt språk, utan att behöva följa programmeringsspråkets regler.
Pseudokod fokuserar på vad programmet ska göra – inte hur det ska göras i kod.
3.5.1 Pseudokod
Pseudokod är ett verktyg som programmerare använder för att planera och beskriva algoritmer innan de skriver den faktiska koden. Det är ett informellt sätt att skriva ned programlogik som är lätt att läsa och förstå, både för programmerare och andra intressenter.
Varför använda pseudokod?
- Enkelhet: Det låter oss fokusera på logiken utan att oroa oss för syntaxen i ett specifikt programmeringsspråk.
- Kommunikation: Det är lättare att diskutera och dela idéer med andra när man använder ett gemensamt, enkelt språk.
- Planering: Hjälper till att identifiera problem och tänka igenom lösningar innan kodningen börjar.
Pseduokod är en skriftlig beskrivning av lösningen där vi med så normalt språk som möjligt skall beskriva lösningen i punktform. Om varje punkt är formulerad så att den endast gör en instruktion så kan pseudokoden vara grunden till en välkommenterad kod.
Jag kommer visa hur pseudokod används genom att beskriva en uppgift som vi har pratat om tidigare. Uppgiften jag vill jobba med är den som vi gick igenom i kapitel 3.3 där vi skapade vår första if-elif-else-sats där vi frågar efter åldern på en person och avgör om denna personen är minderårig, pensionär eller myndig.
Pseudokod kan vi skriva olika detaljerat, det kan vara värt att skriva en mer överskådlig beskrivning av lösningen, speciellt om det är en större applikation som skall skrivas, för att sedan gå in på djupet och skriva den mer detaljerad.
Övergripande
- Fråga användaren efter hens ålder.
- Om ålder är mindre än 18, skriv ut att användaren är minderårig.
- Annars om åldern är större än 64, skriv ut att användaren troligtvis är pensionär.
- Annars skriv ut att användaren troligtvis jobbar.
Detta sätt att skriva är helt ok, hela lösningen av uppgiften finns bland dessa fyra punkter. Nu visar jag ett annat sätt att skriva samma lösning på. Den är lite mer detaljerad.
Lite mer detaljerat
- Fråga användaren efter hens ålder.
- Om ålder är mindre än 18
- Skriv ut att användaren är minderårig
- Annars om åldern är större än 64
- Skriv ut att användaren troligtvis är pensionär
- Annars
- Skriv ut att användaren troligtvis jobbar
Nu valde jag att skriva det med punkter där jag indenterade vad som händer om ett villkor gäller, vilket gör att det väldigt mycket liknar vår selektion (if/elif/else), och att det troligtvis känns enklare att bygga en korrekt kod för den som håller på att lära sig.
Från pseudokod till Python
# Fråga användaren efter hens ålder
ålder = int(input("Ange din ålder: "))
# Om åldern är mindre än 18
if ålder < 18:
print("Du är minderårig")
# Annars om åldern är större än 64
elif ålder > 64:
print("Du är troligtvis pensionär")
# Annars
else:
print("Du är troligtvis vuxen och jobbar")
Som du ser liknar koden nästan punktlistan rad för rad. Om du skriver tydlig pseudokod först, blir själva kodningen ofta enkel.
Hur skriver man effektiv pseudokod?
- Var tydlig och koncis: Använd enkla meningar och undvik onödig information.
- Använd nyckelord: Vid selektioner används "om, annars om, annars" och vid iterationer används "för, medan, så länge som", vi återkommer till iterationer i nästa moment.
- Fokusera på logik: Beskriv vad som ska göras, inte hur det ska göras i kod.
Fördelar med pseudokod
- Språkoberoende: Kan användas oavsett vilket programmeringsspråk som ska användas senare.
- Lätt att förstå: Även de som inte är bekanta med programmeringsspråkets syntax kan följa logiken.
- Flexibilitet: Lätt att ändra och förbättra innan man börjar med den faktiska kodningen.
Om du nu kikar igenom uppgiften i kapitel 3.3 så ser du att kommentarerna i den koden är väldigt lika de punkter som jag skrivit i vår pseudokod. Att lösa uppgiften med pseudokod först och sedan använda dessa punkter som kommentarer under tiden vi bygger vår applikation är ett smidigt sätt att hitta lösningen först och undvika att få problem med själva koden.
Övning 3.5a – Från kod till pseudokod
Skriv pseudokod till följande lilla program:
x = int(input("Ange ett tal: "))
if x % 2 == 0:
print("Jämnt")
else:
print("Udda")
Tips: Använd 3–4 tydliga punkter. Fokusera på vad programmet gör, inte detaljer om syntaxen.
Lösningsförslag
- Be användaren mata in ett heltal och spara det i x.
- Om talet är jämnt (delbart med 2 utan rest)
- Skriv ut "Jämnt".
- Annars
- Skriv ut "Udda".
Uppgift: m03u08 – Planera med pseudokod
Skriv pseudokod för din lösning till m03u04 (skoldagen). Fokusera på att beskriva vad programmet gör, inte hur. Använd 5–8 tydliga punkter som följer logiken i din kod.
Tips
- Varje punkt ska motsvara en instruktion i programmet.
- Indentering kan användas för att visa vad som händer inom en if-sats.
- Prova att låta någon annan läsa din pseudokod – förstår de vad programmet gör?
Uppgift: m03u09
Här ser du pseudokod för en lösning. Kopiera alla punkter och gör dem till kommentarer i ditt program. Sedan skriver du kod till de kommentarer som du har skrivit. Din uppgift blir att koda programmet så att det följer pseudokoden.
- Fråga användaren efter ett heltal.
- Fråga användaren efter ytterligare ett heltal.
- Multiplicera de två heltalen.
- Om de två heltalen är lika stora
- Skriv ut sidornas längd och vad "kvadratens area är"
- Annars
- Skriv ut sidornas längd och vad "rektangelns area är"
Reflektion
När du är klar, jämför din färdiga kod med pseudokoden. Stämde logiken? Behövde du lägga till något steg? Det är helt normalt att justera pseudokoden när man testar i praktiken – det är en del av processen.
Fördjupning – Pseudokod som kommentarer
Du kan använda din pseudokod direkt i programmet genom att lägga in varje punkt som en kommentar. Sedan fyller du på koden steg för steg under varje rad. Det hjälper dig att hålla fokus och bygga i rätt ordning.
# 1. Fråga användaren efter ett tal # 2. Fråga efter ett till # 3. Multiplicera talen # 4. Om de är lika → skriv att det är en kvadrat # 5. Annars → skriv att det är en rektangel
3.6 Nästlade selektioner
En nästlad selektion är ibland något vi behöver använda oss av. Det handlar om att det finns en selektion inne i en annan selektion. Ibland går det att undvika detta genom att skriva om våra uttryck. Men ibland är det inte möjligt att göra det, eller ens önskvärt ifall vi får väldigt komplicerade uttryck som resultat. Vi bygger vidare på några av våra tidigare exempel för att visa hur det fungerar.
Vi gör ett enkelt exempel;
Kodexempel: enkel if-sats
# Fråga efter ålder och lagra denna i variabeln age
age = int(input("Ange din ålder: "))
# if age < 18
if age < 18: # Alla minderåriga
print("Du är minderårig ", end="")
if age < 2: # under 2 år
print("och är nog hemma med dina föräldrar.")
elif age < 6: # under 6 år
print("och du går i förskolan.")
elif age < 12: # under 12 år
print("och går i skolan, förhoppningsvis har du många läxor.")
else: # Övriga minderåriga
print(" men tonåring och läser på högstadie, gymnasie eller högskolan.")
elif age < 20: # Alla under 20
print("Du är myndig, tonåring och läser på gymnasiet eller högskolan.")
elif age > 64: # Alla över 64
print("du är troligtvis pensionär.")
else: # Alla andra
print("jobba, jobba, jobba!")
Här gäller det att vara extra noggrann eftersom det enda sätt som vi kan visa vilken kod som tillhör en selektion är att den koden är indenterad ett steg. Det innebär att under vår selektion så flyttar vi in koden ett steg med tab (indenterar) och sedan vid nästa selektion så indenterar vi ett steg till. Det här går att göra i väldigt många steg men det brukar tillslut innebära att koden är näst intill oläslig.
Nästlade selektioner används oftare än vad du kan tro, men du kommer också stöta på andra kontrollstrukturer som kan/bör nästlas och det är inte sällan som en eller flera loopar nästlas och inne i varje sådan loop finns det en eller flera nästlade selektioner. Så det är lika bra att lära sig när det fortfarande är relativt enkelt.
3.6.1 Pseudokod
Hur markerar vi i vår pseudokod att det är en nästlad selektion? Det enklaste sättet är att visa det genom ett extra djup i vår punktlista. Samtidigt så är det inte alltid vi som avgör att det kommer bli en nästlad selektion utan det kan vara något som kodaren vill välja. Hur som helst så har vi nu kontrollen på pseudokoden och själva kodningen så då kan vi visa hur vi tänkte när vi kodade lösningen.
Övergripande
- Fråga användaren efter hens ålder.
- Om ålder är mindre än 18, skriv ut
Du är minderårig
. - Om ålder är mindre än 2, skriv ut att
och är nog hemma med dina föräldrar.
- Om ålder är mindre än 6, skriv ut att
och du går i förskolan.
- Om ålder är mindre än 12, skriv ut att
och går i skolan, förhoppningsvis har du många läxor.
- Annars skriv ut
men tonåring och läser på högstadie, gymnasie eller högskolan.
- Annars om åldern är mindre än 20, skriv ut
Du är myndig, tonåring och läser på gymnasie eller högskolan.
. - Annars om ålder > 64 skriv ut
du är troligtvis pensionär.
. - Annars skriv ut
jobba, jobba, jobba!
De punkter som är på nivå två
är de punkter som tillhör den nästlade selektionen.
Övning 3.6a – Nästlade selektioner (a–c)
I denna övning tränar du på att använda, och jämföra, nästlade if-satser och och sammansatta uttryck. Denna övning används för att visa att det finns flera olika sätt att lösa dessa utmaningar på.
- (a) Bibliotekets öppettider – nästlat beslut
Biblioteket har öppet:- Vardagar (mån–fre): kl. 10–18
- Lördag: kl. 11–15
- Söndag: stängt
dag(1–7 där 1=mån … 7=sön) ochtimme(0–23). Använd nästlade selektioner för att skriva utÖppet
ellerStängt
.Lösningsförslag (a)
# (a) Nästlade selektioner dag = int(input("Dag (1=mån ... 7=sön): ")) timme = int(input("Timme (0-23): ")) print("Biblioteket är ", end="") if 1 <= dag <= 5: # mån–fre if 10 <= timme <= 18: print("öppet") else: print("stängt") elif dag == 6: # lör if 11 <= timme <= 15: print("öppet") else: print("stängt") elif dag == 7: # sön print("stängt") else: print("Ogiltig dag") - (b) Samma logik utan nästling – sammansatta uttryck
Skriv om programmet i (a) så att du inte använder nästling, utan ett enda sammansatt villkor.Lösningsförslag (b)
# (b) Sammansatt villkor, utan nästling dag = int(input("Dag (1=mån ... 7=sön): ")) timme = int(input("Timme (0-23): ")) print("Biblioteket är ", end="") if (1 <= dag <= 5 and 10 <= timme <= 18) or (dag == 6 and 11 <= timme <= 15): print("öppet") else: print("stängt") - (c) Utökning: lunchstängt på vardagar
Lägg till regeln: Vardagar är det lunchstängt kl. 12 (endast heltimmen 12). Lördag oförändrat, söndag stängt. Gör först en nästlad variant och sedan en sammansatt variant.Lösningsförslag (c1) – nästlad
# (c1) Nästlad med lunchstängt kl. 12 på vardagar dag = int(input("Dag (1=mån ... 7=sön): ")) timme = int(input("Timme (0-23): ")) print("Biblioteket är ", end="") if 1 <= dag <= 5: # mån–fre if 10 <= timme <= 18: if timme == 12: # lunchstängt print("stängt (lunch)") else: print("öppet") else: print("stängt") elif dag == 6: # lör if 11 <= timme <= 15: print("öppet") else: print("stängt") elif dag == 7: # sön print("stängt") else: print("Ogiltig dag / timme")Lösningsförslag (c2) – sammansatt
# (c2) Sammansatt uttryck med lunchstängt dag = int(input("Dag (1=mån ... 7=sön): ")) timme = int(input("Timme (0-23): ")) print("Biblioteket är ", end="") if (1 <= dag <= 5 and timme == 12): print("stängt (lunch)") elif (1 <= dag <= 5 and 10 <= timme <= 18) or (dag == 6 and 11 <= timme <= 15): print("öppet") else: print("stängt")
Tips
- Visa nästling tydligt med indentering. I del (b) kan du ofta ersätta nästling med
and/oroch parenteser. - Testa gränsvärden: 09, 10, 12, 15, 18, 19 samt olika dagar (5, 6, 7).
- Vill du göra inmatning mer robust? Validera att
1 <= dag <= 7och0 <= timme <= 23.
Uppgift: m03u10
Du skall bygga en applikation där elever skall få göra ett val vilken inriktning de vill läsa på sitt program. Det finns två program, som eleven redan har valt och tillhör, och nu skall du fråga vilken inriktning eleven vill läsa. Du skall lösa detta med nästlade selektioner. Fråga eleven efter dess namn och sedan, på lämpligt sätt, vilket program hen läser. När du har fått reda på programmet så skall du fråga vilken av inriktningarna som eleven vill läsa. För det ena programmet finns det två möjliga inriktningar och för det andra programmet finns det tre inriktningar att välja bland.
Skriv sedan ut elevens namn, samt vilken inriktning eleven har valt. Skapa pseudokod till din lösning, använd det gärna som verktyg för att planera lösningen innan du skriver kod.
Följande program och inriktningar är valbara.
NA - Naturvetenskapsprogrammet
NANAS - Naturvetenskap och samhälle
NANAT - Naturvetenskap
TE - Teknikprogrammet
TEDES - Design och produktutveckling
TEINF - Informations- och medieteknik
TETEK - Teknikvetenskap
Tips1: Använd förkortningarna och gör om allt till versaler för att lättare kunna arbeta med det som matas in.
Tips2: Om du vill avsluta programmet innan du har nått slutet så kan du göra det med följande kod;
Kodexempel: Avsluta programmet
# importerar modulen sys import sys # funktionen exit() stänger av programmet sys.exit()
Uppgift: m03u11 (extra)
Om du tidigare har löst uppgift m03u05b så kan du fundera på hur du kan bygga om denna lösning med nästlade selektioner istället för att skriva allt för avancerade uttryck.
Bygg om lösningen på lämpligt sätt och reflektera över skillnader, vilken lösning du föredrar och hur du kan använda detta i senare uppgifter i kursen.
3.7 Avrundning av momentet
Detta moment avslutas med två diagnoser som säkerställer att du har förstått grunderna:
- En teoretisk diagnos i form av en quiz med 10 frågor på de viktigaste begreppen.
- En praktisk diagnos där du får skriva kod och lösa en eller flera uppgifter med fokus på det du lärt dig i momentet.
Syftet är att både kontrollera dina kunskaper och ge dig en chans att öva på provliknande situationer.
3.7.1 Checklista inför diagnosen
För att vara förberedd bör du kunna:
Checklistan