Last active
August 29, 2015 14:22
-
-
Save mkowoods/a6e258f1286f4d235203 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import update_wrapper | |
def decorator(d): | |
def _d(fn): | |
return update_wrapper(d(fn), fn) | |
update_wrapper(_d, d) | |
return _d | |
def decorator(d): | |
return lambda fn: update_wrapper(d(fn), fn) | |
decorator = decorator(decorator) | |
@decorator | |
def n_ary(f): | |
"""Given binary function f(x, y), return an n_ary function such | |
that f(x, y, z) = f(x, f(y,z)), etc. Also allow f(x) = x.""" | |
def n_ary_f(x, *args): | |
if len(args) == 0: | |
return x | |
elif len(args) == 1: | |
return f(x, args[0]) | |
else: | |
return f(x, n_ary_f(args[0], *args[1:])) | |
return n_ary_f | |
@n_ary | |
def sum_like(x, y = None): | |
return x + y if y else x | |
@decorator | |
def countcalls(f): | |
"Decorator that makes the function count calls to it in the dict callcounts[f]" | |
def _f(*args): | |
callcounts[_f] += 1 | |
return f(*args) | |
callcounts[_f] = 0 | |
return _f | |
callcounts = {} | |
@decorator | |
def memo(f): | |
"""Decorator that caches the return value for each call to f(args). Then when called again with same args, we can | |
just look it up.""" | |
cache = {} | |
def _f(*args): | |
try: | |
return cache[args] | |
except KeyError: | |
cache[args] = results = f(*args) | |
return result | |
except TypeError: | |
return f(args) | |
return _f | |
print sum_like(1,2,3,4,5,6) | |
@countcalls | |
def main(x, y , z): | |
return sum([x, y, z]) | |
@countcalls | |
def test(): | |
return 1 | |
@decorator | |
def trace(f): | |
"""produces a human readable version of a recursive funciton""" | |
indent = ' ' | |
def _f(*args): | |
signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args))) | |
print '%s--> %s' % (trace.level*indent, signature) | |
trace.level += 1 | |
try: | |
result = f(*args) | |
print '%s<-- %s == %s' % ((trace.level-1)*indent, | |
signature, result) | |
finally: | |
trace.level -= 1 | |
return result | |
trace.level = 0 | |
return _f | |
def disabled(f): | |
"""can disable existing decorators through assignment e.g. trace = disabled""" | |
return f | |
for n in range(50): | |
main(1, 2, 3) | |
for n in range(460): | |
test() | |
print callcounts | |
@trace | |
def fib(n): | |
if n == 0 or n == 1: | |
return 1 | |
else: | |
return fib(n-1) + fib(n-2) | |
print fib(6) #running this in the browser's IDE will not display the indentations! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment