Vilkår (if-tester)#
Læringsutbytte
Etter å ha arbeidet med dette temaet, skal du kunne:
bruke vilkår til å systematisere valg i programkode
forklare hvordan sammenlikninger og kommandoene
if,elifogelsestyrer hva et program gjørillustrere og løse kjemiske og naturvitenskapelige problemstillinger med sammensatt kode der vilkår inngår
Innledende oppgave
Før du går i gang med å programmere, prøv å forklare hva følgende kodesnutter gjør. Hvilke av programmene skriver ut noe når pH = 5.5?
pH = 5.5
if pH < 7:
print("Løsningen er sur.")
pH = 5.5
if pH > 7:
print("Løsningen er basisk.")
pH = 5.5
if pH < 7:
print("Løsningen er sur.")
else:
print("Løsningen er ikke sur.")
pH = 5.5
if pH < 7:
print("Løsningen er sur.")
elif pH > 7:
print("Løsningen er basisk.")
else:
print("Løsningen er nøytral.")
Definisjon#
Vilkår
Et vilkår, eller en betingelse, er en logisk test for å sjekke om et kriterium er oppfylt. Dersom kriteriet er oppfylt, utføres det en handling. Dersom kriteriet ikke er oppfylt, blir ikke handlingen utført. Vilkår beskrives ofte i programmering som en «hvis-setning» (if i Python).
Vilkår er sentrale i programmering, men også i kjemisk problemløsing. Vi trekker ofte konklusjoner som avhenger av én eller flere målte eller beregnede størrelser: Hvis pH er lavere enn en bestemt verdi, klassifiserer vi løsningen på én måte. Hvis absorbansen ligger utenfor kalibreringsområdet, må prøven kanskje fortynnes eller måles på nytt. Hvis reaksjonskvotienten er mindre enn likevektskonstanten, vil systemet bevege seg i én retning mot likevekt.
Et dataprogram kan utføre slike valg konsekvent, men det er vi som må bestemme hvilke kriterier som er kjemisk meningsfulle. Et vilkår er derfor også en måte å gjøre de faglige antakelsene våre tydelige på.
Vi kan bruke klassifisering av en løsning som et enkelt eksempel. I en forenklet modell ved omtrent 25 °C sier vi at en løsning er sur dersom pH er lavere enn 7. Dette kan beskrives med følgende pseudokode:
hvis pH er mindre enn 7:
klassifisering = "sur"
hvis ikke:
klassifisering = "ikke sur"
Dersom vi oversetter pseudokoden til Python-kode, ser vi at logikken og strukturen er ganske lik:
if pH < 7:
klassifisering = "sur"
else:
klassifisering = "ikke sur"
Underveisoppgave
Lag et lite program med variabelen temperatur = 35. Programmet skal skrive ut «Temperaturen er høyere enn romtemperatur.» dersom temperaturen er høyere enn 25 °C, og «Temperaturen er 25 °C eller lavere.» ellers. Tenk spesielt på kolon og innrykk.
temperatur = 35
# Skriv if-else-testen her
Løsningsforslag
temperatur = 35
if temperatur > 25:
print("Temperaturen er høyere enn romtemperatur.")
else:
print("Temperaturen er 25 °C eller lavere.")
Vilkår i Python#
La oss se nærmere på pH-eksempelet. Vi legger først til input slik at pH-en er opp til brukeren av programmet:
pH = float(input("Oppgi pH: "))
if pH < 7:
print("Løsningen er sur.")
Programmet ber altså brukeren om å taste inn en pH-verdi som deretter konverteres til et flyttall. Vilkåret starter med if, etterfulgt av en logisk test. Her tester vi om pH er mindre enn 7. Dersom testen er sann, skrives beskjeden ut. Vi må ha et kolon etter testen og innrykk på alt som hører til vilkåret. Dersom testen ikke er sann, skjer det ingenting.
Selve testen har alltid én av de logiske verdiene True (sann) eller False (usann). Vi kan undersøke dette direkte:
pH = 5.5
print(pH < 7) # Skriver ut True
print(pH > 7) # Skriver ut False
Dersom vi vil at det skal skje noe også når testen ikke er sann, kan vi legge til else:
pH = float(input("Oppgi pH: "))
if pH < 7:
print("Løsningen er sur.")
else:
print("Løsningen er ikke sur.")
Dersom testen pH < 7 ikke er sann, blir beskjeden etter else skrevet ut. Vi kan legge til flere kriterier ved å bruke elif, som er en forkortelse for else if:
pH = float(input("Oppgi pH: "))
if pH < 7:
print("Løsningen er sur.")
elif pH > 7:
print("Løsningen er basisk.")
else:
print("Løsningen er nøytral.")
Det er en logisk konklusjon at pH er 7 dersom den verken er mindre enn eller større enn 7. Derfor trenger else ingen ny test. Dersom vi likevel vil teste om to verdier er like, bruker vi ==:
if pH == 7:
print("pH-verdien er nøyaktig 7.")
Legg merke til at == brukes for å teste om to størrelser er like. Dersom vi bruker ett likhetstegn (=), prøver Python å tilordne en verdi til en variabel. De ulike sammenlikningsoperatorene er oppsummert i tabellen nedenfor.
Symbol |
Betydning |
|---|---|
|
Større enn |
|
Mindre enn |
|
Er lik |
|
Mindre enn eller lik |
|
Større enn eller lik |
|
Ikke lik |
Det er noen ting å passe spesielt på når vi programmerer med vilkår:
Alt som er rykket inn, utføres kun hvis testen ovenfor er sann. Innrykk er derfor en del av strukturen i Python, ikke bare pynt.
elifsjekker et nytt kriterium, menselsebrukes dersom ingen av kriteriene underifogelifer sanne.Bare den første sanne testen i en sammenhengende
if–elif–else-struktur blir utført. Rekkefølgen på testene kan derfor påvirke resultatet.Vi må begynne med
if, menselifogelseer valgfrie.En ny
ifstarter en ny og uavhengig test.
Du kan kjøre og endre pH-programmet i editoren nedenfor.
Når tall nesten er like#
Målte og beregnede flyttall er sjelden nøyaktige. En pH-verdi som i teorien skal være 7, kan for eksempel bli lagret som 6.999999999. Da vil testen pH == 7 være usann. Ofte er det bedre å undersøke om verdien ligger innenfor en rimelig toleranse:
pH = 6.99
toleranse = 0.01
if abs(pH - 7) <= toleranse:
print("Løsningen er nøytral")
Løsningen er nøytral
Hvor stor toleransen bør være, avhenger av måleusikkerheten og hva beregningen skal brukes til. I tillegg avhenger pH-verdien for en nøytral løsning av temperaturen. Kriteriet pH = 7 er derfor en forenkling som passer omtrent ved 25 °C.
Sammensatte vilkår#
Noen ganger må flere kriterier være oppfylt samtidig. Da kan vi kombinere tester med and, or og not.
Operator |
Betydning |
|---|---|
|
Begge kriteriene må være sanne |
|
Minst ett av kriteriene må være sant |
|
Snur en logisk verdi fra sann til usann eller omvendt |
Anta for eksempel at en analysemetode har et anbefalt absorbansområde fra 0,10 til 1,00. Da kan vi undersøke om en måling ligger i området slik:
absorbans = 0.82
if absorbans >= 0.10 and absorbans <= 1.00:
print("Målingen ligger i det anbefalte området.")
else:
print("Vurder å justere prøven eller målebetingelsene.")
Python lar oss også skrive den samme testen som en kjedet sammenlikning:
if 0.10 <= absorbans <= 1.00:
print("Målingen ligger i det anbefalte området.")
Tallgrensene er bare et eksempel. Det gyldige området må bestemmes ut fra instrumentet, kalibreringen og analysemetoden som faktisk brukes.
Med or kan vi teste om absorbansen ligger utenfor området:
if absorbans < 0.10 or absorbans > 1.00:
print("Målingen ligger utenfor det anbefalte området.")
Underveisoppgave
Gibbs’ frie energi, \(\Delta G\), kan brukes til å vurdere om en prosess er termodynamisk favorisert under bestemte betingelser. Fullfør programmet slik at det skiller mellom negativ, positiv og tilnærmet null fri energi. Bruk en toleranse på 0,01 kJ/mol rundt null.
delta_G = float(input("Oppgi ΔG i kJ/mol: "))
toleranse = 0.01
# Skriv vilkåret her
Løsningsforslag
delta_G = float(input("Oppgi ΔG i kJ/mol: "))
toleranse = 0.01
if delta_G < -toleranse:
print("Prosessen er termodynamisk favorisert i framoverretningen.")
elif delta_G > toleranse:
print("Prosessen er ikke termodynamisk favorisert i framoverretningen.")
else:
print("Systemet er omtrent ved likevekt.")
Fortegnet til \(\Delta G\) sier noe om den termodynamiske drivkraften under de gitte betingelsene, men ikke hvor raskt prosessen går.
Nøstede vilkår#
Vi kan også ha vilkår inni vilkår. Dette er spesielt nyttig dersom en ny vurdering bare er relevant når et tidligere kriterium er oppfylt. Da får hvert nytt nivå et ekstra innrykk.
Nedenfor ser du et forenklet eksempel fra kvalitetskontroll av en spektrofotometrisk måling. Absorbansen vurderes bare dersom prøven allerede er blankkorrigert.
blankkorrigert = input("Er målingen blankkorrigert (ja/nei)? ").strip().lower()
if blankkorrigert == "ja":
absorbans = float(input("Oppgi absorbansen: "))
if 0.10 <= absorbans <= 1.00:
print("Målingen ligger i det anbefalte området.")
else:
print("Vurder å fortynne prøven eller endre målebetingelsene.")
elif blankkorrigert == "nei":
print("Blankkorriger målingen før absorbansen vurderes.")
else:
print("Svar med 'ja' eller 'nei'.")
Her hører den innerste if–else-strukturen til det første vilkåret. Den blir derfor bare undersøkt når brukeren har svart ja. Kommandoene strip() og lower() fjerner eventuelle mellomrom og gjør teksten om til små bokstaver. Dermed blir for eksempel Ja tolket som ja.
Nøsting er nyttig når testene faktisk er avhengige av hverandre. For mange nivåer kan derimot gjøre programmet vanskelig å lese. Da kan det være bedre å dele problemet opp i flere trinn eller bruke sammensatte vilkår.
Oppgaver#
Oppgave 3.1
Forklar hvorfor de to programmene nedenfor skriver ut ulike temperaturer. Hva blir skrevet ut i hvert tilfelle?
temperatur = 25
if temperatur > 20:
temperatur = temperatur + 5
temperatur = temperatur + 2
print(temperatur)
temperatur = 25
if temperatur > 20:
temperatur = temperatur + 5
else:
temperatur = temperatur + 2
print(temperatur)
Løsningsforslag
Temperaturen er større enn 20, og begge programmene utfører derfor temperatur = temperatur + 5.
I det første programmet ligger temperatur = temperatur + 2 utenfor vilkåret. Linja utføres derfor uansett om testen er sann eller usann. Programmet skriver ut 32.
I det andre programmet tilhører den samme beregningen else-delen. Den utføres bare dersom temperaturen ikke er større enn 20. Programmet skriver derfor ut 30.
Oppgave 3.2
Lag et program som tar temperatur, smeltepunkt og kokepunkt som input. Programmet skal skrive ut om stoffet er i fast fase, væskefase eller gassfase. La programmet gi en egen beskjed dersom temperaturen er nøyaktig lik smeltepunktet eller kokepunktet.
Dette er en forenklet modell for et rent stoff ved et bestemt trykk. Ved faseovergangene kan to faser være til stede samtidig.
Løsningsforslag
temperatur = float(input("Temperatur i °C: "))
smeltepunkt = float(input("Smeltepunkt i °C: "))
kokepunkt = float(input("Kokepunkt i °C: "))
if temperatur < smeltepunkt:
print("Stoffet er i fast fase.")
elif temperatur == smeltepunkt:
print("Stoffet er ved smeltepunktet.")
elif temperatur < kokepunkt:
print("Stoffet er i væskefase.")
elif temperatur == kokepunkt:
print("Stoffet er ved kokepunktet.")
else:
print("Stoffet er i gassfase.")
Oppgave 3.3
En analysemetode har i denne oppgaven et anbefalt absorbansområde fra 0,10 til 1,00. Lag et program som tar absorbans som input og skiller mellom fire tilfeller: ugyldig negativ verdi, for lav absorbans, absorbans i anbefalt område og for høy absorbans.
Løsningsforslag
absorbans = float(input("Oppgi absorbansen: "))
if absorbans < 0:
print("Absorbansen kan ikke være negativ i denne modellen.")
elif absorbans < 0.10:
print("Absorbansen er lavere enn det anbefalte området.")
elif absorbans <= 1.00:
print("Absorbansen ligger i det anbefalte området.")
else:
print("Absorbansen er høyere enn det anbefalte området.")
Legg merke til at vi ikke trenger å teste nedre grense på nytt i den tredje grenen. Dersom Python kommer så langt, vet vi allerede at absorbansen verken er negativ eller mindre enn 0,10.
Oppgave 3.4
Lag et program som tar reaksjonsentalpien til to reaksjoner som input. Programmet skal skrive ut hvilken reaksjon som er mest eksoterm, eller om reaksjonsentalpiene er like. Husk at den mest eksoterme reaksjonen har den mest negative verdien av \(\Delta H\).
Løsningsforslag
delta_H1 = float(input("ΔH for reaksjon 1 i kJ/mol: "))
delta_H2 = float(input("ΔH for reaksjon 2 i kJ/mol: "))
if delta_H1 < delta_H2:
print("Reaksjon 1 er mest eksoterm.")
elif delta_H2 < delta_H1:
print("Reaksjon 2 er mest eksoterm.")
else:
print("Reaksjonene har lik reaksjonsentalpi.")
Oppgave 3.5
For en reaksjon kan vi sammenlikne reaksjonskvotienten \(Q\) med likevektskonstanten \(K\). Lag et program som tar positive verdier for \(Q\) og \(K\) som input. Programmet skal skrive ut om systemet vil forskyves mot produkter (\(Q < K\)), mot reaktanter (\(Q > K\)), eller er ved likevekt (\(Q = K\)).
Løsningsforslag
Q = float(input("Oppgi reaksjonskvotienten Q: "))
K = float(input("Oppgi likevektskonstanten K: "))
if Q < K:
print("Systemet forskyves mot produkter.")
elif Q > K:
print("Systemet forskyves mot reaktanter.")
else:
print("Systemet er ved likevekt.")
Oppgave 3.6
Modifiser programmet i oppgave 3.5 slik at systemet regnes som tilnærmet ved likevekt når det relative avviket mellom \(Q\) og \(K\) er høyst 1 %. Vi forutsetter at \(K > 0\).
Det relative avviket kan beregnes slik:
Løsningsforslag
Q = float(input("Oppgi reaksjonskvotienten Q: "))
K = float(input("Oppgi likevektskonstanten K: "))
relativt_avvik = abs(Q - K) / K
if relativt_avvik <= 0.01:
print("Systemet er tilnærmet ved likevekt.")
elif Q < K:
print("Systemet forskyves mot produkter.")
else:
print("Systemet forskyves mot reaktanter.")
Testen for tilnærmet likevekt må komme først. Ellers vil nesten alle verdier bli fanget opp av Q < K eller Q > K før toleransen blir undersøkt.
Oppgave 3.7
Lag en enkel stoffmengdekalkulator basert på sammenhengen \(n = m/M\). Brukeren skal velge om programmet skal beregne stoffmengde (n), masse (m) eller molar masse (M). Programmet skal deretter be om de to størrelsene som trengs, utføre riktig beregning og skrive ut svaret med enhet.
Løsningsforslag
valg = input("Hva vil du beregne (n, m eller M)? ").strip()
if valg == "n":
masse = float(input("Masse i g: "))
molar_masse = float(input("Molar masse i g/mol: "))
stoffmengde = masse / molar_masse
print(f"Stoffmengden er {stoffmengde:.3f} mol.")
elif valg == "m":
stoffmengde = float(input("Stoffmengde i mol: "))
molar_masse = float(input("Molar masse i g/mol: "))
masse = stoffmengde * molar_masse
print(f"Massen er {masse:.3f} g.")
elif valg == "M":
masse = float(input("Masse i g: "))
stoffmengde = float(input("Stoffmengde i mol: "))
molar_masse = masse / stoffmengde
print(f"Den molare massen er {molar_masse:.3f} g/mol.")
else:
print("Ugyldig valg. Skriv n, m eller M.")
Oppgave 3.8
Lag et program der du kan taste inn bølgelengden til synlig lys i nm og få ut hvilken farge lyset omtrent tilsvarer. Utvid eventuelt programmet med andre deler av det elektromagnetiske spekteret. Grensene mellom fargene er omtrentlige og kan variere mellom ulike kilder.
Løsningsforslag
bølgelengde = float(input("Skriv inn lysets bølgelengde i nm: "))
if bølgelengde < 380 or bølgelengde > 750:
farge = "utenfor det synlige området"
elif bølgelengde < 420:
farge = "fiolett"
elif bølgelengde < 490:
farge = "blå"
elif bølgelengde < 575:
farge = "grønn"
elif bølgelengde < 585:
farge = "gul"
elif bølgelengde < 650:
farge = "oransje"
else:
farge = "rød"
print(f"Bølgelengden tilsvarer {farge} lys.")
Hvorfor trenger vi ikke skrive den nedre grensa i hver elif-test?
Oppgave 3.9
Lag et program som tar konsentrasjonen av \(H_3O^+\) som input og beregner pH:
Programmet skal deretter skrive ut om løsningen er sur, basisk eller tilnærmet nøytral. Bruk en toleranse på 0,01 pH-enheter rundt pH 7. Test programmet med \([H_3O^+] = 1\cdot 10^{-7}\) mol/L.
Vi bruker pH 7 som nøytralpunkt i denne forenklede oppgaven, altså omtrent 25 °C.
Løsningsforslag
from math import log10
oksonium = float(input("[H3O+] i mol/L: "))
if oksonium <= 0:
print("Konsentrasjonen må være større enn null.")
else:
pH = -log10(oksonium)
toleranse = 0.01
if abs(pH - 7) <= toleranse:
print(f"pH = {pH:.2f}. Løsningen er tilnærmet nøytral.")
elif pH < 7:
print(f"pH = {pH:.2f}. Løsningen er sur.")
else:
print(f"pH = {pH:.2f}. Løsningen er basisk.")
Oppgave 3.10
En buffer virker vanligvis best i området \(pK_a \pm 1\). Lag et program som tar \(pK_a\) og ønsket pH som input. Programmet skal skrive ut om pH ligger innenfor det omtrentlige bufferområdet. Utvid programmet slik at det også forteller om pH ligger under eller over området.
Løsningsforslag
pKa = float(input("Oppgi pKa: "))
pH = float(input("Oppgi ønsket pH: "))
nedre_grense = pKa - 1
øvre_grense = pKa + 1
if nedre_grense <= pH <= øvre_grense:
print("pH ligger innenfor det omtrentlige bufferområdet.")
elif pH < nedre_grense:
print("pH ligger under det omtrentlige bufferområdet.")
else:
print("pH ligger over det omtrentlige bufferområdet.")
Video#
Se videoen nedenfor for å få en gjennomgang av det viktigste når vi skal programmere if-tester i Python: