Computer Science 15-112, Fall 2011
Class Notes:  Practice (through week 11 (recursion, functional programming, object-oriented programming))


  1. Using lambda fn’s with closures): eliminate global canvas
    Here is the original events-example1.py, and then the same example without a global canvas (in events-example1-sans-global.py).  Start with the first and walk through how to derive the second, global-free version.  The steps are detailed in a comment in the second example, and are here, too:
    # changes to not use a global canvas:
    # 1) Do not declare "global canvas" in run() (of course)
    # 2) Make canvas an argument to all relevant functions:
    #    (including init, timerFired, mousePressed, keyPressed, redrawAll)
    #    (and including canvas.after call to timerFired...)
    # 3) In root.bind, we have to fix this problem: the functions that get
    #    bound may only take one argument -- the event -- but now we need
    #    to supply 2 arguments -- the event and the canvas.  We fix this
    #    by providing a lambda function that uses the canvas in a closure.
    #    See the bind calls in run() for details.
     
  2. (OOP application):  Add motion to the adventure game from class
    Here is the partialAdventure0.py code we wrote in class yesterday.  And here is partialAdventure1.py including movement (doGo).  Start with the first, and walk through how to derive the second.  To do this, have each room contain a dictionary (room.exits) mapping a direction to the target room in that direction.  See the code for details.
     
  3. Add a context-specific behavior to the game
    This isn’t OOP-y, but is fun and useful.  The partialAdventure1.py game also includes this behavior:  if you are in the dungeon and carrying the key, only then may you unlock the chains, at which point the skeleton, now freed, moves to the kitchen.  (note that the way we find the kitchen in doUnlock is a bit dicey, but works…)
     
  4. Some recursion tracing
    #medium
    def f(a):
        if (len(a) == 0):
            return []
        else:
            return [a[len(a)/2]] + f(a[:len(a)/2])
     
    # find a value of a so that f(a) returns [1,2,3]
    # sample answer below (***)

     
    #harder
    def f(a, depth=0):
        print "  "*depth, "f(%s,depth=%d):" % (str(a), depth)
        if (type(a) == int):
            result = a
        else:
            result = sum(map(lambda a: f(a, depth+1),a))
        print "  "*depth, "-->", result
        return result       
     
    # what does the following print?  (Be precise, line by line)
    print f([1,[2,[3]],4])


    # sample answer to first problem (***) print f([3, 2, 1, 42])

carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem