This is one of the 100 recipes of the IPython Cookbook, the definitive guide to high-performance scientific computing and data science in Python.

1.1. Introducing the IPython notebook

  1. We assume that you have installed a Python distribution with IPython, and that you are now in an IPython notebook. Type in a cell the following command, and press Shift+Enter to validate it:
In [ ]:
print("Hello world!")

A notebook contains a linear succession of cells and output areas. A cell contains Python code, in one or multiple lines. The output of the code is shown in the corresponding output area.

  1. Now, we do a simple arithmetic operation.
In [ ]:
2+2

The result of the operation is shown in the output area. Let's be more precise. The output area not only displays text that is printed by any command in the cell, it also displays a text representation of the last returned object. Here, the last returned object is the result of 2+2, i.e. 4.

  1. In the next cell, we can recover the value of the last returned object with the _ (underscore) special variable. In practice, it may be more convenient to assign objects to named variables, like in myresult = 2+2.
In [ ]:
_ * 3
  1. IPython not only accepts Python code, but also shell commands. Those are defined by the operating system (Windows, Linux, Mac OS X, etc.). We first type ! in a cell before typing the shell command. Here, we get the list of notebooks in the current directory.
In [ ]:
!ls *.ipynb
  1. IPython comes with a library of magic commands. Those commands are convenient shortcuts to common actions. They all start with % (percent character). You can get the list of all magic commands with %lsmagic.
In [ ]:
%lsmagic

Cell magic have a %% prefix: they apply to an entire cell in the notebook.

  1. For example, the %%writefile cell magic lets you create a text file easily. This magic command accepts a filename as argument. All remaining lines in the cell are directly written to this text file. Here, we create a file test.txt and we write Hello world! in it.
In [ ]:
%%writefile test.txt
Hello world!
In [ ]:
# Let's check what this file contains.
with open('test.txt', 'r') as f:
    print(f.read())
  1. As you can see in the output of %lsmagic, there are many magic commands in IPython. You can find more information about any command by adding a ? after it. For example, here is how we get help about the %run magic command:
In [ ]:
# You can omit this, it is just to force help output
# to print in the standard output, rather than 
# in the pager. This might change in future versions
# of IPython.
from __future__ import print_function
from IPython.core import page
page.page = print
In [ ]:
%run?
  1. We covered the basics of IPython and the notebook. Let's now turn to the rich display and interactive features of the notebook. Until now, we only created code cells, i.e. cells that contain... code. There are other types of cells, notably Markdown cells. Those contain rich text formatted with Markdown, a popular plain text formatting syntax. This format supports normal text, headers, bold, italics, hypertext links, images, mathematical equations in LaTeX, code, HTML elements, and other features, as shown below.
### New paragraph This is *rich* **text** with [links](http://ipython.org), equations: $$\hat{f}(\xi) = \int_{-\infty}^{+\infty} f(x)\, \mathrm{e}^{-i \xi x}$$ code with syntax highlighting: ```python print("Hello world!") ``` and images: ![This is an image](http://ipython.org/_static/IPy_header.png)

New paragraph

This is rich text with links, equations:

$$\hat{f}(\xi) = \int_{-\infty}^{+\infty} f(x)\, \mathrm{e}^{-i \xi x}$$

code with syntax highlighting:

print("Hello world!")

and images:

This is an image

By combining code cells and Markdown cells, you can create a standalone interactive document that combines computations (code), text and graphics.

  1. That was it for Markdown cells. IPython also comes with a sophisticated display system that lets you insert rich web elements in the notebook. Here, we show how to add HTML, SVG (Scalable Vector Graphics) and even Youtube videos in a notebook.

First, we need to import some classes.

In [ ]:
from IPython.display import HTML, SVG, YouTubeVideo

We create an HTML table dynamically with Python, and we display it in the (HTML-based) notebook.

In [ ]:
HTML('''
<table style="border: 2px solid black;">
''' + 
''.join(['<tr>' + 
         ''.join(['<td>{row},{col}</td>'.format(
            row=row, col=col
            ) for col in range(5)]) +
         '</tr>' for row in range(5)]) +
'''
</table>
''')

Similarly here, we create a SVG graphics dynamically.

In [ ]:
SVG('''<svg width="600" height="80">''' + 
''.join(['''<circle cx="{x}" cy="{y}" r="{r}"
        fill="red" stroke-width="2" stroke="black">
        </circle>'''.format(
            x=(30+3*i)*(10-i), y=30, r=3.*float(i)
        ) for i in range(10)]) + 
'''</svg>''')

Finally, we display a Youtube video by giving its identifier to YoutubeVideo.

In [ ]:
YouTubeVideo('j9YpkSX7NNM')
  1. Now, we illustrate the latest interactive features in IPython 2.0+. This version brings graphical widgets in the notebook that can interact with Python objects. We will create a drop-down menu allowing us to display one among several videos.
In [ ]:
from collections import OrderedDict
from IPython.display import display, clear_output
from ipywidgets import Dropdown
#from IPython.html.widgets import DropdownWidget # IPython < 4.x
In [ ]:
# We create a Dropdown widget, with a dictionary containing
# the keys (video name) and the values (Youtube identifier) 
# of every menu item.
dw = Dropdown(options=OrderedDict([
# dw = DropdownWidget(values=OrderedDict([ # IPython < 4.x
                        ('SciPy 2012', 'iwVvqwLDsJo'), 
                        ('PyCon 2012', '2G5YTlheCbw'),
                        ('SciPy 2013', 'j9YpkSX7NNM')]))
# We create a callback function that displays the requested
# Youtube video.
def on_value_change(name, val):
    clear_output()
    display(YouTubeVideo(val))
# Every time the user selects an item, the function
# `on_value_change` is called, and the `val` argument
# contains the value of the selected item.
dw.on_trait_change(on_value_change, 'value')
# We choose a default value.
dw.value = dw.options['SciPy 2013']
# dw.value = dw.values['SciPy 2013'] # IPyhon < 4.x
# Finally, we display the widget.
display(dw)

The interactive features of IPython 2.0 bring a whole new dimension in the notebook, and we can expect many developments in the months and years to come.

You'll find all the explanations, figures, references, and much more in the book (to be released later this summer).

IPython Cookbook, by Cyrille Rossant, Packt Publishing, 2014 (500 pages).