Clean Code; Clear Code

Best practices

Style Guide for Python Code: http://www.python.org/dev/peps/pep-0008/

It ain't c, c++, fortran -- don't code python like it is or it will be slow.

Several examples adapted from: http://www.youtube.com/watch?v=OSGv2VnC0go

Importing libraries

In [122]:
# This is bad
#from numpy import * 

import itertools
#itertools. 

import numpy as np
#np.array(

Lists!

In [123]:
blank_list = [] # how to create a blank list
In [84]:
colors = ['red', 'green', 'blue', 'yellow'] # list
print colors
['red', 'green', 'blue', 'yellow']
In [124]:
# IF YOU SEE THIS
for i in range(len(colors)): # for loop
    print colors[i]
red
green
blue
yellow
In [125]:
# DO THIS INSTEAD
for color in colors:
    print color
red
green
blue
yellow
In [126]:
# If you see this kind of thing in your code
for index in range(len(colors)):
    print index, '-->', colors[index]
0 --> red
1 --> green
2 --> blue
3 --> yellow
In [127]:
# Do this instead
for index, color in enumerate(colors):
    print index, '-->', color
0 --> red
1 --> green
2 --> blue
3 --> yellow
In [128]:
#add list comprehensions
dave = [x**2 for x in xrange(5)]
In [129]:
print dave
[0, 1, 4, 9, 16]

Dictionaries!

In [130]:
blank_dict = {} # how to create a blank... dictionary
In [1]:
dictionary = {'Spider Man':'blue', 'Dave':'green', 'Jonathan':'red' }
print dictionary
{'Dave': 'green', 'Jonathan': 'red', 'Spider Man': 'blue'}
In [2]:
print "Keys: "
for key in dictionary:
    print key
    
Keys: 
Dave
Jonathan
Spider Man
In [3]:
print "Values: "
for value in dictionary.itervalues():
    print value
Values: 
green
red
blue
In [4]:
# dictionaries are unordered! 
for key, value in dictionary.items():
    print key, '-->', value
Dave --> green
Jonathan --> red
Spider Man --> blue
In [5]:
dictionary_two = {key:dictionary[key]*2 for key in dictionary}
dictionary_two.update({"abbie":"purple"})
In [6]:
print dictionary
print dictionary_two
{'Dave': 'green', 'Jonathan': 'red', 'Spider Man': 'blue'}
{'Dave': 'greengreen', 'Jonathan': 'redred', 'Spider Man': 'blueblue', 'abbie': 'purple'}

Other cool ipython notebook features

In [7]:
# Read/write using the with 

with open('text.ascii', 'w') as filehandle:
    filehandle.write('hello!')
In [8]:
# http://stackoverflow.com/questions/3394835/args-and-kwargs

def print_everything(*args):
    """Takes a list of arguments and prints an enumerated list. """
    for count, thing in enumerate(args):
        print '{0}. {1}'.format(count, thing)

print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage
In [9]:
# Similarly, **kwargs allows you to handle named arguments that you have not defined in advance:

def table_things(title_string, **kwargs):
    """Takes a title and a dictionary of elements to print as a table elements.""" 
    print title_string
    print "-" * len(title_string)
    for name, value in kwargs.items():
        print '{0} = {1}'.format(name, value)
    
table_things("Classifying stuff with Dave", apple = 'fruit', cabbage = 'vegetable')
Classifying stuff with Dave
---------------------------
cabbage = vegetable
apple = fruit
In [10]:
names = ['David', 'Jonathan', 'Fred', 'Bob', 'Steve', 'Spider Man']
statuses = ['cool', 'lame', 'lame', 'lame', 'lame', 'cool', ]

cooldict = {name:status for name, status in itertools.izip(names, statuses)}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-f28645ec1aae> in <module>()
      2 statuses = ['cool', 'lame', 'lame', 'lame', 'lame', 'cool', ]
      3 
----> 4 cooldict = {name:status for name, status in itertools.izip(names, statuses)}

NameError: name 'itertools' is not defined
In [ ]:
cooldict
In [ ]:
table_things("Cool factor", **cooldict) # double splat! 

Plotting Workflow Example

In [11]:
import pylab as pl
pl.rcParams['figure.figsize'] = 8, 6  # plotsize 
In [12]:
N_points = 100 # 10, 100
x = np.linspace(0, 2*np.pi, N_points)
f = np.sin(x) 
In [13]:
pl.plot(x, f, label="sin") # color, label
pl.plot(x, np.cos(x), label="cos", color='red') # color, label
pl.legend()
pl.ylabel("sin(x)")
pl.xlabel("radians")
pl.savefig("amazing-1.pdf")

Glimpse of the future

ipython notebook + gist.github.com + nbviewer == easily shareable and reproducible work

Example