Teaching with the IPython Notebook

In [1]:
from IPython.display import HTML
HTML("""
<h1>Hi, I&#8217;m Matt Davis</h1>
<h2>aka @jiffyclub</h2>
""")
Out[1]:

Hi, I’m Matt Davis

aka @jiffyclub

Introduction

Learning to program is serious business and it takes some brain power. Using the IPython Notebook can help free students' minds to focus on the core task of learning how to tell their computer what to do.

I volunteer with Software Carpentry where we teach software engineering skills to mostly grad-school level scientists and engineers. Our typical student does not regularly program and does not feel comfortable writing software. We teach Python to get them out of Excel. Our instruction focuses on fundamentals like loops, conditionals, writing functions, and developing computational thinking. It's a long, tough day for students so we want to give them every edge we can.

In [2]:
from IPython.display import Image
Image(filename='software-carpentry-banner.png', 
      embed=True)
Out[2]:
In [3]:
Image(filename='pic-seattle03.jpg', embed=True)
Out[3]:

Cognitive Load

We can help students more effectively learn by removing unnecessary mental load. Cognitive load theory describes three types of mental loads students must juggle during any learning:

  • Intrinsic load comes from the difficulty of the subject matter itself. For example, learning quantum mechanics could be considered inherently difficult.
  • Extraneous load is imposed by the teaching environment and materials. The extra translation required while learning quantum mechanics in a language you don't speak fluently would be considered extraneous load.
  • Germane load is mental power put toward understanding a topic and connecting it to existing knowledge.

Students have a finite amount of processing power and we want as much as possible to go towards germane load. The IPython Notebook can help us by minimizing extraneous load.

In [4]:
HTML("""
<div style="background-color: yellow; 
     color: brown; font-weight: bold;
     padding: 10px;">INTRINSIC</div>
<div style="background-color: red; 
     color: black; font-weight: bold;
     padding: 10px;">EXTRANEOUS</div>
<div style="background-color: green; 
     color: lightblue; font-weight: bold;
     padding: 10px;">GERMANE</div>
""")
Out[4]:
INTRINSIC
EXTRANEOUS
GERMANE

What is the IPython Notebook?

The IPython Notebook is a browser-based interactive interface to Python. It was added to the IPython family in early 2012 and it's become quite popular since then. It has a ton of great features that I won't be talking about here, but you can learn more on the IPython website.

In [5]:
print 'Hello, PyCon!'
Hello, PyCon!

How does the Notebook help?

The Notebook looks the same across Mac, Linux, and Windows and across all supported browsers. Students don't have to do any extra mental translation between what they see on the instructor's screen and what they see on theirs.

In [6]:
Image(filename='mac_linux_windows.png', 
      embed=True)
Out[6]:

There's no switching between a text editor and the command line, everything happens within the Notebook. In my experience this is a particularly important feature. Students get easily lost when there is frequent window switching and they have to keep track both of where they are and their instructor is.

The Notebook is served by Tornado and it's possible to set up a separate read-only server that people on the local network can connect to. This allows students to scroll around your notebook and see things that have gone off your screen.

With code and its output right next to eachother in the Notebook it's very easy to see the effect of changes and iterate to a solution. Editing multi-line code blocks is no problem in the Notebook's code cells.

The code cells act a little like miniature text editors. There's syntax highlighting, automatic indentation, and tab completion. We'll see more of that in a demonstration of IPython's help features.

In [7]:
for x in range(0, 20, 2):
    if x % 3 == 0:
        print x,
0 6 12 18

Help Features

Much of IPython's popularity is owed to its help features and they come in handy for students too.

In [8]:
from ipythonblocks import BlockGrid, colors

Say you are trying to instantiate a BlockGrid object but don't know all of its arguments. By typing out BlockGrid( and waiting a moment (or pressing tab) a floating help window will show up with the call signature and docstring. Pressing tab again will expand the window and make it scrollable. Typing BlockGrid? will open a similar help string in a frame at the bottom of the Notebook window.

In [ ]:
BlockGrid(

If we make a BlockGrid instance and want to see the methods and attributes available on it typing out grid. and pressing tab will show all of the completions, excepting those that start with an underscore.

These help features put hints at students' fingertips when they aren't sure what to do next and can facilitate self led learning and exploration.

In [9]:
grid = BlockGrid(5, 5, block_size=50)
In [ ]:
grid.

Extensions

Within the Notebook we have access to the display capabilities of the browser including HTML, CSS, and JavaScript. You can harness that capability to rich representations of Python objects and actions. Notebook extensions have been developed within the community that harness this capability.

One of these is ipythonblocks. It provides a Python object that displays in the Notebook as a grid of colored squares. The color of each square can be changed so that students can try indexing, loops, and ifs and immediately see the result. (Disclosure: ipythonblocks is my project.)

In [10]:
for block in grid.animate:
    if block.col == 1 or block.col == 3:
        block.rgb = colors['DarkCyan']
    elif block.row in (0, 2, 4):
        block.rgb = colors['FireBrick']

Another add-on called ipython_nose brings the nose testing framework into the Notebook for automated test discovery and running. The test run result display is augmented with a progress bar style visualization and the tracebacks from failing tests are hidden behind expandable panes. With ipython_nose you don't even have to leave the Notebook to teach test-driven development.

In [11]:
%load_ext ipython_nose
In [12]:
def test_fail():
    assert 1 == 2

def test_error():
    assert 1 / 0

def test_pass():
    assert 1 == 1
In [13]:
%nose
Out[13]:
 
 
1/3 tests passed; 2 failed
failed: __main__.test_fail [toggle traceback]
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 327, in run
    testMethod()
  File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "<ipython-input-12-4fe9bd56cdda>", line 2, in test_fail
    assert 1 == 2
AssertionError
failed: __main__.test_error [toggle traceback]
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 327, in run
    testMethod()
  File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "<ipython-input-12-4fe9bd56cdda>", line 5, in test_error
    assert 1 / 0
ZeroDivisionError: integer division or modulo by zero

Saving and Sharing

At the end of the day after students have done all this great stuff in the Notebook they can press save and shut it down and the next time they open it up everything will be there. The Notebook format is text and it can be easily shared and version controlled. There's always a GitHub repository associated with my boot camps so when we wrap up I commit my work to the repository so students can retrieve it. In another setting students could could submit assignments by pushing Notebooks to repo.

The IPython developers provide a service called nbviewer that renders Notebooks posted on the web. It has become extremely common to share demonstrations of Python topics by making a Notebook, posting it in a repo or gist, and sharing a link to the rendered Notebook on nbviewer. In fact, that's probably how you're reading this now.

Code needn't stand alone in a Notebook, you can also include Markdown for text and $\LaTeX$ for math rendering. Programming examples can be accompanied by richly formatted explanations and links to other resources. It's also possible to embed images (as you've seen here) and videos, both local and via YouTube.

No Free Lunch

The IPython Notebook has many helpful features but it does come with some of its own overhead to watch out for.

Installation

An operational Notebook installation requires three libraries in addition to IPython itself: Tornado, Jinja2, and PyZMQ. Experienced developers won't have any trouble with these libraries but any kind of installation can be a stumbling block for novices.

If you have access to a server you can take care of the installation there and start a Notebook server so that can students connect and start their own Notebook instances. For Software Carpentry boot camps I recommend people install the Anaconda CE all-in-one scientific Python package. Another option is EPD Free. As a last resort I have a Linux virtual machine image prepared with everything students need pre-installed.

In [14]:
HTML("""<h3>Requires:</h3>
<ul>
<li>Tornado</li>
<li>Jinja2</li>
<li>PyZMQ</li>
</ul>
""")
Out[14]:

Requires:

  • Tornado
  • Jinja2
  • PyZMQ

No pdb

Technical limitations of the technologies that drive the Notebook mean it can't run anything that uses the raw_input() function to get input from the user. The largest practical fallout of this is that the Python debugger cannot be used within the Notebook. A workaround is to connect a terminal or QT console IPython session to the same Python kernel as the Notebook to invoke the debugger.

In [15]:
HTML("""
<strong>
<strike>
<code>import pdb</code>
</strike></strong>
""")
Out[15]:
import pdb

Notebook vs. Kernel State

Because Notebooks are flexible, editable documents it's possible to end up with a mismatch between what a Notebook looks like and the actual state of the Python process behind the Notebook. For example, cells can be executed in any order or rearranged after they've been executed. It can be helpful to look at the numbers next to the In/Out prompts because these track the chronological order of cell execution. Cells can also be deleted after they've been executed, but in that case deleting the cell from the Notebook does not remove any variables, functions, or classes defined in that cell.

You can quickly re-sync the Notebook and kernel state by restarting the kernel from the "Kernel" menu and then re-running the entire Notebook via the "Run All" option in the "Cell" menu.

In [16]:
gone = 'Bye-bye!'
In [17]:
print gone
Bye-bye!

Conclusion & Contact

The Notebook is a fantastic way to simplify students' working evironments so they can focus on the task of learning how to tell their computers what to do via Python. The hooks into the browser's display capabilities open up possibilities for making good looking, interactive learning aids.

In [18]:
HTML("""
<div style="border: 5px solid black; 
     padding: 20px; 
     text-align: center;">
    <strong>simplify</strong>
</div>
""")
Out[18]:
simplify

And as a bonus, the Notebook is something that students will continue to use long after they've left your classroom. It's a popular tool for developers of all backgrounds.

In [19]:
HTML("""
<strong>
&hearts; IPython Notebook &hearts;
</strong>
""")
Out[19]:
♥ IPython Notebook ♥
In [20]:
HTML("""
<p>Annotated notebook: 
<a href="http://j.mp/jiffyclub-pycon-talk-2013">
j.mp/jiffyclub-pycon-talk-2013</a></p>
<br>
<p>I love to chat!</p>
<p><ul>
<li><code>@jiffyclub</code></li>
<li><code>jiffyclub@gmail.com</code></li>
</ul></p>
<p>Visit the IPython booth!</p>
""")
Out[20]:

Annotated notebook: j.mp/jiffyclub-pycon-talk-2013


I love to chat!

  • @jiffyclub
  • jiffyclub@gmail.com

Visit the IPython booth!

You can find me online in several places:

or send me an email at jiffyclub@gmail.com.