Tips & Tricks

Quick Tips

Exceptions (try...except)

Exceptions are useful for doing proper error handling


In [ ]:
# basic exception hanlding
try:
    # ... do something
    pass
except WhateverException as e:
    # ... do the handling here
    pass

In [ ]:
# more "verbose" exception hanlding
try:
    # ... do something
    pass
except WhateverException as e:
    # ... do the handling here
    pass
finally:
    # ... code here is always executed
    pass

In [ ]:
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as e:
    print "I/O error({0}): {1}".format(e.errno, e.strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

Never use the "diaper" design pattern ...


In [ ]:
try:
    f = open('adasdasd.foo', 'r')
except:
    pass

execution continues silently and it would be horribly annoying to find what went wrong because no error message or warning will be displayed!!

lambda (inline functions)


In [ ]:
# doing it with a function
def my_square(x):
    return x**2
print(my_square(16))

In [ ]:
# doing it with a lambda
my_square = lambda x: x**2
print(my_square(16))

pythonic "loops"


In [ ]:
for i in range(80, 90):
    print(chr(i))

In [ ]:
for character in map(chr, range(80, 90)):
    print(character)

In [ ]:
import subprocess
import time
import sys

for char in map(chr, range(80, 90)):
    print('   ', char, '   ')
    sys.stdout.flush()
    time.sleep(0.05)
    subprocess.Popen("clear").wait()

In [ ]:
import subprocess
import time
import sys
from IPython.display import clear_output

for char in map(chr, range(128, 256)):
    print('   ', char, '   ')
    time.sleep(0.1)
    clear_output(wait=0.1)

map


In [ ]:
' '.join(map(chr, range(0, 128)))

filter


In [ ]:
x = [1, 2, 10, -1, -8]
x_positive = []
for element in x:
    if element < 0:
        pass
    else:
        x_positive.append(element)
print(x_positive)

more elegant implementation (with filter)


In [ ]:
list(filter(lambda element: element > 0, x))

reduce


In [ ]:
x = range(1000)
def calculate_sum1(array):
    my_sum = 0
    for element in array:
        my_sum += element
    return my_sum
print(calculate_sum(x))

In [ ]:
from functools import reduce
def calculate_sum2(array):
    return reduce(lambda x, y: x + y, array)
print(calculate_sum2(x))

which is faster ?


In [ ]:
%timeit calculate_sum1(x)
%timeit calculate_sum2(x)

comparison to numpy


In [ ]:
import numpy
x = numpy.arange(0, 10000)
%timeit x.sum()

In [ ]:
# for methods/function calls that take lots of time
%time x.sum()

Configuring IPython

put this snippet at the bottom of:

 ~/.ipython/profile_default/ipython_config.py

and relaunch ipython. You have to do this once.


In [ ]:
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
c.InteractiveShellApp.exec_lines.append('print("")')
c.InteractiveShellApp.exec_lines.append('print("disable autoreload in ipython_config.py to improve performance.")')
c.InteractiveShellApp.exec_lines.append('print("finished loading.")')

Editors/IDEs

  • https://atom.io/ (free)
  • emacs (free)
  • vim (free)
  • pycharm (half free)
  • sublime text (half free)
  • eric python (free)
  • sphinx (free)
  • spyder (free - matlab like)
  • eclipse + pydev (free)

debugging

  • pdb
  • ipdb
  • pdb++
  • just put asdasdasdasd
  • breakpoints in the IDE (best way to go to find nasty bugs)

profiling

code coverage

  • pip install coverage
  • py.test plugin (coverage)

extending python

- ctypes
- via numpy (f2py)
- swig
- cython
- numba
- pycuda
- ... many others