Difference between revisions of "CSC111 Lab 9 2014"
(→Challenge 6) |
|||
Line 210: | Line 210: | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
+ | =Catching Exceptions= | ||
<br /> | <br /> | ||
+ | The following code will generate an exception. Run it first! | ||
+ | |||
+ | <source lang="python"> | ||
+ | |||
+ | def divide( x, y ): | ||
+ | z = x / y | ||
+ | return z | ||
+ | |||
+ | a = 10 | ||
+ | b = 5 | ||
+ | c = divide( a, b ) | ||
+ | print( "a = %d b = %d c = %d" % ( a, b, c ) ) | ||
+ | |||
+ | e = 10 | ||
+ | f = 0 | ||
+ | g = divide( e, f ) | ||
+ | print( "e = %d f = %d g = %d" % ( e, f, g ) ) | ||
+ | |||
+ | </source> | ||
<br /> | <br /> | ||
+ | You will have noticed the error reported is a <font color="red"ZeroDivisionError: division by zero</font> | ||
+ | |||
+ | In order to make your code '''robust''' and catch the exception, enclose the dangerous statement with a '''try/catch''' statement, as follows: | ||
<br /> | <br /> | ||
+ | <source lang="python"> | ||
+ | def divide( x, y ): | ||
+ | try: | ||
+ | z = x / y | ||
+ | except ZeroDivisionError: | ||
+ | z = None | ||
+ | return z | ||
+ | </source> | ||
<br /> | <br /> | ||
+ | Deciding to return '''None''' is not necessarily the best practice. It depends on the whole application and what makes sense. | ||
+ | |||
+ | Modify your function and run your program again. You will now have a new error, but this time it is due to the fact that you cannot print '''None''' with a "%d" format. | ||
+ | |||
+ | Since the '''print''' statement generated a <font color="red"TypeError: %d format:</font> exception, protect the print statemen with a '''try/except''' statement that will prevent the program from crashing. | ||
+ | |||
<br /> | <br /> | ||
<br /> | <br /> |
Revision as of 08:38, 2 April 2014
--D. Thiebaut (talk) 23:40, 1 April 2014 (EDT)
Contents
Reading and Writing Text Files
Write Example
# write some variables to file
name = "Smith College"
address = "1 Elm st., Northampton, MA 01063"
file = open( "college.txt", "w" )
file.write( "%s\n" % name )
file.write( "%s\n" % address )
file.close()
Read Example
# read the same file back and print all the lines
file = open( "college.txt", "r" )
for line in file:
print( "line =", line.strip() )
file.close()
Writing Text to File and Reading it Back
Challenge 1 |
- Use the example above and write a program that writes the string text defined below to a file named poem.txt in the same folder (directory) where your program is located.
text = """An Evening by Gwendolyn Brooks A sunset's mounded cloud; A diamond evening-star; Sad blue hills afar; Love in his shroud. Scarcely a tear to shed; Hardly a word to say; The end of a summer day; Sweet Love dead."""
- Once the program terminates, open the file with TextEdit if working on a Mac, or with Notepad if working on Windows. Verify that the file exists and that it contains the poem.
- Put the code that writes the poem to file in a function called writeTextFile( fileName, text ), where fileName is the name of the file, and text the name of the variable. The function should 1) open the file for writing, 2) write text to the file, and 3) close the file.
Verify that your function works by deleting poem.txt and then running your new program. If you function is written correctly, it will have recreated the poem.txt file with the same contents as before.
Challenge 2 |
- Add some code to your program that will read the file just created and print its contents (all the lines) on the screen.
- When this works, put this new code into a function called readTextFile() that is given just the file name (fileName) and that returns a long string that is equal to the contents of the file. Here is an example of how your program will use your new function to read the file and display the string:
text = readTextFile( "poem.txt" )
print( text )
Writing Numbers to File and Reading them Back
Same idea: you write a function that takes a list of numbers and writes them to file, one per line. Then you write a function that reads the numbers back, prints them, and computes their sum. This last part is very important, because to text files contain text, or strings, and when you read that back into variables that are supposed to contain numbers, you must transform the strings into numbers.
Here is the list of numbers to use, and an example of how to organize your main program:
numbers = [ 1, 2, 10, 100, 50, 7 ]
# write the list to file, one number per line
writeIntFile( "numbers.txt", numbers )
# read the file of ints, and return it as a list of ints.
newNumbers = readIntFile( "numbers.txt" )
# print the list of ints and their sum (should be 170)
for x in newNumbers:
print( x )
print( "Sum = ", sum( newNumbers ) )
Creating a Log
Add the function below to your program. Then call it from your main program and "play" with it for a little while. Figure out how to make it stop (read the code!)
from random import choice
def discussion():
canned = [ "Please go on...", "Is that so?", "Please tell me more.", "Really?" ]
print( "Hello!" )
while True:
answer = input( "> " ).strip()
if answer.lower() in [ "bye", "ciao", "later" ]:
break
print( choice( canned ) )
print( "Good bye!" )
Challenge 3 |
- Add some new statements to your function so that it will record the conversation that is taking place on the screen in a log file. A log is simply a text file that contains a list of lines representing actions that have taken place at some point under some circumstances. You may want to call the log log.txt
- Verify that when your function has terminated, a new file exists in your working directory, and that it contains a log of your conversation.
- Run your function again. Finish it with "bye" and check the log file again. Notice that the old conversation has been erased by the new one.
- If we had wanted to add the new conversation at the end of the old one (logs have a tendency to keep everything and never erase prior information), then should have opened the file differently. When we open a file like this:
file = open ( "someFileName.ext", "w" )
the "w" indicates create the file if it does not exist, or erase it if it already exists, and start writing to it." To write to a file without erasing it, we simply replace the "w" by an "a" which means "append" to the end of the file, or create it if it doesn't exist.
file = open( "someFileName.ext", "a" )
Challenge 4 |
- Modify your program so that it appends to the log and never erases it.
Challenge 5 |
- Create a new function called log( fileName, line ) that adds a new line to a log file. This function will open the log, append the list to it, and close it. Using it will make our original discussion function much simpler:
from random import choice
def discussion():
canned = [ "Please go on...", "Is that so?", "Please tell me more.", "Really?" ]
print( "Hello!" )
log( "log.txt", "Hello!" )
while True:
answer = input( "> " ).strip()
log( "log.txt", answer )
if answer.lower() in [ "bye", "ciao", "later" ]:
break
response = choice( canned )
print( response )
log( "log.txt", response )
print( "Good bye!" )
log( "log.txt", "Good bye!" )
Challenge 6 |
- Instead of having canned answers defined in the program, let's put them in a text file. This may seem strange to put strings in a file, except if you think of the Eliza program for the previous homework where the program may add more canned answers to its list as the conversation with the human progresses. If the program were to save the list of canned answers to a file, and restore them from file when it restarts, the program would have "memory" and fool the user in thinking that the program "remembers" parts of a previous conversation.
- Your challenge is to make your conversation function read the canned answers from a different text file where you will have saved canned sentences, one per line.
Catching Exceptions
The following code will generate an exception. Run it first!
def divide( x, y ):
z = x / y
return z
a = 10
b = 5
c = divide( a, b )
print( "a = %d b = %d c = %d" % ( a, b, c ) )
e = 10
f = 0
g = divide( e, f )
print( "e = %d f = %d g = %d" % ( e, f, g ) )
You will have noticed the error reported is a <font color="red"ZeroDivisionError: division by zero</font>
In order to make your code robust and catch the exception, enclose the dangerous statement with a try/catch statement, as follows:
def divide( x, y ):
try:
z = x / y
except ZeroDivisionError:
z = None
return z
Deciding to return None is not necessarily the best practice. It depends on the whole application and what makes sense.
Modify your function and run your program again. You will now have a new error, but this time it is due to the fact that you cannot print None with a "%d" format.
Since the print statement generated a <font color="red"TypeError: %d format:</font> exception, protect the print statemen with a try/except statement that will prevent the program from crashing.