x = int(input("What's x? "))
print(f"x is {x}")
If user input is a
str
, we will get the runtime errorValueError
(the value of variable is not the one expected).
try:
x = int(input("What's x? "))
print(f"x is {x}")
except ValueError:
print("x is not an integer")
- Best practice is we should
try
the fewest lines of code possible
try:
x = int(input("What's x? "))
except ValueError:
print("x is not an integer")
print(f"x is {x}")
Now if user input is a str, we will get the runtime error NameError: name ‘x’ is not defined. This is because the wrong input triggers the Error handling
except
before ‘x’ gets to be defined.
- try and except with
else
block
try:
x = int(input("What's x? "))
except ValueError:
print("x is not an integer")
else:
print(f"x is {x}")
Now if the except block does not get triggered, the
else
block will.
- try and except with
while
loop andelse
block
while True:
try:
x = int(input("What's x? "))
except ValueError:
print("x is not an integer")
else:
break
print(f"x is {x}")
Now, with the
while
loop, if the except block gets triggered, the program will prompt the user again infinitely until the right value is entered.
- Create the function
get_int()
def main():
x = get_int()
print(f"x is {x}")
# Version 1
def get_int():
while True:
try:
x = int(input("What's x? "))
except ValueError:
print("x is not an integer")
else:
break
return x
main()
# Version 2
def get_int():
while True:
try:
x = int(input("What's x? "))
except ValueError:
print("x is not an integer")
else:
return x
The break is not needed,
return x
will stop the loop while returning the value.
# Version 3
def get_int():
while True:
try:
x = int(input("What's x? "))
return x
except ValueError:
print("x is not an integer")
The
else
block can be removed. Placingreturn x
in thetry
statement
# Version 4
def get_int():
while True:
try:
return int(input("What's x? "))
except ValueError:
print("x is not an integer")
We can even avoid an extra line for the
return
x statement and avoid defining x explicitly byreturning
the result ofint(input(...))
- try and except with
pass
def get_int():
while True:
try:
return int(input("What's x? "))
except ValueError:
pass
We can use the
pass
keyword to not act on the error and simply prompt again.
- Final refined version of
get_int()
adding a function parameter
def main():
x = get_int("What's x? ")
print(f"x is {x}")
def get_int(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
pass
main()
We can improve the implementation of the
get_int()
function. It is a good idea formain()
to show the prompt argument("What's x? ")
and theget_int()
to accept a parameter (prompt).
distances = {
"Voyager 1": "163",
"Voyager 2": "136",
"Pioneer 10": "80 AU",
"New Horizons": "58",
"Pioneer 11": "44 AU"
}
def main():
spacecraft = input("Enter a spacecraft: ")
m = convert(distances[spacecraft])
print(f"{m} m away")
def convert(au):
return au * 149597870700
main()
Because passing a
string
to theconvert()
function, the function will attempt to multiply the string by the huge number and this code will result in aMemoryError
. We need to convert the string before converting the units.
def main():
spacecraft = input("Enter a spacecraft: ")
au = float(distances[spacecraft])
m = convert(au)
print(f"{m} m away")
Now we fixed the
string
problem converting the strings tofloats
before they are passed in as arguments toconvert()
. But we still have messy data in some of the key-value pairs, where the value is a string composed of letters and digits =ValueError
- try and except
def main():
spacecraft = input("Enter a spacecraft: ")
try:
au = float(distances[spacecraft])
except ValueError:
print(f"Can’t convert '{distances[spacecraft]}' to a float")
return
m = convert(au)
print(f"{m} m away")
The
try
andexcept
block will now handle theValueError
.
- Adding except blocks for different errors
def main():
spacecraft = input("Enter a spacecraft: ")
try:
au = float(distances[spacecraft])
except KeyError:
print(f" '{spacecraft}' is not in dictionary")
return
except ValueError:
print(f"Can't convert '{distances[spacecraft]}' to a float")
return
m = convert(au)
print(f"{m} m away")
We now have an
except
block for eachValueErrors
andKeyErrors
. It is important to try to anticipate potential errors when writing code and include them in the try and except block.