Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Exceptions and File Input A201 – Dr. Wennstrom Tools for Computing: Python Types of errors There are basically two types of errors: • syntax errors • erroneous state errors >>> excuse = 'I'm sick' SyntaxError: invalid syntax >>> print(hour + ':' + minute + ':' + second) TypeError: unsupported operand type(s) for +: 'int' and 'str’ >>> infile = open('foo.txt') IOError: [Errno 2] No such file or directory: 'foo.txt’ Tools for Computing: Python Syntax errors Syntax errors are due to the incorrect format of a statement • Detected when the statement is translated to machine language, before it is executed. >>> (3+4] SyntaxError: invalid syntax >>> if x == 5 SyntaxError: invalid syntax >>> print 'hello' SyntaxError: invalid syntax >>> ls = [4;5;6] SyntaxError: invalid syntax >>> for i in range(10): print(i) SyntaxError: expected an indented block Tools for Computing: Python Erroneous state errors The program execution gets into an erroneous state during run-time >>> 3 / 0 ZeroDivisionError: division by zero >>> ls NameError: name 'ls' is not defined >>> ls = [12, 13, 14] >>> ls[3] IndexError: list index out of range >>> ls = ls * ls TypeError: can't multiply sequence by non-int of type 'list' >>> int('4.5') ValueError: invalid literal for int() with base 10: '4.5' Tools for Computing: Python Erroneous state errors The program execution gets into an erroneous state during run-time When a run-time error occurs, an “error” object is created • This object has a type that is related to the type of error • The object contains information about the error • The default behavior is to print this information and interrupt the execution of the statement. The “error” object is called an exception; the creation of an exception due to an error is called the raising of an exception The programmer can do something special*, using ways to catch an exception and redirect it so as to override the default behavior elsewhere for handling. *We will see how to do this in a little bit. Tools for Computing: Python Raising an exception By typing Ctrl-C, a user can force a KeyboardInterrupt exception to be raised Any exception can be raised within a program with the raise statement • ValueError, like all exception types, is a class • ValueError() uses the default constructor to create an exception (object) • statement raise switches control flow from normal to exceptional • The constructor can take a “message” argument to be stored in the exception object >>> while True: pass Traceback (most recent call last): File "<pyshell#53>", line 2, in <module> pass KeyboardInterrupt >>> raise ValueError() Traceback (most recent call last): File "<pyshell#54>", line 1, in <module> raise ValueError() ValueError >>> raise ValueError('Just joking...') Traceback (most recent call last): File "<pyshell#55>", line 1, in <module> raise ValueError('Just joking...') ValueError: Just joking... >>> try: raise ValueError() except: print('Caught exception.') Caught exception. >>> Tools for Computing: Python Exception types Technically an exception is a group of types, just like sequence can be strings, tuples, and lists. Some of the built-in exception classes: Exception Explanation KeyboardInterrupt Raised when user hits Ctrl-C, the interrupt key OverflowError Raised when a floating-point expression evaluates to a value that is too large ZeroDivisionError Raised when attempting to divide by 0 IOError Raised when an I/O operation fails for an I/O-related reason IndexError Raised when a sequence index is outside the range of valid indexes NameError Raised when attempting to evaluate an unassigned identifier (name) TypeError Raised when an operation of function is applied to an object of the wrong type ValueError Raised when operation or function has an argument of the right type but incorrect value Tools for Computing: Python Exceptions When the program execution gets into an erroneous state, an exception object is created • This object has a type that corresponds to the type of error • The object contains information about the error • The default behavior is to print this information and "crash" "Exception" does not mean error. It means that the normal execution flow of the program is interrupted and execution switches to the exceptional execution flow. Tools for Computing: Python Exceptions The precise categorization of what counts as a ”runtime error" or just an "exception", is different in different programming languages. We're not going to worry to much about those distinctions in this class. But you do need to know what kinds of situations will cause which type of exception in order to deal with them. To talk about how we will deal with these exceptions without crashing, let's revisit a problem similar to ones we've had in the past. In fact, that will be our quiz for today. Tools for Computing: Python Do this: print("Please enter a number:") user_num = float(input()) print("The square of " + str(user_num) + " is " + str(user_num**2) + ".") If we wanted to verify the user's input first using if, we'd need to somehow predict ahead of time whether or not the user's text will successfully convert into a float. Such as….? The string method .isnumeric() only checks if the numbers are all digits (not decimals or fractions, negative numbers, etc.) You could check all the possibilities ahead of time (.isdigit(), .isdecimal(),…), but that could get complicated. But Python already knows how to convert strings into floats. It'd be nice if we could just ask the interpreter to try to convert the string into a float, and have it just alert us (instead of crashing) if something goes wrong. floatingPoint.py Tools for Computing: Python Catching and handling exceptions We can override the default handling of a raised exception by using a try/except statement If an exception is raised during a try block, then the block of the associated except is executed (ie., our contingency plan) try:= int(input('Enter your age: ')) age print('You're age = int(input('Enter nearly {} years your old.'.format(age)) age: ')) print('You're nearly {} years old.'.format(age + 1)) except: print('Enter your age using digits 0-9!') The except code block is the exception handler Default behavior: Custom behavior: >>> ========== ======================== RESTART ========== RESTART ======================== >>> Enter your age: fifteen ValueError: Enter your age invalid usingliteral digits 0-9! for int() with base 10: 'fifteen' Tools for Computing: Python Format of a try/except statement The format of a try/except is: try: <indented code block> except: <exception handler block> <non-indented statement> The exception handler processes any exception raised in the try block The except statement is said to catch the (raised) exception We can parameterize the except clause to only catch exceptions of a specific type try: <indented code block> except <ExceptionType>: <exception handler block> <non-indented statement> Tools for Computing: Python Format of a try/except statement def read_age(filename): 'converts first line of file filename to an integer and prints it' try: infile = open(filename) age = int(infile.readline()) print('age:', age) except ValueError: print('Value cannot be converted to integer.') We can parameterize the except clause to only catch exceptions of a specific type 1 fifteen age.txt default exception handler prints this >>> read_age('age.txt') Value cannot be converted to integer. >>> read_age('age.text') IOError: No such file or directory: 'age.text' Tools for Computing: Python Multiple exception handlers def read_age(filename): 'converts first line of file filename to an integer and prints it' try: infile = open(filename) age = int(infile.readline()) print('age:', age) except IOError: # executed only if an IOError exception is raised print('Input/Output error.') except ValueError: It is possible to restrict the except statement to catch exceptions of # executed only if a ValueError exception is raised a specific type only print('Value cannot be converted to integer.') except: # executed if an exception other than IOError or ValueError is raised print('Other error.') Tools for Computing: Python Now do this: print("Please enter a number:") try: user_num = float(input()) print("The square of " + str(user_num) + " is " + str(user_num**2) + ".") except ValueError: print("That wasn't a valid number.") tryExcept.py Tools for Computing: Python What we really want is to do this: while True: print("Please enter a number:") try: user_input = float(input()) print("The square of " + str(user_input) + " is " \ + str(user_input**2) + ".") break except ValueError: print("That wasn't a valid number. Please try again.") tryExceptWhileTrue.py Exceptions and Files Tools for Computing: Python What we really want is to do this: There's a whole category of errors that can crop up when working with files. • FileNotFoundError if you try to open a file using a filename that doesn't exist. • IsADirectoryError if you try to open a directory and read it as if it were a text file. • PermissionError if you try to open a file that the current user doesn't have permissions to access. Fortunately, all of these error types related to file input and output are subtypes of IOError, so we can account for any kind of problem involving working with files by just catching the IOErrors. tryExceptWhileTrue.py Tools for Computing: Python Files and the file system root folder / Applications bin Users Mail.app Firefox.app cepope Contents image.jpg MacOS Mail binary file The file system is the OS component that organizes files and provides a way to create, access, and modify files var Shared poem.txt text file poem.txt Info Files are organized in a tree structure • folders (or directories) • regular files The pathname uniquely identifies the file Relative pathnames (relative to current working directory Users) Absolute pathnames • /var/poem.txt • cepope/poem.txt • /Users/cepope/poem.txt • ./cepope/image.jpg • /Applications/Mail.app/ • ../var/poem.txt Tools for Computing: Python Current working directory >>> import os >>> os.getcwd() '/Users' >>> os.chdir('/Users/cepope') >>> os.getcwd() '/Users/cepope' Tools for Computing: Python Opening and closing a file Processing a file consists of: 1. Opening the file 2. Reading from and/or writing to the file 3. Closing the file Built-in function open() is used to open a file • The first input argument is the file pathname — may be absolute or relative to cwd (current working directory) • The second (optional) argument is the file mode • Returns a “file” object File mode 'r' is used to open a file for reading A “file” object is of a type that supports several “file” methods, including close() >>> infile = open('foo.txt') IOError: No such file or directory: 'foo.txt' >>> infile = open('poem.txt', 'r') >>> infile.close() Tools for Computing: Python From now on: every command that works with files must be inside of a try block so that you can catch any IOErrors. Open fileprinter.py from Lab#8 print("Please input a filename.") filename = input("> ") file = open(filename) contents = file.read() print(contents) file.close() Fileprinter.py Tools for Computing: Python Do this: Open fileprinter.py from Lab#8 print("Please input a filename.") filename = input("> ") file = open(filename) contents = file.read() print(contents) file.close() fileprinter.py Tools for Computing: Python Improve using try-except: while True: print("Please input a filename.") filename = input("> ") try: file = open(filename) contents = file.read() file.close() break except IOError: print("There was an error opening that file.") print(contents) There is one problem with this code. If an error happens after the file is opened but before it is closed, then the file never gets closed! fileprinter.py Tools for Computing: Python with and as: Instead of explicitly closing files using .close(), Python 3 has the keywords with and as which will automatically handle the process of making sure that files are closed for you. Here’s the syntax: with command-to-create-file as variable-to-store-file: #code that works with the file object From now on, you should always use with-as when working with files fileprinter.py Tools for Computing: Python Fix up our fileprinter… while True: print("Please input a filename.") filename = input("> ") try: with open(filename) as file: contents = file.read() break except IOError: print("There was an error opening that file.") print(contents) fileprinter_try.py Moving Through a File Tools for Computing: Python Open file mode The file mode defines how the file will be accessed Mode Description r Reading (default) w Writing (if file exists, content is wiped) a Append (if file exists, writes are appended) r+ Reading and Writing t Text (default) b Binary These are all equivalent >>> >>> >>> >>> infile infile infile infile = = = = open('poem.txt') open('poem.txt', 'r') open('poem.txt', 't') open('poem.txt', 'rt') Tools for Computing: Python File methods There are several “file” types; they all support similar “file” methods • Methods read() and readline() return the characters read as a string • Methods readlines() returns the characters read as a list of lines • Method write() returns the number of characters written Usage Description infile.read(n) Read n characters starting from cursor; if fewer than n characters remain, read until the end of file infile.read() Read starting from cursor up to the end of the file infile.readline() Read starting from cursor up to, and including, the end of line character infile.readlines() Read starting from cursor up to the end of the file and return list of lines outfile.write(s) Write string s to file outfile starting from cursor infile.close(n) Close file infile Tools for Computing: Python Reading a file 1 Once upon a midnight dreary, while I pondered weak and weary,\n ⌃ curious volume of forgotten lore,\n 2 Over many a quaint and 3 While I nodded, nearly napping, suddenly there came a tapping\n poem.txt When the file is opened, a cursor is associated with the opened file The initial position of the cursor is: • under the first character of the file, if file mode is r • beyond the end of the file, if file mode is a or w >>> infile = open('poem.txt') >>> infile.read(1) 'O' >>> infile.read(20) 'nce upon a midnight ' >>> infile.readline() 'dreary, while I pondered weak and weary,\n' >>> s = infile.read() >>> len(s) 6238 >>> infile.close() Tools for Computing: Python Patterns for reading a text file Common patterns for reading a file: 1. Read the file content into a string 2. Read the file content into a list of words 3. Read the file content into a list of lines Example: def word_count(filename): line_count(filename): char_count(filename): 'returns the number of lines characters words in file in filename' file filename' infile = open(filename) open(filename, 'r') content lines = = infile.readlines() infile.read() infile.close() words = content.split() return len(lines) len(content) return len(words) Tools for Computing: Python More file methods You can use the method .tell() to figure out exactly where the pointer is, and you can move the pointer to a specific location using .seek(). Example: >>> file.read() "never hope to see one.\nBut I can tell you anyhow,\nI'd rather see than be one.\n" >>> file.read(3) '' >>> file.read() '' >>> file.seek(5) 5 >>> file.tell() 5 >>> file.read(7) 'e never' >>> file.tell() 12 >>> file.seek(0) 0 Tools for Computing: Python Quiz Let's redo our fileprinter.py script so that it reads and prints lines from the file one at a time Solution: while True: print("Please input a filename.") filename = input("> ") try: with open(filename) as file: while True: line = file.readline() if line == "": break else: print(line) break except IOError: print("There was an error opening that file.")