1.2 Boolsk logikk og betingelser
Sammenligning, and/or/not, nøstede uttrykk og if/elif/else — kjernen i både betingelseskoding og den boolske kodesporingen.
Betingelser er den andre halvdelen av grunnmuren. Uten dem gjør programmet det samme hver gang.
- Løkker og betingelser står i 10 av 10 sett i arkivet 2014–2019, altså 100 %. Hver eneste programmeringsoppgave inneholder minst én if.
- Nøstede boolske uttrykk sendt inn i en funksjon er en fast innpakning i sjanger B — kodesporing, altså oppgaven «hva skriver dette programmet ut, eller hva returnerer denne funksjonen?». Typeformen er en funksjon som får to verdier og svarer True eller False etter et sammensatt vilkår.
- Betingelser med grenser (karaktersetting, fartsgrenser, prisintervaller) er den vanligste innpakningen i selve programmeringsdelen.
Dette må sitte — høyeste prioritet av bokas tre nivåer (må sitte, må kunne, bør kjenne til).
- kap. 1.1 — Variabler, datatyper og konvertering: tilordning med =, de fire datatypene, og at alt som kommer inn utenfra er tekst til du konverterer det.
Har du ikke lest kapitlet, er dette du trenger å ta med deg: = setter en verdi inn i et navn, og en verdi som ser ut som et tall kan likevel være tekst.
Om def og return i oppgavene: noen av oppgavene viser den boolske testen pakket inn i en funksjon, fordi det er slik den står på eksamen. Funksjoner er tema for kap. 2.1, og her trenger du bare to lesemåter: def navn(x): betyr «her begynner en oppskrift som får inn verdien x», og return svar betyr «oppskriften sender svar tilbake». Kallet navn(4) kjører oppskriften med x lik 4.
Trenger du en ekstra forklaring av det samme stoffet med andre ord, finnes Variabler, datatyper og uttrykk i et parallelt emne.
Løkke 1 — Spørsmål maskinen kan svare ja eller nei på (~8 min)
En parkeringsautomat må avgjøre om betalingen holder. Det er ett spørsmål med to mulige svar: ja eller nei. I Python heter de to svarene True og False, og de oppstår når du sammenligner to verdier.
Et uttrykk som gir True eller False, kalles et boolsk uttrykk. Navnet kommer fra matematikeren George Boole, som formaliserte akkurat denne regningen.
En verdi som er enten True (sann) eller False (usann). Stor forbokstav, ingen fnutter.
'True' med fnutter er en tekst og oppfører seg helt annerledes — den er blant annet alltid sann når den brukes som betingelse, uansett hva som står i den.
Sannhetsverdier kan lagres i variabler som alle andre verdier: har_betalt = True.
a == b gir True når verdiene er like, a != b når de er ulike.To likhetstegn. Ett likhetstegn er tilordning og betyr noe helt annet. Skriver du if x = 3: stopper programmet med SyntaxError — det er en av de få feilene Python fanger for deg.
Sammenligning på tvers av typer gir False uten feilmelding: 3 == '3' er False, fordi et tall aldri er lik en tekst. Dette er felle #1 fra kap. 1.1 i ny drakt — glemt konvertering gir stille galt svar.
Sammenligner størrelse. <= leses «mindre enn eller lik» og skrives med tegnene i den rekkefølgen — =< finnes ikke.
For tall sammenlignes tallverdien. For tekst sammenlignes tegn for tegn fra venstre, slik at '9' > '10' er True. Store bokstaver kommer før små: 'Å' < 'a' er True.
Sammenligning mellom et tall og en tekst med < gir feilmelding (TypeError), i motsetning til ==, som bare gir False.
Python tillater matematikkens skrivemåte: 0 <= x < 100 betyr at x er minst 0 og mindre enn 100.
Dette er ikke bare kortere enn x >= 0 and x < 100 — det er også lettere å lese riktig, og midtverdien regnes bare ut én gang.
Bruk det når du skal teste et intervall. Karaktergrenser, fartsgrenser og lovlige klokkeslett er alle intervalltester.
Automaten krever 45 kroner. Kunden legger i 50. Hva svarer de ulike sammenligningene?
krav = 45
betalt = 50
print(betalt >= krav)
print(betalt == krav)
print(betalt != krav)
print(0 <= betalt <= 100)Utskrift:
True
False
True
TrueFire spørsmål, fire svar. Legg merke til at hvert av dem er et helt uttrykk med en verdi — de kan lagres, skrives ut og sendes videre akkurat som tall.
Den siste er en kjedet sammenligning, og den leses akkurat slik den ser ut: er betalt mellom 0 og 100, endepunktene medregnet?
(Innstegsoppgave — minimal sporing. Sjanger B — kodesporing, altså «hva skriver programmet ut?».) Hva skriver programmet ut?
x = 7
print(x > 3)
print(x == 7)
print(x != 7)
print(3 < x < 10)Løkke 2 — Å sette sammen flere krav (~10 min)
Sjelden holder det med ett vilkår. En rabatt kan kreve at kunden er under 26 år og har gyldig studentbevis. En alarm kan utløses hvis døren er åpen eller vinduet er knust. Og noen ganger er du ute etter det motsatte av et vilkår.
Tre ord dekker alle tre tilfellene: and, or og not.
a and b er True bare når begge sider er sanne. Én usann side gjør hele uttrykket usant.a | b | a and b |
|---|---|---|
True | True | True |
True | False | False |
False | True | False |
False | False | False |
Tommelfingerregel:
and gjør kravet strengere. Legger du til en and-betingelse, kan færre tilfeller slippe gjennom.a or b er True når minst én side er sann. Bare når begge er usanne, blir uttrykket usant.a | b | a or b |
|---|---|---|
True | True | True |
True | False | True |
False | True | True |
False | False | False |
Merk at
or i Python er «minst én», ikke «nøyaktig én» — det siste heter «enten eller» i dagligtale og finnes ikke som eget ord her.Tommelfingerregel:
or gjør kravet løsere.Snur sannhetsverdien: not True er False, og not False er True.
not x > 3 betyr «det er ikke sant at x er større enn 3», altså det samme som x <= 3. Vær presis her: det motsatte av «større enn» er «mindre enn eller lik», ikke bare «mindre enn».
Ofte er det klarere å snu selve sammenligningen enn å bruke not. if not antall == 0: er riktig, men if antall != 0: leses lettere.
Rekkefølgen fra sterkest til svakest:
1. Sammenligningene (==, <, >= …) — de regnes alltid før de logiske ordene.
2. not
3. and
4. or — svakest.
Det betyr at a or b and c leses som a or (b and c), ikke som (a or b) and c. De to gir forskjellig svar, og forskjellen er en fast kodesporingsfelle.
At sammenligningene kommer først, er grunnen til at x > 0 and y > 0 virker uten parenteser. Sett likevel parenteser når uttrykket blir sammensatt — de koster ingenting og fjerner tvilen.
Python slutter å regne så snart svaret er avgjort. I a and b regnes b ikke ut hvis a allerede er usann, og i a or b ikke hvis a allerede er sann.
Dette er ikke bare en effektivitetsdetalj — det er et verktøy. Skriver du if tekst.isdigit() and int(tekst) > 100:, er du trygg: konverteringen kjøres bare når teksten faktisk er sifre, så int kan ikke krasje.
Rekkefølgen på de to sidene har altså betydning, selv om and ellers ser symmetrisk ut.
Studentrabatt krever alder under 26 og gyldig bevis. Alarmen går hvis døra er åpen eller vinduet er knust. Hva blir svarene for en 24-åring uten bevis, med lukket dør og knust vindu?
alder = 24
har_bevis = False
dor_apen = False
vindu_knust = True
print(alder < 26 and har_bevis)
print(dor_apen or vindu_knust)
print(not har_bevis)
print(alder < 26 or har_bevis and False)Utskrift:
False
True
True
TrueDe tre første er rett fram. Den fjerde er fella: and binder sterkere enn or, så uttrykket leses som alder < 26 or (har_bevis and False). Den venstre siden er sann, og dermed er hele uttrykket sant — uansett hva som står til høyre.
Hadde vi ment (alder < 26 or har_bevis) and False, måtte parentesene stått der. Da hadde svaret blitt False.
Hva skriver programmet ut?
a = True
b = False
print(a and b)
print(a or b)
print(not b)
print(a and not b)Funksjonen under får to tall og svarer True eller False.
def test(x, y):
return (x > 0 and y > 0) or (x == y)
print(test(4, 4))
print(test(4, 0))
print(test(0, 4))
print(test(-2, -2))Hva returnerer funksjonen for hvert av de fire kallene?
Løkke 3 — Verdier som teller som sanne eller usanne (~5 min)
Python godtar hvilken som helst verdi der det ventes en betingelse, ikke bare True og False. Da gjelder en fast regel om hva som teller som sant.
Disse verdiene teller som usanne: tallet 0 (og 0.0), den tomme teksten '', den tomme lista [], den tomme ordboka {} og None.
Alt annet teller som sant — også teksten '0', teksten 'False' og det negative tallet -1. Det er innholdet som avgjør for tekst: en tekst er sann så lenge den har minst ett tegn.
Praktisk konsekvens: if navn: betyr «hvis brukeren skrev noe i det hele tatt». Det er kortformen for if navn != '':, og den brukes flittig i input-behandling.
Gjør en hvilken som helst verdi om til True eller False etter regelen over: bool(0) gir False, bool(-1) gir True, bool('') gir False og bool('0') gir True.
Du trenger den sjelden i en besvarelse, men den er den raskeste måten å kontrollere at du har forstått regelen når du sitter og sporer kode.
Hvilke av verdiene 0, -1, '', '0' og 'False' teller som sanne?
print(bool(0), bool(-1))
print(bool(''), bool('0'), bool('False'))Utskrift:
False True
False True TrueBare tallet 0 og den tomme teksten er usanne. '0' og 'False' er tekster med tegn i seg, og dermed sanne — noe som overrasker mange første gang.
Det er også en praktisk advarsel: leser du et svar fra brukeren og skriver if svar: for å sjekke om han svarte «ja», tar du feil. Den testen sjekker bare at han skrev noe.
Hva skriver programmet ut?
verdier = [0, -3, '', '0', 'nei']
for v in verdier:
if v:
print('sann')
else:
print('usann')Hint til den som ikke har møtt løkker ennå: for v in verdier: betyr bare «gjenta det innrykkede én gang for hver verdi i lista, med v satt til den verdien». Løkker gjennomgås grundig i neste kapittel.
Løkke 4 — if, elif og else (~10 min)
Nå kan programmet velge. En veiledning for fartsbøter har flere trinn: under grensen, litt over, mye over. Trinnene skal prøves i rekkefølge, og bare ett av dem skal gjelde.
Det er nøyaktig oppgaven til if, elif og else.
Kjører den innrykkede blokken bare når betingelsen er sann. Kolonet på slutten er obligatorisk.
Alt som hører til valget, står rykket inn under if-linja. Boka bruker fire mellomrom per nivå, aldri tabulator. Innrykket er ikke pynt — det er Pythons måte å avgjøre hva som hører til.
En if alene er lov, uten else. Da skjer ingenting når betingelsen er usann.
«Ellers, hvis …». Sjekkes bare når alle foregående betingelser i samme kjede var usanne.
Dette er det viktigste å forstå ved trinnvise tester. I en kjede med flere elif kjøres høyst én blokk — den første som slår til. Resten hoppes over uten å bli prøvd.
Skriver du flere selvstendige if-setninger i stedet, prøves alle, og flere kan slå til samtidig. Det gir et helt annet program.
Kjøres når ingen av de foregående betingelsene slo til. Har ingen betingelse selv, og skrives sist i kjeden.
else er valgfri, men på eksamen er den ofte poenget: den fanger opp «alle andre tilfeller», som laveste karakter, «ikke funnet» eller «ingen bot».
Glemmer du den, faller de tilfellene stille gjennom uten at noe skjer — en av de vanligste kildene til at et program «gjør ingenting».
En if inne i en annen if, med ett innrykksnivå til. Den indre testen prøves bare når den ytre var sann.
Nøsting og and kan ofte uttrykke det samme: if a: if b: gjør det samme som if a and b:. Velg and når begge kravene hører sammen, og nøsting når du trenger et eget else på det ytre nivået.
Mer enn to nivåer blir raskt uleselig. Går du dypere, er det som regel et tegn på at en del av logikken hører hjemme i en egen funksjon.
Skal en funksjon svare True eller False, skriv return a > b — ikke if a > b: return True else: return False.
De to gjør nøyaktig det samme, men den korte formen er den sensor forventer, og faget vurderer konsishet eksplisitt: uklare eller unødig lange svar trekker ned.
Samme regel gjelder sammensatte vilkår: return alder < 26 and har_bevis er hele funksjonen.
En kommune har en enkel regel for kontroll på en 60-vei: opp til og med 60 er greit, opptil og med 70 gir advarsel, over det gir bot. Skriv logikken som en kjede, og vis hva som skjer hvis du i stedet skriver tre selvstendige tester.
Riktig løsning er én kjede, der trinnene prøves i rekkefølge:
fart = 68
if fart <= 60:
print('Greit')
elif fart <= 70:
print('Advarsel')
else:
print('Bot')Utskrift:
AdvarselRekkefølgen bærer hele logikken. Når fart <= 60 er usann, prøves fart <= 70 — og siden vi allerede vet at farten er over 60, betyr den testen i praksis «mellom 61 og 70».
Skriver du tre selvstendige if-setninger i stedet, prøves alle tre:
fart = 55
if fart <= 60:
print('Greit')
if fart <= 70:
print('Advarsel')
if fart > 70:
print('Bot')Utskrift:
Greit
AdvarselNå skrives to linjer ut for én bilist. Feilen er ikke i betingelsene — de er de samme — men i at de ikke henger sammen i en kjede.
Uttelling: sensor er ute etter at trinnene er gjensidig utelukkende og dekker alle tilfeller. Kjeden med elif gjør begge deler gratis; tre løse if-er må du selv sikre med lange intervalltester.
Hva skriver programmet ut?
poeng = 82
if poeng >= 90:
print('A')
elif poeng >= 80:
print('B')
elif poeng >= 70:
print('C')
else:
print('D eller lavere')
print('ferdig')En idrettsklubb gir kontingent etter alder: under 6 år er gratis, 6 til og med 17 år koster 800 kroner, 18 til og med 66 år koster 1600 kroner, og fra 67 år koster det 900 kroner.
a) Skriv funksjonen kontingent(alder) som returnerer riktig beløp som et heltall.
b) Forklar med én setning hvorfor rekkefølgen på testene betyr noe.
Hva skriver programmet ut?
temp = 3
vind = 12
if temp < 5:
if vind > 10:
print('kaldt og vindfullt')
else:
print('kaldt')
else:
print('mildt')Funksjonen under sjekker om en tekst kan brukes som et positivt heltall under 100.
def lovlig(tekst):
return tekst.isdigit() and 0 < int(tekst) < 100
print(lovlig('42'))
print(lovlig('0'))
print(lovlig('abc'))
print(lovlig('100'))Hva returnerer de fire kallene — og hvorfor stopper ikke programmet på lovlig('abc')?
Fire feller går igjen, og alle fire har kostet poeng i sporingsoppgaver:
- Ett likhetstegn i en test. if x = 3: er tilordning og gir SyntaxError. Denne fanges av Python, så den er den billigste av de fire.
- Feil presedens i blandede uttrykk. a or b and c leses som a or (b and c). Sett parenteser når du er i tvil.
- if der du mente elif. Selvstendige tester prøves alle, og flere blokker kan kjøre. En elif-kjede kjører høyst én.
- Glemt else. Tilfellene som ingen test fanger, faller stille gjennom. På eksamen er det ofte nettopp restkategorien — laveste karakter, «ikke funnet» — som gir poenget.
En femte, som hører hjemme i kap. 1.1: sammenligner du tekst med tall, får du False uten feilmelding. Det er felle #1 i bokas feilregister — glemt konvertering — og den er like farlig i en if som i et regnestykke.
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.
Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Norges teknisk-naturvitenskapelige universitet. Dette er ikke offisielt studiemateriell. Les mer.