Here are our solutions for the day 19 exercises in the 30 Days of Python series. Make sure you try the exercises yourself before checking out the solutions!
1) Create a short program that prompts the user for a list of grades separated by commas. Split the string into individual grades and use a list comprehension to convert each string to an integer. You should use a try
statement to inform the user when the values they entered cannot be converted.
Let's start by writing our input
call to grab the list of grades. We can also use the split
method to split the string we get back from input
all on the same line.
grades = input("Please enter your grades, separated by commas: ").split(",")
Before we move on, let's consider what happens if the user enters something like this in response to our prompt:
76, 93, 84, 81
Here we have spaces after all of the commas, so our resulting grades
list would be:
['76 ', '93 ', '84 ', '81']
This isn't a problem though, because Python is happy to accept the string '76 '
as a valid argument to int
or float
, and it will strip off the whitespace for us.
It's therefore not necessary to do something like this:
grades = input("Please enter your grades, separated by commas: ").split(",")
grades = [grade.strip() for grade in grades]
Now we get to the meat of the exercise. We need to try to convert each string to an integer, and then we need to catch any exceptions that arise from the user providing invalid values.
In the event that the user enters an invalid value, we're going to get a ValueError
, so this is the exception we need to catch with our except
clause.
grades = input("Please enter your grades, separated by commas: ").split(",")
try:
pass
except ValueError:
pass
Inside the try
clause I'm going to create a list comprehension to convert each string to an integer. I'm then going to assign the result to grades
. If you need a reminder on how list comprehensions work, take another look at day 15.
Inside the except
clause I'm going to write a message informing the user that their data was in an invalid format.
In a more complete application, the rest of our code working with grades
would likely go in an else
clause, but we don't have to worry about that here.
grades = input("Please enter your grades, separated by commas: ").split(",")
try:
grades = [int(grade) for grade in grades]
except ValueError:
print("The grades you entered were in an invalid format.")
2) Investigate what happens when there is a return
statement in both the try
clause and finally
clause of a try
statement.
In order to complete this exercise, we're going to need to write a function, since we need a function actually return from.
We don't have to get too fancy here. This will do:
def func():
pass
Now let's put our try
statement in the function body. I recommend you use something different for the two return values so that we know where our values come from.
Something like the function below would be appropriate:
def func():
try:
return "Returned from the try clause!"
finally:
return "Returned from the finally clause!"
Now let's call our function and see what happens.
def func():
try:
return "Returned from the try clause!"
finally:
return "Returned from the finally clause!"
print(func()) # "Returned from the finally clause!"
Perhaps a little surprisingly, we get the value returned in the finally
clause. This makes some sense though, because the finally
clause always runs, and it will interrupt the return
in the try
clause. It effectively puts that return
on hold while it does its own return
.
The problem is that if we carry out the return
in the finally clause, we end the function execution, so we never come back to do the one in the try
clause. It just gets forgotten about.
3) Imagine you have a file named data.txt
. Open it for reading using Python, but make sure to use a try block to catch an exception that arises if the file doesn't exist. Once you've verified your solution works with an actual file, delete the file and see if your try block is able to handle it.
The content of our data.txt
file is something simple like this:
There is some data here!
It's not terribly important.
We also get told that the exception we need to watch our for is FileNotFoundError
.
With that in mind, let's construct our try
statement:
try:
pass
except FileNotFoundError:
pass
Inside our try
clause we're going to write the code to access the file. I'm just going to print the file contents to the console. In the except
clause I'm going to write a message to the user indicating that the file could not be found.
In a real application, we might take this opportunity to create the file for the user instead.
try:
with open("data.txt", "r") as text_file:
print(text_file.read())
except FileNotFoundError:
print("Error: Couldn't find data.txt")
With that, we're done!