Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

CS1010S Tutorial 8

Message Passing & Stateful Objects


Quick Recap: Dictionary

- d.items() -> Returns a sequence of 2-element tuples, first element


being the key, second being the value
- d.keys() -> Returns a sequence of keys
- d.values() -> Same but for values
- d[key] -> Returns the value associated with this key. O(1)
- d[key] = value -> Assigns value to the key. O(1)
- e.g

d[1] = 2

print(d[1]) -> 2
Quick Recap

- Keys can only be IMMUTABLE values. i.e no list/dictionary

- def f(*args):

args is a tuple of whatever the arguments are, can be any number


of arguments

e.g f(1,2,3,4,5,6,7,8,9,10) is valid and args will be (1,2,3,4,5,6,7,8,9,10)

f() -> args will be ()


Q1
Q1
Widget returns the 2nd last item that was inserted. If there isn’t one then
returns ‘empty’

b) How do we insert 1, 2 and then 3 into the widget?


Q1

widget = make_widget()
widget("insert", 1)
widget("insert", 2)
widget("insert", 3)

c) What is returned when we retrieve from the widget thrice?


Q1

2
Q2

>>> A = make_accumulator ()
>>> A ( 10 )
10
>>> A ( 10 )

20
Q2

def make_accumulator():

def helper(n):

return helper
Q2

def make_accumulator(): Does this work?


result = 0
def helper(n):
result = result + n
return result
return helper
Q2

def make_accumulator():
result = [0]
def helper(n):
result[0] = result[0] + n
return result[0]
return helper
Q3
>>> s = make_monitored ( sqrt )
>>> s ( 100 )
10 . 0
>>> s ("how -many - calls ?")
1
>>> s ( 1024 )
32 . 0
>>> s ("how -many - calls ?")
2
>>> s ("reset - count ")
>>> s ("how -many - calls ?")
0
Q3

def make_monitored(f):
state = 0
def mf(msg):
if msg == "how-many-calls?":
return state
elif msg == "reset-count":
state = 0
else:
state = state + 1
return f(msg)
return mf
Q3

def make_monitored(f):
state = 0
def mf(msg):
nonlocal state
if msg == "how-many-calls?":
return state
elif msg == "reset-count":
state = 0
else:
state = state + 1
return f(msg)
return mf
Q3
make_monitored for such
functions with more args?
def sum_numbers (* numbers ):
s=0
for n in numbers :
s += n
return s
>>> sum_numbers (1 ,2 , 3 )
6
>>> sum_numbers (1 ,2 ,3 ,4 , 5 )
15
Q3

else:
state[0] = state[0] + 1
return f(*args)
Q4
Monte-carlo Integration

This new function accepts the following commands:

(a) "run trials" and a number of trials to run and performs the stated
number of trial.

(b) "trials" will return the number of trials run thus far.

(c) "get estimate" to return the current estimate given the trials run so far.
Q4
def make_monte_carlo_integral(P,x1,y1,x2,y2):
count = [0,0]
area = abs(x2-x1)*abs(y2-y1)
def oplookup(msg,*args):
if msg == "run trials":
for i in range(args[0]):
if P(random.uniform(x1, x2),random.uniform(y1, y2)):
count[0] += 1
count[1] += 1
elif msg == "trials":
return count[1]
elif msg == "get estimate":
return area * count[0]/count[1]
return oplookup
Q5

Make use of dictionary to create a character translator function translate. It


takes 3 strings as arguments: translate(source, destination, string). source
contains the set of characters you want "translated", destination contains
the set of characters to translate to, and string is the string to perform the
translation on.

For example:

>>> translate (" dikn "," lvei ","My tutor IS kind ") "My tutor IS evil "
Q4

def translate(source, dest, base):


dic = {}
for i in range(0, len(source)):
dic[source[i]] = dest[i]
return "".join(map(lambda c: dic[c] if c in dic else c, base))
Q4
Q4
def caesar_cipher(shift, str):
s = shift % 26
l, c = string.ascii_lowercase, string.ascii_uppercase
tl = l[s:] + l[:s]
tc = c[s:] + c[:s]
return translate(l + c, tl + tc, str)
def caesar_cipher(shift, string):
def shift_char(c):
new_ord = ord(c) + shift%26
if new_ord > ord('z') or (ord(c) <= ord('Z') and new_ord > ord('Z')):
new_ord -= 26
return chr(new_ord)
return "".join(map(shift_char, string))

You might also like