-
Notifications
You must be signed in to change notification settings - Fork 54
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -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. | ||||||
|
@@ -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: | ||||||
|
||||||
|
@@ -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? | ||||||
|
@@ -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. | ||||||
- 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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
- 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. | ||||||
|
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Have we talked about what syntax actually means before this? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I wouldn't really call a syntax error benign since it will prevent your code from executing 🤔 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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 | | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
functions aren't going to be doing any type checking at the call, so it's always going to be some operation, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
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): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if x < 0: | ||||||
raise ValueError('Cannot take the square root of a negative number.') | ||||||
return x**0.5 | ||||||
|
||||||
>>> print(squareRoot(-1)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
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`. | ||||||
davidmascharka marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
It is also possible to create custom exceptions using classes, which will be discussed further in Module 4. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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)? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||||||
|
||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have we talked about exception handling elsewhere ( There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.