IPython is a Python interpreter with a few additional, useful features and can often be used instead of the "python" command.
To start an IPython session, simply type ipython into your console.
Jupyter notebooks (or better, the newer Jupyter Lab) is a web interface to IPython with a few additional extras.
To start them, type jupyter notebook or jupyter lab (maybe not yet installed in the venv) respectively.
Jupyter notebooks/lab works with cells. Each cell can have a type, either markdown (for text as this one) or code (or raw, but that's advanced).
A cell can be executed with (default) Shift + Enter while Alt + Enter executes the current cell and adds an empty cell below.
From the moment the first cell is executed, we're inside one Python session. So all the definitions and states are remembered and are only reset by restarting the kernel. The cells can also be executed in an arbitrary order and multiple times. This can be tricky with stateful objects when a cell is executed multiple times. Let's look at it.
# FIRST, EXECUTE CELL BELOW
# otherwise raises error
print(a)
1
# Execute first
a = 1
This can be tricky with stateful objects such as lists. Make sure to reset this objects or just restart the kernel.
# creating the list
list1 = []
# Execute this cell multiple times. List will grow
list1.append(42)
print(list1)
[42]
? command returns the docstring of the corresponding method, class, etc.
dict?
? can also be applied to instances
letters = {"a": 1, "b": 2}
letters?
help(.) gives the full documentation of the object and its methods.
help(dict)
Help on class dict in module builtins:
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
| dict(**kwargs) -> new dictionary initialized with the name=value pairs
| in the keyword argument list. For example: dict(one=1, two=2)
|
| Built-in subclasses:
| StgDict
|
| Methods defined here:
|
| __contains__(self, key, /)
| True if the dictionary has the specified key, else False.
|
| __delitem__(self, key, /)
| Delete self[key].
|
| __eq__(self, value, /)
| Return self==value.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __gt__(self, value, /)
| Return self>value.
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __ior__(self, value, /)
| Return self|=value.
|
| __iter__(self, /)
| Implement iter(self).
|
| __le__(self, value, /)
| Return self<=value.
|
| __len__(self, /)
| Return len(self).
|
| __lt__(self, value, /)
| Return self<value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __or__(self, value, /)
| Return self|value.
|
| __repr__(self, /)
| Return repr(self).
|
| __reversed__(self, /)
| Return a reverse iterator over the dict keys.
|
| __ror__(self, value, /)
| Return value|self.
|
| __setitem__(self, key, value, /)
| Set self[key] to value.
|
| __sizeof__(...)
| D.__sizeof__() -> size of D in memory, in bytes
|
| clear(...)
| D.clear() -> None. Remove all items from D.
|
| copy(...)
| D.copy() -> a shallow copy of D
|
| get(self, key, default=None, /)
| Return the value for key if key is in the dictionary, else default.
|
| items(...)
| D.items() -> a set-like object providing a view on D's items
|
| keys(...)
| D.keys() -> a set-like object providing a view on D's keys
|
| pop(...)
| D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
|
| If the key is not found, return the default if given; otherwise,
| raise a KeyError.
|
| popitem(self, /)
| Remove and return a (key, value) pair as a 2-tuple.
|
| Pairs are returned in LIFO (last-in, first-out) order.
| Raises KeyError if the dict is empty.
|
| setdefault(self, key, default=None, /)
| Insert key with a value of default if key is not in the dictionary.
|
| Return the value for key if key is in the dictionary, else default.
|
| update(...)
| D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
| If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]
| If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v
| In either case, this is followed by: for k in F: D[k] = F[k]
|
| values(...)
| D.values() -> an object providing a view on D's values
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| __class_getitem__(...) from builtins.type
| See PEP 585
|
| fromkeys(iterable, value=None, /) from builtins.type
| Create a new dictionary with keys from iterable and values set to value.
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
IPython supports tab completion giving the list of available functions or for letters function letters description of the function singature. Just start to type what you want and press Tab.
pri # press TAB to make this "print"
p # press TAB to show all the commands starting with "p"
! allows to invoke system shell commands.
!ls
Lecture_ipython.ipynb script.py
IPython comes with a set of functions that can be called in a command-line style.
% runs the line as a command, %% the whole cell
Some examples of magic functions
With %run <filename> we can invoke python scripts in an IPython shell
%run script.py
Hello, I am a script!
%load <filename> loads the content of the file into the cell
# Uncomment the line below to execute it
# %load script.py
The commands time (single execution) and timeit (many executions, more accurate) measure the execution time (single and statistical evaluation)
%time a = 1
CPU times: user 2 µs, sys: 1 µs, total: 3 µs Wall time: 3.81 µs
%%time
for _ in range(int(1e6)):
pass
CPU times: user 39.1 ms, sys: 1.53 ms, total: 40.6 ms Wall time: 39.9 ms
user refers to the time spent to execute the command, sys refers to the time spent in the kernel
%timeit a = 1
10.2 ns ± 0.364 ns per loop (mean ± std. dev. of 7 runs, 100,000,000 loops each)
%%timeit
for _ in range(int(1e6)):
pass
21 ms ± 1.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
We can also store the output of the magic commands in a variable
script_out = %run script.py
Hello, I am a script!
print(script_out) # there is no return value!
None
dict_timing = %time dict(a=1,b=2)
CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 4.05 µs
dict_timing
{'a': 1, 'b': 2}
IPython allows to do interactive debugging using the %%debug magic command.
You can use the usual debug commands for navigation
%%debug
a = 3
for _ in range(a):
a += 1
print("End")
NOTE: Enter 'c' at the ipdb> prompt to continue execution. > <string>(2)<module>() ipdb> p a 6
There is builtin magic for other programming languages.
For example Perl, LaTex and R
%%perl
use strict;
my $a = 5;
while($a > 0) {
print "$a ";
$a--;
}
print "\n";
5 4 3 2 1
%%perl
# Function definition
sub Hello {
print "Hello, World!\n";
}
Hello()
Hello, World!
%%latex
$$a=1+\gamma$$
Some text
\begin{eqnarray}
a^2+b^2 &=&c^2\\
x&=&y
\end{eqnarray}
# Needs rpy2 installed
%load_ext rpy2.ipython
%%R
library(lattice)
attach(mtcars)
# scatterplot matrix
splom(mtcars[c(1,3,4,5,6)], main="MTCARS Data")
The following objects are masked from mtcars (pos = 3):
am, carb, cyl, disp, drat, gear, hp, mpg, qsec, vs, wt
The following objects are masked from mtcars (pos = 4):
am, carb, cyl, disp, drat, gear, hp, mpg, qsec, vs, wt
6
Markdown text can be used to document your work. HTML and custom tags allow you to structure your text and explain your code, for example what a list comprehension is squares = [n**2 for n in numbers].
And even LaTeX code can be used in markdown cells: $\nabla f = (\partial_x f,\partial_y f,\partial_z f)$