300 likes | 453 Views
CS 115 Lecture 18. Exceptions and files Taken from notes by Dr. Neil Moore & Dr. Debby Keen. Run-time errors. Remember the three types of errors: Syntax error (code will not run) Run-time error (detected when code runs, crashes)
E N D
CS 115 Lecture 18 Exceptions and files Taken from notes by Dr. Neil Moore & Dr. Debby Keen
Run-time errors Remember the three types of errors: • Syntax error (code will not run) • Run-time error (detected when code runs, crashes) • Semantic error (not detected by interpreter, program gives incorrect output or behavior) Another name for a run-time error in Python is an exception. • Probably from “the exception, not the rule” • Signaling a run-time error is called raising an exception • Also called “throwing” an exception (C++ and Java)
Exceptions • By default, raising an exception crashes your program. • But exceptions can be caught and handled. • There are many different kinds of exceptions: • TypeError: argument has the wrong type • ValueError: argument has a good type but a bad value • IndexError: accessing a sequence (a string, a list) out of range • ZeroDivisionError: just what it says • IOError: file problem, such as “file not found” • RuntimeError: “none of the above” • https://docs.python.org/3/library/exceptions.html
Catching exceptions By default, exceptions cause the program to crash. • Because that’s better than continuing to run and doing the wrong thing • But sometimes you might have a better idea for how to handle it • For example, type-casting a string to int • if the string wasn’t numeric, Python can’t give you a number • You asked Python to do something and it can’t • Exception! • But maybe you know what to do in this particular case • If it was user input, repeat the input and ask again • If it came from a file, maybe ignore that line • Maybe the program can use a default value • Sometimes you can prevent the exception by checking before you do the action, like comparing a denominator to zero before dividing by it • But there are errors that you cannot check for without trying it
try/except syntax To catch an exception, you use a try / except statement: try: body that might raise an exception except ExceptionClass: handle the exception code that comes after • ExceptionClass is one of that list: ValueError, IOError, etc.
try/except semantics • If the code in the body raises the specified exception: • The body stops executing immediate (like a “goto”) • Doesn’t even finish the current line! • Then Python runs the except block (instead of crashing) • After the body (called the handler) is finished, go on to the code that follows • You can have several except blocks for different exceptions for the same try block. • Or one block for more than one exception: except (ValueError, IndexError):
An exception example • How do we get the input and convert it to a number? number = float(input(“please enter a number: “)) • float(…) raises a ValueError on a non-numeric input • Use try/except block.
Hints for catching exceptions • Have a plan! If you don’t know how to fix the error, don’t catch it • It’s better to crash than to continue with bad data • Keep the try block as small as possible • It should contain the line that might raise the exception • And subsequent lines that depend on its success • Don’t duplicate code in the try and except blocks • That code belongs after the try/except, so it happens either way • Don’t wrap the whole main in a try! • The program probably won’t know which error happened or how to fix it
Dealing with large amounts of data Some programs need a lot of data. How do you handle it? • Hard code it into the source? • That’s hard to change if you’re not a programmer • Ask the user to type it in each time the program runs? • If it’s more than a few pieces, your users will refuse! Or make typos! • Store your data in an external file! Can be as big as your device can hold! • When you type your program, you save it in a file. Data can be saved too!
Why use files to hold data? • They’re easier to edit than a source file • Files persist across runs of your program • And across reboots of your operating system • They can hold LARGE amounts of data (more than will fit in RAM!) • You can use the same data file as input for different programs • You can use the output of one program as input to another
Using files As in other programs (word processors, IDEs, etc.) you must open a file before you can use it in your program. • Create a file object in your program that represents the file on disk • You can read from or write to the object depending on the mode “r”,”w”,”a” • Input or output comes from the file instead of from the user • Syntax: fileobj = open(filename, “r”) # r for reading (input) fileobj = open(filename) # default is reading fileobj = open(filename, “w”) # w for writing • fileobj is a variable that will hold the file object • filename is a string that names the file (can be a constant or a variable)
Filenames • The default location for a data file is the current directory, i.e., the file your py file is saved in • You can specify an absolute path if you want open(“C:\\Users\\me\\input.txt”)
IOError If we are trying to read from a file, what can go wrong? • Maybe the file isn’t there • Or it’s there but you don’t have permissions to access it • Or you do but then your hard drive crashes • In these situations, opening a file raises an IOError exception • Renamed to OSError in Python 3.4 • You can catch the exception just like any other • But there’s no point in trying to open again with the same filename • A common fix is to ask the user for another filename
Exception while opening try: fn = input(“Enter a filename: “) infile = open(fn, “r”) except IOError: print(“Could not open” , fn)
Looping over the lines in a file The simplest way to use an input file once you have successfully opened it is to loop over the lines in the file • A file object can be used as a sequence of lines for a for loop: for line in myfile: • Each line is a string delimited by a newline character. • myfile is a file object, NOT a filename! • When you’re finished with a file, make sure to close the file! • Frees up resources associated with the file • If you don’t, the file will take up memory until the program exits • … if not longer than that!
Text files: characters and bytes Two type of files: • Text file stores a sequence of characters • Binary file stores a sequence of bytes
Text files: what is a line? So if a text file is a sequence of characters, what’s a line? • A sequence of characters delimited by the newline character • Newline (‘\n’) is the line delimiter
Sequential and random access • Sequential access: reading or writing the file in order starting from the beginning and going to the end • Similar to how a for loop works on a list or string • Read the first line, then the second line, etc. No skipping, no backing up! • Random access: reading or writing without regard to order • “Go to byte 7563 and put a 7 there” • Like lists: we can use mylist[5] without having to go through indexes 0 through 4 first • Also called direct access
Sequential and random access • Text files usually use sequential access • Binary files can use either sequential or random access
Reading a line at a time • Here’s one way to read a line at a time for line in file: • This technique is very useful but a little inflexible: • It only lets us use one line per iteration • But what if our file looked like this? Student 1 Score 1 … • The readline method lets you control reading more precisely. line = infile.readline()
Readline • line = infile.readline() • This reads a single line from the file • Returns a string, including the newline at the end • The next time you do input, you get the next line • Even if you use a different input technique next time
Reading a whole file at once Python also gives us two methods that read in the whole file at once • That’s much easier if we need to process the contents out of order • Or if we need to process each line several times • But it doesn’t work if the file is larger than RAM. • readlines gives us the whole file as a list of strings (note the s on the end of the name) line_list = infile.readlines() infile.close() #close, the file is exhausted for line in line_list:
Reading a whole file another way • read gives us the whole (rest of the) file as a single string • newlines and all content = infile.read() infile.close() • As with readlines, you might as well close it immediately • What to do with the string? • You can use split line_list = content.split(“\n”) • Unlike other methods, this gives you a list of strings without newlines Because split removes the delimiter
Output files It’s possible to write to files too • First, open the file for writing: outfile = open(“out.txt”, “w”) # w for write mode • If the file does not already exist, it creates it • If the file already exists, truncates it to zero bytes!! • Cuts everything out of the file to start over • The old data in the file is lost forever! • Opening for writing is both creative and destructive. • You can also open a file for appending: logfile = open(“audit.log”, “a”) # a for append • Adds to the end of an existing file – no truncation, no data lost • If the file doesn’t exist, will still create it. • Which to use? Do you want to add to the file or overwrite it?
Writing to an output file There are two ways to write to an output file: • You can use the same print function that we’ve been using • Just give an extra argument at the end, file = fileobj print(“Hello,”, name, file = outfile) • You can also write a string with the write method • Takes one string argument (nothing else!) outfile.write(“Hello, world!\n”) • Does not automatically add a newline character!
Closing files • You should close a file when you are finished with it outfile.close() • Frees resources (like the file buffer!) • When to close a file? • As soon as you know you don’t have to read / write it again • Immediately after your loop • With read or readlines, immediately after that statement
Files versus lists • Files are • Permanent “persistent” • Bigger (must fit on your device) • Slower to access • Sequential-access (as we do it in this class) • Lists are • Temporary • Smaller (must fit in memory) • Faster to access • Random or sequential access