IPython is an interactive computing environment; not only it is an enhanced interactive Python shell, but it is also an architecture for interactive parallel computing and provides (in recent versions) a very nice notebook like interface.
In case you use the pythonxy distribution under Windows, it is a good idea to start the IPython with mlab-mode enabled; you find several modes in the menu-entry “enhanced console” of pythonxy.
For a good introduction to IPython, you should read the tutorial on using the interactive features:
We resume here the commands that we use frequently in our work. One of the most important features is TAB-completion, you can start typing any function or variable name and by pressing <TAB> obtain a list of suggestions or the unique match for completion.
In [1]: from scipy import linalg
In [2]: linalg.<TAB>
where <TAB> refers to the TAB-key. You should see something like:
In [2]: linalg.
linalg.LinAlgError linalg.clapack linalg.eigvals
linalg.Tester linalg.companion linalg.eigvals_banded
linalg.all_mat linalg.coshm linalg.eigvalsh
linalg.basic linalg.cosm linalg.expm
linalg.bench linalg.decomp linalg.expm2
linalg.blas linalg.decomp_cholesky linalg.expm3
linalg.block_diag linalg.decomp_lu linalg.fblas
linalg.calc_lwork linalg.decomp_qr linalg.flapack
linalg.cblas linalg.decomp_schur linalg.flinalg
linalg.cho_factor linalg.decomp_svd linalg.funm
linalg.cho_solve linalg.det linalg.get_blas_funcs
linalg.cho_solve_banded linalg.diagsvd linalg.hadamard
linalg.cholesky linalg.eig linalg.hankel
linalg.cholesky_banded linalg.eig_banded linalg.hessenberg
linalg.circulant linalg.eigh linalg.hilbert
[...]
IPython examined the linalg submodule, and returned all the possible completions. Once you see an interesting function, you’d like to know how to use it:
In[3]: linalg.eig?<ENTER>
In order to view the actual source code, use two question marks instead of one.
The magic commands (all commands starting by a % sign are called magic because they are not python code but ipython specific control codes.) %pdoc, %pdef, %psource and %pfile will respectively print the docstring, function definition line, full source code and the complete file for any object (when they can be found). If automagic is on (it is by default), you don’t need to type the % explicitly:
np.linalg.svd?
pdoc np.linalg.svd
pdef np.linalg.svd
psource np.linalg.svd
All output results are automatically stored in a global dictionary named Out and variables named _1, _2, etc. alias them. For example, the result of input line 4 is available either as Out[4] or as _4. The last three objects in output history are also kept in variables named _, __ and ___.
Put a ; at the end of a line to suppress the printing of output. The _* variables and the Out[*] list do get updated with the contents of the output, even if it is not printed. You can thus still access the generated results this way for further processing.
The %history command can show you all previous input, without line numbers if desired (option -n) so you can directly copy and paste code either back in IPython or in a text editor. You can also save all your history by turning on logging via %logstart; these logs can later be either reloaded as IPython sessions or used as code for your programs.
Related to the history:
- Up and down arrows (Ctrl-p/Ctrl-n)
- PgUp and PgDn keys
- Search: Ctrl-r and start typing
- Ctrl-a or Home key: go to start of line
- Ctrl-e or End key: end of line
- Ctrl-k: kill to end of line
- Ctrl-L: clear screen
Consider now the files sattelite.py that implements the simplified trajectory of a sattelite:
import numpy as np
from matplotlib import pyplot as plt
op = 2*np.pi; os = 14.*np.pi
R = 4.; r = 0.25
t = np.linspace(0, 2, 2000)
xp = np.cos(op*t)
yp = np.sin(op*t)
xs = xp + r*np.cos(os*t)
ys = yp + r*np.sin(os*t)
plt.plot(xs,ys); plt.show()
The %run magic command:
run sattelite.py
run -t sattelite.py
run -p sattelite.py
run -d sattelite.py
%run also has special flags for timing the execution of your scripts (-t) and for executing them under the control of either Python’s pdb debugger (-d) or profiler (-p). With all of these, %run can be used as the main tool for efficient interactive development of code which you write in your editor of choice.
IPython is a command line-oriented program, without full control of the terminal. Therefore, it doesn’t fully support true multiline editing. However, it has a number of useful tools to help you in dealing effectively with more complex editing.:
%edit 10-20 24 28 # opens an editor with these lines pre-loaded for modification
%save <filename> # saves the lines directly to a named file on disk
Here comes an example showing the working flow with python.
Suppose we want to plot the tajectory of a sattelite of the earth as seen from the sun. After thinking about the mathematics of the problem, we might start by trying an implementation interactively in ipython:
[gradinar@localhost TutCodes]$ ipython
Python 2.6.4 (r264:75706, Jul 14 2010, 09:36:06)
Type "copyright", "credits" or "license" for more information.
IPython 0.10 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]: import numpy as np
In [2]: op = 2*np.pi; os = 14.*np.pi
In [3]: R = 4.; r = 2
In [4]: t = np.linspace(0, 2, 100)
In [5]: xp = np.cos(op*t)
In [6]: yp = np.sin(op*t)
In [7]: xs = xp + r*np.cos(os*t)
In [8]: ys = yp + r*np.sin(os*t)
In [9]: from matplotlib import pyplot as plt
In [10]: plt.plot(xs,ys); plt.show()
/usr/lib64/python2.6/site-packages/matplotlib/backends/backend_gtk.py:621: DeprecationWarning: Use the new widget gtk.Tooltip
self.tooltips = gtk.Tooltips()
Out[10]: [<matplotlib.lines.Line2D object at 0x7f5d8c822050>]
The result is far from satisfactory. Something went wrong with the radia:
In [11]: R = 4.; r = 0.25
In [12]: plt.plot(xs,ys); plt.show()
Out[12]: [<matplotlib.lines.Line2D object at 0x7f5d8c853510>]
Nothing changed? Of course, because we haven’t recomputed the trajectories yet! We do not want to retype everything, so look at the history:
In [13]: hist
1 : import numpy as np
2 : op = 2*np.pi; os = 14.*np.pi
3 : R = 4.; r = 2
4 : t = np.linspace(0, 2, 100)
5 : xp = np.cos(op*t)
6 : yp = np.sin(op*t)
7 : xs = xp + r*np.cos(os*t)
8 : ys = yp + r*np.sin(os*t)
9 : from matplotlib import pyplot as plt
10: plt.plot(xs,ys); plt.show()
11: R = 4.; r = 0.25
12: plt.plot(xs,ys); plt.show()
13: _ip.magic("hist ")
OK, so lines 6 to 10 has to be repeated, but I forgot how it works:
In [14]: rep?
Type: Magic function
Base Class: <type 'instancemethod'>
String Form: <bound method InteractiveShell.rep_f of <IPython.iplib.InteractiveShell object at 0x7f5da06a2d90>>
Namespace: IPython internal
File: /usr/lib/python2.6/site-packages/IPython/history.py
Definition: rep(self, arg)
Docstring:
Repeat a command, or get command to input line for editing
- %rep (no arguments):
Place a string version of last computation result (stored in the special '_'
variable) to the next input prompt. Allows you to create elaborate command
lines without using copy-paste::
$ l = ["hei", "vaan"]
$ "".join(l)
==> heivaan
$ %rep
$ heivaan_ <== cursor blinking
%rep 45
Place history line 45 to next input prompt. Use %hist to find out the
number.
Aha!
In [15]: rep 6-10
lines [u'yp = np.sin(op*t)\nxs = xp + r*np.cos(os*t)\nys = yp + r*np.sin(os*t)\nfrom matplotlib import pyplot as plt\nplt.plot(xs,ys); plt.show()\n']
Out[20]: [<matplotlib.lines.Line2D object at 0x7f5d8c629b90>]
Hmm, still not good, what if we take more points?
In [21]: t = np.linspace(0, 2, 2000)
In [22]: rep 6-10
lines [u'yp = np.sin(op*t)\nxs = xp + r*np.cos(os*t)\nys = yp + r*np.sin(os*t)\nfrom matplotlib import pyplot as plt\nplt.plot(xs,ys); plt.show()\n']
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/home/gradinar/LaTeX_doc/Numcourses/Numcourses/SciPyTools/Start/TutCodes/<ipython console> in <module>()
ValueError: shape mismatch: objects cannot be broadcast to a single shape
Upps, one of the variables is longer. What was there?
In [25]: hist
1 : import numpy as np
2 : op = 2*np.pi; os = 14.*np.pi
3 : R = 4.; r = 2
4 : t = np.linspace(0, 2, 100)
5 : xp = np.cos(op*t)
6 : yp = np.sin(op*t)
7 : xs = xp + r*np.cos(os*t)
8 : ys = yp + r*np.sin(os*t)
9 : from matplotlib import pyplot as plt
10: plt.plot(xs,ys); plt.show()
11: R = 4.; r = 0.25
12: plt.plot(xs,ys); plt.show()
13: _ip.magic("hist ")
14: #?rep
15: _ip.magic("rep 6-10")
16: yp = np.sin(op*t)
17: xs = xp + r*np.cos(os*t)
18: ys = yp + r*np.sin(os*t)
19: from matplotlib import pyplot as plt
20: plt.plot(xs,ys); plt.show()
21: t = np.linspace(0, 2, 2000)
22: _ip.magic("rep 6-10")
23: yp = np.sin(op*t)
24: xs = xp + r*np.cos(os*t)
25: _ip.magic("hist ")
Aha, I rerun the wrong lines; let’s do it again:
In [26]: rep 5-10
lines [u'xp = np.cos(op*t)\nyp = np.sin(op*t)\nxs = xp + r*np.cos(os*t)\nys = yp + r*np.sin(os*t)\nfrom matplotlib import pyplot as plt\nplt.plot(xs,ys); plt.show()\n']
Out[32]: [<matplotlib.lines.Line2D object at 0x7f5d8c556750>]
It looks well; let us save our valuable work in a file. What to save?
In [33]: hist
1 : import numpy as np
2 : op = 2*np.pi; os = 14.*np.pi
3 : R = 4.; r = 2
4 : t = np.linspace(0, 2, 100)
5 : xp = np.cos(op*t)
6 : yp = np.sin(op*t)
7 : xs = xp + r*np.cos(os*t)
8 : ys = yp + r*np.sin(os*t)
9 : from matplotlib import pyplot as plt
10: plt.plot(xs,ys); plt.show()
11: R = 4.; r = 0.25
12: plt.plot(xs,ys); plt.show()
13: _ip.magic("hist ")
14: #?rep
15: _ip.magic("rep 6-10")
16: yp = np.sin(op*t)
17: xs = xp + r*np.cos(os*t)
18: ys = yp + r*np.sin(os*t)
19: from matplotlib import pyplot as plt
20: plt.plot(xs,ys); plt.show()
21: t = np.linspace(0, 2, 2000)
22: _ip.magic("rep 6-10")
23: yp = np.sin(op*t)
24: xs = xp + r*np.cos(os*t)
25: _ip.magic("hist ")
26: _ip.magic("rep 5-10")
27: xp = np.cos(op*t)
28: yp = np.sin(op*t)
29: xs = xp + r*np.cos(os*t)
30: ys = yp + r*np.sin(os*t)
31: from matplotlib import pyplot as plt
32: plt.plot(xs,ys); plt.show()
33: _ip.magic("hist ")
Aha, let us save the lines 1 31 2 11 21 5-8 10 in this order:
In [34]: save testsat.py 1 31 2 11 21 5-8 10
The following commands were written to file `testsat.py`:
import numpy as np
from matplotlib import pyplot as plt
op = 2*np.pi; os = 14.*np.pi
R = 4.; r = 0.25
t = np.linspace(0, 2, 2000)
xp = np.cos(op*t)
yp = np.sin(op*t)
xs = xp + r*np.cos(os*t)
ys = yp + r*np.sin(os*t)
plt.plot(xs,ys); plt.show()
In [35]:
%who/%whos: These functions give information about identifiers you have defined interactively (not things you loaded or defined in your configuration files). %who just prints a list of identifiers and %whos prints a table with some basic details about each identifier.
The point about % with an example on the magic comand %cd:
[gradinar@localhost Start]$ ipython
Python 2.6.4 (r264:75706, Jul 14 2010, 09:36:06)
Type "copyright", "credits" or "license" for more information.
IPython 0.10 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]: cd ..
/home/gradinar/Documents/SciPyTutorial
In [2]: cd = 5
In [3]: cd
Out[3]: 5
In [4]: cd Start
------------------------------------------------------------
File "<ipython console>", line 1
cd Start
^
SyntaxError: invalid syntax
In [5]: %cd Start
/home/gradinar/Documents/SciPyTutorial/Start
In [6]:
More nice documentation on IPython here.