Python and Friends

This is a very quick run-through of some python syntax


In [1]:
# The %... is an iPython thing, and is not part of the Python language.
# In this case we're just telling the plotting library to draw things on
# the notebook, instead of on a separate window.
%matplotlib inline 
#this line above prepares IPython notebook for working with matplotlib

# See all the "as ..." contructs? They're just aliasing the package names.
# That way we can call methods like plt.plot() instead of matplotlib.pyplot.plot().

import numpy as np # imports a fast numerical programming library
import scipy as sp #imports stats functions, amongst other things
import matplotlib as mpl # this actually imports matplotlib
import matplotlib.cm as cm #allows us easy access to colormaps
import matplotlib.pyplot as plt #sets up plotting under plt
import pandas as pd #lets us handle data as dataframes
#sets up pandas table display
pd.set_option('display.width', 500)
pd.set_option('display.max_columns', 100)
pd.set_option('display.notebook_repr_html', True)
import seaborn as sns #sets up styles and gives us more plotting options

The Python Language

Lets talk about using Python as a calculator...


In [2]:
1+2


Out[2]:
3

Notice integer division and floating-point error below!


In [3]:
1/2,1.0/2.0,3*3.2


Out[3]:
(0, 0.5, 9.600000000000001)

Here is how we can print things. Something on the last line by itself is returned as the output value.


In [4]:
print 1+3.0,"\n",5/3.0
5/3


4.0 
1.66666666667
Out[4]:
1

We can obtain the type of a variable, and use boolean comparisons tontest these types.


In [5]:
a=5.0/6.0
print(a)
print type(a)


0.833333333333
<type 'float'>

In [6]:
import types
type(a)==types.FloatType


Out[6]:
True

In [7]:
type(a)==types.IntType


Out[7]:
False

Python and Iteration (and files)

In working with python I always remember: a python is a duck.

What I mean is, python has a certain way of doing things. For example lets call one of these ways listiness. Listiness works on lists, dictionaries, files, and a general notion of something called an iterator.

But first, lets introduce the notion of a comprehension. Its a way of constructing a list


In [8]:
alist=[1,2,3,4,5]
asquaredlist=[i*i for i in alist]
asquaredlist


Out[8]:
[1, 4, 9, 16, 25]

Python has some nifty functions like enumerate and zip. The former gives a list of tuples with each tuple of the form (index, value), while the latter takes elements from each list and outs them together into a tuple, thus creating a list of tuples. The first is a duck, but the second isnt.


In [9]:
enumerate(asquaredlist),zip(alist, asquaredlist)


Out[9]:
(<enumerate at 0x108fb0410>, [(1, 1), (2, 4), (3, 9), (4, 16), (5, 25)])

Someone realized that design flaw and created izip.


In [10]:
from itertools import izip
izip(alist, asquaredlist)


Out[10]:
<itertools.izip at 0x108fafb48>

In [11]:
print enumerate(asquaredlist)


<enumerate object at 0x108fb05f0>

In [12]:
[k for k in enumerate(asquaredlist)]


Out[12]:
[(0, 1), (1, 4), (2, 9), (3, 16), (4, 25)]

Open files behave like lists too! Here we get each line in the file and find its length, using the comprehension syntax to put these lengths into a big list.


In [13]:
linelengths=[len(line) for line in open("hamlet.txt")]#poor code as we dont close the file
print linelengths


[9, 27, 2, 24, 2, 2, 2, 2, 22, 2, 28, 60, 29, 28, 27, 22, 22, 24, 25, 18, 24, 11, 21, 20, 22, 32, 10, 28, 31, 12, 22, 27, 2, 51, 32, 2, 67, 13, 2, 18, 2, 2, 2, 8, 2, 50, 2, 49, 2, 6, 14, 2, 7, 45, 2, 6, 21, 2, 7, 11, 2, 6, 5, 2, 7, 41, 2, 6, 53, 2, 7, 48, 25, 2, 6, 27, 2, 7, 23, 2, 6, 19, 39, 46, 2, 7, 48, 2, 32, 2, 6, 25, 2, 6, 27, 2, 7, 22, 2, 6, 30, 24, 2, 7, 24, 22, 2, 9, 2, 6, 18, 2, 6, 6, 25, 2, 6, 17, 2, 6, 45, 2, 6, 47, 2, 6, 22, 2, 6, 36, 42, 48, 38, 45, 37, 42, 2, 6, 32, 2, 6, 18, 41, 42, 31, 2, 6, 20, 41, 2, 6, 20, 51, 51, 43, 30, 2, 6, 51, 2, 23, 2, 6, 48, 2, 6, 43, 2, 6, 47, 2, 6, 49, 2, 6, 23, 2, 6, 23, 2, 6, 50, 42, 40, 54, 2, 6, 17, 2, 6, 22, 2, 6, 42, 2, 15, 2, 6, 33, 2, 6, 46, 42, 22, 2, 6, 41, 38, 19, 2, 6, 26, 2, 6, 25, 36, 40, 45, 42, 15, 2, 6, 48, 47, 2, 6, 48, 44, 48, 2, 6, 49, 47, 43, 43, 41, 50, 43, 46, 50, 30, 2, 6, 13, 47, 42, 44, 45, 53, 53, 53, 36, 50, 45, 39, 43, 35, 50, 39, 49, 36, 47, 41, 39, 48, 42, 39, 46, 45, 41, 50, 44, 2, 6, 37, 47, 49, 45, 2, 6, 41, 43, 41, 51, 45, 50, 43, 47, 43, 48, 42, 39, 45, 38, 46, 2, 19, 2, 53, 42, 14, 40, 44, 14, 42, 40, 11, 39, 41, 53, 19, 53, 2, 6, 40, 2, 6, 27, 2, 6, 12, 2, 6, 12, 2, 6, 12, 2, 15, 2, 38, 35, 38, 39, 2, 6, 44, 2, 6, 42, 38, 44, 48, 43, 42, 40, 41, 37, 2, 6, 38, 46, 44, 45, 49, 51, 48, 42, 2, 6, 45, 45, 47, 42, 42, 39, 45, 47, 44, 2, 6, 45, 44, 2, 11, 2, 2, 2, 52, 2, 63, 35, 2, 7, 47, 46, 52, 38, 47, 42, 41, 47, 47, 43, 42, 52, 45, 42, 45, 46, 47, 39, 46, 44, 46, 47, 40, 44, 49, 47, 47, 41, 43, 44, 46, 46, 43, 42, 45, 41, 48, 34, 49, 2, 16, 47, 2, 7, 41, 2, 35, 2, 45, 47, 41, 54, 45, 43, 42, 46, 34, 2, 7, 16, 44, 49, 37, 42, 50, 49, 2, 7, 51, 2, 6, 47, 37, 41, 41, 2, 7, 45, 45, 41, 2, 6, 54, 2, 7, 46, 2, 6, 44, 2, 8, 43, 50, 38, 40, 53, 37, 2, 6, 26, 2, 8, 11, 39, 2, 6, 45, 44, 38, 41, 40, 41, 49, 48, 45, 44, 47, 2, 7, 52, 47, 48, 53, 37, 43, 38, 46, 43, 40, 41, 44, 40, 43, 48, 46, 43, 48, 48, 48, 40, 45, 43, 35, 46, 41, 40, 38, 39, 43, 45, 2, 8, 46, 49, 2, 6, 41, 2, 7, 38, 41, 43, 45, 45, 48, 52, 41, 2, 26, 2, 6, 45, 38, 39, 49, 42, 40, 43, 53, 49, 50, 41, 46, 46, 47, 45, 38, 47, 55, 45, 47, 46, 48, 54, 49, 37, 44, 43, 46, 43, 40, 49, 2, 43, 2, 6, 24, 2, 6, 28, 34, 2, 6, 48, 2, 6, 54, 47, 12, 2, 6, 17, 2, 6, 47, 47, 2, 6, 37, 2, 6, 37, 40, 39, 45, 38, 47, 2, 6, 47, 2, 6, 43, 44, 2, 6, 41, 2, 6, 50, 47, 42, 41, 39, 2, 6, 17, 2, 6, 28, 2, 6, 39, 2, 6, 40, 39, 2, 6, 41, 2, 6, 10, 2, 6, 32, 2, 6, 21, 2, 6, 35, 41, 38, 21, 2, 6, 29, 2, 6, 42, 40, 43, 51, 35, 43, 49, 45, 55, 39, 46, 38, 49, 45, 50, 43, 32, 2, 6, 21, 2, 6, 46, 2, 6, 26, 2, 6, 17, 45, 39, 43, 43, 43, 30, 2, 6, 20, 2, 6, 44, 43, 24, 2, 6, 45, 30, 2, 15, 17, 2, 6, 17, 2, 7, 17, 2, 6, 18, 2, 7, 29, 2, 6, 28, 2, 6, 41, 2, 6, 29, 2, 6, 45, 2, 6, 14, 2, 6, 17, 2, 6, 30, 2, 6, 18, 2, 6, 27, 2, 6, 32, 2, 6, 39, 2, 6, 53, 2, 15, 17, 2, 6, 19, 2, 6, 30, 2, 6, 40, 19, 2, 6, 24, 30, 2, 6, 20, 2, 6, 40, 50, 43, 44, 42, 41, 42, 46, 46, 17, 2, 6, 26, 2, 6, 39, 2, 44, 2, 46, 52, 53, 53, 2, 9, 2, 2, 2, 40, 2, 30, 2, 7, 40, 40, 40, 27, 2, 6, 20, 2, 7, 45, 40, 40, 45, 41, 10, 2, 6, 17, 2, 7, 19, 43, 46, 41, 46, 42, 44, 49, 41, 37, 46, 44, 48, 42, 55, 42, 39, 47, 45, 46, 45, 50, 32, 44, 45, 39, 38, 39, 46, 44, 44, 41, 42, 41, 48, 2, 6, 45, 48, 40, 45, 47, 47, 29, 2, 7, 17, 45, 2, 19, 2, 38, 38, 2, 6, 47, 45, 56, 2, 38, 2, 38, 51, 41, 43, 52, 49, 45, 48, 42, 45, 46, 52, 40, 46, 40, 49, 45, 37, 44, 44, 45, 43, 42, 44, 2, 7, 42, 2, 6, 47, 2, 7, 38, 26, 2, 6, 27, 44, 2, 7, 11, 2, 9, 2, 6, 42, 2, 6, 52, 2, 6, 24, 39, 45, 53, 37, 46, 43, 45, 44, 2, 6, 45, 25, 2, 6, 47, 41, 47, 2, 6, 46, 2, 6, 47, 49, 54, 48, 45, 2, 6, 42, 24, 2, 6, 44, 2, 6, 52, 42, 2, 6, 45, 45, 48, 48, 45, 44, 47, 40, 44, 43, 38, 41, 50, 47, 39, 44, 43, 51, 40, 48, 42, 2, 6, 24, 2, 11, 2, 2, 2, 25, 2, 41, 2, 6, 42, 2, 6, 35, 2, 6, 16, 2, 6, 29, 2, 6, 19, 2, 6, 52, 43, 2, 57, 2, 31, 2, 6, 50, 52, 49, 43, 28, 2, 6, 17, 2, 6, 18, 43, 41, 50, 39, 47, 50, 42, 52, 39, 37, 48, 50, 42, 39, 50, 46, 50, 43, 45, 48, 35, 46, 46, 42, 21, 2, 6, 26, 2, 16, 2, 6, 44, 46, 55, 38, 42, 51, 41, 41, 44, 48, 39, 41, 44, 49, 43, 46, 38, 48, 49, 2, 25, 2, 6, 36, 37, 15, 2, 6, 33, 40, 24, 2, 6, 18, 2, 6, 43, 2, 6, 18, 2, 6, 31, 38, 42, 35, 43, 2, 6, 49, 40, 42, 43, 49, 41, 42, 39, 38, 28, 2, 6, 22, 26, 2, 6, 28, 2, 6, 22, 2, 6, 29, 2, 6, 20, 42, 40, 2, 18, 2, 45, 2, 28, 2, 53, 40, 2, 28, 2, 6, 38, 2, 6, 46, 2, 6, 44, 2, 6, 46, 2, 6, 24, 2, 6, 24, 2, 11, 2, 2, 2, 44, 2, 27, 2, 6, 55, 2, 8, 10, 2, 6, 9, 2, 8, 25, 44, 24, 2, 6, 19, 2, 8, 43, 25, 2, 6, 28, 2, 8, 47, 2, 6, 7, 2, 8, 27, 46, 44, 48, 49, 41, 43, 51, 58, 41, 42, 41, 37, 53, 43, 2, 6, 8, 2, 8, 45, 2, 6, 9, 2, 8, 41, 45, 2, 6, 49, 40, 26, 2, 8, 18, 47, 42, 51, 46, 49, 36, 44, 46, 22, 2, 6, 22, 13, 2, 8, 45, 54, 45, 41, 45, 41, 41, 45, 43, 45, 19, 40, 48, 44, 37, 22, 45, 47, 36, 38, 41, 40, 39, 40, 48, 43, 41, 43, 47, 41, 48, 21, 44, 50, 41, 37, 43, 39, 42, 43, 37, 39, 40, 47, 48, 46, 49, 42, 41, 36, 2, 9, 2, 6, 47, 51, 43, 41, 48, 42, 34, 42, 51, 42, 42, 41, 46, 26, 46, 39, 50, 47, 2, 12, 2, 43, 36, 17, 2, 6, 31, 2, 6, 26, 2, 6, 30, 2, 6, 11, 2, 6, 34, 2, 6, 39, 2, 32, 2, 6, 26, 2, 6, 21, 2, 6, 15, 2, 6, 24, 2, 6, 23, 2, 6, 28, 2, 6, 17, 2, 6, 55, 23, 2, 15, 25, 2, 6, 49, 27, 2, 6, 52, 18, 2, 6, 35, 43, 45, 54, 41, 43, 25, 2, 6, 49, 2, 6, 38, 23, 2, 6, 30, 2, 6, 47, 52, 46, 45, 49, 45, 27, 2, 6, 30, 2, 6, 47, 2, 15, 23, 2, 6, 19, 2, 6, 11, 17, 2, 6, 27, 2, 6, 16, 2, 6, 34, 2, 6, 32, 2, 8, 19, 2, 6, 58, 52, 19, 2, 6, 28, 2, 6, 44, 20, 2, 8, 19, 2, 6, 47, 25, 41, 45, 20, 2, 8, 19, 2, 6, 55, 51, 2, 6, 48, 2, 6, 46, 53, 40, 13, 44, 44, 45, 35, 49, 48, 44, 60, 62, 39, 48, 48, 8, 2, 8, 19, 2, 6, 47, 42, 37, 51, 53, 46, 44, 41, 31, 2, 11, 2, 2, 2, 9, 2, 38, 2, 32, 2, 6, 48, 2, 6, 18, 2, 6, 48, 39, 19, 2, 6, 27, 2, 6, 50, 46, 52, 45, 46, 48, 45, 53, 46, 47, 2, 6, 25, 2, 6, 50, 40, 43, 48, 42, 46, 40, 23, 2, 6, 21, 2, 6, 50, 31, 2, 6, 36, 2, 6, 48, 42, 34, 59, 43, 41, 36, 21, 2, 6, 22, 2, 6, 31, 2, 6, 14, 20, 2, 6, 30, 41, 43, 51, 11, 46, 44, 45, 41, 50, 41, 21, 2, 6, 21, 2, 6, 67, 64, 2, 6, 56, 13, 2, 6, 44, 50, 38, 56, 49, 45, 43, 39, 14, 50, 40, 42, 38, 38, 46, 2, 6, 18, 2, 6, 32, 2, 6, 15, 2, 6, 38, 2, 6, 19, 2, 6, 28, 2, 6, 16, 2, 6, 11, 2, 18, 2, 18, 2, 38, 2, 6, 43, 2, 6, 32, 2, 6, 41, 46, 45, 42, 51, 39, 38, 43, 2, 6, 19, 2, 6, 25, 25, 2, 6, 15, 2, 6, 44, 44, 45, 37, 41, 41, 48, 42, 40, 46, 45, 45, 46, 43, 2, 6, 44, 35, 40, 47, 36, 46, 50, 2, 6, 44, 36, 19, 2, 6, 25, 47, 51, 51, 34, 42, 38, 46, 57, 45, 2, 11, 2, 2, 2, 33, 2, 58, 2, 7, 45, 44, 41, 45, 43, 43, 43, 54, 44, 39, 51, 51, 48, 40, 45, 41, 50, 39, 2, 8, 45, 44, 48, 41, 40, 40, 43, 31, 2, 6, 21, 47, 44, 19, 2, 7, 15, 47, 41, 18, 2, 7, 46, 2, 8, 46, 38, 44, 44, 2, 7, 45, 30, 2, 8, 11, 2, 58, 2, 19, 2, 6, 44, 24, 2, 7, 47, 2, 6, 45, 36, 41, 45, 39, 43, 36, 2, 7, 43, 2, 6, 43, 49, 2, 7, 46, 2, 18, 2, 44, 50, 2, 8, 40, 48, 2, 7, 26, 2, 49, 2, 27, 47, 2, 7, 44, 41, 44, 41, 41, 50, 42, 47, 43, 44, 39, 49, 40, 48, 46, 42, 41, 18, 45, 45, 41, 26, 2, 7, 19, 45, 39, 50, 49, 20, 2, 35, 2, 6, 32, 38, 39, 51, 49, 46, 51, 42, 44, 43, 18, 2, 8, 29, 2, 6, 37, 49, 44, 41, 44, 44, 42, 43, 42, 10, 48, 39, 46, 10, 60, 13, 61, 35, 10, 44, 2, 8, 31, 2, 6, 46, 10, 35, 36, 30, 30, 63, 67, 12, 67, 15, 49, 39, 48, 24, 2, 7, 18, 20, 2, 6, 26, 2, 7, 38, 2, 6, 50, 46, 42, 47, 44, 41, 45, 45, 49, 43, 46, 50, 47, 41, 47, 44, 40, 44, 49, 40, 22, 2, 7, 25, 2, 8, 25, 2, 6, 52, 40, 27, 2, 7, 18, 2, 6, 44, 36, 39, 47, 20, 2, 7, 28, 2, 6, 48, 20, 2, 8, 20, 2, 6, 47, 36, 41, 43, 37, 30, 2, 7, 17, 2, 8, 53, 2, 6, 35, 46, 2, 39, 2, 26, 2, 31, 2, 6, 20, 2, 6, 26, 2, 6, 38, 2, 6, 17, 2, 6, 40, 2, 6, 18, 2, 6, 61, 29, 2, 6, 28, 2, 6, 65, 32, 2, 6, 18, 2, 6, 64, 52, 2, 6, 67, 64, 65, 65, 16, 2, 6, 22, 2, 6, 30, 2, 6, 14, 2, 6, 44, 2, 6, 63, 61, 61, 65, 67, 62, 64, 2, 6, 64, 40, 2, 6, 16, 2, 6, 65, 64, 64, 67, 67, 18, 2, 6, 57, 67, 7, 2, 6, 25, 2, 6, 26, 2, 39, 2, 6, 46, 2, 6, 35, 2, 18, 2, 7, 19, 2, 6, 20, 2, 6, 61, 41, 2, 6, 43, 2, 7, 38, 46, 2, 6, 28, 2, 6, 19, 2, 6, 56, 10, 2, 7, 25, 2, 6, 56, 28, 2, 6, 51, 2, 6, 58, 62, 64, 9, 2, 7, 18, 2, 6, 21, 2, 6, 24, 2, 6, 60, 43, 2, 6, 27, 2, 6, 62, 56, 2, 6, 65, 7, 2, 6, 61, 61, 2, 7, 63, 48, 2, 6, 33, 2, 6, 64, 30, 2, 6, 64, 64, 23, 2, 17, 22, 2, 6, 57, 62, 65, 23, 2, 6, 43, 2, 6, 62, 66, 58, 64, 2, 7, 30, 2, 6, 59, 67, 65, 20, 2, 6, 23, 2, 6, 63, 59, 64, 66, 38, 2, 6, 34, 2, 6, 65, 10, 2, 7, 28, 2, 6, 60, 60, 66, 64, 64, 67, 66, 64, 65, 60, 62, 64, 67, 66, 53, 2, 6, 50, 2, 6, 60, 2, 6, 59, 65, 62, 2, 6, 61, 67, 65, 63, 63, 63, 7, 2, 6, 56, 25, 2, 6, 54, 46, 2, 6, 57, 13, 2, 6, 61, 29, 2, 6, 27, 2, 6, 35, 2, 6, 62, 66, 65, 67, 65, 27, 2, 6, 58, 63, 57, 67, 66, 31, 2, 6, 64, 62, 66, 32, 2, 6, 16, 2, 7, 50, 2, 6, 28, 2, 6, 55, 2, 6, 62, 65, 67, 67, 31, 2, 32, 2, 7, 24, 2, 6, 63, 64, 63, 60, 64, 31, 2, 7, 24, 2, 6, 61, 29, 2, 19, 2, 6, 30, 2, 6, 67, 66, 2, 6, 64, 23, 2, 6, 67, 53, 2, 6, 35, 2, 6, 64, 9, 2, 6, 38, 2, 6, 13, 2, 6, 19, 2, 6, 36, 2, 6, 59, 59, 66, 64, 67, 15, 2, 6, 58, 2, 6, 32, 2, 6, 7, 37, 38, 2, 2, 6, 32, 2, 6, 38, 2, 6, 60, 20, 2, 6, 24, 2, 6, 30, 2, 6, 7, 26, 21, 45, 65, 28, 2, 31, 2, 64, 62, 60, 61, 63, 62, 67, 60, 64, 51, 2, 9, 23, 2, 6, 63, 65, 66, 67, 67, 64, 64, 61, 62, 67, 67, 64, 61, 2, 49, 2, 43, 2, 46, 49, 48, 53, 44, 44, 53, 50, 45, 54, 44, 51, 32, 2, 18, 2, 6, 60, 13, 2, 9, 23, 53, 48, 43, 51, 50, 53, 48, 49, 52, 42, 51, 44, 48, 17, 45, 52, 49, 48, 52, 44, 44, 47, 51, 26, 52, 43, 53, 53, 29, 2, 6, 19, 2, 6, 64, 65, 12, 2, 9, 49, 2, 6, 21, 2, 6, 38, 2, 9, 53, 46, 49, 45, 49, 53, 59, 49, 46, 51, 50, 49, 54, 29, 2, 6, 64, 27, 2, 6, 62, 62, 67, 65, 51, 2, 6, 53, 2, 6, 53, 64, 65, 28, 2, 6, 13, 2, 6, 51, 2, 55, 2, 60, 11, 2, 9, 14, 2, 6, 60, 66, 29, 2, 9, 14, 2, 6, 58, 2, 22, 2, 61, 37, 2, 6, 15, 2, 40, 2, 6, 24, 17, 41, 44, 42, 44, 45, 45, 48, 49, 13, 40, 48, 43, 50, 48, 42, 43, 38, 8, 40, 45, 41, 40, 42, 46, 46, 55, 48, 46, 40, 40, 43, 49, 56, 15, 44, 44, 44, 48, 38, 13, 49, 43, 39, 43, 42, 50, 53, 45, 44, 47, 47, 44, 46, 41, 43, 41, 48, 48, 2, 9, 2, 2, 2, 2, 10, 2, 32, 2, 57, 16, 2, 7, 43, 45, 42, 38, 2, 6, 46, 48, 2, 7, 43, 41, 47, 20, 2, 8, 26, 2, 6, 24, 2, 7, 43, 2, 6, 43, 25, 2, 8, 19, 17, 2, 6, 44, 50, 41, 42, 42, 32, 2, 6, 17, 47, 29, 2, 7, 48, 28, 42, 45, 2, 6, 20, 2, 40, 2, 7, 31, 45, 42, 18, 43, 48, 42, 38, 42, 27, 2, 8, 21, 39, 44, 52, 41, 23, 2, 6, 23, 2, 15, 2, 6, 51, 61, 42, 50, 52, 35, 20, 2, 7, 28, 55, 51, 45, 42, 17, 2, 6, 45, 2, 29, 2, 17, 2, 6, 47, 43, 45, 44, 49, 39, 48, 45, 45, 53, 50, 45, 41, 38, 50, 51, 46, 41, 43, 40, 51, 40, 48, 44, 42, 45, 41, 46, 39, 49, 43, 45, 45, 42, 28, 2, 6, 15, 43, 2, 6, 39, 2, 6, 39, 40, 31, 2, 6, 12, 25, 2, 6, 48, 49, 51, 41, 47, 17, 2, 6, 25, 2, 6, 10, 2, 6, 15, 2, 6, 27, 2, 6, 62, 27, 2, 6, 64, 2, 6, 58, 65, 66, 55, 2, 6, 42, 2, 6, 55, 64, 6, 2, 6, 26, 2, 6, 57, 65, 67, 66, 63, 67, 66, 60, 9, 2, 6, 19, 2, 6, 59, 39, 2, 6, 33, 2, 6, 65, 66, 64, 63, 63, 11, 2, 6, 33, 2, 6, 59, 67, 66, 67, 63, 66, 29, 2, 9, 2, 6, 42, 59, 44, 45, 52, 43, 42, 47, 50, 48, 37, 48, 2, 31, 2, 7, 44, 52, 53, 42, 43, 44, 31, 51, 42, 42, 36, 45, 48, 47, 2, 6, 40, 42, 48, 45, 46, 41, 44, 47, 47, 47, 43, 31, 2, 7, 17, 46, 2, 11, 2, 2, 2, 33, 2, 37, 2, 6, 58, 64, 65, 60, 62, 52, 65, 67, 67, 65, 67, 52, 2, 11, 24, 2, 6, 62, 66, 63, 66, 63, 64, 64, 66, 60, 62, 65, 65, 59, 64, 60, 64, 25, 2, 11, 58, 2, 6, 62, 63, 63, 64, 65, 64, 17, 2, 19, 2, 50, 2, 58, 2, 6, 40, 2, 6, 29, 2, 18, 2, 35, 2, 16, 19, 2, 25, 2, 6, 20, 2, 18, 2, 6, 36, 2, 6, 38, 39, 2, 6, 20, 2, 6, 30, 44, 45, 60, 46, 43, 50, 48, 44, 50, 49, 42, 52, 49, 47, 49, 50, 47, 46, 43, 46, 47, 47, 40, 43, 39, 41, 33, 44, 41, 45, 28, 2, 6, 16, 52, 44, 2, 6, 46, 18, 2, 66, 41, 2, 7, 30, 2, 6, 62, 45, 2, 7, 62, 7, 2, 6, 67, 21, 2, 6, 54, 2, 6, 21, 2, 6, 64, 12, 2, 6, 65, 20, 2, 6, 44, 2, 8, 41, 2, 6, 48, 2, 6, 41, 2, 6, 32, 33, 2, 6, 14, 2, 6, 32, 2, 6, 14, 2, 6, 39, 2, 6, 27, 2, 6, 51, 2, 6, 19, 2, 6, 10, 2, 6, 25, 2, 6, 9, 2, 6, 14, 2, 6, 60, 65, 22, 2, 6, 38, 2, 6, 62, 66, 66, 67, 62, 57, 2, 41, 2, 62, 60, 59, 57, 63, 66, 66, 61, 64, 67, 43, 2, 11, 2, 6, 27, 2, 6, 53, 2, 6, 52, 2, 19, 2, 6, 64, 19, 2, 6, 39, 2, 6, 61, 50, 2, 6, 53, 2, 6, 33, 36, 35, 2, 6, 44, 2, 6, 22, 2, 6, 18, 2, 29, 2, 10, 49, 47, 44, 50, 49, 39, 2, 11, 39, 44, 42, 47, 46, 43, 43, 36, 49, 41, 52, 56, 2, 10, 50, 48, 48, 42, 27, 2, 11, 23, 47, 38, 47, 2, 6, 30, 2, 11, 41, 48, 38, 39, 2, 10, 44, 40, 37, 38, 51, 40, 36, 45, 42, 44, 37, 46, 48, 47, 49, 54, 43, 50, 51, 45, 41, 46, 43, 33, 38, 40, 40, 52, 43, 51, 2, 11, 46, 46, 40, 42, 43, 46, 47, 35, 2, 6, 43, 2, 10, 49, 48, 29, 11, 2, 11, 23, 44, 2, 9, 2, 6, 32, 2, 8, 39, 2, 6, 30, 2, 7, 56, 2, 6, 61, 8, 2, 7, 28, 2, 6, 58, 63, 65, 61, 66, 14, 2, 19, 2, 43, 2, 6, 33, 2, 6, 61, 23, 2, 6, 38, 2, 6, 51, 2, 6, 26, 2, 6, 62, 64, 22, 2, 6, 58, 46, 49, 52, 37, 38, 2, 45, 2, 6, 64, 62, 66, 2, 6, 17, 2, 6, 33, 2, 8, 20, 2, 6, 21, 2, 7, 28, 2, 6, 25, 2, 38, 2, 6, 40, 30, 48, 32, 66, 62, 60, 2, 6, 15, 2, 6, 22, 38, 32, 41, 28, 2, 6, 24, 2, 6, 59, 24, 2, 6, 21, 2, 6, 35, 2, 6, 27, 2, 6, 51, 41, 45, 19, 2, 39, 2, 7, 45, 2, 6, 23, 2, 7, 17, 2, 6, 23, 2, 7, 48, 2, 6, 18, 2, 7, 34, 2, 6, 63, 62, 34, 2, 7, 61, 31, 2, 6, 29, 2, 7, 61, 22, 2, 6, 18, 2, 7, 61, 65, 62, 34, 2, 6, 16, 2, 7, 16, 2, 6, 64, 65, 65, 8, 2, 6, 57, 27, 2, 6, 65, 50, 2, 6, 64, 2, 6, 60, 24, 2, 6, 32, 2, 6, 51, 2, 6, 64, 63, 14, 2, 6, 26, 2, 6, 62, 33, 2, 6, 64, 8, 2, 41, 2, 67, 66, 14, 2, 7, 63, 2, 6, 62, 2, 7, 20, 2, 6, 13, 2, 7, 23, 2, 6, 19, 2, 7, 34, 2, 6, 56, 63, 63, 2, 7, 59, 21, 2, 6, 61, 64, 63, 64, 63, 65, 65, 26, 2, 19, 2, 21, 2, 6, 57, 2, 6, 60, 2, 6, 44, 2, 6, 31, 2, 6, 29, 2, 6, 18, 2, 6, 20, 2, 6, 63, 41, 2, 6, 16, 2, 9, 2, 6, 27, 2, 18, 2, 22, 2, 41, 2, 43, 53, 55, 40, 51, 44, 41, 33, 44, 45, 39, 45, 2, 9, 2, 2, 2, 34, 2, 46, 2, 7, 44, 50, 44, 41, 40, 39, 22, 2, 7, 28, 36, 37, 39, 2, 6, 40, 47, 45, 45, 41, 43, 46, 43, 49, 50, 42, 42, 46, 2, 7, 45, 41, 33, 2, 15, 19, 2, 25, 2, 19, 2, 6, 45, 37, 56, 43, 50, 50, 50, 39, 27, 2, 7, 23, 2, 18, 2, 45, 43, 38, 41, 45, 43, 45, 44, 50, 47, 48, 40, 48, 40, 44, 47, 49, 44, 48, 44, 45, 41, 45, 43, 42, 47, 49, 47, 45, 43, 41, 43, 44, 45, 57, 41, 18, 2, 23, 2, 17, 2, 6, 43, 47, 47, 42, 44, 12, 42, 43, 51, 50, 48, 48, 41, 46, 5, 46, 42, 43, 40, 41, 51, 46, 44, 43, 2, 9, 2, 32, 2, 7, 44, 44, 2, 9, 2, 2, 2, 39, 2, 29, 2, 6, 50, 55, 53, 47, 30, 2, 6, 35, 2, 8, 19, 44, 2, 35, 2, 17, 2, 6, 33, 2, 8, 45, 2, 6, 43, 2, 8, 45, 2, 6, 44, 2, 8, 23, 2, 6, 24, 2, 8, 21, 2, 6, 26, 51, 49, 2, 8, 50, 2, 6, 52, 38, 43, 2, 8, 47, 17, 2, 6, 39, 2, 6, 26, 25, 2, 35, 2, 6, 26, 2, 19, 2, 8, 28, 2, 6, 34, 2, 25, 2, 8, 41, 2, 6, 45, 44, 2, 8, 17, 2, 6, 28, 48, 16, 47, 47, 52, 46, 36, 40, 45, 2, 8, 51, 30, 2, 6, 13, 44, 44, 45, 47, 43, 40, 41, 47, 39, 44, 29, 2, 8, 18, 48, 2, 6, 45, 46, 43, 46, 44, 35, 39, 35, 43, 39, 52, 44, 48, 48, 45, 42, 48, 48, 54, 53, 42, 44, 41, 49, 46, 46, 48, 40, 20, 47, 43, 40, 45, 46, 43, 26, 2, 8, 26, 43, 46, 32, 2, 6, 18, 39, 48, 23, 2, 8, 25, 46, 24, 2, 6, 27, 46, 42, 40, 45, 27, 2, 8, 10, 2, 6, 33, 2, 16, 2, 44, 56, 2, 8, 17, 2, 6, 42, 46, 45, 9, 2, 8, 32, 44, 42, 46, 46, 23, 2, 6, 27, 2, 8, 26, 39, 48, 46, 45, 45, 42, 42, 46, 2, 6, 46, 52, 48, 43, 42, 51, 2, 8, 28, 2, 6, 27, 2, 8, 40, 2, 6, 27, 2, 8, 28, 2, 6, 47, 38, 50, 2, 15, 2, 8, 41, 32, 21, 2, 6, 10, 49, 49, 44, 46, 47, 46, 48, 47, 44, 45, 44, 45, 49, 41, 40, 45, 2, 8, 46, 2, 6, 38, 41, 45, 38, 46, 41, 42, 37, 41, 40, 45, 48, 45, 47, 41, 47, 25, 45, 43, 44, 41, 47, 35, 46, 27, 2, 8, 18, 2, 6, 43, 44, 49, 43, 51, 40, 39, 49, 48, 42, 46, 38, 38, 46, 41, 31, 2, 8, 46, 47, 28, 2, 6, 35, 2, 8, 8, 37, 2, 6, 53, 46, 47, 41, 40, 49, 45, 48, 46, 32, 46, 46, 49, 42, 46, 21, 2, 52, 2, 2, 2, 9, 2, 32, 2, 52, 2, 7, 54, 50, 20, 2, 8, 41, 2, 48, 2, 46, 2, 7, 34, 2, 8, 44, 43, 42, 45, 42, 26, 2, 7, 15, 44, 40, 39, 47, 41, 54, 46, 44, 40, 40, 45, 2, 8, 40, 43, 33, 47, 2, 7, 24, 45, 48, 40, 49, 2, 42, 2, 50, 40, 51, 49, 45, 2, 40, 2, 51, 43, 47, 42, 38, 51, 43, 40, 2, 11, 2, 39, 2, 17, 2, 6, 16, 2, 16, 32, 2, 6, 53, 2, 39, 2, 6, 50, 2, 6, 44, 2, 6, 49, 28, 2, 6, 20, 2, 6, 15, 2, 6, 64, 67, 12, 2, 6, 36, 2, 6, 61, 64, 64, 66, 65, 8, 2, 6, 32, 2, 6, 60, 2, 6, 63, 11, 2, 6, 63, 24, 2, 7, 19, 2, 6, 55, 2, 11, 2, 2, 2, 40, 2, 24, 2, 7, 47, 47, 44, 41, 49, 55, 53, 40, 44, 38, 16, 2, 22, 2, 30, 2, 6, 43, 25, 2, 7, 18, 2, 6, 51, 2, 7, 22, 2, 6, 37, 2, 34, 2, 7, 32, 2, 6, 12, 2, 7, 19, 2, 6, 53, 65, 65, 66, 64, 10, 2, 7, 13, 2, 6, 63, 41, 2, 7, 30, 2, 6, 62, 23, 2, 7, 20, 2, 6, 64, 66, 65, 28, 2, 7, 42, 2, 6, 29, 2, 22, 2, 7, 49, 41, 54, 50, 42, 45, 14, 2, 6, 14, 2, 7, 13, 2, 6, 7, 2, 7, 41, 2, 6, 59, 24, 2, 7, 28, 2, 6, 63, 51, 2, 9, 2, 7, 50, 45, 41, 54, 2, 40, 2, 51, 48, 43, 42, 47, 47, 38, 46, 43, 47, 44, 2, 9, 2, 2, 2, 31, 2, 42, 2, 6, 45, 43, 43, 44, 42, 39, 22, 2, 7, 23, 2, 6, 15, 2, 31, 2, 48, 2, 6, 35, 2, 7, 26, 2, 6, 32, 2, 7, 30, 2, 6, 25, 2, 7, 39, 2, 6, 42, 23, 2, 7, 39, 40, 41, 48, 41, 42, 2, 6, 44, 2, 7, 32, 2, 6, 47, 45, 50, 48, 45, 2, 7, 22, 2, 9, 2, 6, 32, 2, 6, 48, 2, 26, 2, 40, 42, 42, 45, 49, 39, 36, 42, 42, 43, 54, 45, 45, 54, 47, 45, 38, 44, 38, 36, 46, 44, 40, 40, 48, 46, 40, 46, 43, 40, 48, 43, 40, 46, 45, 2, 9, 2, 2, 2, 42, 2, 28, 2, 8, 28, 2, 7, 38, 32, 2, 8, 22, 2, 7, 47, 61, 53, 51, 38, 44, 51, 57, 53, 42, 53, 46, 2, 8, 18, 2, 17, 2, 43, 46, 39, 42, 2, 34, 2, 6, 44, 2, 8, 19, 2, 15, 37, 24, 33, 28, 2, 8, 43, 2, 6, 31, 10, 31, 27, 36, 28, 2, 8, 20, 2, 6, 17, 10, 43, 2, 15, 2, 8, 27, 2, 6, 10, 37, 37, 30, 2, 7, 26, 2, 6, 62, 67, 13, 2, 7, 26, 2, 6, 67, 25, 10, 39, 34, 33, 28, 2, 44, 35, 37, 27, 2, 7, 17, 2, 6, 53, 10, 33, 32, 43, 34, 2, 38, 30, 40, 40, 2, 7, 30, 2, 6, 59, 66, 63, 66, 33, 2, 9, 2, 7, 52, 2, 17, 2, 49, 52, 48, 45, 49, 45, 58, 56, 45, 45, 51, 44, 44, 47, 41, 48, 40, 42, 43, 43, 29, 2, 19, 2, 8, 28, 2, 7, 49, 2, 22, 2, 21, 2, 7, 25, 37, 46, 40, 51, 42, 37, 40, 46, 52, 40, 2, 8, 45, 44, 2, 19, 2, 7, 22, 2, 42, 2, 7, 51, 2, 8, 20, 2, 7, 28, 2, 8, 19, 2, 33, 2, 7, 49, 20, 2, 8, 23, 2, 7, 54, 47, 47, 20, 2, 7, 29, 43, 47, 42, 45, 45, 54, 13, 2, 7, 21, 2, 7, 7, 2, 8, 17, 2, 7, 26, 2, 7, 45, 51, 47, 45, 45, 44, 31, 2, 7, 21, 2, 7, 29, 46, 32, 2, 7, 15, 37, 56, 54, 19, 2, 7, 23, 2, 7, 26, 2, 7, 49, 44, 28, 2, 7, 20, 41, 45, 39, 43, 26, 2, 8, 27, 2, 7, 30, 2, 58, 11, 2, 51, 46, 49, 46, 42, 46, 43, 46, 43, 27, 2, 6, 10, 40, 35, 43, 2, 25, 2, 7, 50, 25, 2, 6, 59, 67, 20, 2, 7, 34, 2, 6, 55, 54, 2, 7, 58, 2, 6, 63, 58, 67, 67, 49, 10, 43, 2, 7, 47, 40, 2, 6, 10, 32, 32, 26, 27, 30, 2, 36, 29, 30, 29, 31, 2, 57, 2, 9, 2, 7, 25, 2, 7, 42, 37, 51, 50, 36, 49, 49, 37, 45, 44, 25, 2, 7, 17, 43, 49, 41, 50, 33, 2, 7, 15, 50, 24, 2, 11, 2, 2, 2, 39, 2, 32, 2, 6, 41, 2, 10, 51, 2, 6, 19, 2, 17, 2, 43, 47, 2, 18, 2, 11, 21, 2, 6, 25, 2, 9, 59, 67, 50, 2, 6, 52, 60, 63, 63, 66, 63, 67, 67, 66, 66, 66, 65, 65, 58, 44, 2, 51, 47, 36, 2, 11, 2, 2, 2, 40, 2, 27, 2, 7, 47, 47, 46, 44, 18, 2, 7, 31, 44, 39, 45, 29, 2, 7, 29, 49, 53, 46, 47, 43, 48, 43, 39, 48, 49, 52, 49, 43, 38, 33, 2, 7, 36, 41, 44, 42, 49, 2, 7, 53, 44, 49, 52, 43, 48, 2, 22, 2, 21, 2, 7, 32, 42, 2, 7, 32, 2, 7, 45, 50, 27, 2, 7, 31, 11, 2, 19, 2, 65, 63, 63, 64, 2, 52, 41, 2, 7, 20, 2, 7, 38, 44, 20, 2, 7, 45, 40, 46, 21, 2, 7, 25, 42, 26, 2, 7, 14, 41, 2, 7, 45, 46, 43, 36, 47, 42, 49, 23, 2, 7, 27, 38, 28, 2, 7, 17, 49, 45, 47, 43, 42, 27, 2, 7, 29, 2, 7, 36, 44, 45, 44, 52, 37, 51, 50, 45, 47, 43, 51, 42, 28, 2, 7, 17, 2, 7, 11, 2, 7, 23, 2, 7, 16, 2, 7, 42, 28, 2, 7, 28, 37, 39, 38, 46, 54, 47, 46, 37, 43, 44, 21, 2, 7, 28, 2, 7, 39, 43, 25, 2, 7, 19, 2, 7, 48, 40, 39, 42, 43, 45, 42, 37, 45, 55, 40, 49, 52, 56, 45, 44, 21, 2, 7, 34, 2, 7, 46, 51, 51, 47, 49, 38, 52, 44, 46, 47, 44, 46, 30, 2, 7, 14, 44, 38, 40, 44, 45, 47, 51, 52, 18, 2, 7, 30, 47, 47, 54, 51, 47, 49, 47, 9, 44, 48, 53, 47, 44, 29, 2, 16, 2, 23, 2, 8, 41, 55, 2, 7, 20, 2, 8, 41, 50, 44, 53, 45, 53, 48, 46, 42, 53, 45, 48, 39, 38, 45, 49, 47, 17, 2, 7, 28, 2, 8, 19, 2, 7, 44, 42, 43, 50, 41, 49, 31, 2, 9, 2, 7, 25, 40, 43, 25, 2, 11, 2, 2, 2, 8, 2, 24, 2, 38, 2, 10, 59, 26, 2, 10, 64, 57, 2, 10, 65, 2, 10, 21, 2, 10, 60, 66, 63, 39, 2, 10, 38, 2, 10, 59, 66, 66, 64, 56, 2, 10, 18, 2, 10, 39, 2, 10, 53, 67, 2, 10, 59, 67, 62, 67, 28, 2, 10, 21, 2, 10, 39, 2, 10, 19, 2, 10, 62, 65, 63, 29, 2, 10, 8, 2, 10, 60, 31, 2, 10, 64, 2, 10, 60, 63, 61, 67, 2, 10, 65, 2, 10, 31, 2, 10, 24, 2, 10, 7, 2, 10, 22, 2, 44, 2, 10, 60, 61, 62, 61, 9, 2, 22, 2, 19, 2, 40, 35, 49, 43, 2, 6, 62, 15, 2, 6, 52, 2, 6, 63, 8, 2, 10, 10, 38, 36, 39, 35, 2, 22, 2, 6, 61, 64, 63, 64, 15, 2, 6, 20, 2, 6, 61, 67, 57, 20, 2, 6, 14, 2, 6, 61, 65, 64, 62, 7, 2, 10, 10, 36, 33, 36, 32, 2, 28, 2, 6, 61, 66, 65, 65, 65, 64, 65, 65, 64, 65, 65, 66, 11, 2, 6, 26, 2, 6, 39, 2, 6, 37, 2, 6, 63, 54, 2, 10, 12, 10, 36, 32, 2, 6, 50, 2, 10, 67, 36, 2, 6, 62, 52, 2, 10, 59, 2, 6, 32, 2, 10, 18, 2, 6, 18, 2, 10, 19, 2, 6, 27, 2, 10, 60, 2, 6, 58, 62, 64, 66, 57, 2, 10, 60, 39, 2, 6, 25, 2, 10, 60, 64, 15, 2, 6, 42, 2, 10, 59, 47, 2, 6, 6, 2, 10, 66, 2, 6, 18, 2, 10, 27, 2, 6, 16, 2, 10, 35, 2, 6, 19, 2, 10, 61, 15, 2, 6, 50, 2, 10, 60, 66, 64, 16, 2, 6, 27, 2, 10, 61, 67, 67, 38, 2, 6, 15, 2, 10, 61, 2, 6, 18, 2, 10, 60, 61, 27, 2, 6, 7, 2, 10, 12, 2, 6, 64, 65, 67, 64, 65, 64, 65, 60, 61, 67, 20, 2, 6, 23, 2, 6, 64, 2, 6, 10, 2, 6, 20, 2, 26, 2, 6, 19, 2, 6, 55, 63, 23, 2, 6, 50, 2, 6, 62, 61, 66, 63, 50, 47, 45, 51, 52, 50, 2, 59, 66, 2, 52, 47, 47, 42, 27, 2, 26, 2, 7, 21, 2, 6, 18, 27, 2, 7, 21, 2, 11, 41, 48, 50, 47, 48, 54, 43, 46, 21, 2, 7, 29, 2, 11, 18, 43, 40, 27, 2, 7, 25, 40, 52, 40, 26, 2, 6, 25, 2, 8, 32, 23, 51, 53, 33, 2, 7, 15, 43, 44, 47, 48, 25, 45, 45, 42, 18, 2, 6, 14, 24, 48, 52, 41, 18, 25, 2, 7, 26, 23, 2, 6, 24, 46, 43, 39, 45, 2, 7, 21, 2, 8, 17, 2, 6, 14, 2, 6, 25, 2, 61, 2, 6, 44, 38, 2, 8, 23, 2, 6, 42, 45, 45, 2, 7, 24, 2, 8, 31, 2, 6, 36, 62, 41, 43, 42, 42, 49, 43, 45, 47, 28, 2, 8, 23, 44, 38, 46, 32, 2, 6, 16, 42, 40, 38, 46, 2, 9, 2, 7, 45, 2, 17, 14, 54, 45, 48, 42, 40, 42, 2, 11, 2, 2, 2, 33, 2, 29, 2, 6, 50, 39, 2, 6, 23, 2, 6, 47, 46, 49, 47, 43, 55, 42, 29, 2, 6, 23, 2, 6, 19, 43, 43, 47, 41, 40, 49, 38, 44, 48, 47, 43, 42, 31, 2, 6, 16, 2, 6, 49, 42, 2, 6, 16, 2, 6, 45, 42, 42, 42, 41, 45, 44, 44, 29, 2, 6, 19, 2, 6, 41, 40, 52, 48, 41, 44, 47, 43, 44, 28, 2, 6, 22, 2, 6, 40, 39, 42, 46, 57, 47, 49, 23, 2, 6, 42, 2, 6, 50, 47, 37, 44, 43, 22, 2, 6, 27, 2, 6, 50, 52, 46, 42, 53, 54, 39, 18, 2, 6, 46, 42, 2, 6, 40, 46, 36, 34, 36, 49, 48, 26, 2, 6, 24, 2, 16, 2, 6, 49, 2, 6, 52, 2, 6, 19, 2, 6, 65, 65, 67, 42, 2, 6, 56, 41, 2, 6, 58, 45, 2, 6, 39, 2, 6, 56, 2, 6, 42, 2, 6, 55, 2, 6, 63, 65, 58, 11, 2, 6, 28, 39, 2, 6, 61, 57, 61, 66, 66, 47, 2, 6, 61, 65, 64, 67, 67, 64, 45, 2, 6, 46, 2, 6, 64, 15, 2, 6, 6, 2, 6, 67, 14, 2, 6, 48, 2, 6, 13, 2, 6, 59, 2, 6, 14, 2, 6, 33, 2, 6, 63, 30, 2, 6, 55, 2, 6, 60, 58, 2, 6, 60, 43, 2, 6, 20, 2, 6, 20, 2, 6, 39, 2, 6, 58, 60, 67, 63, 63, 23, 2, 6, 30, 2, 6, 61, 2, 6, 38, 2, 6, 59, 67, 62, 67, 66, 2, 6, 58, 59, 63, 46, 2, 6, 21, 2, 6, 58, 2, 6, 62, 59, 64, 65, 25, 2, 6, 33, 2, 6, 60, 2, 6, 37, 2, 6, 15, 2, 15, 2, 63, 13, 2, 6, 52, 2, 6, 67, 67, 63, 60, 64, 43, 2, 17, 2, 7, 59, 66, 65, 24, 2, 6, 64, 67, 22, 2, 7, 45, 2, 6, 16, 2, 7, 59, 34, 2, 6, 24, 2, 14, 2, 6, 36, 2, 6, 61, 67, 63, 2, 6, 22, 2, 6, 60, 32, 2, 6, 64, 41, 2, 6, 61, 65, 66, 65, 29, 2, 64, 12, 2, 7, 49, 2, 46, 2, 6, 50, 39, 53, 42, 18, 47, 45, 45, 39, 47, 44, 45, 43, 37, 24, 41, 47, 42, 22, 2, 7, 27, 49, 42, 42, 44, 39, 45, 43, 24, 2, 6, 22, 47, 29, 2, 7, 19, 2, 6, 47, 53, 25, 2, 7, 19, 2, 6, 19, 2, 7, 50, 21, 2, 6, 21, 50, 2, 7, 41, 50, 2, 7, 40, 2, 6, 52, 2, 25, 2, 6, 19, 2, 7, 46, 41, 42, 46, 49, 41, 46, 49, 42, 39, 51, 50, 39, 2, 6, 15, 2, 7, 16, 2, 14, 2, 6, 6, 2, 7, 5, 2, 6, 11, 2, 6, 29, 2, 7, 15, 2, 7, 52, 25, 2, 47, 2, 19, 2, 6, 48, 35, 2, 14, 2, 7, 33, 2, 7, 20, 2, 8, 34, 46, 44, 2, 6, 13, 2, 7, 25, 2, 8, 40, 2, 7, 50, 2, 6, 41, 2, 8, 29, 2, 7, 28, 2, 7, 19, 2, 7, 53, 2, 6, 46, 42, 38, 2, 7, 22, 2, 14, 2, 6, 23, 2, 7, 18, 2, 50, 45, 2, 7, 31, 2, 6, 18, 2, 20, 2, 6, 30, 2, 6, 48, 2, 6, 20, 2, 7, 46, 45, 2, 6, 21, 2, 7, 31, 2, 8, 52, 39, 2, 9, 2, 6, 41, 25, 2, 18, 2, 7, 45, 44, 44, 44, 42, 43, 45, 48, 2, 6, 28, 27, 2, 19, 2, 18, 19, 2, 7, 43, 2, 6, 48, 44, 19, 2, 14, 2, 7, 22, 39, 45, 48, 18, 2, 9, 2, 6, 47, 47, 48, 45, 48, 50, 37, 44, 21, 2, 6, 19, 43, 30, 2, 6, 19, 52, 38, 53, 42, 35, 50, 21, 2, 36, 2, 29, 2, 6, 51, 37, 22, 2, 6, 20, 47, 46, 39, 39, 50, 45, 2, 9, 2, 6, 54, 46, 32, 2, 17, 2, 58, 2, 7, 22, 2, 6, 26, 47, 2, 7, 45, 45, 37, 26, 2, 15, 22, 45, 53, 42, 45, 34, 2, 6, 21, 42, 44, 47, 49, 48, 40, 45, 48, 39, 45, 47, 39, 48, 16, 2, 7, 26, 39, 43, 47, 48, 2, 6, 43, 51, 43, 54, 29, 2, 7, 19, 42, 40, 52, 42, 25, 43, 47, 29, 2, 17, 2, 65, 24]

In [14]:
sum(linelengths), np.mean(linelengths), np.median(linelengths), np.std(linelengths)


Out[14]:
(180718, 26.69394387001477, 26.0, 21.029872021427462)

But perhaps we want to access Hamlet word by word and not line by line


In [15]:
hamletfile=open("hamlet.txt")
hamlettext=hamletfile.read()
hamletfile.close()
hamlettokens=hamlettext.split()#split with no arguments splits on whitespace
len(hamlettokens)


Out[15]:
31659

One can use the with syntax which cretaes a context. The file closing is then done automatically for us.


In [15]:
with open("hamlet.txt") as hamletfile:
    hamlettext=hamletfile.read()
    hamlettokens=hamlettext.split()
    print len(hamlettokens)


31659

There are roughly 32,000 words in Hamlet.

The indexing of lists


In [44]:
print hamlettext[:1000]#first 1000 characters from Hamlet.


XXXX
HAMLET, PRINCE OF DENMARK

by William Shakespeare




PERSONS REPRESENTED.

Claudius, King of Denmark.
Hamlet, Son to the former, and Nephew to the present King.
Polonius, Lord Chamberlain.
Horatio, Friend to Hamlet.
Laertes, Son to Polonius.
Voltimand, Courtier.
Cornelius, Courtier.
Rosencrantz, Courtier.
Guildenstern, Courtier.
Osric, Courtier.
A Gentleman, Courtier.
A Priest.
Marcellus, Officer.
Bernardo, Officer.
Francisco, a Soldier
Reynaldo, Servant to Polonius.
Players.
Two Clowns, Grave-diggers.
Fortinbras, Prince of Norway.
A Captain.
English Ambassadors.
Ghost of Hamlet's Father.

Gertrude, Queen of Denmark, and Mother of Hamlet.
Ophelia, Daughter to Polonius.

Lords, Ladies, Officers, Soldiers, Sailors, Messengers, and other
Attendants.

SCENE. Elsinore.



ACT I.

Scene I. Elsinore. A platform before the Castle.

[Francisco at his post. Enter to him Bernardo.]

Ber.
Who's there?

Fran.
Nay, answer me: stand, and u

In [45]:
print hamlettext[-1000:]#and last 1000 characters from Hamlet.


nd, in this upshot, purposes mistook
Fall'n on the inventors' heads: all this can I
Truly deliver.

Fort.
Let us haste to hear it,
And call the noblest to the audience.
For me, with sorrow I embrace my fortune:
I have some rights of memory in this kingdom,
Which now, to claim my vantage doth invite me.

Hor.
Of that I shall have also cause to speak,
And from his mouth whose voice will draw on more:
But let this same be presently perform'd,
Even while men's minds are wild: lest more mischance
On plots and errors happen.

Fort.
Let four captains
Bear Hamlet like a soldier to the stage;
For he was likely, had he been put on,
To have prov'd most royally: and, for his passage,
The soldiers' music and the rites of war
Speak loudly for him.--
Take up the bodies.--Such a sight as this
Becomes the field, but here shows much amiss.
Go, bid the soldiers shoot.

[A dead march.]

[Exeunt, bearing off the dead bodies; after the which a peal of
ordnance is shot off.]

Lets split the word tokens. The first one below reads, give me the second, third, and fourth words (remember that python is 0 indexed). Try and figure what the others mean.


In [16]:
print hamlettokens[1:4], hamlettokens[:4], hamlettokens[0], hamlettokens[-1]


['HAMLET,', 'PRINCE', 'OF'] ['\xef\xbb\xbfXXXX', 'HAMLET,', 'PRINCE', 'OF'] XXXX off.]

In [17]:
hamlettokens[1:8:2]#get every 2nd world between the 2nd and the 9th: ie 2nd, 4th, 6th, and 8th


Out[17]:
['HAMLET,', 'OF', 'by', 'Shakespeare']

range and xrange get the list of integers upto N. But xrange behaves like an iterator. The reason for this is that there is no point generaing all os a million integers. We can just add 1 to the previous one and save memory. So we trade off storage for computation.


In [18]:
mylist=[]
for i in xrange(10):
    mylist.append(i)
mylist


Out[18]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Dictionaries

These are the bread and butter. You will use them a lot. They even duck like lists. But be careful how.


In [19]:
adict={'one':1, 'two': 2, 'three': 3}
print [i for i in adict], [(k,v) for k,v in adict.items()], adict.values()


['three', 'two', 'one'] [('three', 3), ('two', 2), ('one', 1)] [3, 2, 1]

The keys do not have to be strings. From python 2.7 you can use dictionary comprehensions as well


In [20]:
mydict ={k:v for (k,v) in zip(alist, asquaredlist)}
mydict


Out[20]:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

You can construct then nicely using the function dict.


In [46]:
dict(a=1, b=2)


Out[46]:
{'a': 1, 'b': 2}

and conversion to json


In [21]:
import json

In [22]:
s=json.dumps(mydict)
print s


{"1": 1, "2": 4, "3": 9, "4": 16, "5": 25}

In [23]:
json.loads(s)


Out[23]:
{u'1': 1, u'2': 4, u'3': 9, u'4': 16, u'5': 25}

Strings

Basically they behave like immutable lists


In [24]:
lastword=hamlettokens[-1]
print(lastword)


off.]

In [25]:
lastword[-2]="k"#cant change a part of a string


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-55dfef3ad2e5> in <module>()
----> 1 lastword[-2]="k"

TypeError: 'str' object does not support item assignment

In [26]:
lastword[-2]


Out[26]:
'.'

In [ ]:
You can join a list with a separator to make a string.

In [27]:
wierdstring=",".join(hamlettokens)
wierdstring[:1000]


Out[27]:
"\xef\xbb\xbfXXXX,HAMLET,,PRINCE,OF,DENMARK,by,William,Shakespeare,PERSONS,REPRESENTED.,Claudius,,King,of,Denmark.,Hamlet,,Son,to,the,former,,and,Nephew,to,the,present,King.,Polonius,,Lord,Chamberlain.,Horatio,,Friend,to,Hamlet.,Laertes,,Son,to,Polonius.,Voltimand,,Courtier.,Cornelius,,Courtier.,Rosencrantz,,Courtier.,Guildenstern,,Courtier.,Osric,,Courtier.,A,Gentleman,,Courtier.,A,Priest.,Marcellus,,Officer.,Bernardo,,Officer.,Francisco,,a,Soldier,Reynaldo,,Servant,to,Polonius.,Players.,Two,Clowns,,Grave-diggers.,Fortinbras,,Prince,of,Norway.,A,Captain.,English,Ambassadors.,Ghost,of,Hamlet's,Father.,Gertrude,,Queen,of,Denmark,,and,Mother,of,Hamlet.,Ophelia,,Daughter,to,Polonius.,Lords,,Ladies,,Officers,,Soldiers,,Sailors,,Messengers,,and,other,Attendants.,SCENE.,Elsinore.,ACT,I.,Scene,I.,Elsinore.,A,platform,before,the,Castle.,[Francisco,at,his,post.,Enter,to,him,Bernardo.],Ber.,Who's,there?,Fran.,Nay,,answer,me:,stand,,and,unfold,yourself.,Ber.,Long,live,the,king!,Fran.,Bernardo?,Ber.,He.,Fra"

Functions

Functions are even more the bread and butter. You'll see them as methods on objects, or standing alone by themselves.


In [28]:
def square(x):
    return(x*x)
def cube(x):
    return x*x*x
square(5),cube(5)


Out[28]:
(25, 125)

In [29]:
print square, type(cube)


<function square at 0x109a66500> <type 'function'>

In Python, functions are "first-class". This is just a fancy way of saying, you can pass functions to other functions


In [47]:
def sum_of_anything(x,y,f):
    print x,y,f
    return(f(x) + f(y))
sum_of_anything(3,4,square)


3 4 <function square at 0x109a66500>
Out[47]:
25

Python functions can have positional arguments and keyword arguments. Positional arguments are stored in a tuple, and keyword arguments in a dictionary. Note the "starred" syntax


In [50]:
def f(a,b,*posargs,**dictargs):
    print "got",a,b,posargs, dictargs
    return a
print f(1,3)
print f(1,3,4,d=1,c=2)


got 1 3 () {}
1
got 1 3 (4,) {'c': 2, 'd': 1}
1

YOUR TURN create a dictionary with keys the integers upto and including 10, and values the cubes of these dictionaries


In [ ]:
#your code here

Booleans and Control-flow

Lets test for belonging...


In [32]:
a=[1,2,3,4,5]
1 in a


Out[32]:
True

In [33]:
6 in a


Out[33]:
False

Python supports if/elif/else clauses for multi-way conditionals


In [34]:
def do_it(x):
    if x==1:
        print "One"
    elif x==2:
        print "Two"
    else:
        print x
do_it(1)


One

In [35]:
do_it(2), do_it(3)


Two
3
Out[35]:
(None, None)

You can break out of a loop based on a condition. The loop below is a for loop.


In [36]:
for i in range(10):
    print i
    if (i > 5):
        break


0
1
2
3
4
5
6

While loops are also supported. continue continues to the next iteration of the loop skipping all the code below, while break breaks out of it.


In [37]:
i=0
while i < 10:
    print i
    i=i+1
    if i < 5:
        continue
    else:
        break


0
1
2
3
4

Exceptions

This is the way to catch errors.


In [38]:
try:
    f(1)#takes atleast 2 arguments
except:
    import sys
    print sys.exc_info()


(<type 'exceptions.TypeError'>, TypeError('f() takes at least 2 arguments (1 given)',), <traceback object at 0x109a75050>)

All together now

Lets see what hamlet gives us. We convert all words to lower-case


In [39]:
hamletlctokens=[word.lower() for word in hamlettokens]
hamletlctokens.count("thou")


Out[39]:
95

We then find a unique set of words using python's set data structure. We count how often those words occured usinf the count method on lists.


In [52]:
uniquelctokens=set(hamletlctokens)

In [41]:
tokendict={}
for ut in uniquelctokens:
    tokendict[ut]=hamletlctokens.count(ut)

We find the 100 most used words...


In [42]:
L=sorted(tokendict.iteritems(), key= lambda (k,v):v, reverse=True)[:100]
L


Out[42]:
[('the', 1136),
 ('and', 943),
 ('to', 720),
 ('of', 667),
 ('a', 527),
 ('my', 512),
 ('i', 510),
 ('in', 420),
 ('you', 412),
 ('ham.', 358),
 ('that', 337),
 ('it', 324),
 ('is', 320),
 ('his', 295),
 ('not', 270),
 ('with', 264),
 ('this', 250),
 ('your', 241),
 ('for', 231),
 ('but', 228),
 ('as', 216),
 ('he', 202),
 ('be', 201),
 ('what', 183),
 ('have', 174),
 ('will', 149),
 ('so', 143),
 ('me', 142),
 ('we', 132),
 ('do', 128),
 ('are', 126),
 ('him', 122),
 ('our', 119),
 ('king.', 113),
 ('by', 111),
 ('hor.', 110),
 ('or', 109),
 ('if', 109),
 ('on', 109),
 ('no', 107),
 ('shall', 106),
 ('thou', 95),
 ('all', 95),
 ('from', 95),
 ('they', 93),
 ('let', 92),
 ('good', 88),
 ('at', 86),
 ('thy', 86),
 ('pol.', 86),
 ('how', 84),
 ('most', 82),
 ('lord,', 81),
 ('her', 76),
 ('more', 76),
 ('queen.', 76),
 ('like', 75),
 ('would', 74),
 ('was', 73),
 ("'tis", 70),
 ('you,', 66),
 ('may', 65),
 ('very', 64),
 ('laer.', 62),
 ('hath', 62),
 ('[enter', 61),
 ('lord.', 60),
 ('did', 59),
 ('give', 58),
 ('must', 58),
 ('oph.', 58),
 ('their', 57),
 ('o,', 57),
 ('know', 57),
 ("i'll", 56),
 ('an', 55),
 ('should', 55),
 ('which', 55),
 ('some', 54),
 ('when', 54),
 ('come', 54),
 ('upon', 53),
 ('make', 53),
 ('am', 52),
 ('such', 51),
 ('ros.', 51),
 ('than', 51),
 ('there', 50),
 ('where', 49),
 ('now', 48),
 ('go', 48),
 ('o', 46),
 ('us', 46),
 ('clown.', 45),
 ('much', 44),
 ('had', 44),
 ('these', 44),
 ('them', 44),
 ('she', 43),
 ('out', 43)]

Lets get the top 20 of this and plot a bar chart!


In [43]:
topfreq=L[:20]
print topfreq
pos = np.arange(len(topfreq))
plt.bar(pos, [e[1] for e in topfreq]);
plt.xticks(pos+0.4, [e[0] for e in topfreq]);


[('the', 1136), ('and', 943), ('to', 720), ('of', 667), ('a', 527), ('my', 512), ('i', 510), ('in', 420), ('you', 412), ('ham.', 358), ('that', 337), ('it', 324), ('is', 320), ('his', 295), ('not', 270), ('with', 264), ('this', 250), ('your', 241), ('for', 231), ('but', 228)]