Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • linigodelacruz/practicum-lecture-notes
  • stephandehoop/practicum-lecture-notes
  • saghajani/practicum-lecture-notes
  • jeroenkalkman/practicum-lecture-notes
  • python-for-applied-physics/practicum-lecture-notes
5 results
Show changes
Commits on Source (153)
Showing
with 922 additions and 164 deletions
# Mac folder
.DS_Store
*.zip
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
......
outputs:
before_script:
- conda install jupytext -c conda-forge
script:
- "jupytext */Notebook*md Outline\\ of\\ notebooks.md --to notebook"
- "jupytext Additional*/*md --to notebook"
artifacts:
paths:
- "*/Notebook*ipynb"
- "Course_Information/*ipynb"
- "Course_Information/*png"
- "Notebook*/*png"
- "Notebook 5/exercise_data.dat"
- "Notebook 5/v_vs_time.dat"
- "Notebook 5/example2.dat"
- "Outline of notebooks.ipynb"
- "Additional*/*ipynb"
- "Additional*/*png"
name: Lecture_Notebooks
# Feedback
## Which notebook?
## Type of feedback (Typo, mistake, other)
## Copy-paste text from notebook:
## Source file
## Description
## Suggested change (optional)
## Copy paste line of text where it occurs
\ No newline at end of file
## Optional description (not needed for typos)
\ No newline at end of file
%% Cell type:markdown id: tags:
# Additional Programming Concepts in Python
In this notebook, you will learn about additional programming concepts in Python. They are not part of the learning objectives of the course, but you may run into them at some point, or wonder what they are, or find them fun and useful if you already have some programming experience.
*(Much of this material we wrote up in an earlier version of the notebooks, but then moved here when we tweaked the course to fit in the time we have available.)*
## Tuples
### What is a tuple?
The first more complicated data structure we will discuss is a `tuple`. A tuple is a collection of values inside curved brackets. Here is the basic syntax for making a tuple:
```
my_tuple = (a, b, c, ...etc...)
```
As a concrete example, this will create a tuple of three integers:
%% Cell type:code id: tags:
``` python
tup1 = (5,6,7)
print(tup1)
```
%% Output
(5, 6, 7)
%% Cell type:markdown id: tags:
Like the other data types we've see, we can see the tuples we create using `%whos`:
%% Cell type:code id: tags:
``` python
%whos
```
%% Output
Variable Type Data/Info
-----------------------------
tup1 tuple n=3
%% Cell type:markdown id: tags:
Tuples are like lists, but behave a bit differently than python lists. In fact, we've already seen tuples before in the previous notebook when we were looking at `for` loops!
If you are given a tuple, you can check how long it by using the `len()` function built into python:
%% Cell type:code id: tags:
``` python
len(tup1)
```
%% Cell type:markdown id: tags:
Note that tuples do not have to contain integers, they can contain any type of data:
%% Cell type:code id: tags:
``` python
# A tuple of strings
str_tup = ('foo', 'bar')
print(str_tup)
```
%% Cell type:markdown id: tags:
Different than how numpy arrays are typically used, tuples can even be mixed, with each element of a different type:
%% Cell type:code id: tags:
``` python
mixed_tup = (1, 1.05, 7+3j, 'foo')
print(mixed_tup)
```
%% Cell type:markdown id: tags:
And you can even have tuples of tuples:
%% Cell type:code id: tags:
``` python
tup_of_tup = (str_tup, mixed_tup)
print(tup_of_tup)
```
%% Cell type:markdown id: tags:
Tuples support all the same indexing and slicing as arrays.
%% Cell type:markdown id: tags:
Tuples can also contain other tuples! If your tuple contains another tuple, like the example `tup_of_tup`, you can use the square brackets a second time to index into the tuple you extract by the first set of square brackets:
%% Cell type:code id: tags:
``` python
print(tup_of_tup)
print(tup_of_tup[0])
print(tup_of_tup[0][0])
```
%% Cell type:markdown id: tags:
### Looping over tuples without using indices
As mentioned briefly in Notebook 2, python `for` loops can also directly iterate over "iteratable" objects.
The `tuple` (along with lists, which we will see in a bit, and numpy arrays, which we will see in the next notebook), is one such iteratable objecte.
For example, to print all of entries of a `tuple` out in order, we can use directly following:
%% Cell type:code id: tags:
``` python
for n in tup1:
print(n)
```
%% Cell type:markdown id: tags:
During each subsequent iteartion of the loop, the variable `n` will be assigned to the next item that is stored in the tuple.
%% Cell type:markdown id: tags:
## Lists
In this section, we will introduce a very commonly used data structure in python: the `list`.
A list is a list of values, like a `tuple`, but that is made using square brackets:
```
my_list = [a, b, c, ...etc...]
```
%% Cell type:code id: tags:
``` python
l1 = list(range(10))
l1
```
%% Cell type:markdown id: tags:
Like tuples, you can extract single elements of the list using indexing, and extract portions of the list using slicing:
%% Cell type:code id: tags:
``` python
print(l1[0])
print(l1[0:5])
```
%% Cell type:markdown id: tags:
OK, so far so good. But if I have `tuple`, why would I ever want a list?
### Lists vs tupples: Tupples are "immutable", lists are "mutable"
This is a bit of python-speak for saying that you cannot change the values of a tupple, but you can change the values of a list.
What does this mean? It means if I have a list `[5,6,7]` and I want to change the last number in my list to an 8, I can just directly do this:
%% Cell type:code id: tags:
``` python
l1 = [5,6,7]
l1[2] = 8
```
%% Cell type:markdown id: tags:
If I try this with a tuple, I will find that I can't do it!
%% Cell type:code id: tags:
``` python
t1 = (5,6,7)
t1[2] = 8
```
%% Output
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-9c8e47fcf882> in <module>()
1 t1 = (5,6,7)
----> 2 t1[2] = 8
TypeError: 'tuple' object does not support item assignment
%% Cell type:markdown id: tags:
Because of this functionality, **lists are much more powerful as we can change them once we've made them!**
In addition to changing lists by individual indexing, we can also change whole parts of the list using slicing:
%% Cell type:code id: tags:
``` python
l2 = list(range(10))
print(l2)
```
%% Cell type:code id: tags:
``` python
# Replace three entries by zeros
l2 = list(range(10))
l2[4:7] = [0,0,0]
print(l2)
```
%% Cell type:code id: tags:
``` python
# Remove entries from a list by replacing them with an empty list []
l2 = list(range(10))
l2[4:7] = []
print(l2)
```
%% Cell type:markdown id: tags:
### Functions for manipulating lists
In fact, our list object itself has functions built in that allow you to change it! Some examples of things we can do:
%% Cell type:code id: tags:
``` python
# This will add an element to the end of the list
l1.append(10)
l1
```
%% Cell type:code id: tags:
``` python
# This will remove an element from the end of the list
l1.pop()
l1
```
%% Cell type:markdown id: tags:
There are many more functions built into lists, some of which you can find here:
https://docs.python.org/3/tutorial/datastructures.html
%% Cell type:markdown id: tags:
### The problem with lists for scientific computing
Lists look an awful lot like numpy arrays: why don't we just use lists?
In scientific computing, it is very common to want to perform numerical operations on <a href=https://en.wikipedia.org/wiki/Row_and_column_vectors>vectors and matrices</a> of numbers. And also, many times in experiments, the data you will take will be represented by a vector of numbers: for example, the position of a particle as a function of time.
A vector is a collection of numbers in a one-dimentional array:
$$
x = [1, 2, 3, 4, 5]
$$
In Notebook 3, we already introduced python `list`s. A list is also a vector, right? It certainly looks the same! Why do we need something new?
The reason we need something new is that python `list`s are not designed to work in the same way as we expect vectors to from our mathematics classes. For example, in math:
$$
2x = [2,4,6,8,10]
$$
Let's check if this works with lists
%% Cell type:code id: tags:
``` python
l = [1, 2, 3, 4, 5]
print(2*l)
```
%% Output
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
%% Cell type:markdown id: tags:
This certainly does something, but it does not do what we want! It has made the list twice as long by appending two of them together!
Also addition and subtraction doesn't work like we would expect:
%% Cell type:code id: tags:
``` python
print(l+l)
```
%% Cell type:markdown id: tags:
Addition makes the list twice as long? And:
%% Cell type:code id: tags:
``` python
print(l-l)
```
%% Cell type:markdown id: tags:
And subtraction doesn't work at all...clearly, although they look a lot like vectors, in terms of mathematics, lists do not act much like vectors. This is one of the reasons numpy arrays were created.
%% Cell type:markdown id: tags:
## Dictionaries
Another useful data type in python is a "dictionary":
https://docs.python.org/3/tutorial/datastructures.html#dictionaries
At a basic level, a dictionary is a bit like a list that supports non-numeric indices. Dictionaries can be created using the curly brackets in python `{` and `}`.
Here we will create an empty dictionary and start filling it:
%% Cell type:code id: tags:
``` python
delft_lunch_rating = {}
delft_lunch_rating['greek olive'] = 10
delft_lunch_rating['brandmeester'] = 7
delft_lunch_rating['aula'] = "expensive"
delft_lunch_rating['citg'] = "bad"
delft_lunch_rating['doner'] = "good but a bit salty"
```
%% Cell type:markdown id: tags:
This is what our dictionary looks like:
%% Cell type:code id: tags:
``` python
print(delft_lunch_rating)
```
%% Output
{'greek olive': 10, 'brandmeester': 7, 'aula': 'expensive', 'citg': 'bad', 'doner': 'good but a bit salty'}
%% Cell type:markdown id: tags:
I can then look up values in my dictionary using the "keys":
%% Cell type:code id: tags:
``` python
delft_lunch_rating['aula']
```
%% Output
'expensive'
%% Cell type:markdown id: tags:
There are also functions for getting all the keys:
%% Cell type:code id: tags:
``` python
delft_lunch_rating.keys()
```
%% Cell type:markdown id: tags:
My dictionaries can also hold lists if I want:
%% Cell type:code id: tags:
``` python
delft_lunch_rating["greek olive"] = ['good', 10]
```
%% Cell type:markdown id: tags:
Dictionaries are actually a way to implement a basic database in python (I use them in my grading scripts to look up the email addresses and student numbers of a given netid...)
And the Jupyter notebook files actually store a list cells, and each cell consist of a dictionary that contains the text of the cell (and other fun things like metadata). You can see this in action using the <a href=https://nbformat.readthedocs.io/en/latest/api.html>nbformat</a> library, you can actually load a notebook file into your python kernel and poke around it to see what it looks like.
%% Cell type:markdown id: tags:
## Strings
In notebook 1, we already saw strings as variable types.
It turns out that strings are not just simple (immutable) variables like `int`s and `float`s: `str`s are actually data structures that are indexable (like `tuple`s and `list`s).
Strings are immutable, which means they cannot be changed. But they do have lots of built-in functions that can return a new string (or lots of other things!).
Let's look at an example:
%% Cell type:code id: tags:
``` python
s1 = "This is a string"
```
%% Cell type:markdown id: tags:
Indexing a string returns the characters of the string:
%% Cell type:code id: tags:
``` python
print(s1[0])
```
%% Cell type:markdown id: tags:
We can also slice:
%% Cell type:code id: tags:
``` python
print(s1[0:6])
```
%% Cell type:markdown id: tags:
Strings do not allow you to directly change
%% Cell type:markdown id: tags:
### Built-in string functions
Strings have a bunch of useful built-in functions:
https://docs.python.org/3/library/stdtypes.html#string-methods
some of which we will look at here:
### Splitting a string
Strings have a built-in function `split()`. By default, it will return a list of "words" by using whitespaces as the separator:
%% Cell type:code id: tags:
``` python
s1.split()
```
%% Cell type:markdown id: tags:
Passing `.` as an argument, `split()` will use that as a separator, which is useful for working with filenames:
%% Cell type:code id: tags:
``` python
input_file = 'myfile.dat'
output_file = input_file.split('.')[0]
output_file += "_processed.dat"
print(output_file)
```
%% Cell type:markdown id: tags:
### Replacing parts of strings
The function `replace()` replace substrings in your string for you:
%% Cell type:code id: tags:
``` python
s2 = "This is a long sentence. It is a good idea to end it."
print(s2)
print(s2.replace(" is", " was"))
```
%% Cell type:markdown id: tags:
Note that without the space, it will also replace the "is" in "This":
%% Cell type:code id: tags:
``` python
print(s2)
print(s2.replace("is", "was"))
```
%% Cell type:markdown id: tags:
### Testing for the contents of a string
You can check if a substring is found inside a string using the `in` logical operator:
%% Cell type:code id: tags:
``` python
if "this" in "somewhere in this sentence":
print("We found a 'this'")
```
%% Cell type:code id: tags:
``` python
# It is case sensitive:
if "this" in "This is a sentence":
print("This will not get printed")
```
%% Cell type:code id: tags:
``` python
# But you can use the .lower() function of a string to do case insensitive checks
s3 = "This is a sentence"
if "this" in s3.lower():
print("Using .lower(), s3 is converted to all lower-case:\n")
print("s3.lower = '%s'\n" % s3.lower())
print("And now we do find the substring 'this'")
```
%% Cell type:markdown id: tags:
Here, we can also see an example of special characters in strings: a `\n` in a string specifies a "new line":
https://docs.python.org/3/reference/lexical_analysis.html#strings
Note that if you want to print a backslash `\`, you need to put a double backslash in your string: `\\`.
%% Cell type:markdown id: tags:
### String formatting
Until now, we have been printing values of our variables using the standard `str()` conversion of numbers to strings:
%% Cell type:code id: tags:
``` python
a = 11/300
print("The value of a is", a)
# The above print() statement is equivalent to:
output = "The value of a is"
output += " "
output += str(a)
print(output)
```
%% Cell type:markdown id: tags:
But maybe we don't want so many digits in our text output. Say I want only two digits. How can I do this?
For this, python supports "string formatting". My personal preference is to work with traditional "printf-style" formatting, inherited from the C programming language:
https://docs.python.org/3/library/stdtypes.html#printf-style-bytes-formatting
It sounds a bit scary at first, but it's actually pretty easy to use. It works by using a special operator `%` that works with strings.
To use it, you include a special text in your string that starts with `%`, followed by a sequence of numbers and letters that you use to tell python how you want the string to be formatted.
Here are some examples:
%% Cell type:code id: tags:
``` python
# Floating point format with 4 digits
print("The value of a is %.4f" % a)
```
%% Cell type:code id: tags:
``` python
# Exponential notation with two digits
print("The value of a is %.2e" % a)
```
%% Cell type:code id: tags:
``` python
# A string with the formatting not at the end
print("The value of a is %.2e seconds" % a)
```
%% Cell type:markdown id: tags:
# Some additional matrix creation routines
There are several functions for making matrices which you may find useful someday:
https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html
including this one which I use often:
%% Cell type:code id: tags:
``` python
# The identity matrix
print(np.eye(10))
```
%% Cell type:code id: tags:
``` python
# A band diagonal matrix
print(np.eye(10,k=-1))
```
%% Cell type:markdown id: tags:
## Mutable objects and "call by reference"
### The `=` operator
Now that we have introduced some more advanced data types, it is time to go back and revisit one of our first topics: the `=` opeartor.
At the start of the first notebook, we introduced the **assignment operator** `=`, and saw that it could be used to give new values to a variable based on the value of another variable:
%% Cell type:code id: tags:
``` python
a = 5
b = a
print(b)
```
%% Cell type:markdown id: tags:
What happens if we change the value of `a` after the statment `b = a`? For example:
%% Cell type:code id: tags:
``` python
a = 5
b = a
a = 6
```
%% Cell type:markdown id: tags:
What value does `b` have? Does it have the value of `5` that `a` had when we performed the assignment operation, or does it have `6` (the new values of `a`)?
The obvious answer would be that `b` should have the answer `5`, right? Let's check it:
%% Cell type:code id: tags:
``` python
a = 5
b = a
a = 6
print(b)
```
%% Output
5
%% Cell type:markdown id: tags:
OK, that seems to make sense.
Now let's take a look at and examples with lists. We will create a list `a`, using the assignment operator to make a list variable `b = a`, and then change the values in the list `a`.
%% Cell type:code id: tags:
``` python
a = [2,1]
b = a
a[0] = 1
```
%% Cell type:markdown id: tags:
Now question: did `a[0] = 1` change the value of of `b`? Let's check:
%% Cell type:code id: tags:
``` python
print(b)
```
%% Output
[1, 1]
%% Cell type:markdown id: tags:
Changing the values of `a` also changed list `b` for some reason? **WHY!!!!?????!!! WHAT IS GOING ON?!!?**
### "Call by value" and "Call by reference"
To understand what is going on here, we have to understand how computer programs store variables and their values.
When I create a variable `a` in a python by giving it a value `5`, for example, python creates a space in your computers memory where it puts the value `5` and then makes a name for that variable `a` in the kernel's list of variables that points to that spot in memory.
For some types of objects in python, specifically "immutable" ("unchangeable") object types, when you execute the statement `b = a`, python will create a new spot in your computers memory for variable `b`, copy the value `5` into that memory spot, and then makes variable `b` point to this new spot in the kernel's list of variables.
This procedure is called "call by value" in programming languages, and is illustrated here:
<img src="call_by_value.png"></img>
<img src="resource/asnlib/public/call_by_value.png"></img>
For "mutable" objects, python uses a different concept: "call by reference". In call by reference, `b = a` instead does the following: it make a new variable `b` in the list of variables, and make it point to the spot in memory where variable `a` is stored, illustrated here:
<img src="call_by_reference.png"></img>
<img src="resource/asnlib/public/call_by_reference.png"></img>
It is now obvious why changing the values in `a` will also changes the values in `b`: it is because they point to the same data in your computers memory.
"Call by reference" also holds for when you are passing variables to functions:
%% Cell type:code id: tags:
``` python
def set_first_entry_to_zero(x):
x[0] = 0
a = [1,2]
set_first_entry_to_zero(a)
print(a)
```
%% Output
[0, 2]
%% Cell type:markdown id: tags:
We can see that our function changed the value of the variable mylist! This was not possible with integers for example:
%% Cell type:code id: tags:
``` python
def set_to_zero(x):
x = 0
a = 1
set_to_zero(a)
print(a)
```
%% Output
1
%% Cell type:markdown id: tags:
### Why use "call by reference" at all? I find it confusing!
You might ask: why python does this? Well, one reason is that it is that lists, and in particular numpy arrays that we will look at next, can sometime become very big, taking up 100 MB of memory or more. If python used "call by value" for such big things all the time, it would use up massive amounts of memory! Every function call or assignment statement would accdientally use up another 100 MB of memory! By using "call by reference", it can avoid accidentally filling up your computers memory every time you use the `=` operator.
If you really want to have a *copy* of a list (or a numpy array), these objects typically have `copy()` functions built in that return instead a copy of the object, for when you really need one.
%% Cell type:code id: tags:
``` python
a = [2,1]
b = a.copy()
print(b)
a[0] = 1
print(b)
```
%% Cell type:markdown id: tags:
Now, `b` is unaffected by your changes to `a` because the name `b` points to a new copy of the array in memory.
%% Cell type:markdown id: tags:
## Interactive plots with ipywidgets
One of the cool things that is easy to do in Jupter notebooks is to make "interactive" plots.
For example, in the projectile example above, I may want to be able to play with the angle and see how this changes my trajectory. For this, there is a very easy to use and convenient library called `ipywidgets`.
The way it works is we make a function that generates our plot that takes the parameter we want to play with as an argument. We then call an `ipywidgets` function called `interact()`, and it will automatically make a "live update" plot in your web browser in which you can adjust the parameter an see how the plot changes.
Let's look at an example:
%% Cell type:code id: tags:
``` python
from ipywidgets import interact
v0 = 10 # m/s
g = 9.8 # m/s^2
# We will allow theta to be adjusted and start it at 45 degrees
def update_plot(theta=45):
theta *= np.pi/180 # convert to radians
y = -g/(2*v0**2*np.cos(theta)**2)*x**2 + x*np.tan(theta)
plt.plot(x,y)
plt.ylim(-1,6) # Manually set the ylimits
plt.xlabel("Distance (m)")
plt.ylabel("Height (m)")
plt.axhline(0, ls=":", c="grey")
plt.show()
# Now we call interact, and give it a tuple specifiying the min, max and step for the theta slider
interact(update_plot, theta=(0,89,2))
```
%% Cell type:markdown id: tags:
It is a bit slow in updating if you wiggle it too much with the mouse, but if you click on the slider and adjust it using the arrow keys on your keyboard, it works pretty well.
If you are fitting a line to your data, this can also be very useful for getting a good initial guess:
%% Cell type:code id: tags:
``` python
def update_plot2(slope=0.5):
line = t*slope
plt.plot(t,v, '.')
plt.plot(t,line, lw=4)
plt.xlabel("Time (s)")
plt.ylabel("Voltage (V)")
plt.show()
interact(update_plot2, slope=(0,10,0.1))
```
%% Cell type:markdown id: tags:
It is also easy to make two sliders:
%% Cell type:code id: tags:
``` python
def update_plot3(slope=0.5, offset=0):
line = t*slope+offset
plt.plot(t,v, '.')
plt.plot(t,line, lw=4)
plt.xlabel("Time (s)")
plt.ylabel("Voltage (V)")
plt.show()
interact(update_plot3, slope=(0,10,0.1), offset=(-4,3,0.2))
```
%% Cell type:markdown id: tags:
## Functions
### Keyword and optional arguments
In addition to the "positional" arguments we introduced earlier, python also supports another type of argument: the "keyword" argument. These are often used for "optional" arguments that you don't neccessarily need but may want to give the user the option of using. The syntax is:
```
def function_name(var1, optional_var2 = default_value)
...
```
The "default_value" is the value that the optional argument will have if it is not specified by the user.
In python-speak, these "optional" arguement as called "keyword" arguments, and the normal arguments we introduced above are called "positional" arguments. In python, in both defining and using functions, keyword arguments must always come after all of the positional arguments.
Here, we will show an example where we use an optional parameter to change the way we print the status sentence.
%% Cell type:code id: tags:
``` python
def print_status4(x, long=True):
if long:
print("The value of the first input variable is ", x)
else:
print("Val is ", x)
print_status4(1)
print_status4(2.5, long=True)
print_status4(2.4, long=False)
```
%% Output
The value of the first input variable is 1
The value of the first input variable is 2.5
Val is 2.4
%% Cell type:markdown id: tags:
Because python assigns the value of keyword argument variables in the function by matching the keyword and not their position in the list, if you have multiple keyword arguments, you can also change the order of them when you use the function.
For example, if I define a function:
```
def myfunction(x, var1=1, var2=4):
...
```
then both of these would do the same thing:
```
myfunction(1,var1=3, var2=54)
myfunction(1,var2=54, var2=3)
```
Finally, one can also use keywords as a way to send values to functions even if the functions are not defined with keyword arguments. This allows you to change to order of variables you send to a function if you want. For example:
%% Cell type:code id: tags:
``` python
def myfun(x,y):
print("x is", x)
print("y is", y)
```
%% Cell type:code id: tags:
``` python
myfun(1,2)
```
%% Output
x is 1
y is 2
%% Cell type:code id: tags:
``` python
myfun(2,1)
```
%% Output
x is 2
y is 1
%% Cell type:code id: tags:
``` python
myfun(x=1,y=2)
```
%% Output
x is 1
y is 2
%% Cell type:code id: tags:
``` python
myfun(y=2,x=1)
```
%% Output
x is 1
y is 2
%% Cell type:markdown id: tags:
### Python Error Messages with functions
In the first notebook, we learned some of the basics of how to understand python errors.
Sometimes, though, if you are using functions from a library, the error messages can get very long, and trickier to understand.
Here, we will look at how to dissect an example of a more complicated error you can get from a function in a library and how to figure out where the useful information is.
%% Cell type:code id: tags:
``` python
import matplotlib.pyplot as plt
plt.plot([1,2], [1,2,3])
```
%% Output
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-11-19f47447b05c> in <module>()
1 import matplotlib.pyplot as plt
----> 2 plt.plot([1,2], [1,2,3])
C:\Programs\Anaconda3\lib\site-packages\matplotlib\pyplot.py in plot(*args, **kwargs)
3356 mplDeprecation)
3357 try:
-> 3358 ret = ax.plot(*args, **kwargs)
3359 finally:
3360 ax._hold = washold
C:\Programs\Anaconda3\lib\site-packages\matplotlib\__init__.py in inner(ax, *args, **kwargs)
1853 "the Matplotlib list!)" % (label_namer, func.__name__),
1854 RuntimeWarning, stacklevel=2)
-> 1855 return func(ax, *args, **kwargs)
1856
1857 inner.__doc__ = _add_data_doc(inner.__doc__,
C:\Programs\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py in plot(self, *args, **kwargs)
1525 kwargs = cbook.normalize_kwargs(kwargs, _alias_map)
1526
-> 1527 for line in self._get_lines(*args, **kwargs):
1528 self.add_line(line)
1529 lines.append(line)
C:\Programs\Anaconda3\lib\site-packages\matplotlib\axes\_base.py in _grab_next_args(self, *args, **kwargs)
404 this += args[0],
405 args = args[1:]
--> 406 for seg in self._plot_args(this, kwargs):
407 yield seg
408
C:\Programs\Anaconda3\lib\site-packages\matplotlib\axes\_base.py in _plot_args(self, tup, kwargs)
381 x, y = index_of(tup[-1])
382
--> 383 x, y = self._xy_from_xy(x, y)
384
385 if self.command == 'plot':
C:\Programs\Anaconda3\lib\site-packages\matplotlib\axes\_base.py in _xy_from_xy(self, x, y)
240 if x.shape[0] != y.shape[0]:
241 raise ValueError("x and y must have same first dimension, but "
--> 242 "have shapes {} and {}".format(x.shape, y.shape))
243 if x.ndim > 2 or y.ndim > 2:
244 raise ValueError("x and y can be no greater than 2-D, but have "
ValueError: x and y must have same first dimension, but have shapes (2,) and (3,)
%% Cell type:markdown id: tags:
Wow, that was a really big error message. What do I do with all of this?
The most important information is at the very top and at the very bottom (you can just skip the rest for now...).
At the top, it shows us the part of our code that triggered the error:
<img src="big_error_1.png"></img>
<img src="resource/asnlib/public/big_error_1.png"></img>
The error type is a `ValueError`, which according to the documentation, indicates "an argument that has the right type but an inappropriate value".
In the middle there is then a whole bunch of stuff we won't easily understand. What is all of this? This is showing us what is happening inside all the functions of the matplotlib library...probably unless you are a bit of an expert, you will not really understand all of this.
We can learn more, though, by looking at the last line:
<img src="big_error_2.png"></img>
What are `x` and `y`? They are the variable names in the library function in matplotlib where we ended up, so probably also maybe not immediately obvious what they are. But we can see more about the problem: it is complaining that two of the variables do not have the same shape.
If we look up at the line in our code that triggered the error, we can see that we have supplied two arguments that have a different number of elements: `plt.plot([1,2], [1,2,3])`
It would seem that both the first and second variables of the `plot` function should have the same number of elements. Indeed, if we try:
`plt.plot([1,2,3], [1,2,3,])`
then the error goes away:
%% Cell type:code id: tags:
``` python
plt.plot([1,2,3], [1,2,3,])
```
%% Cell type:markdown id: tags:
## Learning objectives list
Not crucial since this notebook is optional, but maybe useful to have.
**Learning objectives for this notebook:**
* Student is able to create and index tuples and lists by hand and using the `range()` operator
* Student is able to loop over tuples and lists without indexing
* Student is able to extract subsets of lists and tuples using slicing
* Student is able to change individual entries of a list using indexing and the assignment operator
* Student is able to use built-in functions of lists
* Student is able to use indexing to extract substrings from a string
* Student is able to use built-in string functions
* Student is able to split a string into a list of strings using the `.split()` function
* Student is able to search in strings using the `in` operator
* Student is able to use formating and the `%` opereator to control how variables are translated into strings
* Student is able to predict how variables behave differently for "mutable" and "non-mutable" objects (call-by-value vs. call-by-reference)
* Student is able to use the `ipywidgets` `interact()` function to explore functions using sliders
%% Cell type:code id: tags:
``` python
```
......
Additional Material/resource/asnlib/public/call_by_reference.png

11.8 KiB

Additional Material/resource/asnlib/public/call_by_value.png

11.9 KiB

Course_Information/Course_Information_anaconda_prompt_windows.png

25.2 KiB

Course_Information/Course_Information_cell_type.png

20.8 KiB

Course_Information/Course_Information_disable_box.png

17.3 KiB

Course_Information/Course_Information_enable_toc.png

14.5 KiB

Course_Information/Course_Information_mac_terminal.png

123 KiB

Course_Information/Course_Information_nbextensions.png

12.2 KiB

Course_Information/Course_Information_notebook_server.png

228 KiB

%% Cell type:markdown id: tags:
## Installing and running the server
%% Cell type:markdown id: tags:
### My Jupyter server has crashed, link does not work
If the link http://localhost:8888 does not work, your server may have crashed (or may be running on a different port if you accidentally started muliple servers).
If this is the case, you should go back to the Anaconda prompt window it was running in and do the following:
1. Type `Ctrl-C`
2. Run the command `jupyter notebook stop`
3. Run the command `jupyter notebook start`
If you cannot find the Anaconda prompt window anymore, you can also open a new Anaconda prompt window and do steps 2 and 3 above.
%% Cell type:markdown id: tags:
### My files are not in my home directory, how do I get to them?
If your files are stored outside of your home directory, for example if they are on your D: drive in windows, you will have to first change directories in the Anaconda prompt to that folder before you run the command `jupyter notebook`.
For example, let's say your files are on the D: drive in a folder `D:\Python\Practicum`. First you should stop the notebook server (see steps 1 and 2 of "Restarting a notebook server") and then you can use the following commands in the Anaconda prompt:
* `d:`
* `cd Python`
* `jupyter notebook`
This will start a notebook server with the "root directory" as `D:\Python`, which will allow you to access all the files in subfolders of `D:\Python`.
%% Cell type:markdown id: tags:
### Why is my web browser going to http://localhost:8889/ (instead of 8888)?
This can happen when you (accidentally) open multiple notebook servers. You can list all the notebook servers that are running using the following command at the Anaconda prompt:
`jupyter notebook list`
You can then close any extra ones you don't want by using the `stop` command with their "port" number (the four numbers after "localhost"). For example, to stop one running on port 8889, use:
`jupyter notebook stop 8889`
%% Cell type:markdown id: tags:
## Using Jupyter Notebooks
%% Cell type:markdown id: tags:
### My code cell sometimes changes to a text cell, how do we change this back?
You have probably changed the "cell type" from "Code" to "Markdown". You can change it back using the menu toolbar dropdown box:
<img src="resource/asnlib/public/Course_Information_cell_type.png"></img>
There also <a href=https://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Notebook%20Basics.html#Keyboard-Navigation>keyboard shortcuts</a> for many things.
Most likely, you pushing the `M` key while the cell was selected in "command" mode (blue border). You can change it back by pushing the `Y` key.
%% Cell type:code id: tags:
``` python
```
---
jupyter:
jupytext:
formats: ipynb,md
text_representation:
extension: .md
format_name: markdown
format_version: '1.1'
jupytext_version: 1.2.2
kernelspec:
display_name: Python 3
language: python
name: python3
---
## Installing and running the server
### My Jupyter server has crashed, link does not work
If the link http://localhost:8888 does not work, your server may have crashed (or may be running on a different port if you accidentally started muliple servers).
If this is the case, you should go back to the Anaconda prompt window it was running in and do the following:
1. Type `Ctrl-C`
2. Run the command `jupyter notebook stop`
3. Run the command `jupyter notebook start`
If you cannot find the Anaconda prompt window anymore, you can also open a new Anaconda prompt window and do steps 2 and 3 above.
### My files are not in my home directory, how do I get to them?
If your files are stored outside of your home directory, for example if they are on your D: drive in windows, you will have to first change directories in the Anaconda prompt to that folder before you run the command `jupyter notebook`.
For example, let's say your files are on the D: drive in a folder `D:\Python\Practicum`. First you should stop the notebook server (see steps 1 and 2 of "Restarting a notebook server") and then you can use the following commands in the Anaconda prompt:
* `d:`
* `cd Python`
* `jupyter notebook`
This will start a notebook server with the "root directory" as `D:\Python`, which will allow you to access all the files in subfolders of `D:\Python`.
### Why is my web browser going to http://localhost:8889/ (instead of 8888)?
This can happen when you (accidentally) open multiple notebook servers. You can list all the notebook servers that are running using the following command at the Anaconda prompt:
`jupyter notebook list`
You can then close any extra ones you don't want by using the `stop` command with their "port" number (the four numbers after "localhost"). For example, to stop one running on port 8889, use:
`jupyter notebook stop 8889`
## Using Jupyter Notebooks
### My code cell sometimes changes to a text cell, how do we change this back?
You have probably changed the "cell type" from "Code" to "Markdown". You can change it back using the menu toolbar dropdown box:
<img src="cell_type.png"></img>
There also <a href=https://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Notebook%20Basics.html#Keyboard-Navigation>keyboard shortcuts</a> for many things.
Most likely, you pushing the `M` key while the cell was selected in "command" mode (blue border). You can change it back by pushing the `Y` key.
```python
```
......@@ -37,11 +37,11 @@ Run the installer with the default options.
On **Windows**, open an "Anaconda prompt" (type "Anaconda prompt" in search in Windows 10, or look for it in the program menu):
<img src="attachment:anaconda_prompt_windows.png" width=50%></img>
<img src="anaconda_prompt_windows.png" width=50%></img>
On **MacOS**, open a "Teminal" app (use "Spotlight Search" and type "Terminal"):
<img src="attachment:mac_terminal.png" width=40%></img>
<img src="mac_terminal.png" width=40%></img>
At the command line of the terminal, run the following command by copy-pasting in the text and typing "enter":
......@@ -57,7 +57,7 @@ From the "Anaconda prompt" (in windows) or from "Terminal" (on MacOS), run the f
This will start the notebook server and automatically open a tab in your web browser sending you to the (local) web address of the notebook server running on your computer, showing you the files in your home directory:
<img width=70% src="attachment:notebook_server.png"><img>
<img width=70% src="notebook_server.png"><img>
If you close your browser, you can always use this link to get back to your local notebook server:
......@@ -75,15 +75,15 @@ http://localhost:8888/
Click on the "Nbextensions" tab:
<img src="attachment:nbextensions.png" width=50%></img>
<img src="nbextensions.png" width=50%></img>
Make sure that this box is not clicked:
<img src="attachment:disable_box.png" width=50%></img>
<img src="disable_box.png" width=50%></img>
<p> And enable the "Table of Contents" extension:
<img src="attachment:enable_toc.png" width=50%></img>
<img src="enable_toc.png" width=50%></img>
## Frequently asked questions
......