Adapted from the ICESat2 Hackweek intro-jupyter-git session. Courtesy of @fperez.
When executing code in IPython, all valid Python syntax works as-is, but IPython provides a number of features designed to make the interactive experience more fluid and efficient.
In the notebook, to run a cell of code, hit Shift-Enter
. This executes the cell and puts the cursor in the next cell below, or makes a new one if you are at the end. Alternately, you can use:
Alt-Enter
to force the creation of a new cell unconditionally (useful when inserting new content in the middle of an existing notebook).Control-Enter
executes the cell and keeps the cursor in the same cell, useful for quick experimentation of snippets that you don't need to keep permanently.print("Hi")
Hi
Getting help:
?
Typing object_name?
will print all sorts of details about any object, including docstrings, function definition lines (for call arguments) and constructor details for classes.
import numpy as np
np.linspace?
np.isclose??
*int*?
An IPython quick reference card:
%quickref
Tab completion, especially for attributes, is a convenient way to explore the structure of any object you’re dealing with. Simply type object_name.<TAB>
to view the object’s attributes. Besides Python objects and keywords, tab completion also works on file and directory names.
np.
File "<ipython-input-7-df0eca0bfa5c>", line 1 np. ^ SyntaxError: invalid syntax
2+10
12
_+10
22
You can suppress the storage and rendering of output if you append ;
to the last cell (this comes in handy when plotting with matplotlib, for example):
10+20;
_
22
The output is stored in _N
and Out[N]
variables:
_11 == Out[11]
True
Previous inputs are available, too:
In[11]
'_'
_i
'In[11]'
%history -n 1-5
1: print("Hi") 2: ? 3: import numpy as np np.linspace? 4: np.isclose?? 5: *int*?
Exercise
Use %history?
to have a look at %history
's magic documentation, and write the last 10 lines of history to a file named log.py
.
!pwd
/Users/lindseyjh/git/geohackweek/datasharing/notebooks
files = !ls
print("files this directory:")
print(files)
files this directory: ['00-conda.ipynb', '01-Introduction Jupyter.ipynb', '02-Beyond Plain Python.ipynb', '__pycache__', 'images', 'index.ipynb', 'mod.py']
!echo $files
[00-conda.ipynb, 01-Introduction Jupyter.ipynb, 02-Beyond Plain Python.ipynb, __pycache__, images, index.ipynb, mod.py]
!echo {files[0].upper()}
00-CONDA.IPYNB
Note that all this is available even in multiline blocks:
import os
for i,f in enumerate(files):
if f.endswith('ipynb'):
!echo {"%02d" % i} - "{os.path.splitext(f)[0]}"
else:
print('--')
00 - 00-conda 01 - 01-Introduction Jupyter 02 - 02-Beyond Plain Python -- -- 05 - index --
The IPyhton 'magic' functions are a set of commands, invoked by prepending one or two %
signs to their name, that live in a namespace separate from your normal Python variables and provide a more command-like interface. They take flags with --
and arguments without quotes, parentheses or commas. The motivation behind this system is two-fold:
To provide an namespace for controlling IPython itself and exposing other system-oriented functionality that is separate from your Python variables and functions. This lets you have a cd
command accessible as a magic regardless of whether you have a Python cd
variable.
To expose a calling mode that requires minimal verbosity and typing while working interactively. Thus the inspiration taken from the classic Unix shell style for commands.
%magic
Line vs cell magics:
Magics can be applied at the single-line level or to entire cells. Line magics are identified with a single %
prefix, while cell magics use %%
and can only be used as the first line of the cell (since they apply to the entire cell). Some magics, like the convenient %timeit
that ships built-in with IPython, can be called in either mode, while others may be line- or cell-only (you can see all magics with %lsmagic
).
Let's see this with some %timeit
examples:
%timeit list(range(1000))
15.1 µs ± 359 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(range(10))
list(range(100))
1.48 µs ± 17.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Line magics can be used even inside code blocks:
for i in range(1, 5):
size = i*100
print('size:', size, end=' ')
%timeit list(range(size))
size: 100 1.09 µs ± 26.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) size: 200 1.62 µs ± 17.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) size: 300 2.84 µs ± 160 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) size: 400 4.6 µs ± 135 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Magics can do anything they want with their input, so it doesn't have to be valid Python (note that the below may not work on a Windows machine, depending on how you are running Jupyter on it):
%%bash
echo "My shell is:" $SHELL
echo "My disk usage is:"
df -h
My shell is: /bin/zsh My disk usage is: Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/disk1s1 466Gi 426Gi 28Gi 94% 4225365 9223372036850550442 0% / devfs 199Ki 199Ki 0Bi 100% 688 0 100% /dev /dev/disk1s4 466Gi 10Gi 28Gi 27% 10 9223372036854775797 0% /private/var/vm map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home
Another interesting cell magic: create any file you want locally from the notebook:
%%writefile test.txt
This is a test file!
It can contain anything I want...
And more...
Writing test.txt
!cat test.txt
This is a test file! It can contain anything I want... And more...
Let's see what other magics are currently defined in the system:
%lsmagic
Available line magics: %alias %alias_magic %autoawait %autocall %automagic %autosave %bookmark %cat %cd %clear %colors %conda %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %pip %popd %pprint %precision %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode Available cell magics: %%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile Automagic is ON, % prefix IS NOT needed for line magics.
def to_optimize(N):
total = [0,0]
ta = 0
tb = 0
for i in range(N):
for j in range(N):
a = i**2
b = j*2
total[0] += a
total[1] += b
return total
%timeit to_optimize(1_000)
464 ms ± 7.21 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%prun to_optimize(1_000)
Not only can you input normal Python code, you can even paste straight from a Python or IPython shell session:
>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
... print(b)
... a, b = b, a+b
1 1 2 3 5 8
In [1]: for i in range(10):
...: print(i, end=' ')
...:
0 1 2 3 4 5 6 7 8 9
And when your code produces errors, you can control how they are displayed with the %xmode
magic:
%%writefile mod.py
def f(x):
return 1.0/(x-1)
def g(y):
return f(y+1)
Overwriting mod.py
Now let's call the function g
with an argument that would produce an error:
import mod
mod.g(0)
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-35-81c06c6c0e90> in <module> 1 import mod ----> 2 mod.g(0) ~/git/geohackweek/datasharing/notebooks/mod.py in g(y) 4 5 def g(y): ----> 6 return f(y+1) ~/git/geohackweek/datasharing/notebooks/mod.py in f(x) 1 2 def f(x): ----> 3 return 1.0/(x-1) 4 5 def g(y): ZeroDivisionError: float division by zero
When running code interactively, it can be tricky to figure out how to debug...
%debug
> /Users/lindseyjh/git/geohackweek/datasharing/notebooks/mod.py(3)f() 1 2 def f(x): ----> 3 return 1.0/(x-1) 4 5 def g(y): ipdb> x 1 ipdb> quit
enjoy = input('Are you enjoying this tutorial? ')
print('enjoy is:', enjoy)
Are you enjoying this tutorial? ? enjoy is: ?
%%
magics¶%%perl
@months = ("July", "August", "September");
print $months[0];
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 300)
y = np.sin(x**2)
plt.plot(x, y)
plt.title("A little chirp")
This is meant to provide a quick overview of some of the things you can do with Jupyter widgets. For more ideas, you can check out the docs, and the notebooks from the ICESat2 Hackweek
import numpy as np
import matplotlib.pyplot as plt
import ipywidgets
%matplotlib inline
def sin_x(x, frequency=1, phase=0):
return np.sin(
2*np.pi*frequency*x + phase
)
def plot_sin_x(frequency=1., phase=0.):
x = np.linspace(-1, 1, 200)
plt.plot(x, sin_x(x, frequency, phase))
widget = ipywidgets.interactive(plot_sin_x)
mywidget = ipywidgets.interactive(
plot_sin_x,
frequency = ipywidgets.FloatSlider(min=0, max=10, value=1),
phase = ipywidgets.FloatSlider(min=-np.pi, max=np.pi, value=0)
)
mywidget
mywidget.children[0].value