% class-9 talking points Announcements Next week is the last required meeting so we need to handle some admin matters. Speakers - We have 4 tonight, have several next week - 2 scheduled, need more, if you haven't scheduled a presentation tonight SEE ME in the breaks or after we adjourn. Make up class - Completely optional, just Q&A, I'll have nothing prepared. Let me know if you'd come and if so, when (in order of pref.) choices: Sat Dec 11 (this Sat am or pm) Sat Dec 18 (am only) Tues Dec 21, usual time. Due next week: Final portfolio progress report - what the state of completion is, how I should review it (give me hardcopy, URL, Google docs or whatever...) Self-evaluation - What you'd want me to say in recommendation, if someone asked "what did s/he do in your Python class?" A few sentences: experience/preparation coming in, your presentation, your portfolio, what you learned that you didn't know when you came in. There will also be an evaluation I will distribute that will go to UW (not me) - that's anonymous from my point of view - they will relay results to me but I won't see them. No more quizzes - My rationale is that we're done with the book -------- Lecture There's a huge number of advanced topics - we'll just look at three. I chose these to show the power and versatility of the language. We don't have time to go in depth but you should know these capabilities exist. 1. Extending the language seamlessly by definining new classes with special methods (vector case study) 2. Lazy evaluation ('just in time') using generators Allows 'infinite data structures' (generator case study) 3. Transform/generate code programmatically at load time (decorator case study) Python is a *programmable* programming language (due to 1,3 above especially) 1. Extending the language seamlessly by definining new classes with special methods (vector case study) vector.py inspired by numpy array and matrix types explain vectors - built in list + does the wrong thing, * crashes inherits from list - yes, we can inherit from built-in types! special methods: __repr__ redefines print etc, __add__, __mul__ redefine +, * Python itself is built from classes and objects, type means class, including the built-in types like list and int note constructor syntax: instead of [] or {}, can use list() or dict() object means instance (of a class) including even 2, try dir(2), sys.getsizeof(2) operator means special method 2 + 2 means int('2').__add__(int('2')) Dozens of special methods, including index and slicing for data structures 'class' is just another type, you could define your own: javaclass or ... This is called a metaobject protocol 2. Lazy evaluation ('just in time') using generators Allows 'infinite data structures' (generator case study) generator.py First demo range and xrange, show MemoryError range is eager - computes all the elements first xrange is lazy - computes each element as needed Sizes chosen to demo memory/speed limitations, may be different on your computer How does xrange work? Python generators code lazy computation, A generator is a function with "yield" instead of "return" generator resumes after yield when you next call it generator remembers program counter and values of local variables between calls raise StopIteration to indicate its done need *never* raise StopIteration - can simulate infinite data structures! Generator expression - shorthand for some generators notice how sum works with generator as well as list sum (and many other fcns) work with anything that observers Iterator protocol 3. Transform/generate code programmatically at load time decorator.py Recall there are usually two passes of computation: 1. first: import the module - usually execute def + class, but can do anything 2. later: use vars, fcns, classes defined at import time You can do arbitrary computations at import time including computations that transform or create code so you can call it later You can define a new function *in a function* and return that function addn in decorator.py You can pass a function as an argument and use that to construct the new function you return sieve in decorator.py The decorator construct formalizes that @sieve in decorator.py Note we can call *any* function a seive by prefixing @sieve memoize - a realistic example motivation: some fcns take a long time to compute, so save results to use over store in dict whose keys are function args and values are function results before call, look up args in dict and either retrieve or call and store Need separate dict for each function, seems like a lot of repetitious coding Decorators to the rescue! How can we use decorator to store information? Can't just have the result of decoration be a function - no permanent storage A decorator can also be a class because classes and objects are callables too call a class to execute its __init__, call an object to execute its __call__ memoize in decorator.py