#!/usr/bin/env python # coding: utf-8 # # Advanced Interactions # # # ### 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) flights = [("Southwest",145,"DCA",1,6.00),("United",31,"IAD",1,7.1),("United",302,"LHR",5,6.5),\ ("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 # # ```python # 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 \"!@!@$@!\"" "".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)) get_ipython().run_line_magic('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[ ]: get_ipython().run_line_magic('pinfo', 'reduce') # In[ ]: # sum() is a built in function...it’s bound to be faster get_ipython().run_line_magic('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'] for a,q in zip(questions, answers): 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 # # instead of ... # 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 # # ```python # 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! # # - start with a file like: # # ```python # 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[ ]: