SlideShare a Scribd company logo
1 of 145
Download to read offline
A Few of My Favorite Things




         Mike Pirnat ā€¢ AG Interactive ā€¢ CodeMash 2012
A Few of My Favorite Things




         Mike Pirnat ā€¢ AG Interactive ā€¢ CodeMash 2012
Disclaimers
The Language
_                                             (                   =
                                          255,
                                       lambda
                                V       ,B,c
                             :c    and Y(V*V+B,B, c
                                -1)if(abs(V)<6)else
               (              2+c-4*abs(V)**-0.4)/i
                 ) ;v,       x=1500,1000;C=range(v*x
                  );import struct;P=struct.pack;M,
            j ='<QIIHHHH',open('M.bmp','wb').write
for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C:
            i ,Y=_;j(P('BBB',*(lambda T:(T*80+T**9
                  *i-950*T **99,T*70-880*T**18+701*
                 T **9      ,T*i**(1-T**45*2)))(sum(
               [              Y(0,(A%3/3.+X%v+(X/v+
                                A/3/3.-x/2)/1j)*2.5
                             /x    -2.7,i)**2 for 
                                A       in C
                                       [:9]])
                                          /9)
                                        )     )

        http://preshing.com/20110926/high-resolution-mandelbrot-in-obfuscated-python
http://preshing.com/20110926/high-resolution-mandelbrot-in-obfuscated-python
The Interactive Shell

$ python
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build
2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for
more information.
>>>
Docstrings...
class Frobulator(object):
    """It frobulates things."""

    def __init__(self, doohickey):
        """A Frobulator needs a doohickey."""
        self.doohickey = doohickey

    def frobulate(self):
        """Frobulate ALL the things!"""
        print "Frobulating..."
        doodad = self.doohickey()
        return FrobulatedThing(doodad)


class FrobulatedThing(object):
    """A thing which has been frobulated."""

    def __init__(self, thing):
        """Make a thing into a frobulated thing."""
        self.thing = thing
...and Help
>>> help(Frobulator)

Help on class Frobulator in module frobulator:

class Frobulator(__builtin__.object)
 | It frobulates things.
 |
 | Methods defined here:
 |
 | __init__(self, doohickey)
 |      A Frobulator needs a doohickey.
 |
 | frobulate(self)
 |      Frobulate ALL the things!
 |
 ...
Comprehensions

ā€¢ List comprehensions
ā€¢ Set comprehensions
ā€¢ Dictionary comprehensions
ā€¢ Generator expressions
List Comprehensions

x = [item for item in series]

x = [do_something(item) for item in series if expression]

things = [Thingy.from_data(x) for x in database_results]

partiers = [x for x in codemashers if x.slides_done()]
List Comprehensions
booze = ['beer', 'wine', 'scotch', 'gin']
soft_drinks = ['water', 'soda', 'juice']

a = [(x, y) for x in booze for y in soft_drinks]

[('beer', 'water'), ('beer', 'soda'), ('beer', 'juice'),
('wine', 'water'), ('wine', 'soda'), ('wine', 'juice'),
('scotch', 'water'), ('scotch', 'soda'), ('scotch',
'juice'), ('gin', 'water'), ('gin', 'soda'), ('gin',
'juice')]
List Comprehensions


b = [x for x in zip(booze, soft_drinks)]

[('beer', 'water'), ('wine', 'soda'), ('scotch', 'juice')]
Set Comprehensions


s = {v for v in 'CODEMASH ROCKS' if v not in 'ABCD'}

set([' ', 'E', 'H', 'K', 'M', 'O', 'S', 'R'])
Dictionary Comprehensions
 d = {key: value for key, value in list_of_tuples}

 d = {
     'Mike': 'Python',
     'Jim': 'Ruby',
     'Brad': 'UX',
     ...
     }

 d1 = {val: key for key, val in d.items()}

 {'Python': 'Mike', 'Ruby': 'Jim', 'UX': 'Brad', ...}
Generators
def f(how_many):
    for number in range(how_many):
        if number**2 > 3:
            yield number * 2

for number in f(5):
    print number

4
6
8
Generator Expressions

gen = (2*x for x in range(5) if x**2 > 3)

for number in gen:
    print number

4
6
8
Properties

class Foo(object):

    def __init__(self, bar=42):
        self.set_bar(bar)

    def get_bar(self):
        return self.bar

    def set_bar(self, bar):
        self.bar = int(bar)
Properties
class Foo(object):

    def __init__(self, bar=42):
        self.bar = bar

    @property
    def bar(self):
        return self._bar

    @bar.setter
    def bar(self, x):
        self._bar = int(x)
Properties
class Foo(object):

    def __init__(self, bar=42):
        self.bar = bar

    @property
    def bar(self):
        return self._bar

    @bar.setter
    def bar(self, x):
        self._bar = int(x)
Properties

>>> foo = Foo()
>>> foo.bar
42
>>> foo.bar = 'abc'
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 9, in bar
ValueError: invalid literal for int() with base 10:
'abc'
Decorators

ā€¢ That funny-looking @ thing
ā€¢ Similar to Javaā€™s annotations
ā€¢ Replaces a function with a wrapper
ā€¢ Augment functionality in a reusable way
Decorators
def be_excellent(wrapped):
    def wrapper(*args, **kwargs):
        print "Be excellent to each other..."
        return wrapped(*args, **kwargs)
    return wrapper

@be_excellent
def party_on(who):
    print "...and party on, {0}!".format(who)

>>> party_on('dudes')
Be excellent to each other...
...and party on, dudes!
Context Managers
ā€¢ That funny ā€œwithā€ thing
ā€¢ Simplify calling code that needs setup and
  teardown
ā€¢ Alternative to try/ļ¬nally structures
ā€¢ Acquire locks, open and close ļ¬les, do
  database transactions, etc.
Before Context Managers

frobulator = Frobulator(...)

try:
    frobulator.frobulate()
finally:
    frobulator.cleanup()
After Context Managers


with Frobulator(...) as frobulator:
    frobulator.frobulate()
class Frobulator(object):

    def __init__(self, ...):
        ...

    def __enter__(self):
        print "Preparing to frobulate..."
        return self

    def __exit__(self, exc_type, exc_value, exc_tb):
        print "Frobulation complete!"

    def frobulate(self):
        print "Frobulating!"
        ...
with Frobulator() as frobulator:
    frobulator.frobulate()


Preparing to frobulate...
Frobulating!
Frobulation complete!
import contextlib

@contextlib.contextmanager
def make_frobulator():
    print "Preparing to frobulate..."
    yield Frobulator()
    print "Frobulation complete!"


with make_frobulator() as frobulator:
    frobulator.frobulate()


Preparing to frobulate...
Frobulating!
Frobulation complete!
The Standard Library
Itertools

ā€¢ Tools for iterating on sequences
ā€¢ Inspired by functional languages
ā€¢ Fast and memory efļ¬cient
ā€¢ Combine to express more complicated
  algorithms
Itertools: chain

from itertools import chain

for x in chain([1, 2, 3], [42, 1138, 2112]):
     print x,


1 2 3 42 1138 2112
Itertools: izip

from itertools import izip

for x in izip([1, 2, 3], [42, 1138, 2112]):
    print x,


(1, 42) (2, 1138) (3, 2112)
Itertools: islice
from itertools import islice, count

for x in islice(count(), 5):
    print x,

for x in islice(count(), 5, 10):
    print x,

for x in islice(count(), 0, 100, 10):
    print x,

0 1 2 3 4
5 6 7 8 9
0 10 20 30 40 50 60 70 80 90
Itertools: islice
from itertools import islice, count

for x in islice(count(), 5):
    print x,

for x in islice(count(), 5, 10):
    print x,

for x in islice(count(), 0, 100, 10):
    print x,

0 1 2 3 4
5 6 7 8 9
0 10 20 30 40 50 60 70 80 90
Itertools: imap


from itertools import imap

for thingy in imap(Thingy.from_data, database_results):
    ...
Itertools: cycle
from itertools import cycle

for x in cycle(['wake up', 'meet Ned', 'romance Rita']):
    print x

wake up
meet Ned
romance Rita
wake up
meet Ned
romance Rita
wake up
meet Ned
...
Itertools: repeat

from itertools import repeat

for x in repeat("stop hitting yourself", 5):
    print x

stop   hitting   yourself
stop   hitting   yourself
stop   hitting   yourself
stop   hitting   yourself
stop   hitting   yourself
Functools

ā€¢ Tools for manipulating functions
ā€¢ Partial
ā€¢ Wraps a callable with default arguments
ā€¢ Alternative to lambdas and closures
Functools: Partial
from functools import partial

def f(a, b=2):
    print a, b

f1 = partial(f, 'fixed_a')
f2 = partial(f, b='fixed_b')

>>> f1(b=1138)
fixed_a 1138

>>> f2(1138)
1138 fixed_b
Functools: Partial
def category_is(category, item):
    categories = [x.lower() for x in item.categories]
    if category.lower() in categories:
        return True
    return False

is_python = partial(category_is, 'python')
is_cat_pictures = partial(category_is, 'catpix')

...

python_posts = [item for item in blog_posts if is_python(item)]

cat_posts = [item for item in blog_posts if is_cat_pictures(item)]
Collections
ā€¢ Beyond the basic list, dict, tuple, and set...
ā€¢ Counter
ā€¢ Defaultdict
ā€¢ OrderedDict
ā€¢ Namedtuple
ā€¢ ...and more
Counter
counter = {}
for char in "Hello there, CodeMash!":
    if char not in counter:
        counter[char] = 1
    else:
        counter[char] += 1

print counter

{'a': 1, ' ': 2, 'C': 1, 'e': 4, 'd': 1, 'H': 1, 'M': 1,
'l': 2, 'o': 2, ',': 1, 's': 1, 'r': 1, '!': 1, 't': 1,
'h': 2}
Counter
counter = {}
for char in "Hello there, CodeMash!":
    if char not in counter:
        counter[char] = 1
    else:
        counter[char] += 1

print counter

{'a': 1, ' ': 2, 'C': 1, 'e': 4, 'd': 1, 'H': 1, 'M': 1,
'l': 2, 'o': 2, ',': 1, 's': 1, 'r': 1, '!': 1, 't': 1,
'h': 2}
Counter

from collections import Counter
counter = Counter("Hello there, CodeMash!")
print counter

Counter({'e': 4, ' ': 2, 'l': 2, 'o': 2, 'h': 2, 'a': 1,
'C': 1, 'd': 1, 'H': 1, 'M': 1, ',': 1, 's': 1, 'r': 1,
'!': 1, 't': 1})
Counter

from collections import Counter
counter = Counter("Hello there, CodeMash!")
print counter

Counter({'e': 4, ' ': 2, 'l': 2, 'o': 2, 'h': 2, 'a': 1,
'C': 1, 'd': 1, 'H': 1, 'M': 1, ',': 1, 's': 1, 'r': 1,
'!': 1, 't': 1})
Namedtuple
import math

def distance(a, b):
    return math.sqrt(
        (a[0] - b[0])**2 +
        (a[1] - b[1])**2 +
        (a[2] - b[2])**2
    )

a = (1, 2, 3)
b = (-1, -2, 42)
print distance(a, b)

39.25557285278104
Namedtuple
from collections import namedtuple
Point = namedtuple('Point', 'x y z')

def distance(a, b):
    return math.sqrt(
        (a.x - b.x)**2 +
        (a.y - b.y)**2 +
        (a.z - b.z)**2
    )

a = Point(x=1, y=2, z=3)
b = Point(-1, -2, 42)
print distance(a, b)

39.25557285278104
Difļ¬‚ib
s1 = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Phasellus dui nunc, faucibus id ullamcorper eget, tempus
vitae nisl. Donec quis semper risus. Curabitur sit amet
tellus eget metus accumsan porta nec nec lorem. Ut vitae
sem nisl. Praesent pulvinar feugiat nibh fringilla
semper. Nullam cursus tempor lorem ut egestas. Nullam
suscipit gravida turpis ac porttitor. Curabitur eleifend
augue at risus commodo pretium. Aliquam eget magna
risus, ut lobortis metus. Cum sociis natoque penatibus
et magnis dis parturient montes, nascetur ridiculus mus.
Etiam non magna sit amet nulla porttitor molestie sit
amet vel sem. Vestibulum sit amet nisl a velit
adipiscing porta id non urna. Duis ullamcorper dictum
ipsum sit amet congue.
"""
Difļ¬‚ib
s2 = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Phasellus dui nunc, faucibus id ullamcorper eget, tempus
vitae nisl. Donec quis semper risus. Curabitur sit amet
tellus eget metus accumsan porta nec nec lorem. Ut vitae
sem nisl. Praesent pulvinar feugiat nibh fringilla
semper. Nullam cursus tempor lorem ut egestas. Nullam
suscipit gravida turpis ac porttitor. Curabitur eleifend
augue at risus commodo pretium. Aliquam eget magna
risus, ut lobortis montes. Cum sociis natoque penatibus
et magnis dis parturient metus, nascetur ridiculus mus.
Etiam non magna sit amet nulla porttitor molestie sit
amet vel sem. Vestibulum sit amet nisl a velit
adipiscing porta id non urna. Duis ullamcorper dictum
ipsum sit amet congue.
"""
Difļ¬‚ib

import difflib

differ = difflib.Differ()
diff = differ.compare(s1.splitlines(), s2.splitlines())
print 'n'.join(diff)
Difļ¬‚ib
  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Phasellus dui nunc, faucibus id ullamcorper eget, tempus
  vitae nisl. Donec quis semper risus. Curabitur sit amet
  tellus eget metus accumsan porta nec nec lorem. Ut vitae
  sem nisl. Praesent pulvinar feugiat nibh fringilla
  semper. Nullam cursus tempor lorem ut egestas. Nullam
  suscipit gravida turpis ac porttitor. Curabitur eleifend
  augue at risus commodo pretium. Aliquam eget magna
- risus, ut lobortis metus. Cum sociis natoque penatibus
?                      --

+ risus, ut lobortis montes. Cum sociis natoque penatibus
?                     +++

- et magnis dis parturient montes, nascetur ridiculus mus.
?                           ^^ ^

+ et magnis dis parturient metus, nascetur ridiculus mus.
?                           ^ ^

  Etiam non magna sit amet nulla porttitor molestie sit
  amet vel sem. Vestibulum sit amet nisl a velit
  adipiscing porta id non urna. Duis ullamcorper dictum
  ipsum sit amet congue.
Difļ¬‚ib


diff = difflib.unified_diff(
        s1.splitlines(), s2.splitlines(), lineterm='')
print 'n'.join(diff)
Difļ¬‚ib

---
+++
@@ -7,8 +7,8 @@
 semper. Nullam cursus tempor lorem ut egestas. Nullam
 suscipit gravida turpis ac porttitor. Curabitur eleifend
 augue at risus commodo pretium. Aliquam eget magna
-risus, ut lobortis metus. Cum sociis natoque penatibus
-et magnis dis parturient montes, nascetur ridiculus mus.
+risus, ut lobortis montes. Cum sociis natoque penatibus
+et magnis dis parturient metus, nascetur ridiculus mus.
 Etiam non magna sit amet nulla porttitor molestie sit
 amet vel sem. Vestibulum sit amet nisl a velit
 adipiscing porta id non urna. Duis ullamcorper dictum
Ast

ā€¢ Use Python to process abstract syntax trees
  of Python grammar
ā€¢ Helps introspect about what the current
  grammar looks like
ā€¢ Helps write secure code
Ast

# Danger:
foo = eval(bar)

# Safe:
foo = ast.literal_eval(bar)
Multiprocessing
ā€¢ Like threading, but with subprocesses
ā€¢ Local and remote concurrency
ā€¢ Spawn processes or entire pools
ā€¢ Communicate via queues or pipes
ā€¢ Shared state via shared memory or
  manager/server process
import os
from multiprocessing import Process

def info(title):
    print title
    print 'parent process:', os.getppid()
    print 'process id:', os.getpid()

def f(name):
    info('function f')
    print 'hello', name

if __name__ == '__main__':
    info('main')
    p = Process(target=f, args=('world',))
    p.start()
    p.join()
$ python process.py
main
parent process: 18647
process id: 31317
----------
function f
parent process: 31317
process id: 31318
----------
hello world
import os
from multiprocessing import Pool

def g(x):
    info('function g('+str(x)+')')
    return x * x

if __name__ == '__main__':
    info('main')
    pool = Pool(2)
    print pool.map(g, range(100))
$ python process.py     parent process: 31369
main                    parent process: 31369
module name: __main__   process id: 31370
parent process: 18647   process id: 31371
process id: 31369       ----------
----------              ----------
function g(0)           function g(4)
module name: __main__   module name: __main__
parent process: 31369   parent process: 31369
process id: 31370       function g(14)
----------              process id: 31370
function g(1)           module name: __main__
module name: __main__   ----------
parent process: 31369   parent process: 31369
process id: 31370       function g(5)
----------              process id: 31371
function g(13)          module name: __main__
function g(2)
module name: __main__   ...
parent process: 31369
process id: 31370       [0, 1, 4, 9, 16, 25, ..., 8836,
----------              9025, 9216, 9409, 9604, 9801]
module name: __main__
function g(3)
module name: __main__
Third Party Packages
Third Party Packages

ā€¢ Most available on PyPI--http://pypi.python.org
ā€¢ pip install packagename
ā€¢ easy_install packagename
Virtualenv

ā€¢ Makes an isolated Python environment
ā€¢ Donā€™t pollute your global site-packages
ā€¢ Insulates Python projects from one another
ā€¢ Don't have to be root
Virtualenv
$ virtualenv directory

$ virtualenv --python=/path/to/specific/python directory

$ cd directory
$ . bin/activate

$ easy_install whatever
$ pip install whatever

...do stuff...

$ deactivate
Datetime and Dateutil
ā€¢ Pythonā€™s datetime provides date, time,
  datetime, and timedelta objects
ā€¢ Dateutil provides powerful extensions
ā€¢ Parsing
ā€¢ Olson-driven timezones
ā€¢ Recurrence
Parsing

>>> from dateutil.parser import parse

>>> parse('01/01/2012')
datetime.datetime(2012, 1, 1, 0, 0)

>>> parse('2012-01-01')
datetime.datetime(2012, 1, 1, 0, 0)
Timezones
>>> from dateutil import zoneinfo

>>> zone = zoneinfo.gettz('US/Eastern')
>>> zone
tzfile('America/New_York')
>>> zone2 = zoneinfo.gettz('US/Hawaii')

>>> dt = datetime.now(zone)
>>> dt
datetime.datetime(2012, 1, 13, 13, 46, 54, 997825,
tzinfo=tzfile('America/New_York'))

>>> dt.astimezone(zone2)
datetime.datetime(2012, 1, 13, 8, 46, 54, 997825,
tzinfo=tzfile('Pacific/Honolulu'))
Recurrence
>>> from dateutil.rrule import rrule, YEARLY, MONTHLY,
WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY, BY_EASTER

>>> rr = rrule(YEARLY, dtstart=datetime(1948, 2, 24))

>>> rr.after(datetime(2012, 1, 1))
datetime(2012, 2, 24, 0, 0)

>>> rr.between(datetime(2010, 1, 1),
        datetime(2012, 1, 1))
[datetime(2010, 2, 24, 0, 0),
        datetime(2011, 2, 24, 0, 0)]
howoldismykid.com
def periods_between(freq, start_date, end_date):

Ā Ā Ā Ā # dateutil.rrule falls down for monthly recurrences where the start
    # date's day is greater than the number of days in a subsequent month
    # in the range; ie, when start date is 10/31/2010, and end date is
    # 3/13/2011, rrule's between will only produce 2 instances, 12/31 and
    # 1/31, rather than 4.
Ā Ā Ā Ā if freq == MONTHLY and start_date.day > 28:
Ā Ā Ā Ā Ā Ā Ā Ā start_date = datetime.datetime(start_date.year, start_date.month,
Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā 28, start_date.hour, start_date.minute, start_date.second)

Ā Ā Ā Ā # Same problem but for "Pirates of Penzance" leap day birthdays...
Ā Ā Ā Ā elif freq == YEARLY and is_leap_day(start_date):
Ā Ā Ā Ā Ā Ā Ā Ā start_date = datetime.datetime(start_date.year, start_date.month,
Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā 28, start_date.hour, start_date.minute, start_date.second)

Ā Ā Ā Ā rr = rrule(freq, dtstart=start_date)
Ā Ā Ā Ā periods = len(rr.between(start_date, end_date))
Ā Ā Ā Ā return periods
howoldismykid.com
>>> start_date = datetime(2007, 9, 10)
>>> end_date = datetime(2012, 1, 13)

>>> periods_between(YEARLY, start_date, end_date)
4

>>> periods_between(MONTHLY, start_date, end_date)
52

>>> periods_between(WEEKLY, start_date, end_date)
226

>>> periods_between(DAILY, start_date, end_date)
1585
Nose

ā€¢ Find, run, and report results of test suites
ā€¢ Low-friction setup
ā€¢ Extendable with plugins (more later)
ā€¢ http://readthedocs.org/docs/nose/en/latest/
Nose

# test_foo.py

def test_a_thing():
    assert False

def test_another_thing():
    assert True
Nose
$ nosetests tests/test_foo.py
F.
======================================================================
FAIL: test_foo.test_a_thing
----------------------------------------------------------------------
Traceback (most recent call last):
   File "/Users/mpirnat/Code/frobulator/lib/python2.7/site-packages/
nose-1.1.2-py2.7.egg/nose/case.py", line 197, in runTest
     self.test(*self.arg)
   File "/Users/mpirnat/Code/frobulator/src/frobulator/tests/test_foo.py",
line 2, in test_a_thing
     assert False
AssertionError

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)
Nose
class TestWhenFrobulating(object):

    def setup(self):
        self.frobulator = Frobulator()
        self.frobulator.frobulate()

    def test_that_it_frobulated(self):
        assert self.frobulator.has_frobulated

    def teardown(self):
        self.frobulator.cleanup()
Nose

$ nosetests
.
--------------------------------------------------------
Ran 1 test in 0.005s

OK
Nose: Useful Flags

ā€¢ --processes=number
ā€¢ -x
ā€¢ --pdb
ā€¢ --pdb-failures
ā€¢ --failed
Nose Plugins
ā€¢ Add custom behavior to your test run
ā€¢ Get coverage statistics (coverage)
ā€¢ Measure cleanliness with PEP-8 (tissue)
ā€¢ Emit human-readable spec-style results
  (pinocchio)
ā€¢ Or write your own...
class TestGeneratesLotsOfFailures(object):

    def test_generates_failures(self):

        def _make_a_test(i):
            # start with some wins
            if i < 7:
                assert True

            # but then it hits the fan...
            elif i < 30:
                assert False

            # then be a little random
            elif i % 3 == 0:
                assert False
            else:
                assert True

        for i in range(50):
            yield _make_a_test, i
$ nosetests test_epic_fail.py

.......FFFFFFFFFFFFFFFFFFFFFFFF..F..F..F..F..F..F.
[lots of test failure output; use your imagination...]
--------------------------------------------------------
Ran 50 tests in 0.010s

FAILED (errors=30)
import os
from nose.plugins import Plugin

class F7U12(Plugin):

    name = 'f7u12'
    enabled = True

    def options(self, parser, env=os.environ):
        super(F7U12, self).options(parser, env=env)

    def configure(self, options, config):
        super(F7U12, self).configure(options, config)
        self.config = config
        if not self.enabled:
            return
def setOutputStream(self, stream):
    self.stream = stream
    return self.stream

def begin(self):
    self.failure_count = 0

def handleFailure(self, test, err):
    self.failure_count += 1

    if self.failure_count < 8:
        self.stream.write('F')
    else:
        self.stream.write('U')
    return True
$ nosetests --with-f7u12 test_epic_fail.py

.......FFFFFFFFUUUUUUUUUUUUUUUU..U..U..U..U..U..U.
[lots of test failure output; use your imagination...]
--------------------------------------------------------
Ran 50 tests in 0.010s

FAILED (errors=30)
Mock
ā€¢ Mock object framework
ā€¢ Avoid writing custom stubs
ā€¢ Uses ā€œAction/Assertā€ model (not ā€œRecord/
  Replayā€)
ā€¢ Can also patch out module and class
  attributes in the scope of a test
ā€¢ http://www.voidspace.org.uk/python/mock/
Mock

from mock import Mock

foo = Mock()
foo.bar()
foo.bar.baz(42)
foo.bar.baz.return_value = "whatever"

assert foo.bar.called
foo.bar.baz.assert_called_with(42)
Mock

class TestWhenFrobulating(object):

    def setup(self):
        self.doohickey = Mock()
        self.frobulator = Frobulator(self.doohickey)
        self.frobulator.frobulate()

    def test_it_uses_the_doohickey(self):
        assert self.doohickey.called
Mock
from mock import patch

class TestWhenFrobulating(object):

    @patch('frobulator.DingleHopper')
    def setup(self, dingle_hopper_class):
        self.dingle_hopper = Mock()
        dingle_hopper_class.return_value = 
                self.dingle_hopper
        self.frobulator = Frobulator()
        self.frobulator.frobulate()

    def test_it_uses_a_dingle_hopper(self):
        assert self.dingle_hopper.called
Coverage

ā€¢ Measure coverage of your codebase during
  program execution
ā€¢ Integrates with several test runners to
  measure test coverage
ā€¢ http://nedbatchelder.com/code/coverage/
#!/usr/bin/env python

class Frobulator(object):
    """It frobulates things."""

    def __init__(self, doohickey):
        """A Frobulator needs a doohickey."""
        self.doohickey = doohickey

    def frobulate(self):
        """Frobulate ALL the things!"""
        print "Frobulating..."
        doodad = self.doohickey()
        return FrobulatedThing(doodad)


class FrobulatedThing(object):
    """A thing which has been frobulated."""

    def __init__(self, thing):
        """Make a thing into a frobulated thing."""
        self.thing = thing


if __name__ == '__main__':
    x = FrobulatedThing(42)
#!/usr/bin/env python

class Frobulator(object):
    """It frobulates things."""

    def __init__(self, doohickey):
        """A Frobulator needs a doohickey."""
        self.doohickey = doohickey

    def frobulate(self):
        """Frobulate ALL the things!"""
        print "Frobulating..."
        doodad = self.doohickey()
        return FrobulatedThing(doodad)


class FrobulatedThing(object):
    """A thing which has been frobulated."""

    def __init__(self, thing):
        """Make a thing into a frobulated thing."""
        self.thing = thing


if __name__ == '__main__':
    x = FrobulatedThing(42)
$ coverage run frobulator.py

$ coverage report -m
Name         Stmts   Miss Cover    Missing
------------------------------------------
frobulator      12      4    67%   8, 12-14
from mock import Mock, patch
from frobulator import Frobulator, FrobulatedThing


class TestWhenFrobulating(object):

    def setup(self):
        self.doohickey = Mock()
        self.doohickey.return_value = 42

        self.frobulator = Frobulator(self.doohickey)
        self.result = self.frobulator.frobulate()

    def test_it_uses_a_doohickey(self):
        assert self.doohickey.called

    def test_it_returns_a_frobulated_thing(self):
        assert isinstance(self.result, FrobulatedThing)
$ nosetests --with-coverage --cover-package frobulator
..
Name         Stmts    Miss Cover   Missing
------------------------------------------
frobulator      12       1   92%   26
------------------------------------------
Ran 2 tests in 0.008s

OK
Useful Flags

ā€¢ --cover-erase
ā€¢ --cover-inclusive
ā€¢ --cover-tests
Lettuce

ā€¢ Like Cucumber
ā€¢ BDD test framework
ā€¢ Natural language augmented by code
ā€¢ Big wins pairing Devs + QA + Biz
ā€¢ http://lettuce.it/
Lettuce Vocabulary

ā€¢ Features
ā€¢ Scenarios
ā€¢ Steps
ā€¢ World
ā€¢ Terrain
Feature: The website has a homepage
    In order to demo Lettuce
    As a presenter
    I want to test the homepage of a website

    Scenario: Verify the site is up
        Given I access the url "http://localhost:8000/"
        Then I get a status "200"
from lettuce import step, world
from nose.tools import assert_equals
import requests


@step(r'I access the url "(.*)"')
def access_url(step, url):
    world.response = requests.get(url)


@step(r'I get a status "(.*)"')
def get_status(step, expected_status):
    expected_status = int(expected_status)
    assert_equals(world.response.status_code,
            expected_status)
Snake-Guice

ā€¢ Framework for Dependency Injection
ā€¢ Reduce coupling!
ā€¢ Improve testability!
ā€¢ http://code.google.com/p/snake-guice/
Snake-Guice
ā€¢ Bind identiļ¬ers to things you want to inject
ā€¢ Decorate code with injection hints
ā€¢ Use injector to get instance with all
  dependencies resolved and injected
ā€¢ Construct with mocks in tests, minimize the
  need for patching
Deļ¬ne the Identiļ¬er


class IFrobulator(object):
    pass
Decorate Your Code

from snakeguice import inject


class WankelRotator(object):

    @inject(frobulator=IFrobulator)
    def __init__(self, frobulator):
        self.frobulator = frobulator
Decorate Your Code

from snakeguice import inject


class WankelRotator(object):

    @inject(frobulator=IFrobulator)
    def __init__(self, frobulator):
        self.frobulator = frobulator
Conļ¬gure Bindings

from frobulator import Frobulator


class BindingModule(object):

    def configure(self, binder):
        binder.bind(IFrobulator, to=Frobulator)
Get an Instance

from snakeguice import Injector
import WankelRotator

injector = Injector(BindingModule())
rotator = injector.get_instance(WankelRotator)
Requests

ā€¢ A human-friendly alternative to urllib2
ā€¢ Maturing rapidly
ā€¢ http://python-requests.org/
Using Requests

import requests

# Authentication!
r = requests.get('https://api.github.com',
        auth=('user', 'pass'))

print r.status_code
print r.headers['content-type']
Using Requests

# Posting name-value pair form data
post_data = {'foo': 'bar', 'baz': 'quux', ...}
r = requests.post(url, data=post_data)

# Posting a glob of JSON
r = requests.post(url, data=json.dumps(post_data))

# Multipart file attachment
files = {'my_file.xls': open('my_file.xls', 'rb')}
r = requests.post(url, files=files)
Using Requests

# Custom headers!
headers = {'X-foo': 'bar'}
r = requests.get(url, headers=headers)

# Cookies!
cookies = {'a_cookie': 'is delicious'}
r = requests.get(url, cookies=cookies)
Pylons
ā€¢ http://docs.pylonsproject.org/en/latest/docs/
  pylons.html
ā€¢ MVCish web framework
ā€¢ Glues together several component projects
ā€¢ Can use your preferred components
ā€¢ Somewhat dead (evolved into Pyramid)
Pylons
ā€¢ Request/response: webob
ā€¢ URL dispatch: routes
ā€¢ Input validation: formencode
ā€¢ Persistence/ORM: sqlalchemy
ā€¢ Session: beaker
ā€¢ Templates: mako
from routes import Mapper


def make_map(config):
    """Create, configure and return the routes Mapper"""
    map = Mapper(directory=config['pylons.paths']['controllers'],
                 always_scan=config['debug'])
    ...

    map.connect('/', controller='main', action='index')
    map.connect('/contact', controller='contact', action='index',
            conditions={'method':'GET'})
    map.connect('/contact', controller='contact', action='send',
            conditions={'method':'POST'})

    return map
from howoldismykid.lib.base import BaseController, 
        render


class MainController(BaseController):

    def index(self):
        # Return a rendered template
        return render('/main.mako')
from formencode import Schema, validators

class ContactForm(Schema):
    email = validators.Email(not_empty=True)
    subject = validators.String(not_empty=True)
    message = validators.String(not_empty=True)
from pylons.decorators import validate
from howoldismykid.lib.base import BaseController, render
from howoldismykid.model.forms import ContactForm

class ContactController(BaseController):

    def __init__(self, *args, **kwargs):
        BaseController.__init__(self, *args, **kwargs)
        self.emailer = Emailer(SMTP, USER, PW, FAKE_EMAIL)

    def index(self):
        # Return a rendered template
        return render('/contact.mako')

    @validate(schema=ContactForm(), form="index", prefix_error=False)
    def send(self):
        validated = self.form_result
        self.emailer.send_mail(validated['email'], EMAIL,
                validated['subject'], validated['message'])
        return render('/contact_done.mako')
<!DOCTYPE HTML>
<html>
    <head>
        ${self.head_tags()}
        ...
    </head>
    <body>
        <div id="header">...</div>
        <div id="content">
            ${self.body()}
        </div>

        <div id="footer">...</div>

        <%include file="google_analytics.mako"/>
        ${self.foot_tags()}

    </body>
</html>
<%inherit file="/base.mako" />

<%def name="head_tags()">
<title>How Old Is My Kid?</title>
</%def>

<h2>Contact Us</h2>

<p>Suggest a new feature, let us know how we're doing, or just say hi.</p>

<form method="POST" action="/contact" id="contact-form">
    <p><label for="email">Email:</label> <input type="text" name="email"
id="email" /></p>
    <p><label for="subject">Subject:</label> <input type="text"
name="subject" id="subject" /></p>
    <p><label for="message">Message:</label><br />
<textarea name="message" id="message"></textarea></p>
    <p><input type="submit" value="Submit" /></p>
</form>

<%def name="foot_tags()">
<script type="text/javascript">
$(document).ready(function() {
    $("button, input:submit").button();
});
</script>
</%def>
Django
ā€¢ https://www.djangoproject.com/
ā€¢ Full stack/harder to replace components
ā€¢ Lots of reusable apps
ā€¢ Admin interface
ā€¢ Lots of deployment options (Google)
ā€¢ Not dead
from django.conf.urls.defaults import patterns, url

urlpatterns = patterns('',
    url(r'^/$', 'howoldismykid.views.main',
            name='main'),
    url(r'^/contact/$', 'howoldismykid.views.contact',
            name='contact'),
)
from django.shortcuts import render

def main(request):
    return render(request, 'main.html')
from django import forms


class ContactForm(forms.Form):

    email = forms.EmailField(label='Email Address')
    subject = forms.CharField(label='Subject')
    message = forms.CharField(label='Message',
            widget=forms.Textarea)
from contact.forms import ContactForm
from django.shortcuts import render

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            emailer = 
                    Emailer(SMTP, USER, PW, FAKE_EMAIL)
            emailer.send_mail(
                    form.cleaned_data['email'], EMAIL,
                    form.cleaned_data['subject'],
                    form.cleaned_data['message'])
            return render(request, 'contact_done.html')
    else:
        form = ContactForm()

    return render(request, 'contact.html',
        {'form': form })
<!DOCTYPE HTML>
<html>
    <head>
        {% block head_tags %}...{% endblock %}
        ...
    </head>
    <body>
        <div id="header">...</header>
        <div id="content">
            {% block content %}It goes here.{% endblock %}
        </div>

        <div id="footer">...</div>

        {% include "google_analytics.html" %}
        {% block foot_tags %}{% endblock %}

    </body>
</html>
{% extends 'base.html' %}

{% block head_tags %}
<title>How Old Is My Kid?</title>
{% endblock %}

{% block content %}
<h2>Contact Us</h2>

<p>Suggest a new feature, let us know how we're doing, or just say hi.</p>

<form method="POST" action="/contact" id="contact-form">
    {% csrf_token %}
    {{ form.as_p }}
    <p><input type="submit" value="Submit" /></p>
</form>
{% endblock %}

{% block foot_tags %}
<script type="text/javascript">
$(document).ready(function() {
    $("button, input:submit").button();
});
</script>
{% endblock %}
The Culture
Planet Python

ā€¢ http://planet.python.org/
ā€¢ Aggregate feed of Python blogs
ā€¢ Great way to follow what's going on
ā€¢ Minimize newsgroup/mailing list burdens
ā€¢ Easy to be included
The Python Ecosystem

ā€¢ http://mirnazim.org/writings/python-
  ecosystem-introduction/
ā€¢ Great introduction to the Python ecosystem
ā€¢ Everything you need to get up and running
The Hitchhikerā€™s Guide

ā€¢ http://docs.python-guide.org/
ā€¢ Opinionated advice about using Python
ā€¢ Basics
ā€¢ Scenario-speciļ¬c details and
  recommendations
PyMotW
ā€¢ Explored a different standard library module
  every week
ā€¢ Examples, examples, examples
ā€¢ http://www.doughellmann.com/PyMOTW/
ā€¢ The Python Standard Library by Example
  http://www.doughellmann.com/books/byexample/
Podcasts
ā€¢ http://www.radiofreepython.com/
ā€¢ http://frompythonimportpodcast.com/
ā€¢ http://djangodose.com/
ā€¢ http://advocacy.python.org/podcasts/
ā€¢ http://www.awaretek.com/python/
ā€¢ Start your own! Be the change you want...
PyOhio

ā€¢ Free as in $0.00
ā€¢ Columbus, Ohio
ā€¢ Last weekend in July
ā€¢ http://pyohio.org
PyCon
ā€¢ Great people
ā€¢ Great vibe
ā€¢ All volunteerā€“personal ownership
ā€¢ Video! http://pycon.blip.tv/
ā€¢ 2012 & 2013: Santa Clara
ā€¢ 2014 & 2015: Montreal
TiP BoF

ā€¢ Testing in Python Birds of a Feather
ā€¢ Lightning Talks
ā€¢ Heckling...
...and goats
The Zen


ā€¢ Guiding principles
ā€¢ Sage advice
ā€¢ >>>   import this
The Zen
ā€¢ Beautiful is better than ugly.   ā€¢ Readability counts.
ā€¢ Explicit is better than          ā€¢ Special cases aren't special
   implicit.                          enough to break the rules.

ā€¢ Simple is better than            ā€¢ Although practicality beats
   complex.                           purity.

ā€¢ Complex is better than           ā€¢ Errors should never pass
   complicated.                       silently.

ā€¢ Flat is better than nested.      ā€¢ Unless explicitly silenced.
ā€¢ Sparse is better than dense.
The Zen
ā€¢ In the face of ambiguity,    ā€¢ Although never is often
   refuse the temptation to       better than right now.
   guess.
                               ā€¢ If the implementation is
ā€¢ There should be oneā€“            hard to explain, it's a bad
   and preferably only oneā€“       idea.
   obvious way to do it.
                               ā€¢ If the implementation is
ā€¢ Although that way may not       easy to explain, it may be a
   be obvious at ļ¬rst unless      good idea.
   you're Dutch.
                               ā€¢ Namespaces are one
ā€¢ Now is better than never.       honking great idea -- let's
                                  do more of those!
What About You?
Fin

ā€¢ Twitter: @mpirnat
ā€¢ Blog: http://mike.pirnat.com
ā€¢ Win a special prizeā€“name all the movies
ā€¢ Thanks for coming!

More Related Content

What's hot

PHP 7 ā€“ What changed internally?
PHP 7 ā€“ What changed internally?PHP 7 ā€“ What changed internally?
PHP 7 ā€“ What changed internally?Nikita Popov
Ā 
Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real Worldosfameron
Ā 
Nikita Popov "Whatā€™s new in PHP 8.0?"
Nikita Popov "Whatā€™s new in PHP 8.0?"Nikita Popov "Whatā€™s new in PHP 8.0?"
Nikita Popov "Whatā€™s new in PHP 8.0?"Fwdays
Ā 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
Ā 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance TriviaNikita Popov
Ā 
PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010
PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010
PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010Qiangning Hong
Ā 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
Ā 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)RORLAB
Ā 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentationManav Prasad
Ā 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Nikita Popov
Ā 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
Ā 
Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Charles Nutter
Ā 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
Ā 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...Fwdays
Ā 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
Ā 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to PigChris Wilkes
Ā 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are ComingNikita Popov
Ā 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalKent Ohashi
Ā 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...takeoutweight
Ā 

What's hot (20)

PHP 7 ā€“ What changed internally?
PHP 7 ā€“ What changed internally?PHP 7 ā€“ What changed internally?
PHP 7 ā€“ What changed internally?
Ā 
Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real World
Ā 
Nikita Popov "Whatā€™s new in PHP 8.0?"
Nikita Popov "Whatā€™s new in PHP 8.0?"Nikita Popov "Whatā€™s new in PHP 8.0?"
Nikita Popov "Whatā€™s new in PHP 8.0?"
Ā 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
Ā 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
Ā 
PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010
PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010
PythonäŗŽWeb 2.0ē½‘ē«™ēš„åŗ”ē”Ø - QCon Beijing 2010
Ā 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Ā 
Active Support Core Extensions (1)
Active Support Core Extensions (1)Active Support Core Extensions (1)
Active Support Core Extensions (1)
Ā 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
Ā 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?
Ā 
Scala vs Ruby
Scala vs RubyScala vs Ruby
Scala vs Ruby
Ā 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
Ā 
Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Ƙredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Ā 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
Ā 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
Ā 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
Ā 
Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to Pig
Ā 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
Ā 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
Ā 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Ā 

Viewers also liked

Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...Michael Pirnat
Ā 
Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)
Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)
Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)James Titcumb
Ā 
Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)
Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)
Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)Tom Lee
Ā 
A Few of My Favorite Things
A Few of My Favorite ThingsA Few of My Favorite Things
A Few of My Favorite Thingsstumpteacher
Ā 
Jack's Favorite Things
Jack's Favorite ThingsJack's Favorite Things
Jack's Favorite ThingsSimonRoyals
Ā 
My favorite things
My favorite thingsMy favorite things
My favorite thingsAllyson Haney
Ā 
Favorite things sample
Favorite things sampleFavorite things sample
Favorite things samplehillaryalex
Ā 
Yaru,unit1animals
Yaru,unit1animalsYaru,unit1animals
Yaru,unit1animalsKenji Saietto
Ā 
Kristinaā€™s favorite things
Kristinaā€™s favorite thingsKristinaā€™s favorite things
Kristinaā€™s favorite thingsGreg Miller
Ā 
Tinaā€™s Favorite Things
Tinaā€™s Favorite ThingsTinaā€™s Favorite Things
Tinaā€™s Favorite ThingsTina Merritt
Ā 
My favourite thing
My favourite thingMy favourite thing
My favourite thinglffl
Ā 
Game favorite clothes
Game favorite clothesGame favorite clothes
Game favorite clothesLjubica Ruzinska
Ā 
Sam's Favorite Things
Sam's Favorite ThingsSam's Favorite Things
Sam's Favorite ThingsSimonRoyals
Ā 
Declarative Syntax Definition - Grammars and Trees
Declarative Syntax Definition - Grammars and TreesDeclarative Syntax Definition - Grammars and Trees
Declarative Syntax Definition - Grammars and TreesGuido Wachsmuth
Ā 
Emmyā€™s favorite things
Emmyā€™s favorite thingsEmmyā€™s favorite things
Emmyā€™s favorite thingsguest8bf0bb
Ā 
My favorite things
My favorite thingsMy favorite things
My favorite thingsCaleighFerree
Ā 

Viewers also liked (20)

Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Shiny, Letā€™s Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulner...
Ā 
Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)
Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)
Climbing the Abstract Syntax Tree (Bulgaria PHP 2016)
Ā 
Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)
Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)
Hugging Abstract Syntax Trees: A Pythonic Love Story (OSDC 2010)
Ā 
A Few of My Favorite Things
A Few of My Favorite ThingsA Few of My Favorite Things
A Few of My Favorite Things
Ā 
Jack's Favorite Things
Jack's Favorite ThingsJack's Favorite Things
Jack's Favorite Things
Ā 
My favorite things
My favorite thingsMy favorite things
My favorite things
Ā 
Favorite things sample
Favorite things sampleFavorite things sample
Favorite things sample
Ā 
Yaru,unit1animals
Yaru,unit1animalsYaru,unit1animals
Yaru,unit1animals
Ā 
Kristinaā€™s favorite things
Kristinaā€™s favorite thingsKristinaā€™s favorite things
Kristinaā€™s favorite things
Ā 
Tinaā€™s Favorite Things
Tinaā€™s Favorite ThingsTinaā€™s Favorite Things
Tinaā€™s Favorite Things
Ā 
Clothes
ClothesClothes
Clothes
Ā 
Clothes
ClothesClothes
Clothes
Ā 
My favourite thing
My favourite thingMy favourite thing
My favourite thing
Ā 
Game favorite clothes
Game favorite clothesGame favorite clothes
Game favorite clothes
Ā 
Aula 2
Aula 2Aula 2
Aula 2
Ā 
Clothes
ClothesClothes
Clothes
Ā 
Sam's Favorite Things
Sam's Favorite ThingsSam's Favorite Things
Sam's Favorite Things
Ā 
Declarative Syntax Definition - Grammars and Trees
Declarative Syntax Definition - Grammars and TreesDeclarative Syntax Definition - Grammars and Trees
Declarative Syntax Definition - Grammars and Trees
Ā 
Emmyā€™s favorite things
Emmyā€™s favorite thingsEmmyā€™s favorite things
Emmyā€™s favorite things
Ā 
My favorite things
My favorite thingsMy favorite things
My favorite things
Ā 

Similar to A Few of My Favorite (Python) Things

Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python TricksBryan Helmig
Ā 
Python-GTK
Python-GTKPython-GTK
Python-GTKYuren Ju
Ā 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
Ā 
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonakaptur
Ā 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05cKaz Yoshikawa
Ā 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchainedEduard TomĆ s
Ā 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slidejonycse
Ā 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
Ā 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingMuthu Vinayagam
Ā 
Python GTK (Hacking Camp)
Python GTK (Hacking Camp)Python GTK (Hacking Camp)
Python GTK (Hacking Camp)Yuren Ju
Ā 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonUC San Diego
Ā 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonAnoop Thomas Mathew
Ā 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby HackersEleanor McHugh
Ā 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerDavid MuƱoz Dƭaz
Ā 
The Vanishing Pattern: from iterators to generators in Python
The Vanishing Pattern: from iterators to generators in PythonThe Vanishing Pattern: from iterators to generators in Python
The Vanishing Pattern: from iterators to generators in PythonOSCON Byrum
Ā 

Similar to A Few of My Favorite (Python) Things (20)

Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python Tricks
Ā 
Python-GTK
Python-GTKPython-GTK
Python-GTK
Ā 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Ā 
Python Puzzlers
Python PuzzlersPython Puzzlers
Python Puzzlers
Ā 
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Ā 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
Ā 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
Ā 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Ā 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
Ā 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
Ā 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
Ā 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
Ā 
Python GTK (Hacking Camp)
Python GTK (Hacking Camp)Python GTK (Hacking Camp)
Python GTK (Hacking Camp)
Ā 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
Ā 
Python crush course
Python crush coursePython crush course
Python crush course
Ā 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in Python
Ā 
Python 1
Python 1Python 1
Python 1
Ā 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
Ā 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
Ā 
The Vanishing Pattern: from iterators to generators in Python
The Vanishing Pattern: from iterators to generators in PythonThe Vanishing Pattern: from iterators to generators in Python
The Vanishing Pattern: from iterators to generators in Python
Ā 

Recently uploaded

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
Ā 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
Ā 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
Ā 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vƔzquez
Ā 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
Ā 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
Ā 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
Ā 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
Ā 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
Ā 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
Ā 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
Ā 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
Ā 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
Ā 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
Ā 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
Ā 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
Ā 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
Ā 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
Ā 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
Ā 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
Ā 

Recently uploaded (20)

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
Ā 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
Ā 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
Ā 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Ā 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Ā 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
Ā 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
Ā 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
Ā 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
Ā 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
Ā 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
Ā 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
Ā 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
Ā 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
Ā 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Ā 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Ā 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
Ā 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Ā 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Ā 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
Ā 

A Few of My Favorite (Python) Things

  • 1. A Few of My Favorite Things Mike Pirnat ā€¢ AG Interactive ā€¢ CodeMash 2012
  • 2. A Few of My Favorite Things Mike Pirnat ā€¢ AG Interactive ā€¢ CodeMash 2012
  • 3.
  • 5.
  • 6.
  • 7.
  • 8.
  • 10. _ ( = 255, lambda V ,B,c :c and Y(V*V+B,B, c -1)if(abs(V)<6)else ( 2+c-4*abs(V)**-0.4)/i ) ;v, x=1500,1000;C=range(v*x );import struct;P=struct.pack;M, j ='<QIIHHHH',open('M.bmp','wb').write for X in j('BM'+P(M,v*x*3+26,26,12,v,x,1,24))or C: i ,Y=_;j(P('BBB',*(lambda T:(T*80+T**9 *i-950*T **99,T*70-880*T**18+701* T **9 ,T*i**(1-T**45*2)))(sum( [ Y(0,(A%3/3.+X%v+(X/v+ A/3/3.-x/2)/1j)*2.5 /x -2.7,i)**2 for A in C [:9]]) /9) ) ) http://preshing.com/20110926/high-resolution-mandelbrot-in-obfuscated-python
  • 12. The Interactive Shell $ python Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
  • 13. Docstrings... class Frobulator(object): """It frobulates things.""" def __init__(self, doohickey): """A Frobulator needs a doohickey.""" self.doohickey = doohickey def frobulate(self): """Frobulate ALL the things!""" print "Frobulating..." doodad = self.doohickey() return FrobulatedThing(doodad) class FrobulatedThing(object): """A thing which has been frobulated.""" def __init__(self, thing): """Make a thing into a frobulated thing.""" self.thing = thing
  • 14. ...and Help >>> help(Frobulator) Help on class Frobulator in module frobulator: class Frobulator(__builtin__.object) | It frobulates things. | | Methods defined here: | | __init__(self, doohickey) | A Frobulator needs a doohickey. | | frobulate(self) | Frobulate ALL the things! | ...
  • 15. Comprehensions ā€¢ List comprehensions ā€¢ Set comprehensions ā€¢ Dictionary comprehensions ā€¢ Generator expressions
  • 16. List Comprehensions x = [item for item in series] x = [do_something(item) for item in series if expression] things = [Thingy.from_data(x) for x in database_results] partiers = [x for x in codemashers if x.slides_done()]
  • 17. List Comprehensions booze = ['beer', 'wine', 'scotch', 'gin'] soft_drinks = ['water', 'soda', 'juice'] a = [(x, y) for x in booze for y in soft_drinks] [('beer', 'water'), ('beer', 'soda'), ('beer', 'juice'), ('wine', 'water'), ('wine', 'soda'), ('wine', 'juice'), ('scotch', 'water'), ('scotch', 'soda'), ('scotch', 'juice'), ('gin', 'water'), ('gin', 'soda'), ('gin', 'juice')]
  • 18. List Comprehensions b = [x for x in zip(booze, soft_drinks)] [('beer', 'water'), ('wine', 'soda'), ('scotch', 'juice')]
  • 19. Set Comprehensions s = {v for v in 'CODEMASH ROCKS' if v not in 'ABCD'} set([' ', 'E', 'H', 'K', 'M', 'O', 'S', 'R'])
  • 20. Dictionary Comprehensions d = {key: value for key, value in list_of_tuples} d = { 'Mike': 'Python', 'Jim': 'Ruby', 'Brad': 'UX', ... } d1 = {val: key for key, val in d.items()} {'Python': 'Mike', 'Ruby': 'Jim', 'UX': 'Brad', ...}
  • 21. Generators def f(how_many): for number in range(how_many): if number**2 > 3: yield number * 2 for number in f(5): print number 4 6 8
  • 22. Generator Expressions gen = (2*x for x in range(5) if x**2 > 3) for number in gen: print number 4 6 8
  • 23. Properties class Foo(object): def __init__(self, bar=42): self.set_bar(bar) def get_bar(self): return self.bar def set_bar(self, bar): self.bar = int(bar)
  • 24. Properties class Foo(object): def __init__(self, bar=42): self.bar = bar @property def bar(self): return self._bar @bar.setter def bar(self, x): self._bar = int(x)
  • 25. Properties class Foo(object): def __init__(self, bar=42): self.bar = bar @property def bar(self): return self._bar @bar.setter def bar(self, x): self._bar = int(x)
  • 26. Properties >>> foo = Foo() >>> foo.bar 42 >>> foo.bar = 'abc' Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 9, in bar ValueError: invalid literal for int() with base 10: 'abc'
  • 27. Decorators ā€¢ That funny-looking @ thing ā€¢ Similar to Javaā€™s annotations ā€¢ Replaces a function with a wrapper ā€¢ Augment functionality in a reusable way
  • 28. Decorators def be_excellent(wrapped): def wrapper(*args, **kwargs): print "Be excellent to each other..." return wrapped(*args, **kwargs) return wrapper @be_excellent def party_on(who): print "...and party on, {0}!".format(who) >>> party_on('dudes') Be excellent to each other... ...and party on, dudes!
  • 29. Context Managers ā€¢ That funny ā€œwithā€ thing ā€¢ Simplify calling code that needs setup and teardown ā€¢ Alternative to try/ļ¬nally structures ā€¢ Acquire locks, open and close ļ¬les, do database transactions, etc.
  • 30. Before Context Managers frobulator = Frobulator(...) try: frobulator.frobulate() finally: frobulator.cleanup()
  • 31. After Context Managers with Frobulator(...) as frobulator: frobulator.frobulate()
  • 32. class Frobulator(object): def __init__(self, ...): ... def __enter__(self): print "Preparing to frobulate..." return self def __exit__(self, exc_type, exc_value, exc_tb): print "Frobulation complete!" def frobulate(self): print "Frobulating!" ...
  • 33. with Frobulator() as frobulator: frobulator.frobulate() Preparing to frobulate... Frobulating! Frobulation complete!
  • 34. import contextlib @contextlib.contextmanager def make_frobulator(): print "Preparing to frobulate..." yield Frobulator() print "Frobulation complete!" with make_frobulator() as frobulator: frobulator.frobulate() Preparing to frobulate... Frobulating! Frobulation complete!
  • 36. Itertools ā€¢ Tools for iterating on sequences ā€¢ Inspired by functional languages ā€¢ Fast and memory efļ¬cient ā€¢ Combine to express more complicated algorithms
  • 37. Itertools: chain from itertools import chain for x in chain([1, 2, 3], [42, 1138, 2112]): print x, 1 2 3 42 1138 2112
  • 38. Itertools: izip from itertools import izip for x in izip([1, 2, 3], [42, 1138, 2112]): print x, (1, 42) (2, 1138) (3, 2112)
  • 39. Itertools: islice from itertools import islice, count for x in islice(count(), 5): print x, for x in islice(count(), 5, 10): print x, for x in islice(count(), 0, 100, 10): print x, 0 1 2 3 4 5 6 7 8 9 0 10 20 30 40 50 60 70 80 90
  • 40. Itertools: islice from itertools import islice, count for x in islice(count(), 5): print x, for x in islice(count(), 5, 10): print x, for x in islice(count(), 0, 100, 10): print x, 0 1 2 3 4 5 6 7 8 9 0 10 20 30 40 50 60 70 80 90
  • 41. Itertools: imap from itertools import imap for thingy in imap(Thingy.from_data, database_results): ...
  • 42. Itertools: cycle from itertools import cycle for x in cycle(['wake up', 'meet Ned', 'romance Rita']): print x wake up meet Ned romance Rita wake up meet Ned romance Rita wake up meet Ned ...
  • 43. Itertools: repeat from itertools import repeat for x in repeat("stop hitting yourself", 5): print x stop hitting yourself stop hitting yourself stop hitting yourself stop hitting yourself stop hitting yourself
  • 44. Functools ā€¢ Tools for manipulating functions ā€¢ Partial ā€¢ Wraps a callable with default arguments ā€¢ Alternative to lambdas and closures
  • 45. Functools: Partial from functools import partial def f(a, b=2): print a, b f1 = partial(f, 'fixed_a') f2 = partial(f, b='fixed_b') >>> f1(b=1138) fixed_a 1138 >>> f2(1138) 1138 fixed_b
  • 46. Functools: Partial def category_is(category, item): categories = [x.lower() for x in item.categories] if category.lower() in categories: return True return False is_python = partial(category_is, 'python') is_cat_pictures = partial(category_is, 'catpix') ... python_posts = [item for item in blog_posts if is_python(item)] cat_posts = [item for item in blog_posts if is_cat_pictures(item)]
  • 47. Collections ā€¢ Beyond the basic list, dict, tuple, and set... ā€¢ Counter ā€¢ Defaultdict ā€¢ OrderedDict ā€¢ Namedtuple ā€¢ ...and more
  • 48. Counter counter = {} for char in "Hello there, CodeMash!": if char not in counter: counter[char] = 1 else: counter[char] += 1 print counter {'a': 1, ' ': 2, 'C': 1, 'e': 4, 'd': 1, 'H': 1, 'M': 1, 'l': 2, 'o': 2, ',': 1, 's': 1, 'r': 1, '!': 1, 't': 1, 'h': 2}
  • 49. Counter counter = {} for char in "Hello there, CodeMash!": if char not in counter: counter[char] = 1 else: counter[char] += 1 print counter {'a': 1, ' ': 2, 'C': 1, 'e': 4, 'd': 1, 'H': 1, 'M': 1, 'l': 2, 'o': 2, ',': 1, 's': 1, 'r': 1, '!': 1, 't': 1, 'h': 2}
  • 50. Counter from collections import Counter counter = Counter("Hello there, CodeMash!") print counter Counter({'e': 4, ' ': 2, 'l': 2, 'o': 2, 'h': 2, 'a': 1, 'C': 1, 'd': 1, 'H': 1, 'M': 1, ',': 1, 's': 1, 'r': 1, '!': 1, 't': 1})
  • 51. Counter from collections import Counter counter = Counter("Hello there, CodeMash!") print counter Counter({'e': 4, ' ': 2, 'l': 2, 'o': 2, 'h': 2, 'a': 1, 'C': 1, 'd': 1, 'H': 1, 'M': 1, ',': 1, 's': 1, 'r': 1, '!': 1, 't': 1})
  • 52. Namedtuple import math def distance(a, b): return math.sqrt( (a[0] - b[0])**2 + (a[1] - b[1])**2 + (a[2] - b[2])**2 ) a = (1, 2, 3) b = (-1, -2, 42) print distance(a, b) 39.25557285278104
  • 53. Namedtuple from collections import namedtuple Point = namedtuple('Point', 'x y z') def distance(a, b): return math.sqrt( (a.x - b.x)**2 + (a.y - b.y)**2 + (a.z - b.z)**2 ) a = Point(x=1, y=2, z=3) b = Point(-1, -2, 42) print distance(a, b) 39.25557285278104
  • 54. Difļ¬‚ib s1 = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dui nunc, faucibus id ullamcorper eget, tempus vitae nisl. Donec quis semper risus. Curabitur sit amet tellus eget metus accumsan porta nec nec lorem. Ut vitae sem nisl. Praesent pulvinar feugiat nibh fringilla semper. Nullam cursus tempor lorem ut egestas. Nullam suscipit gravida turpis ac porttitor. Curabitur eleifend augue at risus commodo pretium. Aliquam eget magna risus, ut lobortis metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam non magna sit amet nulla porttitor molestie sit amet vel sem. Vestibulum sit amet nisl a velit adipiscing porta id non urna. Duis ullamcorper dictum ipsum sit amet congue. """
  • 55. Difļ¬‚ib s2 = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dui nunc, faucibus id ullamcorper eget, tempus vitae nisl. Donec quis semper risus. Curabitur sit amet tellus eget metus accumsan porta nec nec lorem. Ut vitae sem nisl. Praesent pulvinar feugiat nibh fringilla semper. Nullam cursus tempor lorem ut egestas. Nullam suscipit gravida turpis ac porttitor. Curabitur eleifend augue at risus commodo pretium. Aliquam eget magna risus, ut lobortis montes. Cum sociis natoque penatibus et magnis dis parturient metus, nascetur ridiculus mus. Etiam non magna sit amet nulla porttitor molestie sit amet vel sem. Vestibulum sit amet nisl a velit adipiscing porta id non urna. Duis ullamcorper dictum ipsum sit amet congue. """
  • 56. Difļ¬‚ib import difflib differ = difflib.Differ() diff = differ.compare(s1.splitlines(), s2.splitlines()) print 'n'.join(diff)
  • 57. Difļ¬‚ib Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus dui nunc, faucibus id ullamcorper eget, tempus vitae nisl. Donec quis semper risus. Curabitur sit amet tellus eget metus accumsan porta nec nec lorem. Ut vitae sem nisl. Praesent pulvinar feugiat nibh fringilla semper. Nullam cursus tempor lorem ut egestas. Nullam suscipit gravida turpis ac porttitor. Curabitur eleifend augue at risus commodo pretium. Aliquam eget magna - risus, ut lobortis metus. Cum sociis natoque penatibus ? -- + risus, ut lobortis montes. Cum sociis natoque penatibus ? +++ - et magnis dis parturient montes, nascetur ridiculus mus. ? ^^ ^ + et magnis dis parturient metus, nascetur ridiculus mus. ? ^ ^ Etiam non magna sit amet nulla porttitor molestie sit amet vel sem. Vestibulum sit amet nisl a velit adipiscing porta id non urna. Duis ullamcorper dictum ipsum sit amet congue.
  • 58. Difļ¬‚ib diff = difflib.unified_diff( s1.splitlines(), s2.splitlines(), lineterm='') print 'n'.join(diff)
  • 59. Difļ¬‚ib --- +++ @@ -7,8 +7,8 @@ semper. Nullam cursus tempor lorem ut egestas. Nullam suscipit gravida turpis ac porttitor. Curabitur eleifend augue at risus commodo pretium. Aliquam eget magna -risus, ut lobortis metus. Cum sociis natoque penatibus -et magnis dis parturient montes, nascetur ridiculus mus. +risus, ut lobortis montes. Cum sociis natoque penatibus +et magnis dis parturient metus, nascetur ridiculus mus. Etiam non magna sit amet nulla porttitor molestie sit amet vel sem. Vestibulum sit amet nisl a velit adipiscing porta id non urna. Duis ullamcorper dictum
  • 60. Ast ā€¢ Use Python to process abstract syntax trees of Python grammar ā€¢ Helps introspect about what the current grammar looks like ā€¢ Helps write secure code
  • 61. Ast # Danger: foo = eval(bar) # Safe: foo = ast.literal_eval(bar)
  • 62. Multiprocessing ā€¢ Like threading, but with subprocesses ā€¢ Local and remote concurrency ā€¢ Spawn processes or entire pools ā€¢ Communicate via queues or pipes ā€¢ Shared state via shared memory or manager/server process
  • 63. import os from multiprocessing import Process def info(title): print title print 'parent process:', os.getppid() print 'process id:', os.getpid() def f(name): info('function f') print 'hello', name if __name__ == '__main__': info('main') p = Process(target=f, args=('world',)) p.start() p.join()
  • 64. $ python process.py main parent process: 18647 process id: 31317 ---------- function f parent process: 31317 process id: 31318 ---------- hello world
  • 65. import os from multiprocessing import Pool def g(x): info('function g('+str(x)+')') return x * x if __name__ == '__main__': info('main') pool = Pool(2) print pool.map(g, range(100))
  • 66. $ python process.py parent process: 31369 main parent process: 31369 module name: __main__ process id: 31370 parent process: 18647 process id: 31371 process id: 31369 ---------- ---------- ---------- function g(0) function g(4) module name: __main__ module name: __main__ parent process: 31369 parent process: 31369 process id: 31370 function g(14) ---------- process id: 31370 function g(1) module name: __main__ module name: __main__ ---------- parent process: 31369 parent process: 31369 process id: 31370 function g(5) ---------- process id: 31371 function g(13) module name: __main__ function g(2) module name: __main__ ... parent process: 31369 process id: 31370 [0, 1, 4, 9, 16, 25, ..., 8836, ---------- 9025, 9216, 9409, 9604, 9801] module name: __main__ function g(3) module name: __main__
  • 68. Third Party Packages ā€¢ Most available on PyPI--http://pypi.python.org ā€¢ pip install packagename ā€¢ easy_install packagename
  • 69. Virtualenv ā€¢ Makes an isolated Python environment ā€¢ Donā€™t pollute your global site-packages ā€¢ Insulates Python projects from one another ā€¢ Don't have to be root
  • 70. Virtualenv $ virtualenv directory $ virtualenv --python=/path/to/specific/python directory $ cd directory $ . bin/activate $ easy_install whatever $ pip install whatever ...do stuff... $ deactivate
  • 71. Datetime and Dateutil ā€¢ Pythonā€™s datetime provides date, time, datetime, and timedelta objects ā€¢ Dateutil provides powerful extensions ā€¢ Parsing ā€¢ Olson-driven timezones ā€¢ Recurrence
  • 72. Parsing >>> from dateutil.parser import parse >>> parse('01/01/2012') datetime.datetime(2012, 1, 1, 0, 0) >>> parse('2012-01-01') datetime.datetime(2012, 1, 1, 0, 0)
  • 73. Timezones >>> from dateutil import zoneinfo >>> zone = zoneinfo.gettz('US/Eastern') >>> zone tzfile('America/New_York') >>> zone2 = zoneinfo.gettz('US/Hawaii') >>> dt = datetime.now(zone) >>> dt datetime.datetime(2012, 1, 13, 13, 46, 54, 997825, tzinfo=tzfile('America/New_York')) >>> dt.astimezone(zone2) datetime.datetime(2012, 1, 13, 8, 46, 54, 997825, tzinfo=tzfile('Pacific/Honolulu'))
  • 74. Recurrence >>> from dateutil.rrule import rrule, YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY, BY_EASTER >>> rr = rrule(YEARLY, dtstart=datetime(1948, 2, 24)) >>> rr.after(datetime(2012, 1, 1)) datetime(2012, 2, 24, 0, 0) >>> rr.between(datetime(2010, 1, 1), datetime(2012, 1, 1)) [datetime(2010, 2, 24, 0, 0), datetime(2011, 2, 24, 0, 0)]
  • 75. howoldismykid.com def periods_between(freq, start_date, end_date): Ā Ā Ā Ā # dateutil.rrule falls down for monthly recurrences where the start # date's day is greater than the number of days in a subsequent month # in the range; ie, when start date is 10/31/2010, and end date is # 3/13/2011, rrule's between will only produce 2 instances, 12/31 and # 1/31, rather than 4. Ā Ā Ā Ā if freq == MONTHLY and start_date.day > 28: Ā Ā Ā Ā Ā Ā Ā Ā start_date = datetime.datetime(start_date.year, start_date.month, Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā 28, start_date.hour, start_date.minute, start_date.second) Ā Ā Ā Ā # Same problem but for "Pirates of Penzance" leap day birthdays... Ā Ā Ā Ā elif freq == YEARLY and is_leap_day(start_date): Ā Ā Ā Ā Ā Ā Ā Ā start_date = datetime.datetime(start_date.year, start_date.month, Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā 28, start_date.hour, start_date.minute, start_date.second) Ā Ā Ā Ā rr = rrule(freq, dtstart=start_date) Ā Ā Ā Ā periods = len(rr.between(start_date, end_date)) Ā Ā Ā Ā return periods
  • 76. howoldismykid.com >>> start_date = datetime(2007, 9, 10) >>> end_date = datetime(2012, 1, 13) >>> periods_between(YEARLY, start_date, end_date) 4 >>> periods_between(MONTHLY, start_date, end_date) 52 >>> periods_between(WEEKLY, start_date, end_date) 226 >>> periods_between(DAILY, start_date, end_date) 1585
  • 77. Nose ā€¢ Find, run, and report results of test suites ā€¢ Low-friction setup ā€¢ Extendable with plugins (more later) ā€¢ http://readthedocs.org/docs/nose/en/latest/
  • 78. Nose # test_foo.py def test_a_thing(): assert False def test_another_thing(): assert True
  • 79. Nose $ nosetests tests/test_foo.py F. ====================================================================== FAIL: test_foo.test_a_thing ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/mpirnat/Code/frobulator/lib/python2.7/site-packages/ nose-1.1.2-py2.7.egg/nose/case.py", line 197, in runTest self.test(*self.arg) File "/Users/mpirnat/Code/frobulator/src/frobulator/tests/test_foo.py", line 2, in test_a_thing assert False AssertionError ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=1)
  • 80. Nose class TestWhenFrobulating(object): def setup(self): self.frobulator = Frobulator() self.frobulator.frobulate() def test_that_it_frobulated(self): assert self.frobulator.has_frobulated def teardown(self): self.frobulator.cleanup()
  • 82. Nose: Useful Flags ā€¢ --processes=number ā€¢ -x ā€¢ --pdb ā€¢ --pdb-failures ā€¢ --failed
  • 83. Nose Plugins ā€¢ Add custom behavior to your test run ā€¢ Get coverage statistics (coverage) ā€¢ Measure cleanliness with PEP-8 (tissue) ā€¢ Emit human-readable spec-style results (pinocchio) ā€¢ Or write your own...
  • 84. class TestGeneratesLotsOfFailures(object): def test_generates_failures(self): def _make_a_test(i): # start with some wins if i < 7: assert True # but then it hits the fan... elif i < 30: assert False # then be a little random elif i % 3 == 0: assert False else: assert True for i in range(50): yield _make_a_test, i
  • 85. $ nosetests test_epic_fail.py .......FFFFFFFFFFFFFFFFFFFFFFFF..F..F..F..F..F..F. [lots of test failure output; use your imagination...] -------------------------------------------------------- Ran 50 tests in 0.010s FAILED (errors=30)
  • 86.
  • 87. import os from nose.plugins import Plugin class F7U12(Plugin): name = 'f7u12' enabled = True def options(self, parser, env=os.environ): super(F7U12, self).options(parser, env=env) def configure(self, options, config): super(F7U12, self).configure(options, config) self.config = config if not self.enabled: return
  • 88. def setOutputStream(self, stream): self.stream = stream return self.stream def begin(self): self.failure_count = 0 def handleFailure(self, test, err): self.failure_count += 1 if self.failure_count < 8: self.stream.write('F') else: self.stream.write('U') return True
  • 89. $ nosetests --with-f7u12 test_epic_fail.py .......FFFFFFFFUUUUUUUUUUUUUUUU..U..U..U..U..U..U. [lots of test failure output; use your imagination...] -------------------------------------------------------- Ran 50 tests in 0.010s FAILED (errors=30)
  • 90. Mock ā€¢ Mock object framework ā€¢ Avoid writing custom stubs ā€¢ Uses ā€œAction/Assertā€ model (not ā€œRecord/ Replayā€) ā€¢ Can also patch out module and class attributes in the scope of a test ā€¢ http://www.voidspace.org.uk/python/mock/
  • 91. Mock from mock import Mock foo = Mock() foo.bar() foo.bar.baz(42) foo.bar.baz.return_value = "whatever" assert foo.bar.called foo.bar.baz.assert_called_with(42)
  • 92. Mock class TestWhenFrobulating(object): def setup(self): self.doohickey = Mock() self.frobulator = Frobulator(self.doohickey) self.frobulator.frobulate() def test_it_uses_the_doohickey(self): assert self.doohickey.called
  • 93. Mock from mock import patch class TestWhenFrobulating(object): @patch('frobulator.DingleHopper') def setup(self, dingle_hopper_class): self.dingle_hopper = Mock() dingle_hopper_class.return_value = self.dingle_hopper self.frobulator = Frobulator() self.frobulator.frobulate() def test_it_uses_a_dingle_hopper(self): assert self.dingle_hopper.called
  • 94. Coverage ā€¢ Measure coverage of your codebase during program execution ā€¢ Integrates with several test runners to measure test coverage ā€¢ http://nedbatchelder.com/code/coverage/
  • 95. #!/usr/bin/env python class Frobulator(object): """It frobulates things.""" def __init__(self, doohickey): """A Frobulator needs a doohickey.""" self.doohickey = doohickey def frobulate(self): """Frobulate ALL the things!""" print "Frobulating..." doodad = self.doohickey() return FrobulatedThing(doodad) class FrobulatedThing(object): """A thing which has been frobulated.""" def __init__(self, thing): """Make a thing into a frobulated thing.""" self.thing = thing if __name__ == '__main__': x = FrobulatedThing(42)
  • 96. #!/usr/bin/env python class Frobulator(object): """It frobulates things.""" def __init__(self, doohickey): """A Frobulator needs a doohickey.""" self.doohickey = doohickey def frobulate(self): """Frobulate ALL the things!""" print "Frobulating..." doodad = self.doohickey() return FrobulatedThing(doodad) class FrobulatedThing(object): """A thing which has been frobulated.""" def __init__(self, thing): """Make a thing into a frobulated thing.""" self.thing = thing if __name__ == '__main__': x = FrobulatedThing(42)
  • 97. $ coverage run frobulator.py $ coverage report -m Name Stmts Miss Cover Missing ------------------------------------------ frobulator 12 4 67% 8, 12-14
  • 98. from mock import Mock, patch from frobulator import Frobulator, FrobulatedThing class TestWhenFrobulating(object): def setup(self): self.doohickey = Mock() self.doohickey.return_value = 42 self.frobulator = Frobulator(self.doohickey) self.result = self.frobulator.frobulate() def test_it_uses_a_doohickey(self): assert self.doohickey.called def test_it_returns_a_frobulated_thing(self): assert isinstance(self.result, FrobulatedThing)
  • 99. $ nosetests --with-coverage --cover-package frobulator .. Name Stmts Miss Cover Missing ------------------------------------------ frobulator 12 1 92% 26 ------------------------------------------ Ran 2 tests in 0.008s OK
  • 100. Useful Flags ā€¢ --cover-erase ā€¢ --cover-inclusive ā€¢ --cover-tests
  • 101. Lettuce ā€¢ Like Cucumber ā€¢ BDD test framework ā€¢ Natural language augmented by code ā€¢ Big wins pairing Devs + QA + Biz ā€¢ http://lettuce.it/
  • 102. Lettuce Vocabulary ā€¢ Features ā€¢ Scenarios ā€¢ Steps ā€¢ World ā€¢ Terrain
  • 103. Feature: The website has a homepage In order to demo Lettuce As a presenter I want to test the homepage of a website Scenario: Verify the site is up Given I access the url "http://localhost:8000/" Then I get a status "200"
  • 104. from lettuce import step, world from nose.tools import assert_equals import requests @step(r'I access the url "(.*)"') def access_url(step, url): world.response = requests.get(url) @step(r'I get a status "(.*)"') def get_status(step, expected_status): expected_status = int(expected_status) assert_equals(world.response.status_code, expected_status)
  • 105. Snake-Guice ā€¢ Framework for Dependency Injection ā€¢ Reduce coupling! ā€¢ Improve testability! ā€¢ http://code.google.com/p/snake-guice/
  • 106. Snake-Guice ā€¢ Bind identiļ¬ers to things you want to inject ā€¢ Decorate code with injection hints ā€¢ Use injector to get instance with all dependencies resolved and injected ā€¢ Construct with mocks in tests, minimize the need for patching
  • 107. Deļ¬ne the Identiļ¬er class IFrobulator(object): pass
  • 108. Decorate Your Code from snakeguice import inject class WankelRotator(object): @inject(frobulator=IFrobulator) def __init__(self, frobulator): self.frobulator = frobulator
  • 109. Decorate Your Code from snakeguice import inject class WankelRotator(object): @inject(frobulator=IFrobulator) def __init__(self, frobulator): self.frobulator = frobulator
  • 110. Conļ¬gure Bindings from frobulator import Frobulator class BindingModule(object): def configure(self, binder): binder.bind(IFrobulator, to=Frobulator)
  • 111. Get an Instance from snakeguice import Injector import WankelRotator injector = Injector(BindingModule()) rotator = injector.get_instance(WankelRotator)
  • 112. Requests ā€¢ A human-friendly alternative to urllib2 ā€¢ Maturing rapidly ā€¢ http://python-requests.org/
  • 113. Using Requests import requests # Authentication! r = requests.get('https://api.github.com', auth=('user', 'pass')) print r.status_code print r.headers['content-type']
  • 114. Using Requests # Posting name-value pair form data post_data = {'foo': 'bar', 'baz': 'quux', ...} r = requests.post(url, data=post_data) # Posting a glob of JSON r = requests.post(url, data=json.dumps(post_data)) # Multipart file attachment files = {'my_file.xls': open('my_file.xls', 'rb')} r = requests.post(url, files=files)
  • 115. Using Requests # Custom headers! headers = {'X-foo': 'bar'} r = requests.get(url, headers=headers) # Cookies! cookies = {'a_cookie': 'is delicious'} r = requests.get(url, cookies=cookies)
  • 116. Pylons ā€¢ http://docs.pylonsproject.org/en/latest/docs/ pylons.html ā€¢ MVCish web framework ā€¢ Glues together several component projects ā€¢ Can use your preferred components ā€¢ Somewhat dead (evolved into Pyramid)
  • 117. Pylons ā€¢ Request/response: webob ā€¢ URL dispatch: routes ā€¢ Input validation: formencode ā€¢ Persistence/ORM: sqlalchemy ā€¢ Session: beaker ā€¢ Templates: mako
  • 118. from routes import Mapper def make_map(config): """Create, configure and return the routes Mapper""" map = Mapper(directory=config['pylons.paths']['controllers'], always_scan=config['debug']) ... map.connect('/', controller='main', action='index') map.connect('/contact', controller='contact', action='index', conditions={'method':'GET'}) map.connect('/contact', controller='contact', action='send', conditions={'method':'POST'}) return map
  • 119. from howoldismykid.lib.base import BaseController, render class MainController(BaseController): def index(self): # Return a rendered template return render('/main.mako')
  • 120. from formencode import Schema, validators class ContactForm(Schema): email = validators.Email(not_empty=True) subject = validators.String(not_empty=True) message = validators.String(not_empty=True)
  • 121. from pylons.decorators import validate from howoldismykid.lib.base import BaseController, render from howoldismykid.model.forms import ContactForm class ContactController(BaseController): def __init__(self, *args, **kwargs): BaseController.__init__(self, *args, **kwargs) self.emailer = Emailer(SMTP, USER, PW, FAKE_EMAIL) def index(self): # Return a rendered template return render('/contact.mako') @validate(schema=ContactForm(), form="index", prefix_error=False) def send(self): validated = self.form_result self.emailer.send_mail(validated['email'], EMAIL, validated['subject'], validated['message']) return render('/contact_done.mako')
  • 122. <!DOCTYPE HTML> <html> <head> ${self.head_tags()} ... </head> <body> <div id="header">...</div> <div id="content"> ${self.body()} </div> <div id="footer">...</div> <%include file="google_analytics.mako"/> ${self.foot_tags()} </body> </html>
  • 123. <%inherit file="/base.mako" /> <%def name="head_tags()"> <title>How Old Is My Kid?</title> </%def> <h2>Contact Us</h2> <p>Suggest a new feature, let us know how we're doing, or just say hi.</p> <form method="POST" action="/contact" id="contact-form"> <p><label for="email">Email:</label> <input type="text" name="email" id="email" /></p> <p><label for="subject">Subject:</label> <input type="text" name="subject" id="subject" /></p> <p><label for="message">Message:</label><br /> <textarea name="message" id="message"></textarea></p> <p><input type="submit" value="Submit" /></p> </form> <%def name="foot_tags()"> <script type="text/javascript"> $(document).ready(function() { $("button, input:submit").button(); }); </script> </%def>
  • 124. Django ā€¢ https://www.djangoproject.com/ ā€¢ Full stack/harder to replace components ā€¢ Lots of reusable apps ā€¢ Admin interface ā€¢ Lots of deployment options (Google) ā€¢ Not dead
  • 125. from django.conf.urls.defaults import patterns, url urlpatterns = patterns('', url(r'^/$', 'howoldismykid.views.main', name='main'), url(r'^/contact/$', 'howoldismykid.views.contact', name='contact'), )
  • 126. from django.shortcuts import render def main(request): return render(request, 'main.html')
  • 127. from django import forms class ContactForm(forms.Form): email = forms.EmailField(label='Email Address') subject = forms.CharField(label='Subject') message = forms.CharField(label='Message', widget=forms.Textarea)
  • 128. from contact.forms import ContactForm from django.shortcuts import render def contact(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): emailer = Emailer(SMTP, USER, PW, FAKE_EMAIL) emailer.send_mail( form.cleaned_data['email'], EMAIL, form.cleaned_data['subject'], form.cleaned_data['message']) return render(request, 'contact_done.html') else: form = ContactForm() return render(request, 'contact.html', {'form': form })
  • 129. <!DOCTYPE HTML> <html> <head> {% block head_tags %}...{% endblock %} ... </head> <body> <div id="header">...</header> <div id="content"> {% block content %}It goes here.{% endblock %} </div> <div id="footer">...</div> {% include "google_analytics.html" %} {% block foot_tags %}{% endblock %} </body> </html>
  • 130. {% extends 'base.html' %} {% block head_tags %} <title>How Old Is My Kid?</title> {% endblock %} {% block content %} <h2>Contact Us</h2> <p>Suggest a new feature, let us know how we're doing, or just say hi.</p> <form method="POST" action="/contact" id="contact-form"> {% csrf_token %} {{ form.as_p }} <p><input type="submit" value="Submit" /></p> </form> {% endblock %} {% block foot_tags %} <script type="text/javascript"> $(document).ready(function() { $("button, input:submit").button(); }); </script> {% endblock %}
  • 132. Planet Python ā€¢ http://planet.python.org/ ā€¢ Aggregate feed of Python blogs ā€¢ Great way to follow what's going on ā€¢ Minimize newsgroup/mailing list burdens ā€¢ Easy to be included
  • 133. The Python Ecosystem ā€¢ http://mirnazim.org/writings/python- ecosystem-introduction/ ā€¢ Great introduction to the Python ecosystem ā€¢ Everything you need to get up and running
  • 134. The Hitchhikerā€™s Guide ā€¢ http://docs.python-guide.org/ ā€¢ Opinionated advice about using Python ā€¢ Basics ā€¢ Scenario-speciļ¬c details and recommendations
  • 135. PyMotW ā€¢ Explored a different standard library module every week ā€¢ Examples, examples, examples ā€¢ http://www.doughellmann.com/PyMOTW/ ā€¢ The Python Standard Library by Example http://www.doughellmann.com/books/byexample/
  • 136. Podcasts ā€¢ http://www.radiofreepython.com/ ā€¢ http://frompythonimportpodcast.com/ ā€¢ http://djangodose.com/ ā€¢ http://advocacy.python.org/podcasts/ ā€¢ http://www.awaretek.com/python/ ā€¢ Start your own! Be the change you want...
  • 137. PyOhio ā€¢ Free as in $0.00 ā€¢ Columbus, Ohio ā€¢ Last weekend in July ā€¢ http://pyohio.org
  • 138. PyCon ā€¢ Great people ā€¢ Great vibe ā€¢ All volunteerā€“personal ownership ā€¢ Video! http://pycon.blip.tv/ ā€¢ 2012 & 2013: Santa Clara ā€¢ 2014 & 2015: Montreal
  • 139. TiP BoF ā€¢ Testing in Python Birds of a Feather ā€¢ Lightning Talks ā€¢ Heckling...
  • 141. The Zen ā€¢ Guiding principles ā€¢ Sage advice ā€¢ >>> import this
  • 142. The Zen ā€¢ Beautiful is better than ugly. ā€¢ Readability counts. ā€¢ Explicit is better than ā€¢ Special cases aren't special implicit. enough to break the rules. ā€¢ Simple is better than ā€¢ Although practicality beats complex. purity. ā€¢ Complex is better than ā€¢ Errors should never pass complicated. silently. ā€¢ Flat is better than nested. ā€¢ Unless explicitly silenced. ā€¢ Sparse is better than dense.
  • 143. The Zen ā€¢ In the face of ambiguity, ā€¢ Although never is often refuse the temptation to better than right now. guess. ā€¢ If the implementation is ā€¢ There should be oneā€“ hard to explain, it's a bad and preferably only oneā€“ idea. obvious way to do it. ā€¢ If the implementation is ā€¢ Although that way may not easy to explain, it may be a be obvious at ļ¬rst unless good idea. you're Dutch. ā€¢ Namespaces are one ā€¢ Now is better than never. honking great idea -- let's do more of those!
  • 145. Fin ā€¢ Twitter: @mpirnat ā€¢ Blog: http://mike.pirnat.com ā€¢ Win a special prizeā€“name all the movies ā€¢ Thanks for coming!