#!/usr/bin/env python
# coding: utf-8
# # The Jupyter notebook
#
# [IPython](https://ipython.org) provides a **kernel** for [Jupyter](https://jupyter.org).
# Jupyter is the name for this notebook interface,
# and the document format.
#
#
#
#
# Notebooks can contain [Markdown](https://help.github.com/articles/markdown-basics/) like this cell here,
# as well as mathematics rendered with [mathjax](https://mathjax.org):
#
# $$
# \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
# 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
# {1+\frac{e^{-8\pi}} {1+\ldots} } } }
# $$
# In[ ]:
get_ipython().system('head -n 32 "Intro to IPython.ipynb"')
# [nbviewer](https://nbviewer.org) is a service that renders notebooks to HTML,
# for sharing and reading notebooks on the Internet.
#
# [This notebook](https://nbviewer.jupyter.org/81c2a94563d102d93895) on nbviewer.
#
# You can also convert notebooks to HTML and other formats locally with `jupyter nbconvert`.
# # IPython: beyond plain Python
#
# Follow along: https://github.com/minrk/inf3331-ipython
# 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.
# ## First things first: running code, getting help
# 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.
# In[ ]:
print("Hi")
# In[ ]:
import time
for i in range(10):
print(i, end=' ')
time.sleep(1)
# In[ ]:
i
# Getting help:
# In[ ]:
get_ipython().show_usage()
# 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.
# In[ ]:
import collections
get_ipython().run_line_magic('pinfo', 'collections.namedtuple')
# In[ ]:
get_ipython().run_line_magic('pinfo2', 'collections.Counter')
# In[ ]:
c = collections.Counter('abcdeabcdabcaba')
# In[ ]:
get_ipython().run_line_magic('pinfo', 'c.most_common')
# In[ ]:
c.most_common(2)
# with '\*', you can do a wildcard search:
# In[ ]:
get_ipython().run_line_magic('psearch', '*int*')
# In[ ]:
import numpy as np
get_ipython().run_line_magic('psearch', 'np.*array*')
# An IPython quick reference card:
# In[ ]:
get_ipython().run_line_magic('quickref', '')
# ## Tab completion
# Tab completion, especially for attributes, is a convenient way to explore the structure of any object you’re dealing with. Simply type `object_name.` to view the object’s attributes. Besides Python objects and keywords, tab completion also works on file and directory names.
# In[ ]:
np.array2string
# ## The interactive workflow: input, output, history
# In[ ]:
2+10
# In[ ]:
_+10
# 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):
# In[ ]:
10+20;
# In[ ]:
_
# The output is stored in `_N` and `Out[N]` variables:
# In[ ]:
Out[21]
# In[ ]:
_15 == Out[15]
# `%history` lets you view and search your history
# In[ ]:
get_ipython().run_line_magic('history', '-n 1-5')
# **Exercise**
#
# Using this info, how could we write the last 10 lines of history to a file?
# In[ ]:
# ## Accessing the underlying operating system
# In[ ]:
import os
print(os.getcwd())
# In[ ]:
get_ipython().system('pwd')
# In[ ]:
get_ipython().system('ls -la')
# In[ ]:
ls
# In[ ]:
files = get_ipython().getoutput('ls')
print("My current directory's files:")
print(files)
# In[ ]:
for f in files:
print(f * 2)
# In[ ]:
get_ipython().system('echo $files')
# In[ ]:
get_ipython().system('echo {files[0].upper()}')
# Note that all this is available even in multiline blocks:
# In[ ]:
import os
for i,f in enumerate(files):
if f.endswith('ipynb'):
get_ipython().system('echo {"%02d" % i} - "{os.path.splitext(f)[0]}"')
else:
print('--')
# In[ ]:
get_ipython().run_line_magic('history', '-t 22')
# ## Beyond Python: magic functions
# 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 orthogonal namespace for controlling IPython itself and exposing other system-oriented functionality.
#
# - 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.
# Line vs cell magics:
# In[ ]:
get_ipython().run_line_magic('timeit', 'list(range(1000))')
# In[ ]:
get_ipython().run_cell_magic('timeit', '', 'list(range(10))\nlist(range(100))\n')
# Line magics can be used even inside code blocks:
# In[ ]:
for i in range(1, 5):
size = i*100
print('size:', size, end=' ')
get_ipython().run_line_magic('timeit', 'list(range(size))')
# In[ ]:
get_ipython().run_line_magic('timeit', 'time.sleep(0.1)')
# In[ ]:
get_ipython().run_line_magic('pinfo', '%timeit')
# Magics can do anything they want with their input, so it doesn't have to be valid Python:
# In[ ]:
get_ipython().run_cell_magic('bash', '', 'echo "My shell is:" $SHELL\necho "My disk usage is:"\ndf -h\n')
# In[ ]:
get_ipython().run_cell_magic('ruby', '', 'puts "hello"\n')
# Another interesting cell magic: create any file you want locally from the notebook:
# In[ ]:
get_ipython().run_cell_magic('writefile', 'test.txt', 'This is a test file!\nIt can contain anything I want...\n\nAnd more...\n')
# In[ ]:
get_ipython().system('cat test.txt')
# Let's see what other magics are currently defined in the system:
# In[ ]:
get_ipython().run_line_magic('lsmagic', '')
# In[ ]:
import math
math.pi
# In[ ]:
get_ipython().run_line_magic('precision', '2')
math.pi
# In[ ]:
get_ipython().run_line_magic('pinfo', '%precision')
# ## Running normal Python code: execution and errors
# Not only can you input normal Python code, you can even paste straight from a Python or IPython shell session:
# In[ ]:
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b
# In[ ]:
import sys
for i in range(32):
print(i, end=' ')
time.sleep(0.1)
# And when your code produces errors, you can control how they are displayed with the `%xmode` magic:
# In[ ]:
get_ipython().run_cell_magic('writefile', 'mod.py', '\ndef f(x):\n return 1.0/(x-1)\n\ndef g(y):\n return f(y+1)\n')
# Now let's call the function `g` with an argument that would produce an error:
# In[ ]:
import mod
mod.g(0)
# In[ ]:
get_ipython().run_line_magic('xmode', 'verbose')
# In[ ]:
mod.g(0)
# ## Raw Input in the notebook
# Since 1.0 the IPython notebook web application support `raw_input` which for example allow us to invoke the `%debug` magic in the notebook:
# In[ ]:
get_ipython().run_line_magic('debug', '')
# Don't foget to exit your debugging session. Raw input can of course be use to ask for user input:
# In[ ]:
colour = input('What is your favourite colour? ')
print('colour is:', colour)
# ## Running code in other languages with special `%%` magics
# In[ ]:
get_ipython().run_cell_magic('perl', '', '@months = ("July", "August", "September");\nprint $months[0];\n')
# In[ ]:
get_ipython().run_cell_magic('ruby', '', 'name = "world"\nputs "Hello #{name.capitalize}!"\n')
# ## Plotting in the notebook
# This magic configures matplotlib to render its figures inline:
# In[ ]:
get_ipython().run_line_magic('matplotlib', 'inline')
# In[ ]:
import numpy as np
import matplotlib.pyplot as plt
# In[ ]:
x = np.linspace(0, 2*np.pi, 300)
y = np.sin(x**2)
plt.plot(x, y)
plt.title("A little chirp")
fig = plt.gcf() # let's keep the figure object around for later...
# ### Widgets
# In[ ]:
from ipywidgets import interact
@interact
def show_args(num=5, text='hello', check=True):
print(locals())
# In[ ]:
import sympy
from sympy import Symbol, Eq, factor
x = Symbol('x')
sympy.init_printing(use_latex='mathjax')
x
# In[ ]:
@interact(n=(1,21))
def factorit(n):
return Eq(x**n-1, factor(x**n-1))
# In[ ]: