61A Lecture 12Monday, September 26Implementing DiceRandom numbers are useful for experimentationThey also appear in lots of algorithms, e.g.,•Primality tests•Machine learning techniques2def make_dice(sides=6): seed = 1 def dice(): nonlocal seed seed = (16807 * seed) % 2147483647 return seed % sides + 1 return dice231 - 1S.K. Park and K.W. Miller, " Random Number Generators: Good Ones Are Hard To Find", Communications of the ACM, October 1988, pp. 1192-1201.http://www.math.utah.edu/~pa/Random/Random.htmlReferential Transparency, Lost• Expressions are referentially transparent if substituting an expression with its value does not change the meaning of a program.3• Re-binding operations violate the condition of referential transparency because they let us define functions that do more than just return a value; we can change the environment, causing values to mutate.mul(add(2, mul(4, 6)), add(3, 5))mul(add(2, 24 ), add(3, 5))mul( 26 , add(3, 5))Demomake_container('Hi')Implementing a Mutable Container Object4def make_container(contents): def get(): return contents def put(value): nonlocal contents contents = value return get, putget, put = make_container('Hi')make_container(contents):make_container:...contents: 'Hi'def get():def put():return get, put......make_containerget():return contentsget:put(value):nonlocal contentscontents = valueput:put:get:,DemoPython Lists['Demo']5http://docs.python.org/py3k/library/stdtypes.html#mutable-sequence-typesSharing and Identity with Lists6suits = ['!', '"', '#', '$']nest = list(suits)nest[0] = suitsnest[0][2]suits.append('Joker')nest[0].pop()nest:01 2 3suits:! "#$0 1 2 3Joker4Testing for Identity7suits:nest:! "#$01 2 30 1 2 3>>> suits is nest[0]True>>> suits is ['!', '"', '#', '$']False>>> suits == ['!', '"', '#', '$']TrueList Comprehensions8>>> suits = ['heart', 'diamond', 'spade', 'club']>>> from unicodedata import lookup>>> [lookup('WHITE ' + s.upper() + ' SUIT') for s in suits]['%', '&', ''', '('][<map exp> for <name> in <iter exp> if <filter exp>]Short version: [<map exp> for <name> in <iter exp>]Unlike generator expressions, the map expression is evaluated when the list comprehension is evaluated.Dispatch FunctionsA technique for packing multiple behaviors into one function9 def make_pair(x, y): """Return a function that behaves like a pair.""" def dispatch(m): if m == 0: return x elif m == 1: return y return dispatchMessage argument can be anything, but strings are most commonThe body of a dispatch function is always the same:•One conditional statement with several clauses•Headers perform equality tests on the messageA Mutable Container That Uses Message Passing10def make_container(contents): def get(): return contents def put(value): nonlocal contents contents = value return get, putdef make_container_dispatch(contents): def dispatch(message, value=None): nonlocal contents if message == 'get': return contents if message == 'put': contents = value return dispatchDemoImplementing Mutable Recursive Lists11 def make_mutable_rlist(): contents = empty_rlist def dispatch(message, value=None): nonlocal contents if message == 'len': return len_rlist(contents) elif message == 'getitem': return getitem_rlist(contents, value) elif message == 'push_first': contents = make_rlist(value, contents) elif message == 'pop_first': f = first(contents) contents = rest(contents) return f elif message == 'str': return str(contents) return dispatchRecursive List Refresher
View Full Document