Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add section on errors and descriptions of Python versions #131

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ Given this basic understanding of what the Python programming language is, we no
## Python Scripts
You can save the the valid code from the preceding section in a text file using a simple text editor, and *voilà* you have written a **Python script**: a text file containing Python code. It is standard to save this text file using the suffix `.py` (e.g. `my_code.py`), rather than the familiar `.txt` (e.g. `my_text.txt`). There is nothing special about the `.py` suffix; it simply helps differentiate files that contain Python code from run-of-the-mill text files, which contain plain English.

Although you can use simple text editors to write Python scripts (e.g. notepad (Win), TextEdit (Mac), nano (Linux)), there are much more sophisticated editors that provide an "integrated development environment" (IDE) for writing code. An IDE, configured to support Python, will warn you if you have written code that violates Python's grammar rules, similar to the way word processing software warns you if you have made a spelling mistake. More on IDEs in a later section.
Although you can use simple text editors to write Python scripts (e.g. notepad (Win), TextEdit (Mac), nano (Linux)), there are much more sophisticated editors that provide an "integrated development environment" (IDE) for writing code. An IDE, configured to support Python, will warn you if you have written code that violates Python's grammar rules, similar to the way word processing software warns you if you have made a spelling mistake. More on IDEs in a later section.

<div class="alert alert-warning">

**WARNING**:
**WARNING**:

Do not use word processing programs, like Microsoft Word, to write code. They will "silently" change the characters written in your file, such as the type of quotation marks being used. This will cause errors in your code.
Do not use word processing programs, like Microsoft Word, to write code. They will "silently" change the characters written in your file, such as the type of quotation marks being used. This will cause errors in your code.
</div>

Now that you have a Python script, how do you get the computer to read it and follow its instructions? You will need to install a **Python interpreter** on your computer to accomplish this. This is what people mean, whether they know it or not, when they tell you to "install Python" on your computer.
Expand All @@ -91,20 +91,20 @@ The first Python interpeter was written in the programming language C, and is kn

<div class="alert alert-warning">

**Note**:
**Note**:

Python interpreters have been in written in programming languages other than C, like in Java (Jython) and Go (Grumpy). These are not guaranteed to be up-to-date with the latest specifications of the Python language, and are rarely used in comparison to the CPython interpreter.
</div>

<div class="alert alert-warning">

**About Installing Python**:
**About Installing Python**:

Do not download and install Python from python.org. There isn't anything wrong with this, but a later section will provide you with explicit instructions for installing Python on your machine.
Do not download and install Python from python.org. There isn't anything wrong with this, but a later section will provide you with explicit instructions for installing Python on your machine.

</div>

If you "install Python on your computer" from [python.org](https://www.python.org/downloads/release/python-363/), you are essentially downloading an executable program onto your machine that operates as a Python interpreter. On Windows, for instance, this program is called `python.exe`. This program is the result of the aforementioned CPython code, and it is capable of performing the all of the tasks of a Python interpreter. Additionally, you are downloading a large suite of useful tools and functions that you can utilize in your code. This is known as the Python standard library; take a moment to look over its contents [here](https://docs.python.org/3/library/index.html#the-python-standard-library).
If you "install Python on your computer" from [python.org](https://www.python.org/downloads/release/python-363/), you are essentially downloading an executable program onto your machine that operates as a Python interpreter. On Windows, for instance, this program is called `python.exe`. This program is the result of the aforementioned CPython code, and it is capable of performing the all of the tasks of a Python interpreter. Additionally, you are downloading a large suite of useful tools and functions that you can utilize in your code. This is known as the Python standard library; take a moment to look over its contents [here](https://docs.python.org/3/library/index.html#the-python-standard-library).

Once you have a Python interpreter installed on your machine, using it to execute a Python script is quite simple. Assume for the sake of simplicity that the `python` interpreter program and `my_script.py` are in the same directory (a.k.a 'folder') in your computer. Then, in a terminal (`cmd.exe` for Windows) you can execute the following command:

Expand All @@ -116,7 +116,7 @@ this will instruct the Python interpreter program `python` to read your text fil

In practice, you will be able to simply execute `python my_script.py` in any directory, and your computer will know where to look to find the `python` program. This will be set up during the installation process.

It may be confusing to think that the Python language is interpreted by using a program written in another language. How, then, is that language interpreted? The answer, in the case of CPython, is that C code need not be interpreted; programs exist for Windows, Mac, and Linux that can translate C code directly into machine instructions.
It may be confusing to think that the Python language is interpreted by using a program written in another language. How, then, is that language interpreted? The answer, in the case of CPython, is that C code need not be interpreted; programs exist for Windows, Mac, and Linux that can translate C code directly into machine instructions.

<!-- #region -->
## Why Python?
Expand Down Expand Up @@ -144,6 +144,21 @@ As such, Python is a language that is conducive to rapidly prototyping and testi
We will be relying heavily on Python and a library for doing optimized numerical computations, called NumPy, throughout this course.
<!-- #endregion -->

<!-- #region -->
## Keeping Up To Date

New versions of Python come out periodically, bringing new features and fixes. The most recent version of Python is Python 3.8.1, but many packages do not yet support this, so many machines still use the relatively recent Python 3.7.6.

All Python versions numbers use the A.B.C format. The three numbers denote major releases, minor releases, and patches.

- The first number denotes major releases to the language. The most current major release is Python 3, but Python 2 is still in use. When a major release comes out, it means that older code will not work with the new release. Running Python 2 code in a Python 3 interpreter will yield errors, as will running Python 3 code in a Python 2 interpreter. Although Python 2 is still used in many legacy applications, Python 3 is much more modern and is more widely used.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The first number denotes major releases to the language. The most current major release is Python 3, but Python 2 is still in use. When a major release comes out, it means that older code will not work with the new release. Running Python 2 code in a Python 3 interpreter will yield errors, as will running Python 3 code in a Python 2 interpreter. Although Python 2 is still used in many legacy applications, Python 3 is much more modern and is more widely used.
- The first number denotes major releases to the language. The most current major release is Python 3, but Python 2 is still in use. When a major release comes out, it means that older code may not work with the new release. Running Python 2 code in a Python 3 interpreter may yield errors, likewise for running Python 3 code in a Python 2 interpreter. Although Python 2 is still used in many legacy applications, Python 3 is much more modern and is more widely used.

More importantly, Python 2 is deprecated and not supported at all. Do we want to talk about it at all? I forget what's been said about it already

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can find, there isn't any current mention of Python 2. Seems like about 15% of Python people are still stuck on Python 2, so I think it bears mention? That being said, it should be clearer in that section that Python 2 is deprecated and that people should only really be using Python 3.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HardBoiled800 this material on Python versioning should be a separate PR. PRs should generally be monolithic.

- The second number denotes a minor release. When a minor release comes out, older code will run in the new interpreter, but new code will not necessarily be compatible with older versions. Python 3.7 and 3.8 are great examples of this - any code that works in Python 3.7 will run in Python 3.8, but new syntax has been added that will not work with Python 3.7.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The second number denotes a minor release. When a minor release comes out, older code will run in the new interpreter, but new code will not necessarily be compatible with older versions. Python 3.7 and 3.8 are great examples of this - any code that works in Python 3.7 will run in Python 3.8, but new syntax has been added that will not work with Python 3.7.
- The second number denotes a minor release. When a minor release comes out, older code will run in the new interpreter, but new code will not necessarily be compatible with older versions. Python 3.7 and 3.8 are great examples of this - any code that works in Python 3.7 will run in Python 3.8, but new syntax has been added that will not work in Python 3.7.

- The third and final number denotes a patch, which generally means bug fixes and performance improvements. All code within the same minor release will run on all other patches within that minor release - all Python 3.7.6 code is compatible with a Python 3.7.1 interpreter, and vice versa. Patches are released fairly often, and their changes only occur 'under the hood'.

We will be using Python 3 in this course. Python 3.7.6 is compatible with most packages while Python 3.8.1 is not yet, so if you need to use a variety of packages it is safer to stick with Python 3.7.6. Otherwise, you will have no problems switching to Python 3.8.1.

<!-- #endregion -->

## Summary

- Python is a programming language - it provides us with a simple set of grammatical rules that allow us to write human-readable text, which can be translated unambiguously to instruct a computer to perform tasks.
Expand Down
112 changes: 112 additions & 0 deletions Python/Module2_EssentialsOfPython/Errors_and_Debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
jupyter:
jupytext:
text_representation:
extension: .md
format_name: markdown
format_version: '1.2'
jupytext_version: 1.3.0rc1
kernelspec:
display_name: Python 3
language: python
name: python3
---

<!-- #raw raw_mimetype="text/restructuredtext" -->
.. meta::
:description: Topic: Basics of Python Objects, Difficulty: Easy, Category: Section
:keywords: exceptions, errors, bugs, debug, fix
<!-- #endraw -->

<!-- #region -->
# Errors

Unfortunately, not all code is perfect. As you write more complicated programs, you will doubtless run into some errors that you will need to figure out how to fix. Although debugging skills will come with practice, it can be helpful to understand errors, what causes them, and how to fix them. The different types of errors can be broken down into three categories: syntax errors, exceptions, and logic errors.


<!-- #endregion -->

<!-- #region -->
## Syntax Errors

Syntax errors are by far the easiest errors to debug, and they will be the most common errors while you are learning to program. Syntax errors are raised when the Python interpreter is unable to understand your code due to a typo or some misplaced syntax. When a syntax error occurs, the interpreter will stop running. It will also display the `SyntaxError` code, and will often give a line number or explanation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Syntax errors are by far the easiest errors to debug, and they will be the most common errors while you are learning to program. Syntax errors are raised when the Python interpreter is unable to understand your code due to a typo or some misplaced syntax. When a syntax error occurs, the interpreter will stop running. It will also display the `SyntaxError` code, and will often give a line number or explanation.
Syntax errors are by far the easiest errors to debug, and they will be the most common errors while you are learning to write code. Syntax errors are raised when the Python interpreter is unable to understand your code due to a typo or some incorrect syntax. When a syntax error occurs, the interpreter will stop running. It will also display the `SyntaxError` code, and will often give a line number or explanation.

Have we talked about what syntax actually means before this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if there's been a strict definition, but the word is definitely used many times before this. Regardless I can make it a bit more clear.


Most syntax errors are benign and easily detectable, such as mispelling a name or forgetting a piece of punctuation. Occasionally you will encounter a tricky syntax error where you cannot find your mistake in the line. When this happens, remember to look out for punctuation mistakes, especially in parentheses. Misplaced parentheses can be difficult to detect, but are relatively simple to fix once detected.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Most syntax errors are benign and easily detectable, such as mispelling a name or forgetting a piece of punctuation. Occasionally you will encounter a tricky syntax error where you cannot find your mistake in the line. When this happens, remember to look out for punctuation mistakes, especially in parentheses. Misplaced parentheses can be difficult to detect, but are relatively simple to fix once detected.
Most syntax errors are easily detectable, such as mispelling a name or forgetting a piece of punctuation. Occasionally, you will encounter a tricky syntax error where you cannot find your mistake in the line. When this happens, remember to look out for punctuation mistakes, especially in parentheses. Misplaced parentheses can be difficult to detect, but are relatively simple to fix once detected.

I wouldn't really call a syntax error benign since it will prevent your code from executing 🤔

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say it is benign in the sense that it doesn't lead to unexpected behavior in your program


Many modern IDEs will automatically detect syntax errors, and will sometimes automatically place punctuation and indentations. As such, syntax errors are becoming more easily avoidable, but it is still important to know how to spot and fix them.

<!-- #endregion -->

<!-- #region -->
## Exceptions
An exception occurs when a piece of code is valid and understood by the interpreter, but for some reason the interpreter is unable to execute the action. Exceptions can occur when a function is passed an incompatible type of input, when the program is asked to something it cannot, and in many other circumstances. Python has many types of built-in exceptions that can be raised, but here are several that you are likely to encounter and their causes:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"...when the program is asked to something it cannot,..."

asked to do something it cannot? To compute something it cannot? Need some extra word in there


| Exception | Causes |
| ------------- |:-------------:|
| `IndexError` | Attempting to index or slice into a list with an index outside of the list's range |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `IndexError` | Attempting to index or slice into a list with an index outside of the list's range |
| `IndexError` | Attempting to index into a list with an index outside of the list's range |

slicing outside the bounds is fine:

>>> [1, 2, 3][4:10]
[]

| `KeyError` | Attempting to access a dictionary value with a key that is not in the dictionary |
| `NameError` | Referencing a variable or function that is not yet defined |
| `TypeError` | Passing an object of an invalid type into a function or operation |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `TypeError` | Passing an object of an invalid type into a function or operation |
| `TypeError` | Passing an object of an invalid type into an operation |

functions aren't going to be doing any type checking at the call, so it's always going to be some operation, no?

Copy link
Collaborator Author

@samaocarpenter samaocarpenter Jan 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only thought would be that this could pop up when libraries are used - passing an invalid type into a lot of library functions will raise a TypeError. I know numpy uses a lot of TypeErrors, and I'm sure other libraries do as well -

Same applies to ValueErrors - is there a cleaner way to phrase this?

| `ValueError` | Passing an object of an appropriate type but invalid value to a function or operation |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `ValueError` | Passing an object of an appropriate type but invalid value to a function or operation |
| `ValueError` | Passing an object of an appropriate type but invalid value to an operation |

| `ZeroDivisionError` | Attempting to divide by zero. Can also be raised when a function is passed a value that would force it to divide by zero |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `ZeroDivisionError` | Attempting to divide by zero. Can also be raised when a function is passed a value that would force it to divide by zero |
| `ZeroDivisionError` | Attempting to divide by zero |

the latter case results from the former; the operation raises the error, not passing a value into the function


These six exceptions are the most common exceptions you will face, as they cover many possible issues. There exist many more specific exceptions for complicated errors, but they are much rarer and tend to only appear in very specific cases. Let's look at a piece of code that will raise an exception.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should have a link to the official exceptions page in here. I think most of the table above can essentially be copied from there, maybe with some additional exposition or with some details omitted.


```python
# attempting to take the square root of a negative number
>>> from math import sqrt
>>> math.sqrt(-1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
>>> math.sqrt(-1)
>>> sqrt(-1)

ValueError: math domain error

```

The math library cannot take the square root of a negative number. Because the number passed as an argument is technically the correct type, but is not compatible with the function, a `ValueError` is raised. Whenever you encounter one of these exceptions, be sure that you understand why the encounter is raised before you try to fix it.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The math library cannot take the square root of a negative number. Because the number passed as an argument is technically the correct type, but is not compatible with the function, a `ValueError` is raised. Whenever you encounter one of these exceptions, be sure that you understand why the encounter is raised before you try to fix it.
The `math` library cannot take the square root of a negative number. Because the number passed as an argument is technically the correct type, but is not compatible with the function, a `ValueError` is raised. Whenever you encounter one of these exceptions, be sure that you understand why the encounter is raised before you try to fix it.


It is also possible to raise exceptions on purpose with the `raise` statement. If you are writing a function that is designed only for certain inputs, it can be worthwhile to verify that inputs will be valid. As an example, let's create our own square root function.

```python
def squareRoot(x):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def squareRoot(x):
def square_root(x):

if x < 0:
raise ValueError('Cannot take the square root of a negative number.')
return x**0.5

>>> print(squareRoot(-1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
>>> print(squareRoot(-1))
>>> square_root(-1)

ValueError: Cannot take the square root of a negative number.
```

When the invalid value is passed, our function raises a ValueError rather than allowing the function to run with the value, possibly causing a worse or more confusing error. Clearly, in this case it was much better to raise an exception than to allow the program to continue! The `assert` statement can also be used to raise errors in the format `assert [boolean statement], 'error message'`, but it tends to be less informative and less powerful than simply using `raise`.

It is also possible to create custom exceptions using classes, which will be discussed further in Module 4.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe link to module 4 here

<!-- #endregion -->


<!-- #region -->
## Logic Errors

Logic errors occur when your code will run in the interpreter, but does not behave as expected. Whenever you write a function that works but outputs something incorrect, you have committed a logic error. Logic errors are very easy to commit and can be incredibly difficult to solve. It's impossible to completely avoid logic errors, but if you take care while programming and debugging, they can often be avoided or fixed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Logic errors occur when your code will run in the interpreter, but does not behave as expected. Whenever you write a function that works but outputs something incorrect, you have committed a logic error. Logic errors are very easy to commit and can be incredibly difficult to solve. It's impossible to completely avoid logic errors, but if you take care while programming and debugging, they can often be avoided or fixed.
Logic errors occur when your code will run in the interpreter, but will not behave as expected. Whenever you write a function that runs but outputs something incorrect, you have committed a logic error. Logic errors are very easy to commit and can be incredibly difficult to solve. It's impossible to completely avoid logic errors, but if you take care while programming and debugging, they can often be avoided or fixed.

works -> runs because if it's outputting incorrect values it's not really working 😬


Before writing a complex program, it is often smart to write psuedocode beforehand to ensure that your algorithm makes sense and will do what you want it to. It is important to understand how your program will work before you write it. After writing the program, it can be helpful to take another walk through how the program works, and make sure that every step makes sense. Some programmers keep rubber ducks at their desks and try to explain their code to the duck when they hit a bug. Sometimes, simply walking through your code slowly and describing everything can help you see an error that you otherwise may have missed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have we talked about pseudocode before this?

also placemark for myself because I want to revisit this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pseudocode isn't mentioned anywhere in the site as far as I can tell. Where do you think it would be good to include a discussion on pseudocode? I don't want to overcomplicate this section but it's definitely something we should talk about


Breaking your code down into functions can help with readability, usability, and debugging, especially as the scale of your project grows. It is much easier to find the error in ten functions, each with fifty lines, than it is to find the error in one block of code that is five hundred lines long. Testing out different parts of your code independently to verify that they work is essential to debugging.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Breaking your code down into functions can help with readability, usability, and debugging, especially as the scale of your project grows. It is much easier to find the error in ten functions, each with fifty lines, than it is to find the error in one block of code that is five hundred lines long. Testing out different parts of your code independently to verify that they work is essential to debugging.
Breaking your code down into functions can help with readability, usability, and debugging, especially as the scale of your project grows. It is much easier to find an error in ten functions, each with fifty lines, than it is to find an error in one block of code that is five hundred lines long. Testing out different parts of your code independently to verify that they work is essential to debugging.

might want to add a note here that says we'll discuss testing in more detail in Module 6


To find particularly elusive bugs, many IDEs come with debugging software that allows you to step through your program slowly and monitor the internal processes. Debuggers can be overkill for simpler bugs, but they can be invaluable tools when you cannot find a bug on your own.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we haven't really said much here. We've mentioned debuggers exist but haven't really said what they do (e.g. what does it mean to "step through your program slowly"?). May want to note that this is a topic outside the scope of this website and optionally include some helpful links to pdb, etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha part of this is because I am incredibly bad at using debuggers and barely understand how they work. I'll add some links

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HardBoiled800 you ought not write instructional material about topics you "barely understand"! 😛 It is better to simply ask for someone else to contribute.


If all else fails, it's best to simply move on and return to the program after some time has passed. A bug that may seem impossible to fix may become much easier after a good night's sleep or a meal.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If all else fails, it's best to simply move on and return to the program after some time has passed. A bug that may seem impossible to fix may become much easier after a good night's sleep or a meal.
If all else fails, it's best to simply move on and return to the program after some time has passed. A bug that may seem impossible to fix may become much easier after a good night's sleep or a meal.

not sure "move on" is the best phrasing here. Move on meaning just keep working while knowing your code is broken? Move on meaning take a break (which seems what's intended here)?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that advice like "have a good night's sleep" fits in with the rest of the tone of PLYMI. To keep the material lean, I generally stick to material that provides guidance that is immediately actionable.

If there is a need to talk about methods for debugging, including high level aspects like taking a nap, I would prefer to simply link to a high-quality external resource. That topic deserves a lengthy discussion that includes stackoverflow, debuggers, print statements, and testing.


<!-- #endregion -->

<!-- #region -->
## Summary

It is inevitable that you will have to deal with errors, so understanding what they are and how to fix them can be invaluable.

- Syntax errors occur when your code cannot be read by the Python interpreter
- Exceptions occur when your code is readable, but cannot be run correctly
- Logic errors occur when your code runs, but does not behave as expected


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have we talked about exception handling elsewhere (try/except)? If not, this should probably be added to this section

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have not. I believe @HardBoiled800 is meaning to loop back to add that

<!-- #endregion -->

## Link to Official Documentation

- [Built-in Exceptions](https://docs.python.org/3/library/exceptions.html)