#!/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[ ]: