You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
785 lines
21 KiB
785 lines
21 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "radical-beast",
|
|
"metadata": {},
|
|
"source": [
|
|
"<!--\n",
|
|
"title: Debugging Principles and Techniques\n",
|
|
"type: lesson\n",
|
|
"duration: \"00:40\"\n",
|
|
"creator: Brandi Butler\n",
|
|
"-->\n",
|
|
"\n",
|
|
"<h1>Debugging Principles and Techniques</h1>\n",
|
|
"\n",
|
|
"<!--\n",
|
|
"\n",
|
|
"\n",
|
|
"## Overview\n",
|
|
"This lesson is meant to give students the skills needed to debug their own code. There is a mix of demo, You Do, and We Do to keep it fresh while running through many common errors. We throw a lot of errors at them very quickly - the idea is to get them comfortable recognizing errors and solving them, not to memorize them.\n",
|
|
"\n",
|
|
"Then, it guides students in how to use `Try`-`Except` blocks when errors are expected/unavoidable. Last, some time is spent teaching students how to handle situations that are problematic, but don't usually throw errors specifically, including endless loops, off-by-one errors, and logical errors.\n",
|
|
"\n",
|
|
"\n",
|
|
"#### Helpful Table of Errors\n",
|
|
"\n",
|
|
"| Error Type | Most Common Cause |\n",
|
|
"| -------------- | ------------------------------------------------------|\n",
|
|
"| AttributeError | Attempting to access a non-existent attribute |\n",
|
|
"| KeyError | Attempting to access a non-existent key in a dict |\n",
|
|
"| ImportError | A module you tried to import doesn't exist |\n",
|
|
"| IndexError | You attempted to access a list element that doesn't exist |\n",
|
|
"| IndentationError | Indenting code in an invalid way |\n",
|
|
"| IOError | Accessing a file that doesn't exist |\n",
|
|
"| NameError | Attempting to use a module you haven't imported/installed |\n",
|
|
"| OverflowError | You made a number larger than the maximum size |\n",
|
|
"| RuntimeError | The error doesn't fit into any other category |\n",
|
|
"| SyntaxError | A typo, such as forgetting a colon |\n",
|
|
"| TypeError | Using two different types in an incompatible way |\n",
|
|
"| ValueError | When you are trying to convert bad keyboard input to a number |\n",
|
|
"| ZeroDivisionError | Dividing By Zero |\n",
|
|
"\n",
|
|
"## Learning Objectives\n",
|
|
"In this lesson, students will:\n",
|
|
"\n",
|
|
"* Troubleshoot common types of errors.\n",
|
|
"* Implement basic exception mitigation.\n",
|
|
"* Troubleshoot logic errors.\n",
|
|
"\n",
|
|
"## Duration\n",
|
|
"40 minutes\n",
|
|
"\n",
|
|
"## Suggested Agenda\n",
|
|
"\n",
|
|
"| Time | Activity |\n",
|
|
"| --- | --- |\n",
|
|
"| 0:00 - 0:03 | Welcome |\n",
|
|
"| 0:04 - 0:16 | Recognizing Errors |\n",
|
|
"| 0:17 - 0:23 | Exception Handling |\n",
|
|
"| 0:24 - 0:37 | Untyped Errors |\n",
|
|
"| 0:38 - 0:40 | Summary |\n",
|
|
"\n",
|
|
"\n",
|
|
"## In Class: Materials\n",
|
|
"- Projector\n",
|
|
"- Internet connection\n",
|
|
"- Python3\n",
|
|
"-->\n",
|
|
"\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Lesson Objectives\n",
|
|
"\n",
|
|
"*After this lesson, you will be able to...*\n",
|
|
"\n",
|
|
"* Troubleshoot common types of errors.\n",
|
|
"* Implement basic exception mitigation.\n",
|
|
"* Troubleshoot logic errors.\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: Error Messages\n",
|
|
"\n",
|
|
"\n",
|
|
"Have you found a shiny red error message before? What do you think has happened here?\n",
|
|
"\n",
|
|
"<!--  -->"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "optimum-terror",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = 5\n",
|
|
"y = 0\n",
|
|
"\n",
|
|
"x / y"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "homeless-module",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n",
|
|
"\n",
|
|
"## Making Errors Into Friends\n",
|
|
"\n",
|
|
"On the surface, errors are frustrating! However, we'll walk through some common ones. You'll see:\n",
|
|
"\n",
|
|
"- Errors sometimes say exactly what's wrong.\n",
|
|
"- Some errors have very common causes.\n",
|
|
"- Errors may say exactly how to fix the issue.\n",
|
|
"- Python errors are very helpful and have clear messages.\n",
|
|
"\n",
|
|
"<!--  -->\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## We Do: IndexError\n",
|
|
"\n",
|
|
"Let's debug this code together.\n",
|
|
"\n",
|
|
"**Protip**: Index errors typically happen when you attempt to access a list index that doesn't exist."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "weekly-listing",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"race_runners = [\"Yuna\", \"Bill\", \"Hyun\"]\n",
|
|
"\n",
|
|
"first_place = race_runners[1]\n",
|
|
"second_place = race_runners[2]\n",
|
|
"third_place = race_runners[3]\n",
|
|
"\n",
|
|
"print(\"The winners are:\", first_place, second_place, third_place)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "failing-level",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"</aside>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## You Do: Fix a NameError\n",
|
|
"\n",
|
|
"Directions: Fix it!\n",
|
|
"\n",
|
|
"*Hints*:\n",
|
|
"- Run the code to get the error.\n",
|
|
"- What kind of error is it? What is the error message?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "discrete-stone",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Get a number between 2 and 8.\n",
|
|
"my_nums = 5\n",
|
|
"\n",
|
|
"# Print the number\n",
|
|
"print(my_num)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "sharing-storage",
|
|
"metadata": {},
|
|
"source": [
|
|
"- We most commonly get a `NameError` if we use a variable:\n",
|
|
" * Without defining it.\n",
|
|
" * *Before* defining it\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## KeyError\n",
|
|
"\n",
|
|
"Accessing a key in a dictionary that doesn't exist.\n",
|
|
"\n",
|
|
"Commonly caused by:\n",
|
|
"- A misspelling.\n",
|
|
"- Mixing uppercase and lowercase.\n",
|
|
"\n",
|
|
"The error message tells you exactly what key is missing!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "quantitative-tournament",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_favorites = {\n",
|
|
" \"Food\": \"Lobster Rolls\",\n",
|
|
" \"Song\": \"Bohemian Rhapsody\",\n",
|
|
" \"Flower\": \"Iris\",\n",
|
|
" \"Band\": \"Tom Petty & the Heartbreakers\",\n",
|
|
" \"Color\": \"Green\",\n",
|
|
" \"Movie\": \"The Princess Bride\",\n",
|
|
" \"Programming Language\": \"Python\"\n",
|
|
"}\n",
|
|
"\n",
|
|
"# This is okay!\n",
|
|
"print(\"My favorite color is\", my_favorites[\"Color\"])\n",
|
|
"\n",
|
|
"# This is NOT okay! (Case sensitivity!)\n",
|
|
"print(\"My favorite color is\", my_favorites[\"color\"])\n",
|
|
"\n",
|
|
"# This is NOT okay! (Key doesn't exist)\n",
|
|
"print(\"My favorite restaurant is\", my_favorites[\"Restaurant\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "subtle-population",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## AttributeError\n",
|
|
"\n",
|
|
"* More general than `KeyError`, but the same idea.\n",
|
|
"* Accessing an attribute (e.g., function or property) that doesn't exist"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "advisory-composer",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class Dog():\n",
|
|
" def __init__(self, name):\n",
|
|
" self.name = name\n",
|
|
"\n",
|
|
" def bark(self):\n",
|
|
" print(\"Bark!\")\n",
|
|
"\n",
|
|
"# Declare a new dog instance\n",
|
|
"my_dog = Dog(\"Fido\")\n",
|
|
"\n",
|
|
"# Call the bark method\n",
|
|
"my_dog.bark() # OK!\n",
|
|
"\n",
|
|
"# Call the run method\n",
|
|
"my_dog.run() # AttributeError!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "domestic-threshold",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: SyntaxError\n",
|
|
"\n",
|
|
"Let's run the code together. What happens? How can we fix it?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "educational-mongolia",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_age = 13\n",
|
|
"\n",
|
|
"if my_age = 18:\n",
|
|
" print(\"I may vote.\")\n",
|
|
"else:\n",
|
|
" print(\"I may not vote.\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "qualified-miniature",
|
|
"metadata": {},
|
|
"source": [
|
|
"</aside>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: TypeError\n",
|
|
"\n",
|
|
"`TypeError` and its message tell us:\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "partial-howard",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_num = 5 + \"10\"\n",
|
|
"print(my_num)\n",
|
|
"# TypeError: unsupported operand type(s) for +: 'int' and 'str'"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "precious-aberdeen",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"What do we learn from this error message? Have you learned a way to fix this?\n",
|
|
"\n",
|
|
"**Fun Fact**: Some languages, like JavaScript, let this code run (breaking something!).\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## IndentationError\n",
|
|
"\n",
|
|
"May be caused by:\n",
|
|
"\n",
|
|
"* Not enough indentation\n",
|
|
"* Mismatched indentation\n",
|
|
"* Mixing tabs and spaces!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "coupled-jacob",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_age = 13\n",
|
|
"\n",
|
|
"if my_age == 16:\n",
|
|
" print(\"I may drive.\")\n",
|
|
"else:\n",
|
|
"print(\"I may not drive.\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "limited-relevance",
|
|
"metadata": {},
|
|
"source": [
|
|
"</aside>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## ValueError\n",
|
|
"\n",
|
|
"Most commonly caused by trying to convert a bad string into a number.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "threaded-caution",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# This is okay!\n",
|
|
"my_num = int(\"10\")\n",
|
|
"\n",
|
|
"# This throws a ValueError\n",
|
|
"my_num = int(\"Moose\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "fantastic-martin",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## RuntimeError\n",
|
|
"\n",
|
|
"The worst error to see!\n",
|
|
"\n",
|
|
"* When no other error type fits.\n",
|
|
"* You need to rely on the error message content.\n",
|
|
"* May be used for custom errors.\n",
|
|
"\n",
|
|
"**Example**: `RuntimeError` is like if I said to you:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"`Please eat the piano`\n",
|
|
"\n",
|
|
"\n",
|
|
"You can understand what's being asked, but can't actually do that!\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Quick Review\n",
|
|
"\n",
|
|
"There are many types of errors in Python!\n",
|
|
"\n",
|
|
"Usually, the error has a name or description that says exactly what's wrong.\n",
|
|
"\n",
|
|
"Think about `IndentationError` or `IndexError` - what went wrong?\n",
|
|
"\n",
|
|
"Sometimes, you'll see `RuntimeError`. Python throws us this if something is broken but it can't say specifically what - like `Please eat the piano`. Revisit your code and see what might have happened.\n",
|
|
"\n",
|
|
"**Next Up:** A list of common errors, then ways to prevent errors.\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## List of Common Errors\n",
|
|
"\n",
|
|
"This chart's for you to refer to later - don't memorize it now!\n",
|
|
"\n",
|
|
"| Error Type | Most Common Cause |\n",
|
|
"| --- | ---|\n",
|
|
"| `AttributeError` | Attempting to access a non-existent attribute |\n",
|
|
"| `KeyError` | Attempting to access a non-existent key in a dict |\n",
|
|
"| `ImportError` | A module you tried to import doesn't exist |\n",
|
|
"| `IndexError` | You attempted to access a list element that doesn't exist |\n",
|
|
"| `IndentationError` | Indenting code in an invalid way |\n",
|
|
"| `IOError` | Accessing a file that doesn't exist |\n",
|
|
"| `NameError` | Attempting to use a module you haven't imported/installed |\n",
|
|
"| `OverflowError` | You made a number larger than the maximum size |\n",
|
|
"| `RuntimeError` | The error doesn't fit into any other category |\n",
|
|
"| `SyntaxError` | A typo, such as forgetting a colon |\n",
|
|
"| `TypeError` | Using two different types in an incompatible way |\n",
|
|
"| `ValueError` | When you are trying to convert bad keyboard input to a number |\n",
|
|
"| `ZeroDivisionError` | Dividing By Zero |\n",
|
|
"\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: Throwing Errors\n",
|
|
"\n",
|
|
"Sometimes, we might have code that we expect to throw an error.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "interesting-digit",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# The user might not give us a number!\n",
|
|
"my_num = int(input(\"Please give me a number:\"))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "adult-protection",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"What if the user types a string like \"Moose\"?\n",
|
|
"\n",
|
|
"- This causes a `ValueError` - we'll be trying to make an int out of a string \"Moose\".\n",
|
|
"- We can anticipate and prepare for it!\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Try-Except\n",
|
|
"\n",
|
|
"A `Try`-`Except` block is the way we can catch errors in Python. We can catch:\n",
|
|
"\n",
|
|
"- One error (`except ValueError:`)\n",
|
|
"- Multiple errors (`except (ValueError, KeyError):`)\n",
|
|
"- Any/every error (`except:`)\n",
|
|
"\n",
|
|
"Always try to specify the error, if possible!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "northern-petite",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_num = None\n",
|
|
"\n",
|
|
"while my_num is None:\n",
|
|
" try:\n",
|
|
" my_num = int(input(\"Please give me a number:\"))\n",
|
|
" except ValueError as err:\n",
|
|
" print(\"That was not good input, please try again!\")\n",
|
|
" print(\"Error was\", err)\n",
|
|
"\n",
|
|
"print(\"Thanks for typing the number\", my_num)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "everyday-lingerie",
|
|
"metadata": {},
|
|
"source": [
|
|
"</aside>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: Switching Gears\n",
|
|
"\n",
|
|
"Not every programming error is caught by an error message!\n",
|
|
"\n",
|
|
"* Can anyone say what is wrong with this code?\n",
|
|
"* What might happen if you run it?\n",
|
|
"\n",
|
|
"**Do not try to run the below code**.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "veterinary-porcelain",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# my_num = 1\n",
|
|
"\n",
|
|
"# while my_num < 10:\n",
|
|
"# print(my_num)\n",
|
|
"# my_num + 1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "dietary-amsterdam",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: Another Infinite Loop\n",
|
|
"\n",
|
|
"It's easy to accidentally make an infinite loop. What's the problem here?\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "suburban-socket",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# am_hungry = True\n",
|
|
"# fridge_has_food = True\n",
|
|
"\n",
|
|
"# while am_hungry or fridge_has_food:\n",
|
|
"# print(\"Opening the fridge!\")\n",
|
|
"# am_hungry = False"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "practical-nashville",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Infinite Infinite Loops!\n",
|
|
"\n",
|
|
"Most common infinite loops are a result of:\n",
|
|
"\n",
|
|
"* A `while` loop's condition never becomes `False`.\n",
|
|
"* Forgetting to increment a counter variable.\n",
|
|
"* Logic inside the loop that restarts the loop.\n",
|
|
"* Bad logic in a `while` loop's condition (e.g., putting `or` instead of `and`)\n",
|
|
"\n",
|
|
"Be careful to check your end conditions!\n",
|
|
"\n",
|
|
"If you find your program running endlessly, interrrupt or stop the kernel to stop it!\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Discussion: Logic Error\n",
|
|
"\n",
|
|
"\n",
|
|
"Here, we want to find the average of `8` and `10`. The answer should be `9`, because `8 + 10 == 18`, then `18 / 2 == 9`\n",
|
|
"\n",
|
|
"What happened and why?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "private-victor",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = 8\n",
|
|
"y = 10\n",
|
|
"average = x + y / 2\n",
|
|
"print(average)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "consolidated-remark",
|
|
"metadata": {},
|
|
"source": [
|
|
"</aside>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Quick Review: Common Errors\n",
|
|
"\n",
|
|
"- If you expect an error, use a try/except block:\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "involved-nylon",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"my_num = None\n",
|
|
"\n",
|
|
"while my_num is None:\n",
|
|
" try:\n",
|
|
" my_num = int(input(\"Please give me a number:\"))\n",
|
|
" except ValueError as err:\n",
|
|
" print(\"That was not good input, please try again!\")\n",
|
|
" print(\"Error was\", err)\n",
|
|
"\n",
|
|
"print(\"Thanks for typing the number\", my_num)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "collaborative-philippines",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"- Logic problems are common but won't throw a helpful error. Always check end conditions on your `while` loops!\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Print Statements for Sanity Checks\n",
|
|
"\n",
|
|
"**Pro Tip**: If something is wonky and you don't know why, starting `print`ing.\n",
|
|
"\n",
|
|
"* Use `print` statements on each line to peek at the values.\n",
|
|
"* Remember to remove debugging statements once the problem is solved!\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ongoing-competition",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = 8\n",
|
|
"y = 10\n",
|
|
"get_average = x + y / 2\n",
|
|
"print(\"get_average is\", get_average) # Print out what this equals (it's wrong!)\n",
|
|
"testing_sum = x + y # To figure out why, break it down.\n",
|
|
"print(\"testing_sum is\", testing_sum) # Print out each step.\n",
|
|
"testing_average = testing_average / 2\n",
|
|
"print(\"testing_average is\", testing_average) # The individual math test works\n",
|
|
"# We know there must be a problem with the logic in \"average\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "theoretical-specific",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"When your programs become very complex, adding `print` statements will be a great help.\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## You Do: Wrapping it Up\n",
|
|
"\n",
|
|
"\n",
|
|
"Can you fix the code below?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "upper-delight",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"new_phone = Phone(5214)\n",
|
|
"\n",
|
|
"class Phone:\n",
|
|
" def __init__(self, phone_number):\n",
|
|
" self.number = phone_number\n",
|
|
"\n",
|
|
" def call(self, other_number):\n",
|
|
" print(\"Calling from\" self.number, \"to\", other_number)\n",
|
|
"\n",
|
|
" def text(self, other_number, msg):\n",
|
|
" print(\"Sending text from\", self.number, \"to\", other_number\n",
|
|
" print(msg)\n",
|
|
"\n",
|
|
"test_phone = Phone()\n",
|
|
"test_phone.call(515)\n",
|
|
"test_phone.text(int(\"text 141\"), \"Hi!\")\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "improved-czech",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"</aside>\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Summary and Q&A\n",
|
|
"\n",
|
|
"* Python has many common built-in errors.\n",
|
|
"* Use `try`-`except` syntax to catch an expected error.\n",
|
|
"* Logic issues don't throw errors, so be careful!\n",
|
|
"* Use `print` statements to walk through your code line-by-line.\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## Additional Resources\n",
|
|
"\n",
|
|
"* [List of Built-In Errors](https://www.tutorialspoint.com/python/standard_exceptions.htm)\n",
|
|
"* [Error Flowchart PDF](https://www.dropbox.com/s/cqsxfws52gulkyx/drawing.pdf)\n",
|
|
"* [Try-Except Documentation](http://www.pythonforbeginners.com/error-handling/python-try-and-except)\n",
|
|
"- [A deep dive into try/except clauses](https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/)\n",
|
|
"- To get advanced, add [logging](https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/) to your code.\n",
|
|
"- To get very advanced, include [unit tests](http://www.diveintopython.net/unit_testing/index.html); the [pytest module](http://pythontesting.net/framework/pytest/pytest-introduction/) is great.\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.7.6"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|