Felhantering

Ett program ska inte krascha bara för att användaren skriver fel. Felhantering innebär att man försöker förutse vad som kan gå fel och programmerar så att felen tas om hand. Målet är att du ska kunna använda try och except.

Vad kan gå fel?

Vanliga orsaker till fel är till exempel att

  • användaren skriver in något oväntat, till exempel text när programmet vill ha ett tal,
  • programmet försöker dividera med noll,
  • internetanslutningen är långsam eller borta,
  • en server som programmet ska hämta data från har kraschat.

Kör programmet och skriv hej i stället för ett tal:

Python · du kan ändra koden
tal = int(input("Skriv ett heltal: "))
print(f"Dubbla talet är {tal * 2}")

Programmet kraschar med ett ValueError: texten hej går inte att omvandla till ett heltal.

try och except

Kod som riskerar att krascha läggs i ett try-block. Uppstår ett fel hoppar programmet till except, som tar hand om felet i stället för att programmet kraschar. Du kan fånga en viss sorts fel, som ValueError, eller alla fel med ett except: utan feltyp.

Python · du kan ändra koden
try:
    tal = int(input("Skriv ett heltal: "))
    print(f"Dubbla talet är {tal * 2}")
except ValueError:
    print("Du måste skriva ett heltal.")
except:
    print("Något annat gick fel.")

Några vanliga fel:

ValueError
Värdet går inte att omvandla, till exempel int("hej").
ZeroDivisionError
Division med noll, till exempel 10 / 0.
TypeError
Fel datatyp, till exempel "5" + 5.
IndexError
Indexet finns inte i listan.
KeyError
Nyckeln finns inte i ett dictionary.

Försök igen tills det blir rätt

Genom att lägga try i en while True-loop kan användaren få försöka igen. Loopen avbryts med break först när omvandlingen lyckas — blir det fel startar loopen om och frågar igen.

Python · du kan ändra koden
while True:
    try:
        value = float(input("Ange temperaturvärdet: "))
        break
    except ValueError:
        print("Inte ett tal, prova igen.")

print(f"Temperaturen är {value}")

Uppgifter

Uppgift · Räkna med mig! – med felhantering

Gör om programmet Räkna med mig! från kapitlet om input och output, men med felhantering. Programmet ska inte krascha om användaren skriver något som inte är ett tal, eller om det andra talet är 0. De två fel du behöver fånga är:

  • ValueError – inmatningen går inte att omvandla till ett tal,
  • ZeroDivisionError – det går inte att dividera med 0.
Din lösning · du kan ändra koden
# Skriv din kod här
Visa lösningsförslag
Python · du kan ändra koden
print("Välkommen till Räkna med mig!")

while True:
    try:
        tal1 = float(input("Skriv det första talet: "))
        tal2 = float(input("Skriv det andra talet: "))
        break
    except ValueError:
        print("Det där var inte ett tal. Försök igen.")

print(f"Summan av talen är {tal1 + tal2}")
print(f"Differensen av talen är {tal1 - tal2}")
print(f"Produkten av talen är {tal1 * tal2}")

try:
    print(f"Kvoten av talen är {tal1 / tal2:.2f}")
except ZeroDivisionError:
    print("Kvoten går inte att räkna ut – man kan inte dividera med 0.")

Uppgift · Temperaturomvandling

Skriv ett program som omvandlar mellan temperaturskalorna Celsius (C), Fahrenheit (F) och Kelvin (K).

  1. Fråga användaren vilken skala temperaturen anges i: C, F eller K.
  2. Fråga efter temperaturvärdet som ska omvandlas, till exempel 15 för 15 grader.
  3. Skriv ut temperaturen i de två andra skalorna.

Felkontroller:

  • Om användaren inte skriver C, F eller K ska programmet skriva ut ett felmeddelande.
  • Temperaturer under absoluta nollpunkten finns inte: under 0 i Kelvin, under −273,15 i Celsius eller under −459,67 i Fahrenheit ska ge ett felmeddelande.
  • Lägg in try/except på de ställen där du tror att det kan bli fel.

Formler för omvandlingen:

Celsius
Till
Fahrenheit
Formel
F = C · 9/5 + 32
Celsius
Till
Kelvin
Formel
K = C + 273,15
Fahrenheit
Till
Celsius
Formel
C = (F − 32) · 5/9
Fahrenheit
Till
Kelvin
Formel
K = (F − 32) · 5/9 + 273,15
Kelvin
Till
Celsius
Formel
C = K − 273,15
Kelvin
Till
Fahrenheit
Formel
F = (K − 273,15) · 9/5 + 32

Tänk på att Python skriver decimaltal med punkt: 273,15 blir 273.15 i koden.

Din lösning · du kan ändra koden
# Skriv din kod här
Visa lösningsförslag
Python · du kan ändra koden
while True:
    # upper() gör om till stora bokstäver, så att även c, f och k fungerar
    skala = input("Vilken skala anger du temperaturen i? (C, F eller K) ").upper()
    if skala == "C" or skala == "F" or skala == "K":
        break
    print("Du måste skriva C, F eller K.")

while True:
    try:
        värde = float(input("Ange temperaturvärdet: ").replace(",", "."))
        break
    except ValueError:
        print("Inte ett tal, prova igen.")

# Räkna först om till Celsius – då räcker det att kontrollera en gräns.
if skala == "C":
    celsius = värde
elif skala == "F":
    celsius = (värde - 32) * 5 / 9
else:
    celsius = värde - 273.15

if celsius < -273.15:
    print("Så kallt kan det inte bli – det är under absoluta nollpunkten.")
else:
    fahrenheit = celsius * 9 / 5 + 32
    kelvin = celsius + 273.15
    if skala != "C":
        print(f"{celsius:.2f} °C")
    if skala != "F":
        print(f"{fahrenheit:.2f} °F")
    if skala != "K":
        print(f"{kelvin:.2f} K")

Snabbkoll

Har du förstått?

1.När körs koden under except ValueError:?

2.Vilket fel ger 10 / 0?

3.Varför läggs try ofta i en while True-loop med break?