The file parse_ints.py contains a program that does the following:
prompts for and reads in a line of input
tokenizes the string by splitting it into a list of strings that were separated by white space.
computes the sum of the tokens by converting each to an int
prints the sum
Save parse_ints.py to your directory and run it. If you give it the input:
10 20 30 40
It should print:
The sum of the integers on the line is 100.
Now try a line that contains both integers and other values, for example:
We have 2 dogs and 1 cat.
You will get a ValueError
when it tries to call int()
on "We",
which is not an integer. One way around this is to put the loop that
computes the sum inside a try block and handle the ValueError
, by
passing. This way if it's not an integer it doesn't cause an error;
it goes to the exception handler, which does nothing. Do this as
follows:
Modify the program to add a try statement that encompasses the
entire for loop. Handle a ValueError
and have pass
for the except
body.
Compile and run the program and enter a line with mixed integers and other values. You should find that it stops summing at the first non-integer, so the input "We have 2 dogs and 1 cat" will produce a sum of 0, and the line "1 fish 2 fish red fish blue fish" will produce a sum of 1. This is because the entire loop is inside the try, so when an exception is raised the loop is terminated.
To make it continue, move the try and except clauses inside the loop. Now when an exception is thrown, the next statement is the next iteration of the loop, so the entire line is processed. Both the dogs-and-cats input and the fish input should now give a sum of 3.
The file factorials.py contains a program that calls
the factorial
function of the class to compute the factorials of
integers entered by the user. Save the file to your directory, study
the code, and run factorials.py to see how it works. Try to break the
program, there are two different ways that you can, non-integer input,
and negative input. You can use exceptions to handle both types of
input errors. First, fix the non-integer input errors by doing the
following:
When a non integer input is entered the call to the built-in
function int
fails with a ValueError
. Modify the loop body so
that if a value error is produced, the factorial function will not be
executed and the result will not be printed, but instead it should
print "invalid input". In either case the program should still prompt
the user for another factorial. Run the program and verify that it
continues to run if an integer is not entered.
Try entering a negative integer to the program. Note that the
program does not crash, but it produces erroneous output, factorial
does not exist for negative integers. The pre-condition for the
compute_factorial
function is that the input must be a positive
integer. This means that it is the calling function's responsibility
to not pass invalid input. However, by using exceptions, it is
possible for a function to pass information back to the calling
function about how its preconditions were not met. This make both
finding and dealing with errors in code much easier.
Fix the negative-integer input error by raising a ValueError
in
the compute_factorial
function if the non_negative_integer
parameter is negative. You do this by instantiating a ValueError
object, and using the raise statement. Note, the value error should specify a string
explaining why the exception was raised. Run the program and verify
that inputting a negative integer does not stop the program.
Putting checks on user input to prevent program crashes is often
called idiot-proofing code. The factorial program from the previous
exercise is now idiot-proof, but it could be more user friendly. For
example, if the user enters invalid input it doesn't inform the user
why the input was invalid. The compute_factorials
function can
easily distinguish between why an exception was raised if the
exceptions are different. Currently, however, both exceptions,
non-integer and negative integer exceptions, are ValueError
exceptions. This can be fixed by using inheritance to create a new
exception type, BadInputError
, by doing the following:
Inside the factorials.py file create a new class called
BadInputError
that extends Exception
. Add the __init__
method
to the class that takes a message that describes the error and stores
it as an instance variable. Also add the __str__
method to the
class that returns the message instance variable.
In the compute_factorial
function change the type of the raised
exception to BadInputError
. In the compute_factorials
function
add a second except clause for a BadInputError
. The body of the
BadInputError
clause should print an error message explaining that
the input must be non-negative. Also modify the print statement of
the ValueError
except clause to state that the input must be an
integer. Run the program and verify that a different message is
printed depending on the error in the input.
Submit a zip file of your code on the course Inquire site that uses your last names as the file name.