### Lambda Functions¶

(anonymous functions) from Lisp & functional programming

In [ ]:
tmp = lambda x: x**2
print(type(tmp))

In [ ]:
tmp(2)

In [ ]:
# forget about creating a new function name...just do it!
(lambda x,y: x**2+y)(2,4.5)

In [ ]:
## create a list of lambda functions
lamfun = [lambda x: x**2, lambda x: x**3, \
lambda y: math.sqrt(y) if y >= 0 else "Really? I mean really? %f" % y]

In [ ]:
for l in lamfun: print(l(-1.3))

lambda functions are meant to be short, one liners. If you need more complex functions, probably better just to name them
In [ ]:
# %load airline.py
airports = {"DCA": "Washington, D.C.", "IAD": "Dulles", "LHR": "London-Heathrow", \
"SVO": "Moscow", "CDA": "Chicago-Midway", "SBA": "Santa Barbara", "LAX": "Los Angeles",\
"JFK": "New York City", "MIA": "Miami", "AUM": "Austin, Minnesota"}

# airline, number, heading to, gate, time (decimal hours)
("Aeroflot",34,"SVO",5,9.00),("Southwest",146,"CDA",1,9.60), ("United",46,"LAX",5,6.5),\
("Southwest",23,"SBA",6,12.5),("United",2,"LAX",10,12.5),("Southwest",59,"LAX",11,14.5),\
("American", 1,"JFK",12,11.3),("USAirways", 8,"MIA",20,13.1),("United",2032,"MIA",21,15.1),\
("SpamAir",1,"AUM",42,14.4)]

In [ ]:
help(list.sort)

In [ ]:
flights.sort(key=lambda x: x[4]) ;
print(flights)

In [ ]:
import pprint
pprint.pprint(flights)


## Multiple column sorting¶

operator.itemgetter(item[, args...])¶


Return a callable object that fetches item from its operand using the operand’s __getitem__() method. If multiple items are specified, returns a tuple of lookup values.

http://docs.python.org/library/operator.html#module-operator

In [ ]:
import operator
flights.sort(key=operator.itemgetter(4,1,0))
flights


### Filter is a certain way to do list comprehension¶

filter(function, sequence) returns a sequence consisting of those items from the sequence for which function(item) is true

In [ ]:
mylist=[num for num in range(101) if (num & 2) and (num & 1) and (num % 11 != 0.0)]
print(mylist)

In [ ]:
def f(num): return (num & 2) and (num & 1) and (num % 11 != 0.0)

mylist = list(filter(f,range(101)))
print(mylist)

In [ ]:
mylist = list(map(lambda num: (num & 2) and (num & 1) and (num % 11 != 0.0),range(101)))
print(mylist)


if the input is a string, so is the output...

In [ ]:
## also works on strings...try it with lambdas!
import string
a="Charlie Brown said \"[email protected][email protected][email protected]!\""
"".join([c for c in a if c in string.ascii_letters])

In [ ]:
", ".join([str(num) for num in range(101) if (num & 2) and \
(num & 1) and (num % 11 != 0.0)])


[back]

### Map is just another way to do list comprehension¶

In [ ]:
def timesthree(x): return x*3
list(map(timesthree,"spam"))

In [ ]:
list(map(lambda x: x**3, range(1,10)))


### Reduce returns one value¶

reduce(function, sequence) returns a single value constructed by calling the binary function on the first two items of the sequence, then on the result and the next item, and so on

In [ ]:
from functools import reduce
# sum from 1 to 10
reduce(lambda x,y: x + y, range(1,11))
%timeit reduce(lambda x,y: x + y, range(1,11))

In [ ]:
reduce(lambda x,y: x + y, range(11,1,-1))

In [ ]:
list(range(11,1,-1))

In [ ]:
a = ["a","b"]

In [ ]:
reduce?

In [ ]:
# sum() is a built in function...it’s bound to be faster
%timeit sum(range(1,11))


### zip()¶

built in function to pairwise concatenate items in iterables into a list of tuples

In [ ]:
list(zip(["I","you","them"],["=spam","=eggs","=dark knights"]))

In [ ]:
list(zip(["I","you","them"],["=spam","=eggs","=dark knights"],["!","?","#"]))

In [ ]:
a = list(zip(["I","you","them"],["=spam","=eggs","=dark knights"],["!","?","hello","blah"]))

In [ ]:
a[0][1] = "=eggs"

In [ ]:
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
print('What is your %s?  It is %s' % (q,a))


not to be confused with zipfile module which exposes file compression

# try, except, finally¶

• Billy: Let's keep going with "Airplanes", for \$200. • Bobby Wheat: "Airplanes" for \$200: "And what is the Deal With the Black Box?"
• [ Tommy buzzes in ] Tommy!
• Tommy: It's the only thing that survives the crash - why don't they build the whole plane out of the Black Box!

http://snltranscripts.jt.org/91/91rstandup.phtml

http://www.nbc.com/saturday-night-live/video/standup-and-win/2868123

### Wrap volatile code in try/except/finally¶

In [ ]:
tmp = input("Enter a number and I'll square it: ") ; print(float(tmp)**2)


do this...

In [ ]:
def f():
try:
tmp = input("Enter a number and I'll square it: ")
print(float(tmp)**2)
except:
print("dude. I asked you for a number and %s is not a number." % tmp)
finally:
print("thanks for playing!")

In [ ]:
f()


#### Wrap volatile code in try/except/finally¶

try:
# volatile stuff here
tmp = raw_input("Enter a number “ + \
and I'll square it: ")
print(float(tmp)**2)
except:
# upon error, jump here inside except and execute that code
print("dude. I asked you for a number and " + \
"%s is not a number." % tmp)
finally:
# regardless of whether you hit an error, execute everything inside the finally block
print("thanks for playing!")

In [ ]:
try:
print("eat at" % joes)
finally:
print("bye.")

• errors in Python generate what are called “exceptions”
• exceptions can be handled differently depending on what kind of exception they are (we’ll see more of that later)
• except “catches” these exceptions
• you do not have to catch exceptions (try/finally) is allowed. Finally block is executed no matter what!

# exec & eval¶

exec is a statement which executes strings as if they were Python code

In [ ]:
a = "print('checkit')"
print(a)

In [ ]:
exec(a)

In [ ]:
a = "x = 4.56"

In [ ]:
exec(a)

In [ ]:
print(x)

In [ ]:
exec("del x")

In [ ]:
print(x)

• dynamically create Python code (!)
• execute that code w/ implications for current namespace
In [ ]:
import math
while True:
bi = input("what built in function would you like me to coopt? ")
if bi in ('?',"",'end'):
break
nn = input("what new name would you like to give it? ")
exec("%s = %s" % (nn,bi))

In [ ]:
jsin(math.pi/2)


eval is an expression which evaluates strings as Python expressions

In [ ]:
x = eval('5')  ; print(x)             # x <- 5
x = eval('%d + 6' % x)  ; print(x)   # x <- 11
x = eval('abs(%d)' % -100) ; print(x) # x <- 100

In [ ]:
eval('if 1: x = 4') # INVALID; if is a statement, not an expression.


# Breakout¶

Write a code which generates python code that approximates the function: $$x^2 + x$$

hints:

• randomly generate lambda functions using a restricted vocabulary: voc =["x","x"," ","+","-","*","/","1","2","3"]

• evaluate these lambda functions at a fix number of x values and save the difference between those answers and x**2 + x

• catch errors!

import random
import numpy

voc =["x","x"," ","+","-","*","/","1","2","3"]

nfunc       = 1000000
maxchars = 10  # max how many characters to gen
eval_places = numpy.arange(-3,3,0.4)
sin_val     = eval_places**2 + eval_places
tries       = []
for loop...

In [ ]: