4. Betinget programmering#
I dette kapitlet skal vi se litt nærmere på hvordan man ved programmering kan få output som er valg foretatt av dataprogrammet på bakgrunn av at du ber om noe (“gir input”). Å forstå hvordan dette skjer gjør det lettere å forholde seg til større datasett der man er ute etter bestemte utvalg som ikke så lett kan sees og hentes ut manuelt. I dette kapitlet lærer du altså enda et sett med grunnstener. Nå går vi fra datatyper til operatorer.
Om et dataprograms oppførsel#
Vi har sett at dataprogrammer kan betraktes som “levende” vesener
(anførselstegnene er viktige!). Et program kjører linje etter linje,
og hver linje kan forandre på programmets
status (verdiene i programmets variabler).
Dersom linje 5 er en kopi av linje
3, er det ikke sikkert at begge linjer har
nøyaktig samme utfall. Sannsynligvis ikke.
I eksempel under oppstår det
forskjellige verdier i variabelen i
(hhv. 2 og 3), etter at hver av de
to identiske linjene, 2 og 4, er kjørt.
1i = 1
2i += 1
3print("linje 3:", i)
4i += 1
5print("linje 5:", i)
linje 3: 2
linje 5: 3
Det er heller ikke slik at våre programmer behøver å oppføre seg likt hver gang de kjøres. Det avhenger av omstendigheter som programmet er ment å reagere på, og det er dette som gjør programmer så nyttige.
Tenker datamaskiner?#
Nei. Datamaskiner tenker ikke. Allikevel er programmene som kjøres på dem ofte meget avanserte. Hemmeligheten er at våre programmer foretar beslutninger basert på valgalternativer. Disse valgalternativene er ofte uttrykt ved variabelverdier. Alle programmeringsspråk, Python inkludert, er utstyrt med beslutningsstrukturer. Med disse strukturene kan programmet “velge” èn av flere kjøreveier.
Å kjøre linje for linje er den enkleste formen for beslutningsstruktur. Men i hver linje kan vi legge til veivalg, til og med valg som gjør at avlesingen går tilbake til linje 1 igjen. Det er dette vi skal gi en introduksjon til her.
⚠️ Merk! Dataprogrammer “tenker” ikke. De tar beslutninger (foretar valg), basert på klart formulerte betingelser.
Enkle logiske uttrykk og beslutningsstrukturer#
Logiske uttrykk#
Under ser vi et kort program.
Uttrykket i == 0
på linje 2 kaller vi et logisk uttrykk. Dette er noe litt annet enn å tilordne en variabel en verdi.
På norsk lyder den i
er lik 0
. Dette uttrykket kan ha èn av to verdier,
True
eller False
.
Legg merke til =
på linje 1 og ==
på linje 2.
=
(i
settes lik 0
) er en tilordning, og forandrer variabelens
verdi (dersom den ikke var 0
fra før). ==
er et sammenligningsuttrykk,
og sjekker at verdiene på høyre og venstre side er like, uten å forandre verdien.
Python har flere slike sammenligningsuttrykk, og vi ser på disse litt senere.
1i = 0
2print(i == 0)
True
1print(i == 1)
False
if-testen#
If-testen er den mest grunnleggende beslutningsstrukturen i både Python og
de fleste andre programmeringsspråk. La oss starte med et enkelt eksempel.
Under ser vi et kort program. Linje 2, if i == 0:
er en test, et spørsmål
til systemet. Vi spør “om i
er lik 0
”, og videre ber vi om at den printer noe hvis det er riktig. Dersom det
logiske uttrykket er True
, kjøres line 3, hvis False
kjøres den ikke.
1i = 0
2if i == 0:
3 print("i er 0!")
4print("Takk og farvel.")
i er 0!
Takk og farvel.
I neste eksempel ser vi en kjøring hvor i
ble satt til
1
, og linje 3 derfor “hoppes over”. Legg merke til at uttrykket i == 0
,
som bare er et testuttrykk ikke forandrer verdien i i
, i motsetning til
i = 0
som er en tilordning som kan forandre verdien.
1i = 1
2if i == 0:
3 print("i er 0!")
4print("Takk og farvel.")
Takk og farvel.
✍️ Oppgave: Kopier inn koden i cellen over i en celle i din egen notebook. Gjør en endring hvor du setter if i == 1:
på linje 2. Kjør cellen.
Bruk av kolon (:) og innrykk#
I motsetning til de fleste andre programmeringsspråk, er programstrukturen i Python uttrykt i programkodens[1] oppsett (engelsk: “layout”), og nivået av en gruppe kodelinjer bestemmes av mengden innrykk. Under ser du at kodelinjene 3, 4 og 5, som er rykket inn i forhold til if-testen, kjøres eller hoppes over samlet.
1i = 0
2if i == 0:
3 print("i")
4 print("er")
5 print("0!")
6print("Takk og farvel.")
i
er
0!
Takk og farvel.
1i = 1
2if i == 0:
3 print("i")
4 print("er")
5 print("0!")
6print("Takk og farvel.")
Takk og farvel.
⚠️ Merk! Kolon og innrykk må være på plass. Kombinasjonen gjør at akkurat de print-operasjonene kun er koblet til if
-spørsmålet i linjen over. Legg merke til følgende feilsituasjonen:
1i = 1
2if i == 0:
3print("i")
4 print("er")
5 print("0!")
6print("Takk og farvel.")
Cell In[8], line 3
print("i")
^
IndentationError: expected an indented block after 'if' statement on line 2
Prøv gjerne å fjerne eller kolon for å se hva som da skjer.
Logiske uttrykk og testoperatorer#
Som tidligere nevnt er et logisk uttrykk et spørsmål,
som besvares med True
eller
False
. Et logisk uttrykk kan anta forskjellige former, og
tester ofte på variabelverdier. Variabelverdier blir til på
forskjellige måter. De kan hentes fra databaser eller filer, eller de kan
settes av programmet under kjøring. I eksemplene foran har vi sett
logiske uttrykk som tester om en variabel har en bestemt verdi (i == 1
).
Disse uttrykkene tester på tallverdier, men både tall- og tekstvariabler kan
brukes i logiske uttrykk. Tegn som ==
og >
kalles ofte for testoperatorer.
Nedenfor tester vi om verdien i en variabel er større enn 5 eller ikke:
1i = 6
2if i > 5:
3 print("i er større enn 5!")
4print("Takk og farvel.")
i er større enn 5!
Takk og farvel.
Kort og godt er vi ute etter å vite om noe stemmer eller ikke, gjerne fordi det er vanskelig å vite ved å bare se på datasettet med det blotte øyet. Denne typen programmering kan vi også bruke hvis vi ønsker å ta ut noen spesifikke rader av et datasett for å lage et nytt datasett. Dette er noe vi vil komme tilbake til i del III av denne boka.
⚠️ Merk! En beslutningsstruktur bruker en betingelse, uttrykt ved et logisk uttrykk, for å velge en bestemt kjørevei. Logiske uttrykk bruker variabler og testoperatorer.
Python støtter flere testoperatorer som kan brukes i logiske uttrykk. Nedenfor vises varianter av logiske uttrykk som bruker forskjellige testoperatorer.
Testoperator |
Beskrivelse |
Eksempler |
---|---|---|
|
om en variabelverdi er lik en bestemt verdi |
A. |
|
om en variabelverdi er lik en annen variabelverdi |
|
|
om en variabelverdi er mindre enn en annen verdi |
A. |
|
om en variabelverdi er større enn en annen |
A. |
|
om en variabelverdi er mindre enn eller lik en annen |
|
|
om en variabelverdi er større enn eller lik en annen |
|
Beslutningsstrukturer for flere valgalternativer#
If
-testen er en enkel struktur som bestemmer om et program skal
eller ikke skal utføre en sekvens med handlinger. I mer kompliserte
situasjoner foreligger det flere valgalternativer. Vi snakker da om
en forgrening: programmet har flere mulige grener, og
kan utføre èn av disse.
If - else strukturen#
Ofte trenger programmet å vite eksplisitt hva det skal gjøre også
dersom det logiske uttrykket er usant (har verdien False
).
Dette ordnes med en
else-gren som settes rett etter if-grenen. I eksempelet under ser
man at programmet velger om det skal kjøre linje 3 eller 5 basert på verdien i
variabelen i
.
1i = 0
2if i == 0:
3 print("i er 0!")
4else:
5 print("i er ikke 0!")
6print("Takk og farvel.")
i er 0!
Takk og farvel.
1i = 1
2if i == 0:
3 print("i er 0!")
4else:
5 print("i er ikke 0!")
6print("Takk og farvel.")
i er ikke 0!
Takk og farvel.
Teste på motsatt (negert) betingelse: !=#
Noen applikasjoner krever at vi utfører en handling bare hvis en
betingelse ikke er oppfylt. Dette kan i og for seg gjøres med en
else-gren, men det er kanskje mer elegant å
uttrykke betingelsen omvendt, med en negeringsoperator. !=
leses
på norsk er ulik.
Se eksempel under.
1navn = "Michael"
2print("Det er sant at du ikke heter Jens?")
3if navn != "Jens":
4 print("Ja, det er sant.")
Det er sant at du ikke heter Jens?
Ja, det er sant.
if-elif-else-strukturen#
elif
kan brukes når vi skal
ha mer enn to grener i en betingelse. Med
if-elif-else
-strukturen kan vi tilrettelegge for håndtering av
flere mulige utfall.
I eksempel under er det lagt opp til tre
alternativer. En if
-gren og en elif
-gren som oppgir to distinkte
alternativer, og en else
-gren som angir standardhandlingen (engelsk: “default”), altså
hvis ingen av de angitte betingelsene er oppfylt. Vi kan bruke så mange
elif
-grener vi bare ønsker.
1kategori = "ungdom"
2if kategori == "ungdom":
3 pris = 200
4elif kategori == "senior":
5 pris = 250
6else:
7 pris = 500
8print("pris =", pris)
pris = 200
Nøsting av tester#
Med Nøsting (engelsk: “nesting”) av tester menes at vi utfører en test bare hvis det logiske uttrykket til en annen test har et visst utfall.
Vi
nøster inn èn betinget struktur som en gren av en annen struktur.
I eksemplet under, utgjør linjene 3-6 if-grenen (linje 2).
If-testen på linje 3 blir ikke kjørt hvis verdien i barnealder
er 2 eller mindre.
Merk deg også bruken av kolon etterfulgt 4-blank-innrykk[2] hver gang et nytt
nivå innføres (linje 2-3, 3-4, 5-6, 7-8).
1barnealder = 5
2if barnealder > 2:
3 if barnealder < 6:
4 print("Barnet går i barnehagen.")
5 else:
6 print("Barnet går på skolen.")
7else:
8 print("Barnet er for ungt.")
Barnet går i barnehagen.
✍️ Oppgave: Prøv å skrive om programkoden i if-elif-else-eksemplet som en nøstet struktur.
Sammensatte logiske uttrykk#
Av og til trenger vi å uttrykke mer kompliserte betingelser enn en enkel test kan uttrykke. Stort sett er det mulig å løse disse med de nøstede strukturene omtalt ovenfor, men dette kan resultere i lang og rotete programkode. Sammensatte logiske uttrykk, som bruker logiske kombinasjoner, er ofte mer elegante og resulterer i kortere, mer fokusert kode. Vi ser på to kombinasjoner:
and
(logisk OG): to eller flere betingelser som skal stemme samtidigor
(logisk ELLER): minst én av to eller flere betingelser skal stemme.
Disse kombinasjonene kan være byggesteiner i sammensatte logiske uttrykk. Her ser vi på noen eksempler hvor én forekomst av en logisk operasjon utgjør testen.
Logisk OG (and)#
Se eksempelet under. Dersom hele det kombinerte logiske
uttrykket i if
-grenen skal være sant, kreves det at begge
deluttrykk er sanne samtidig. Hele det logiske uttrykk på linje 3 er sant
hvis alderen er større enn 67 samtidig som kjønnet er kvinne.
1alder = 65
2kjonn = "kvinne"
3if alder > 67 and kjonn == "kvinne":
4 print("Som kvinnelig pensjonist får du en blomst.")
En annen, typisk bruk av OG-kombinasjonen
(and
), er når man skal teste om verdien i en tallvariabel (for
eksempel alder) befinner seg innenfor et gitt intervall. Dèt gjør den
hvis den er større enn eller lik minstegrensen samtidig som
det er mindre enn eller lik størstegrensen. Se eksempel under.
1barnealder = 5
2if barnealder >= 2 and barnealder <= 5:
3 print("Barnet går i barnehagen.")
Barnet går i barnehagen.
Logisk ELLER (or)#
Et logisk uttrykk med to deluttrykk koblet med or
er sant
dersom minst ett av deluttrykkene er sant (eller dersom begge er
sanne samtidig). Se eksempel under. Her
får man rabatt enten man er
en kvinne eller en senior (eller begge deler).
1alder = 65
2kjonn = "kvinne"
3if alder > 67 or kjonn == "kvinne":
4 print("Enten kvinner eller pensjonist (eller både og)")
Enten kvinner eller pensjonist (eller både og)
Videre lesning for spesielt interesserte#
I dette kapitlet har vi sett på de mest grunnleggende
beslutningsstrukturene i Python.
Det finnes noen andre if
-baserte beslutningsstrukturer, og
de som er særlig interesserte kan lese mer om dise her:
https://realpython.com/python-conditional-statements