{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#Errors and Exception Handling\n", "\n", "In this lecture we will learn about Errors and Exception Handling in Python. You've definitely already encountered errors by this point in the course. For example:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "ename": "SyntaxError", "evalue": "EOL while scanning string literal (, line 1)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print 'Hello\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n" ] } ], "source": [ "print 'Hello" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note how we get a SyntaxError, with the further description that it was an EOL (End of Line Error) while scanning the string literal. This is specific enough for us to see that we forgot a single quote at the end of the line. Understanding these various error types will help you debug your code much faster. \n", "\n", "This type of error and description is known as an Exception. Even if a statement or expression is syntactically correct, it may cause an error when an attempt is made to execute it. Errors detected during execution are called exceptions and are not unconditionally fatal.\n", "\n", "You can check out the full list of built-in exceptions [here](https://docs.python.org/2/library/exceptions.html). now lets learn how to handle errors and exceptions in our own code." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##try and except\n", "\n", "The basic terminology and syntax used to handle errors in Python is the **try** and **except** statements. The code which can cause an exception to occue is put in the *try* block and the handling of the exception is the implemented in the *except* block of code. The syntax form is:\n", "\n", " try:\n", " You do your operations here...\n", " ...\n", " except ExceptionI:\n", " If there is ExceptionI, then execute this block.\n", " except ExceptionII:\n", " If there is ExceptionII, then execute this block.\n", " ...\n", " else:\n", " If there is no exception then execute this block. \n", "\n", "We can also just check for any exception with just using except: To get a better understanding of all this lets check out an example: We will look at some code that opens and writes a file:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Content written successfully\n" ] } ], "source": [ "try:\n", " f = open('testfile','w')\n", " f.write('Test write this')\n", "except IOError:\n", " # This will only check for an IOError exception and then execute this print statement\n", " print \"Error: Could not find file or read data\"\n", "else:\n", " print \"Content written successfully\"\n", " f.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now lets see what would happen if we did not have write permission (opening only with 'r'):" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: Could not find file or read data\n" ] } ], "source": [ "try:\n", " f = open('testfile','r')\n", " f.write('Test write this')\n", "except IOError:\n", " # This will only check for an IOError exception and then execute this print statement\n", " print \"Error: Could not find file or read data\"\n", "else:\n", " print \"Content written successfully\"\n", " f.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Great! Notice how we only printed a statement! The code still ran and we were able to continue doing actions and running code blocks. This is extremely useful when you have to account for possible input errors in your code. You can be prepared for the error and keep running code, instead of your code just breaking as we saw above.\n", "\n", "We could have also just said except: if we weren't sure what exception would occur. For example:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: Could not find file or read data\n" ] } ], "source": [ "try:\n", " f = open('testfile','r')\n", " f.write('Test write this')\n", "except:\n", " # This will check for any exception and then execute this print statement\n", " print \"Error: Could not find file or read data\"\n", "else:\n", " print \"Content written successfully\"\n", " f.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Great! Now we don't actually need to memorize that list of exception types! Now what if we kept wanting to run code after the exception occurred? This is where **finally** comes in.\n", "##finally\n", "The finally: block of code will always be run regardless if there was an exception in the try code block. The syntax is:\n", "\n", " try:\n", " Code block here\n", " ...\n", " Due to any exception, this code may be skipped!\n", " finally:\n", " This code block would always be executed.\n", "\n", "For example:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Always execute finally code blocks\n" ] } ], "source": [ "try:\n", " f = open(\"testfile\", \"w\")\n", " f.write(\"Test write statement\")\n", "finally:\n", " print \"Always execute finally code blocks\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use this in conjunction with except. Lets see a new example that will take into account a user putting in the wrong input:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def askint():\n", " try:\n", " val = int(raw_input(\"Please enter an integer: \"))\n", " except:\n", " print \"Looks like you did not enter an integer!\"\n", " \n", " finally:\n", " print \"Finally, I executed!\"\n", " print val " ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter an integer: 5\n", "Finally, I executed!\n", "5\n" ] } ], "source": [ "askint()" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter an integer: five\n", "Looks like you did not enter an integer!\n", "Finally, I executed!\n" ] }, { "ename": "UnboundLocalError", "evalue": "local variable 'val' referenced before assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mUnboundLocalError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0maskint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36maskint\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m\"Finally, I executed!\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0mval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mUnboundLocalError\u001b[0m: local variable 'val' referenced before assignment" ] } ], "source": [ "askint()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice how we got an error when trying to print val (because it was never properly assigned) Lets remedy this by asking the user and checking to make sure the input type is an integer:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def askint():\n", " try:\n", " val = int(raw_input(\"Please enter an integer: \"))\n", " except:\n", " print \"Looks like you did not enter an integer!\"\n", " val = int(raw_input(\"Try again-Please enter an integer: \"))\n", " finally:\n", " print \"Finally, I executed!\"\n", " print val " ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter an integer: f\n", "Looks like you did not enter an integer!\n", "Try again-Please enter an integer: f\n", "Finally, I executed!\n" ] }, { "ename": "ValueError", "evalue": "invalid literal for int() with base 10: 'f'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0maskint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36maskint\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mexcept\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m\"Looks like you did not enter an integer!\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mval\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mraw_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Try again-Please enter an integer: \"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m\"Finally, I executed!\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'f'" ] } ], "source": [ "askint()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hmmm...that only did one check. How can we continually keep checking? We can use a while loop!" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def askint():\n", " while True:\n", " try:\n", " val = int(raw_input(\"Please enter an integer: \"))\n", " except:\n", " print \"Looks like you did not enter an integer!\"\n", " continue\n", " else:\n", " print 'Yep thats an integer!'\n", " break\n", " finally:\n", " print \"Finally, I executed!\"\n", " print val " ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter an integer: five\n", "Looks like you did not enter an integer!\n", "Finally, I executed!\n", "Please enter an integer: five\n", "Looks like you did not enter an integer!\n", "Finally, I executed!\n", "Please enter an integer: four\n", "Looks like you did not enter an integer!\n", "Finally, I executed!\n", "Please enter an integer: 4\n", "Yep thats an integer!\n", "Finally, I executed!\n" ] } ], "source": [ "askint()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Great! Now you know how to handle errors and exceptions in Python with the try, except, else, and finally notation!**" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }