Try   HackMD

CS 1358 Introduction to Programming in Python SC11

tags: pythonSC

Definitions and Short Answers - functions

  1. In Python, ArithmeticError is a base class of FloatingPointError, OverflowError, and ZeroDivisionError. So,

    a. Does ArithmeticError inherit from FloatingPointError ? Or does FloatingPointError inherit from ArithmeticError?

    FloatingPointError inherit from ArithmeticError

    b. Does FloatingPointError inherit from OverflowError ? Or ZeroDivisionError? Or is there any inheritance relationship between them?

    No inheritance relationship between them

    c. Is ZeroDivisionError a superclass of ArithmeticError? Or the other way around?

    subclass

  2. Let a, f, o, and z respectively denote an instance of ArithmeticError, FloatingPointError, OverflowError, and ZeroDivisionError.

    a. Is a an instance of FloatingPointError?

    No

    b. Is f an instance of ArithmeticError?

    Yes

    c. Does z inherit from ZeroDivisionError? Or what is the correct word for the relationship?

    is an instance of ZeroDivisionError

    d. Does o inherit from ArithmeticError?

    No, it's an instance

  3. Which of the following evaluates to True?

    • isinstance(f, ArithmeticError)
    • isinstance(z, FloatingPointError)
    • isinstance(a, ZeroDivisionError)
    • issubclass(OverflowError, ArithmeticError)
    • issubclass(FloatingPointError, ZeroDivisionError)
    • issubclass(ArithmeticError, ZeroDivisionError)
  4. Suppose you want to define a class named MyList by subclassing from the built-in list class.

    ​​​​class MyList(list): ​​​​ def __repr__(self): ​​​​ return self.__class__.__name__ + '(' + _____ + ')'

    a. This class does not define the __init__() method. Does this mean you can't call MyList as a constructor? If you can call MyList as a constructor, what method is actually called?

    you can call MyList as a constructor. the arguments are the same as those you pass to a list() constructor. It inherits the constructor from its superclass, namely list's __init__() method.

    b. By defining the __repr__() method in MyList class, what happens to the base class's (i.e., list class's) __repr__() method? Is it replaced? Or does it continue to exist?

    both __repr__() exist. It is just shadowed while inside MyList. That is, MyList's __repr__ will be found first and used, but list's __repr__ continues to exist, unaffected and unmodified.

    c. How does MyList's __repr__() method invoke its superclass list's __repr__() method to render the actual list content as constructor argument?

    super().__repr__()

  5. If you define a find() method in MyList class
    a. does it need to call the list's find() method?

    no

    b. Does it automatically call list's find() method?

    no
    super().find(val)

  6. MyList's sort() method is defined as follows:

    ​​​​class MyList(list): ​​​​ #__repr__() and find() not shown ​​​​ def sort(self): ​​​​ D ={'NoneType': 0, 'int': 1, 'float': 1, 'str': 2, ​​​​ 'tuple': 3, 'list': 4} ​​​​ return super().sort(key=lambda x: \ ​​​​ (D.get(type(x).__name__, 5), x)), ​​​​ reverse=reverse) ​​​​ # additional definition not shown

    a. What does type(x).__name__ do? What is the value of

    type(3).__name__? 'int'
    type((12, 34)).__name__? 'tuple'
    type('hello').__name__? 'str'
    type({}).__name__? 'dict'

    b. Given the value of D defined on lines 4-5, what does D.get(k, v) do and how is it different from D[k]? What is the value of

    D.get(type(3).__name__, 5) 1
    D.get(type((12, 34)).__name__, 5) 3
    D.get(type('hello').__name__, 5) 2
    D.get(type([]).__name__, 5) 4
    D.get(type(3+2j).__name__, 5) 5
    D.get(type({}).__name__, 5) 5

    c. Let

    ​​​​k = lambda x:(D.get(type(x).__name__, 5),x) 
    ​​​​L = [7.4, 2, 'world', 'bye', (13, 24), (14, 28), None]
    

    then what is the value of list(map(k, L)) ?

    ​​​​[(1, 7.4), (1, 2), (2, 'world'), (2, 'bye'),\
    ​​​​(3, (13, 24)), (3, (14, 28)), (0, None)]
    

    list(sorted(map(k, L)))?

    ​​​​[(0, None), (1, 2), (1, 7.4), (2, 'bye'),\
    ​​​​(2, 'world'), (3, (13, 24)), (3, (14, 28))]
    
  7. In the revised version of MyList class's sort method,

    ​​​​  class MyList(list):
    ​​​​     # __repr__() and find() not shown
    ​​​​     def sort(self, key=None, reverse=False):
    ​​​​         D ={'NoneType': 0, 'int': 1, 'float': 1, 'str': 2,
    ​​​​             'tuple': 3, 'list': 4}
    ​​​​         return super().sort(key=lambda x: \
    ​​​​                        (D.get(type(x).__name__, 5), \
    ​​​​                        key(x) if key is not None else x),\
    ​​​​                      reverse=reverse)
    ​​​​    # additional definition not shown
    

    a. What is the meaning of line 9, reverse=reverse in this context?

    this is to pass a parameter by name. The callee list's parameter named reverse (left hand side of the equal sign) gets the value of the expression reverse, which is the caller's (i.e., MyList's sort()'s) parameter named reverse.

    b. If the caller does not pass a key parameter on line 3, then what is the value of the expression

    ​​​​lambda x: key(x) if key is not None else x
    
    ​​​​lambda x: x
    

    c. if the caller passes a callable object to the key parameter on line 3, then what is the value of the expression

    ​​​​lambda x: key(x) if key is not None else x
    
    ​​​​lambda x: key(x)
    
  8. In the ColorPoint class:

    ​​​​class Point:
    ​​​​    def __init__(self, x, y):
    ​​​​        self._x = x
    ​​​​        self._y = y
    ​​​​    def __repr__(self):
    ​​​​        return __class__.__name__ + \
    ​​​​            repr((self._x, self._y))
    ​​​​class ColorPoint(Point):
    ​​​​    def __init__(self, x, y, color):
    ​​​​        super().__init__(x, y)
    ​​​​        self._color = color
    ​​​​    def __repr__(self):
    ​​​​        return __class__.__name__ +\
    ​​​​            repr((self._x, self._y, self._color))    
    

    a. What is the purpose of line 10?

    calls the base class's constructor on the object being constructed to initialize the base class's attributes

    b. After line 10, what attributes are defined in self?

    self._x and self._y

    c. If ColorPoint class doesn't define its own __repr__ but instead chooses to inherit it, what will be printed on the line below?

    ​​​​>>> p = Point(2, 3)
    ​​​​>>> p
    ​​​​Point(2, 3)
    ​​​​>>> q = ColorPoint(4, 5, 'black')
    ​​​​>>> q
    
    

    Point(4, 5)

  9. What is the meaning of polymorphism in a programming language like Python? Does it mean an object can take on different names? Or does it mean a name can refer to one of different possible objects?

    means many models

  10. Why is the built-in str() considered an overloaded function?

    You can modify your __str__ method in class

  11. What is the meaning of operator overloading?

    You can modify the operator for your class

  12. To overload operators +, -, *, / for the Point class above, what do you have to declare?

    def __add__(self, B)
    def __sub__(self, B)
    def __mul__(self, B)
    def __truediv__(self, B)

  13. Assume x = 3, what are the values of the following expressions, if valid? If not valid, why not, and how can it be fixed?

    • x.__add__(2) x = 5
    • 2.__add__(x) SyntaxError: invalid syntax
    • x.__add__(2.) NotImplemented
    • 2..__add__(x) x = 5.0
  14. In the Vector class,

    ​​​​import operator as op
    ​​​​class Vector:
    ​​​​    def __init__(self, *v):
    ​​​​        self._v = list(v) # covert tuple to list
    ​​​​    def __repr__(self):
    ​​​​        return __class__.__name__+repr(tuple(self._v))
    ​​​​    def __add__(self, right):
    ​​​​        return Vector(*map(op.add, self._v, right._v)) 
    ​​​​    # op.add is same as lambda x,y: x+y
    ​​​​    def __sub__(self, right):
    ​​​​        return Vector(*map(op.sub, self._v, right._v))
    
    ​​​​x = Vector(1, 2, 3)
    ​​​​y = Vector(4, 5, 6)
    ​​​​z = x + y
    ​​​​i = id(x)
    ​​​​x += y
    ​​​​j = id(x)
    ​​​​print(i == j)
    
    

    a. When x = Vector(1, 2, 3) is called, what is the value of parameter v on line 3?

    (1, 2, 3)

    b. What is the equivalent method syntax when z = x + y is executed? In other words, the statement can be written in the form of
    z = object.method(arg)
    What are the object, method, and arg?

    z = x.__add__(y)

    c. By the time z = x + y finishes execution, how many times has the Vector constructor been called?

    3 times

    d. Does line 17 print True or False? Explain.

    False, we didn't define __iadd__

  15. In the previous problem, Python understands how to execute line x += y as x = x.__add__(y) So why would you ever need to overload the __iadd__(self, other) method? Isn't it redundant?

    it needs to construct another Vector, waste memory an d less efficient

  16. Assume x and y refer to the two Vector instances. In order to support the following operator syntax, what special methods must be defined in the Vector class, and what is the equivalent object.method(args) syntax? Fill in the last column of the table below.

    operator syntax example equivalent object.method(args) syntax
    indexing x[3] x.__getitem__(3)
    slicing x[2:5] x.__getitem__(slice(2, 5))
    indexed assignment x[1] = 5 x.__setitem__(1, 5)
    sliced assignment x[0:2] = (8, 6) x.__setitem__(slice(0, 2),(8, 6))
  17. Given that binary operators << and >> have lower precedence than binary operators + and -, and all are left associative, in what order does Python evaluate the expression m + n << p - q >> r

    • ((m + n) << (p - q)) >> r
    • (m + (n << p)) - (q >> r)
    • (m + n) << ((p - q) >> r)
    • m + ((n << p) - (q >> r))
  18. Both str() and repr() return a string of an object. What is their difference? Suppose you have x = 'hello\n', what is the value of

    ​​​​a. list(str(x)) == ['h', 'e', 'l', 'l', 'o', '\n'] 
    ​​​​b. list(repr(x)) == ["'", 'h', 'e', 'l', 'l', 'o', '\\', 'n', "'"]
    
  19. If you overload the len() special method in your Vector class, how does Python expect the user to call it on an instance v?

    ​​​​> len(v)