Jupyter Notebooks

Introduction

A really nice feature of Python is the Jupyter Notebook. These notebooks run in your browser. They use a Markdown, (see this cheatsheet for help) with HTML and LaTex mixed in, to nicely format the text comments, and they use full Python to do computations. There are plugins to do C++ or Julia as well, if you insist.

This document is itself a Jupyter notebook. You can look at it on GitHub, which renders a static picture for you, but if you download it and launch it on your own system, you can make modifications, save the result, and run the Python code directly in the notebook.

It is possible to run the notebooks on other servers. You can pass the GitHub URL for the "raw" notebook, and upload it to the server so you have your own copy, which you can then modify. Since all this is still someone new, it doesn't always work quite as expected. Initially I looked at Binder, recently I looked at Microsoft Azure. If you really need a server, I can also give you access to my own, running at UNH. Please email me if you do.

We will make use of Jupyter notebooks in Physics 605, and for some homework and lab reports. It is a very convenient way for your to submit your work. You can submit the notebook (.ipynb extension) or submit a GitHub URL pointing to your own repository.

You can easily convert the notebooks to pure Python scripts, or HTML webpage, or Latex pages. You can print the result to paper or to pdf. A Jupyter notebook can also be exported to pdf directly if you install Pandoc and LaTex.

Getting Started

To get started wiht Jupyter Notebooks, you first need to have installed ipython and the jupyter libraries. Fortunately this is already done for you if you installed the Anaconda Python distribution. See Installing Python on MyCources for details.

There are several ways to get the notebook server started on you own machine:

  • You can use the "Anaconda-Navigator" and click on "Launch" for the Jupyter notebooks.
  • You can type "jupyter notebook", or "jupyter-notebook", in a terminal, Powershell, or command window.

Usually you want to start Jupyter from the directory where all your code resides, so that the "home" window shows your code or the directories where your code is. See: Jupyter Documentation for more details.

A Jupyter server will start up on your system, and usually, starts your browser on a page http://localhost:8888

Entering and running code

In a Jupyter notebook you type text into the input box, and if you are done, you type shift+enter to execute that code. The same is true for the Markdown text, type shift+enter and the text is rendered pretty.

Note that for a notebook with a bunch of Python code in it, you usually need to execute the in[] lines in order, since what was computed before may be needed later in the notebook.

At the top of the notebook document in your browser, you see a standard menu bar. Note the black square for "interrupt kernel". That is what you hit if you had some code that takes too long to complete and is now hogging your computer's CPU. The circular arrow allows you to re-launch the kernel, which is a full reset. That means that the in[] fields need to be executed again from the 1st one.

You switch the type of input, between code, Markdown, Raw, with the selector box next to the arrow. The Markdown input does not a an in[] in front, and usually does not need to be executed again.

To re-edit an input that you previously executed, just double click the input box.

Remember regularly save your work when writing notebooks! 🙂

Document your code

I cannot emphasize enough how important it is that you document what you write. That means, you add comments and explanations to the actual program statements. If you create a notebook, use the MarkDown text cells to describe the code, and use Python comments to describe details of what the code is doing.


In [ ]:
# This is an example of a Python comments. Everything after a # symbol is ignored by Phython, so you use it
# explain what your code is doing. What is written above and below here is MarkDown text cells.

Using Matplotlib in a Notebook

If you want matplotlib, the plotting library that we will be using in this course, to work properly in a notebook, the prefered way is to enter the following lines at the very beginning of the Python code in your notebook. You do this so that it knows your code is running inline in the notebook and is not supposed to pop up a window.


In [2]:
# This helps matplotlib to realize you are woring from a notebook.
%matplotlib inline                 
import matplotlib.pyplot as plt    # This statement imports matplotlib.pyplot and renames it "plt", to save typing.

Getting started with some Python

A great place to learn about the Python language is in the Tutorial, which is part of the Python documentation. Here is super brief mini tutorial to get you started. This is not a replacement of a real tutorial!

Here is the most basic bit of Python code, something that just prints "Hello World", which is traditionally the start of any programming course.


In [3]:
print("Hello World")


Hello World

Now, lets make that more interesting. How about 10 lines of "Hello World", each line indented one extra space.


In [4]:
for i in range(10):
    print(" "*i + "Hello World")


Hello World
 Hello World
  Hello World
   Hello World
    Hello World
     Hello World
      Hello World
       Hello World
        Hello World
         Hello World

Here you see some interesting features of Python compared to other languages:

  • Python uses indentation to create a program block. In C++,C, or Java, this is done with {}, which is why those languages are sometimes called "bracket hell".
  • Instead of the for(int i=0;i<10;i++){} construct in C, we use range(10).
    • The range(10) construct actually produces a list: [0,1,2,3,4,5,6,7,8,9] and then itterates over the list.
  • In Python you usually do not need to declare a variable. Python figures out on its own what type a variable is.
    • If you want to know, use the type() build in function.
  • In python many operations, like multiply a space " " by an integer, "just make sense". Except when it doesn't 😬

One of the huge benefits of programming in Python is that you can start an interactive python shell (type ipython on the command line) and try out what the effect is of some bit of code. Or you can do this in a notebook.

Something else to point out: commends start with a #. Everything after the # is ignored by the Python interpreter.


In [5]:
i = 10 # This is an integer
type(i)


Out[5]:
int

In [6]:
i = 0.123 # Now, i is float
type(i)


Out[6]:
float

In [13]:
i=1
alist = [1,23,3.4,5,"Hello you!"] # now i is a list, with integers, floats and a string mixed up inside. Python doesn't care.
print(type(alist))                # You can print just about anything, and usually it looks OK.
print(type(alist[4]))
print(alist)
print("As a binary number we have {} = {} or as hexidecimal ={}".format(alist[i],bin(alist[i]),hex(alist[i])))


<class 'list'>
<class 'str'>
[1, 23, 3.4, 5, 'Hello you!']
As a binary number we have 23 = 0b10111 or as hexidecimal =0x17

Here you see another feature of Python. A variable (in this case i) is not reassigned a new value, but instead it is destroyed and recreated. So in the first line i was an integer, in the second line, a new variable, also called i is created and this time it is a float. Usually you do not need to worry about this behavior, but occasionally it can give interesting side effects.

Getting help

For almost everything in Python, help is build right into the system. You can simply type help(object) to get help on that object. The help you get is often a bit terse. Search the internet and you will find a wealth of information.


In [14]:
help("if")


The "if" statement
******************

The "if" statement is used for conditional execution:

   if_stmt ::= "if" expression ":" suite
               ( "elif" expression ":" suite )*
               ["else" ":" suite]

It selects exactly one of the suites by evaluating the expressions one
by one until one is found to be true (see section Boolean operations
for the definition of true and false); then that suite is executed
(and no other part of the "if" statement is executed or evaluated).
If all expressions are false, the suite of the "else" clause, if
present, is executed.

Related help topics: TRUTHVALUE

Tuples, Lists, Arrays, Dictionaries

In Python there are a few different ways of creating a collection of things: tuple, list, set, array and dictionary. In Fortran and C you pretty much only have the idea of an array, which in those languages is essentially a range of computer memory locations. In Java you also have collections, and there are a whole confusing lot more if them. In C++ you have array, and STL containers, and again there are a whole lot of them.

In Python, a list is an object that contains a list of other objects, or values. You create one like this:


In [15]:
my_list = ["one",2,"three",3.141]
print(my_list)


['one', 2, 'three', 3.141]

You can stick any other object in your list, including classes and functions, and you can mix them all up. In that way the list is quite different from most other languages, which require their arrays to have a uniform contents. The items in the list start at item 0, so:


In [16]:
print(my_list[0])


one

You can change the values in a list by re-assigning them to something different, and you can add new values, or delete values. Learn more about lists here and then here

Tuples look very much like a list, except that once created you cannot change the values that are in a tuple; they are immutable. An example tuple:


In [17]:
my_tuple = (0,1,'OK',"another string")
print(my_tuple[3])


another string

Learn more about tuples here

An important aspect of lists is "List comprehensions". These are fast and compact ways of dealing with lists. A complicated example: create a list that contains tuples (x,x^2,x^3) for x from 0 to 99. Then find the index of the tuple where x^2 is larger than 20 but smaller than 40. (of course we know that is the indexes: 5 and 6, but still):


In [18]:
a = [(x,x*x,x*x*x) for x in range(100)]
found = [ y for y in a if y[1] > 20 and y[1]<40]   # this selects the correct items in a
ind = [ a.index(i) for i in found]                 # this finds the index.
print(ind)


[5, 6]

The dictionary is a very handy object in Python. It allows you to build a list of items where the index is some object (like a string) instead of a number. You can create one, add to it, and then look things up in it, like this:


In [19]:
d = {"one":1, "two":"Wednesday", 4:"February", 3.141:"Pi","Pi":3.14157}
d['Coconuts']="Hard but yummy"   # Add something to the list
print(d["Pi"], " and ",d[3.141])


3.14157  and  Pi

Note that if you try to get something from the dictionary that isn't there (e.g. print d[5]), you get a "Key error", the key (the first object for each dictionary item) wasn't there. You can use "in" to test if it exists.


In [20]:
s = 5
if s in d:
    print(d[s])
else:
    print("Not found")


Not found

You can itterate over the dictionary like this:


In [24]:
for (key,value) in d.items():
    print("We have "+str(key)+" = "+str(value))


We have one = 1
We have two = Wednesday
We have 4 = February
We have 3.141 = Pi
We have Pi = 3.14157
We have Coconuts = Hard but yummy

Keep Going

I hope this got you started. Some of the many things you would want to learn about in Python:

The Tutorial will get you going with all of this.

Remember: You don't need to know everything about Python in order to get going using it. Just try at the ipython prompt. Before you know it, you will be using ipython as your default calculator...