549 lines
18 KiB
Plaintext
549 lines
18 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c22bb274-b34a-415d-96a5-aabee2a87b59",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Exceptions in Python\n",
|
|
"\n",
|
|
"Most of the time we're concerned with the \"correct\" path through a program.\n",
|
|
"Sometimes things can go wrong, and we need to take an \"exceptional\" path."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "c69f70a0-f070-4d3c-adaa-a4520cd73af5",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def my_func(a, b):\n",
|
|
" \"\"\" what can go wrong with this function? \"\"\"\n",
|
|
" if a > b:\n",
|
|
" return a / b\n",
|
|
" else:\n",
|
|
" return a * c"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"id": "6eabe23e-d4dc-442c-b405-4adc9fae7417",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"1.3333333333333333"
|
|
]
|
|
},
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"my_func(4, 3)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "ade6c979-7fd0-460e-b6cf-be8cd800e230",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"5.0"
|
|
]
|
|
},
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"my_func(10, 2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "1ef88eb5-0852-4d97-bd25-340b83730442",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "ZeroDivisionError",
|
|
"evalue": "division by zero",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n",
|
|
"Cell \u001b[0;32mIn[2], line 4\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\" what can go wrong with this function? \"\"\"\u001b[39;00m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m a \u001b[38;5;241m>\u001b[39m b:\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m*\u001b[39m c\n",
|
|
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"my_func(10, 0)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"id": "776c8d17-0c17-49a6-9a1d-ef5fbaf7859b",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "NameError",
|
|
"evalue": "name 'c' is not defined",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m)\u001b[49m\n",
|
|
"Cell \u001b[0;32mIn[1], line 6\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m/\u001b[39m b\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m----> 6\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m*\u001b[39m \u001b[43mc\u001b[49m\n",
|
|
"\u001b[0;31mNameError\u001b[0m: name 'c' is not defined"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"my_func(2, 10)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "b7a97b68-43a1-4c10-8621-284d434b12a9",
|
|
"metadata": {},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"id": "1191e7d1-4037-47d7-a899-4f0c0d6846ff",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "TypeError",
|
|
"evalue": "'>' not supported between instances of 'int' and 'str'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[7], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m1\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
|
|
"Cell \u001b[0;32mIn[1], line 2\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mmy_func\u001b[39m(a, b):\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m>\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m:\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m/\u001b[39m b\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n",
|
|
"\u001b[0;31mTypeError\u001b[0m: '>' not supported between instances of 'int' and 'str'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"my_func(10, \"1\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"id": "9b301d27-ce89-424f-bf21-cd42f7ef724e",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "TypeError",
|
|
"evalue": "unsupported operand type(s) for /: 'str' and 'str'",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[8], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_func\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43ma\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
|
|
"Cell \u001b[0;32mIn[1], line 3\u001b[0m, in \u001b[0;36mmy_func\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mmy_func\u001b[39m(a, b):\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m a \u001b[38;5;241m>\u001b[39m b:\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m a \u001b[38;5;241m*\u001b[39m c\n",
|
|
"\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for /: 'str' and 'str'"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"my_func(\"b\", \"a\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6c8c321f-0a0f-4116-94e0-cb91421c1492",
|
|
"metadata": {},
|
|
"source": [
|
|
"We could try to think of all possible conditions, and our simple function would become much longer & harder to read. \n",
|
|
"\n",
|
|
"Often there is no better solution than to have an error occur, so Python **raises an exception** and that is what happens here."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0877c7a7-a636-47a1-a5d2-05ff8e5bb920",
|
|
"metadata": {},
|
|
"source": [
|
|
"The above types are called rumtime exceptions, because we don't see them until the code runs.\n",
|
|
"\n",
|
|
"This is different from a `SyntaxError` which means that Python can't parse our statements:\n",
|
|
"\n",
|
|
"```\n",
|
|
"# Syntax Errors\n",
|
|
"def my_func(a, b,: # missing )\n",
|
|
" if a > b\n",
|
|
" return a / b # missing colon\n",
|
|
" else { return a * c } # python doesn't use braces\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "14c7426d-9b73-4712-b204-db9cd6bcde67",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Built-in Exceptions\n",
|
|
"\n",
|
|
"* `Exception` (base type)\n",
|
|
" * `ValueError`\n",
|
|
" * `TypeError`\n",
|
|
" * `KeyError`\n",
|
|
" * `IndexError`\n",
|
|
" * `NotImplementedError`\n",
|
|
" * `OSError`\n",
|
|
" * `FileNotFoundError`\n",
|
|
"\n",
|
|
"And many more: https://docs.python.org/3/library/exceptions.html#exception-hierarchy\n",
|
|
"\n",
|
|
"Note that exceptions form a hierarchy, we'll discuss this in more detail when we come to inheritance.\n",
|
|
"\n",
|
|
"## Handling Exceptions\n",
|
|
"\n",
|
|
"In practice, exceptions are **raised**, and either **caught** or not. An uncaught exception stops the program and prints an error message to the screen as you've seen.\n",
|
|
"\n",
|
|
"We handle exceptions with `try-except` blocks."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "5022b7c8-a19f-45cb-9d40-58abc48de961",
|
|
"metadata": {
|
|
"tags": []
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "NameError",
|
|
"evalue": "name 'd' is not defined",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
|
"Cell \u001b[0;32mIn[5], line 5\u001b[0m\n\u001b[1;32m 3\u001b[0m b \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;66;03m#c = a / b\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43md\u001b[49m)\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlast line of try\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mZeroDivisionError\u001b[39;00m:\n",
|
|
"\u001b[0;31mNameError\u001b[0m: name 'd' is not defined"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"try:\n",
|
|
" a = 3\n",
|
|
" b = 0\n",
|
|
" #c = a / b\n",
|
|
" print(d)\n",
|
|
" print(\"last line of try\")\n",
|
|
"except ZeroDivisionError:\n",
|
|
" c = 0\n",
|
|
" print(f\"can't divide by zero, set c = {c}\")\n",
|
|
"#except NameError:\n",
|
|
"# print(\"used unknown name\")\n",
|
|
"print(\"and then this happens\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c996bd03-f79b-49de-874d-cd6cb076a70a",
|
|
"metadata": {},
|
|
"source": [
|
|
"If an exception occurs within a `try` block, execution will jump to the appropriate `except` block if one exists.\n",
|
|
"\n",
|
|
"Typically you want to handle different errors differently, you can also handle multiple errors with one block by using any of the following:\n",
|
|
"\n",
|
|
"```python\n",
|
|
"# multiple except blocks for different behaviors\n",
|
|
"try:\n",
|
|
" something()\n",
|
|
"except ValueError:\n",
|
|
" ...\n",
|
|
"except IndexError:\n",
|
|
" ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"```python\n",
|
|
"# one block w/ multiple types in a tuple\n",
|
|
"try:\n",
|
|
" somthing()\n",
|
|
"except (ValueError, IndexError, KeyError): # tuple of return values\n",
|
|
" ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"```python\n",
|
|
"# base exception type, use sparingly\n",
|
|
"try:\n",
|
|
" something()\n",
|
|
"except ArithmeticError: # catches all errors derived from ArithmeticError\n",
|
|
" ...\n",
|
|
"except Exception: # catches all runtime exceptions\n",
|
|
" ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"\n",
|
|
"```python\n",
|
|
"# DO NOT USE: bare except\n",
|
|
"try:\n",
|
|
" something();\n",
|
|
"except: \n",
|
|
" ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"```python\n",
|
|
"try:\n",
|
|
" something()\n",
|
|
"except OSError: # will catch all subclasses of OSError\n",
|
|
" ...\n",
|
|
"```"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "34060dea-77e4-420d-9895-5d866635f620",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Raising Exceptions\n",
|
|
"\n",
|
|
"To raise an exception, you use the `raise` keyword, which similarly to `return` exits a function immediately.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"id": "fd6d0e12-eae2-466e-8536-db5d246091f0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def f(positive):\n",
|
|
" if positive < 0:\n",
|
|
" raise ValueError(\"f requires a positive argument\")\n",
|
|
" return positive * positive"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"id": "58c691a9-14ed-4fe1-9b0d-eb9b52a4d44d",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"9"
|
|
]
|
|
},
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"f(3)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"id": "5fd8e7ee-53c6-4cd1-8748-cd66f06da9ac",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"got an error: f requires a positive argument\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"try:\n",
|
|
" y = f(-1)\n",
|
|
"except ValueError as exc:\n",
|
|
" y = 0\n",
|
|
" print(\"got an error: \", exc)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"id": "769fb253-ae47-4e47-a6fd-9a37e1ef3d5e",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"0\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(y)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f86298c9-b7b4-4f9c-81c5-ad16df15b233",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Defining Custom Exception Types\n",
|
|
"\n",
|
|
"Sometimes you can use an existing type, but in practice it is very common to want to define custom exception types.\n",
|
|
"\n",
|
|
"Custom exception types let you handle your programs errors differently from Python's built in types:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"id": "af5d3624-3f4f-4f1d-9292-388f909a3bfd",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class InvalidColor(Exception):\n",
|
|
" \"\"\" This exception is raised when an invalid color is passed. \"\"\"\n",
|
|
" pass\n",
|
|
"\n",
|
|
"VALID_COLORS = (...)\n",
|
|
"\n",
|
|
"def draw_point(x, y, color):\n",
|
|
" if color not in VALID_COLORS:\n",
|
|
" raise InvalidColor(\"color should be one of the valid colors\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "5b82f7b0-49bd-4781-a2af-3d55a7ec0ae6",
|
|
"metadata": {},
|
|
"source": [
|
|
"Exception classes must inherit from `Exception` or another exception.\n",
|
|
"\n",
|
|
"We'll talk more about inheritance next, but for now, just know that you need the `(Exception)` portion of the class declaration line."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d93053ab-4cd7-4751-bc81-3f6d13a7d908",
|
|
"metadata": {},
|
|
"source": [
|
|
"## try-except-finally-else\n",
|
|
"\n",
|
|
"The full syntax for `try-except` includes two more optional clauses `finally` and `else`.\n",
|
|
"\n",
|
|
"These work somewhat like `elif`/`else`:\n",
|
|
"\n",
|
|
"```python\n",
|
|
"try:\n",
|
|
" something()\n",
|
|
"except Exception as e: # \"as e\" allows using the exception if needed\n",
|
|
" ... # executes only if exception was raised\n",
|
|
"else:\n",
|
|
" ... # executes if no exception raised\n",
|
|
"finally:\n",
|
|
" ... # executes after try/except/else no matter what\n",
|
|
"```\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"id": "320d3309-099a-4f2e-9096-983101bfc157",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"else executed\n",
|
|
"always prints at the end\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"try:\n",
|
|
" 1 / 2\n",
|
|
"except ValueError as e:\n",
|
|
" print(\"got a value error:\", e)\n",
|
|
"except Exception as e:\n",
|
|
" print(\"got some other error:\", type(e), e)\n",
|
|
"else:\n",
|
|
" print(\"else executed\")\n",
|
|
"finally:\n",
|
|
" print(\"always prints at the end\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0ed69652-c95d-4745-8aa2-ac2171d06ad5",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Best Practices\n",
|
|
"\n",
|
|
"Catch the narrowest exception that you need to, so that you don't accidentally \"handle\" exceptions that you don't intend to.\n",
|
|
"\n",
|
|
"Throw the most specific exception that you can, so that it can be handled by unique code if needed.\n",
|
|
"\n",
|
|
"Provide useful error messages as the argument to your exception. All exception types by default take a string that'll be used as a message:\n",
|
|
"\n",
|
|
"`raise ValueError(\"say why the value was rejected\")`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2d6c25cf-cd55-4d33-99f3-7b0d5f7eab86",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"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.10.15"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|