Suggested Homework #6 (for Quiz #6 on 02/26/08)

Consider the Python code below:

class Count:
  ctr = 0
  def __init__(self,init,fnext):
     self.ctr = init
     self.n = fnext

  def nextValue(self):
     return self.n(self.ctr)
     
  def next(self):
     self.ctr = self.nextValue()
     return self.ctr

class DCount(Count):
  def nextValue(self):
     return self.n(self.n(self.ctr))


c = Count(1,lambda x: x + 1)
d = DCount(1,lambda x: 2*x)
c.next()
d.next()
f = d.next

r1 = DCount.ctr
r2 = c.ctr
r3 = d.ctr
r4 = f()
r5 = Count.next(d)

def accelerate(C,n):
  class aC(C):
     def next(self):
	 for i in range(n): C.next(self)
	 return self.ctr
  return aC

E = accelerate(Count,5)
e = E(0,lambda x: x + 1)


r6 = e.nextValue()
r7 = e.next()

(a) What are the attributes of the namespace Count ?
(b) What are the attributes of the namespace DCount ?
(c) Which class is the super class, which class is the subclass ?
(d) Which methods does the subclass inherit from the superclass ?
(e) Which methods of the superclass get overridden by the subclass ?
(f) What are the values of r1,r2,r3,r4,r5 ?
(g) Describe the input and output of the function accelerate ?
(h) What are the values of r6,r7 ?


Problem 2:

Consider the Python code below:


def checkargtype(id,type):
  def decorator(f):
    def decorated(*args):
      if not(isinstance(args[id],type)):    
        raise Exception("Arg %d (%s) not of type %s" % (id,repr(args[id]),repr(type)))
      return f(*args)
    decorated.__name__ = f.__name__
    return decorated
  return decorator

def checkreturntype(type):
  def decorator(f):
    def decorated(*args):
      rv=f(*args)
      if not(isinstance(rv,type)):
          raise Exception("Return value (%s) not of type %s" % (repr(rv),repr(type)))
      return rv
    decorated.__name__=f.__name__
    return decorated
  return decorator    





@checkargtype(0,str)
@checkreturntype(type(None))
def printstring(s):
    print s

@checkargtype(0,list)
@checkargtype(1,int)
@checkargtype(2,str)
@checkreturntype(tuple)  # tuple here refers to the tuple type
def foo(s1,n,s2,f):
    return f([s1*n,s2])

What is the output (what is printed, what is returned, and what, if any, exceptions are raised) for each of the following (you may want to experiment a little with the tuple function before trying these out):

>>> printstring("foo")
>>> printstring(1)
>>> printstring()
>>> foo([1,2,3],2,"test",tuple)
>>> foo([1,2,3],"hmm...","test",tuple)
>>> foo({},{},{},{})