ECE326 – Fall 2019: Week 2 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. Assignment in Python is always by reference. T F

2. Dynamically typed languages do not perform type checking. T F

3. global keyword is required to read a global variable from inside a function. T F

2. Multiple Answers [2 marks each]

Pick all answers that are correct. You will lose 1 mark per wrong choice, down to 0 marks. 1. Which of the following operations are allowed inside a pure function?

(a) Read from a constant global variable (b) Read from a static function variable () Modify a local variable () Call print function to write to console (e) Call another pure function

2. In Python 3, print returns the string it printed to screen. Which is the following is true?

(a) print is a statement (b) print is an expression (c) you can assign print to a variable, i.e. a = print (d) you can pass print to a function, i.e. foo(print) (e) you can assign a value to print, i.e. print = 5

3. Short Answers

1. What does this expression evaluate to? [2 marks]

>> { b : a for a, b in enumerate(“HELLO”) }

2. What slice of the word “washington” will give the result of “ogisw”? (Give answer in the form [i:j:k])

4. Programming Question [10 marks]

Write a function reverse_dict() that will reverse keys and values such that the original values become the new keys to lists of one or more values that were the original keys. For example:

{“bob”: 2, “greg”: 3, “joe”: 2, “tom”: 1, “dave”: 2, “stu”: 3, “mike”: 5} becomes:

{ 1: [“tom”], 2: [“bob”, “joe”, “dave”], 3: [“stu”], 5: [“mike”] }

ECE326 – Fall 2019: Week 3 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. Overloading virtual functions in C++ is an example of multiple dispatch. T F

2. You can declare an opaque on the stack. T F

3. Pure are not necessarily pure functions. T F

4. A virtual function overloading an operator is an example of dynamic dispatch. T F

5. Dynamically-typed interpreted language cannot implement early binding. T F

2. Short Answers

1. Override the eat method in Animal so that the eat method in Dog will, in addition to what Animal.eat already does, print “Wags its tail” at the very end. Show the entire class definition for Dog. [3 marks]

class Animal: … # may change this function in the future def eat(food): print(str(food) + “ is delicious”)

2. Write an expression with equivalent result as the following list comprehension, using only the map and filter function for control flow. [2 marks]

[ str(v) for v in range(10, 100) if not (v//10+v%10)%7 ]

3. Prototype-based Programming [10 marks]

In Prototype-based programming, all objects have the type Object. The base object initially has no attribute. We wish to program with this paradigm in Python. Create a Person object out of the base object, followed by inheriting from the Person object to create a Student object. Finally, make an instance of Student. A Person object should have the data attributes: name, age, and gender, with a method called birthday() that increments age. A Student object should have the data attributes: id, gpa, and year. Create an instance of Student named “me” with your credential (can be fake). Choose suitable defaults for the prototypes.

class Object: pass base = Object()

4. Virtual Tables [10 marks] a. For the following inheritance hierarchy, draw a virtual table for each class and draw an arrow from each entry in the virtual table to their definition in the C++ classes. [7 marks] struct A { virtual void foo() { cout << “A.foo”; } virtual void bar() { cout << “A.bar”; } void baz() { cout << “A.baz”; } };

struct B : public A { virtual void bar() { cout << “B.bar”; } };

struct C : public B { virtual void foo() { cout << “C.foo”; } void baz() { cout << “C.baz”; } };

struct D : public A { virtual void foo() { cout << “D.foo”; } void baz() { cout << “D.baz”; } };

b. What is the output of the following program? [3 marks]

D d = D(); C c = C(); A * ad = &d; A * ac = &c; ac->baz(); ad->foo(); ac->bar();

ECE326 – Fall 2019: Week 4 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. With C3 Linearization, Python completely solves the diamond problem. T F

2. 0x8888FEDC is a 4- aligned address. T F

3. Suppose class A is inherited by class B, and C, monotonicity guarantees that A will behave the same for both B and C. T F

4. Adding a new pure virtual function to a base class with many existing derived classes is an example of a fragile base class problem. T F

5. The main difference between delegation and type embedding is that with type embedding, you can no longer reference the embedded member by name. T F

2. Multiple Answers [2 marks each]

Pick all answer(s) that are correct. You will lose 1 mark per wrong choice, down to 0 marks. 1. Which of the following are true about mixins?

(a) It requires subclass to complete its implementation. (b) It can contain both member variables and functions. (c) It is used as a super type to the derived class. (d) Using it requires method forwarding. (e) The order in which mixins are composed may change behaviour of the subclass.

2. Java only supports single inheritance with runtime polymorphism. Which of the following is true?

(a) Java does not support mixins. (b) Java does not need virtual tables. (c) Casting pointers (internally, Java does not expose pointers to programmers) in Java will never require point offsetting. (d) Java does not need to deal with inheritance-related ambiguity. (e) Java does not have method resolution order. 3. Virtual Base Class in C++ [10 marks]

Draw the data layout of class X (include padding assuming 8-byte alignment, and write down the size of each sub-structure) and all the virtual tables generated for class X and its ancestors. struct B { int b1; int b2; virtual void foo() { cout << “A.foo”; } virtual ~A() {} }; struct P : virtual public B { long p1; virtual void foo() override { cout << “P.foo”; } }; struct Q : public P { int q1; }; struct N : virtual public B { char n1[30]; }; struct X : public N, public Q { int x1; virtual void foo() override { cout << “X.foo”; } };

4. Method Resolution Order [10 marks]

a. For the following inheritance hierarchy in Python, draw a diagram of the hierarchy. [2 marks]

class A: pass class B: pass class C: pass class D: pass class E: pass class P(A, B, C): pass class Q(D, B, E): pass class R(D, A): pass class X(P, R, Q): pass

b. What is the C3 Linearization of X? [8 marks]

ECE326 – Fall 2019: Week 5 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. is a subset of metaprogramming. T F

2. If no deep copy is required (e.g. class has no pointer), move semantics performs no better than copy semantics. T F

3. If specialization is not used (i.e. not instantiated), its code is not generated for the final executable. T F

4. For template T foo(), you can write int a = foo() to instantiate the function template foo with an int parameter . T F

5. The new operator in C++ couples heap allocation and constructor invocation. T F 2. Short Answers

1. Use container_of to return a pointer to the parent object of member field base. [2 marks]

struct base { int x, y, z; };

struct derived { int a; struct base b; char c[10]; };

struct derived * get_derived(struct base * b) {

} 2. Implement binary search algorithm using a function template, assume swap template function has already been implemented and the array is sorted. [5 marks] template /* find index of val in array of size n */ int binary_search(const T & val, T * array, int n) {

} 3. Implement a template class named Triple that is a tuple of 3 elements of the same type. Overload enough operators so that binary search template you implemented above can be instantiated for Triple. Use lexicographical order. [5 marks] template class Triple {

}; 3. Generic Programming [10 marks]

Create a generic Queue class without using templates. Implement the Queue using a singly linked list, with the member functions, push_back, that pushes new elements to end of the queue, front, which returns the first element of the queue, and pop_front, which removes the first element of the queue.

4. Template Programming [10 marks]

Using the generic Queue made in Question 3, write a FIFO class template, which allows type- safe use of the generic Queue class for any parameterized type. Use move semantics for push_back instead of copy semantics.

ECE326 – Fall 2019: Week 6 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. In Python, types are reified at runtime. T F

2. The decorator function is called every time the decorated function is called. T F

3. C++11 supports static reflection. T F

4. In multiple inheritance, TypeError is raised when there is a shared base . T F

5. type is to classes as object is to instances. T F

2. Multiple Answers [2 marks each]

Pick all answer(s) that are correct. You will lose 1 mark per wrong choice, down to 0 marks. 1. Which of the following statements about descriptors or properties are true?

(a) A descriptor can manage multiple attributes at once, a property can only manage one. (b) A descriptor with only __get__ can be overwritten or deleted, a property with only getter cannot. (c) A descriptor can manage a method, a property cannot (data attribute only). (d) A descriptor keeps data within its own instance, a property uses that of the parent instance. (e) A descriptor with only __set__ has the same behaviour as a property with only setter.

2. Which of the following statements about class decorators or are true?

(a) Both class decorators and metaclasses require only a callable object to work. (b) Both class decorators and metaclasses must return a class (new or existing). (c) Class decorators do not support inheritance, metaclasses do. (d) Class decorators modifies a class only after it is created, metaclasses modifies a class only before and during class creation. (e) Metaclass is the only way to overload operators for classes.

3. Decorator [10 marks]

Create a decorator, memoize, that will cache results of the decorated function. You may assume: 1. The decorated function will be a pure function. 2. Only positional arguments are used by the decorated function, no keyword arguments. 3. All arguments are hashable types

4. Metaclass [10 marks]

Write a metaclass, MethodCounter, that will add the functionality to a class such that it counts how many times a method is called by any instance of the class. For example, if a called foo twice and b called foo once, then the count for foo should be three (both a and b are instances of the class that inherits your metaclass). Remember that it should keep a separate count for each method. Hint: use the built-in function callable to check if an attribute is callable.

5. Descriptor [10 marks]

Write a descriptor that will check the type and the range of the managed attribute before allowing it to be stored. The descriptor should also disallow deletion of the managed attribute. Here is how your descriptor is used: class Foo: likelihood = Attr(type=float, minimum=0.0, maximum=1.0) Note that omitting any one of the checks results in not making that check. For example, if type is omitted, then type checking is disabled. Similarly, if maximum is omitted, then upper bound is unlimited (not checked). Raise AttributeError if the check fails.

ECE326 – Fall 2019: Week 7 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. A covariant tuple parameter is always type-safe. T F

2. Widening conversion guarantees you can get back the original data if needed. T F

3. In C++, type inference for variable declaration (using the auto keyword) cannot fail. T F

4. systems do not have knowledge of the underlying . T F

5. explicit keyword is used to prevent implicit conversion of class objects when the class overloads the cast operator. T F

2. Short Answers

1. Give an example to show that contravariant function return type is not type safe. [2 marks]

2. What is the value of the following expression? What is the name of the behaviour? Assume the integer is 32-. [2 marks] int a = 1 << 31; printf(“%d”, -a);

3. Write a safe C macro, CIRCLE_AREA, that takes one parameter and will calculate the radius of a circle. You also need to define the constant PI. [3 marks]

4. Write the precondition and postcondition for the square root function, sqrt() that takes in a double and returns a double. Suppose Complex is a subclass of double, what’s the variance relationship between double sqrt(double) and Complex sqrt(Complex)? [3 marks]

3. Tagged Union [10 marks]

Complete the implementation of the tagged union example from class by adding a copy constructor, overload the equality operator, and type-safe getter/setter function

struct Tagged { enum { INT, STR } tag; union { // anonymous union (members int * i; // can enter parent scope) string * s; }; Tagged(int i) : tag(INT), i(new int(i)) {} Tagged(const char * s) : tag(STR), s(new string(s)) {} ~Tagged() { if (tag == INT) delete i; else delete s; }

Tagged(const Tagged & rhs) {

}

bool operator==( const Tagged & rhs) {

}

const string * get_str() const {

}

void set_str(const string & s) {

} }; ECE326 – Fall 2019: Week 8 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. C macro functions always produce syntactically correct C/C++ code. T F

2. Once a macro is used, it cannot be used during the same macro expansion. T F

3. To prevent infinite recursion, it is not possible for concatenation to form a token that can be used as a macro. T F

4. The main benefit of optional compilation over inheritance is performance (speed). T F

5. Clever use of C preprocessor macro allows for static introspection. T F

6. A constexpr function or variable is exclusively for compile-time use. T F

2. Generic Programming [10 marks]

Use C macros instead of template programming to generate a Stack class of generic element type. Your stack should be type safe and should have the pop and push member functions. Assume input will be an unadorned type (not a pointer, not a reference, not const or other qualifiers).

// creates a class named IntStack with integer elements DEFINE_STACK(IntStack, int);

// creates a class named ComplexStack with Complex elements DEFINE_STACK(ComplexStack, Complex);

3. Compile-Time String [10 marks]

Write a compile-time class, ConstStr, which provides the following three compile-time methods: 1) hash(), which returns a djb2 hash of the string (http://www.cse.yorku.ca/~oz/hash.html), 2) startswith(substr), which only returns true if the string starts with the substring substr, and 3) endswith(substr), which only returns true if the string ends with the substring substr.

4. C Macro [5 marks]

The PP_NARG macro can count the number of arguments that is passed into the maco function. However, it doesn’t work correctly if no arguments are passed in. Fix the macro so that it also supports no arguments.

#define PP_NARG(...) PP_NARG_(__VA_ARGS__, PP_RSEQ_N()) #define PP_NARG_(...) PP_ARG_N(__VA_ARGS__) #define PP_ARG_N( _1, _2, _3, _4 _5, _6, _7, _8, _9, N, ...) N #define PP_RSEQ_N() 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

ECE326 – Fall 2019: Week 9 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. Type traits in C++ is an example of reflective programming. T F

2. Unevaluated context means the expression cannot be evaluated (i.e. is ill-formed). T F

3. To use an integer vector iterator inside a template, the type of the iterator is specified as typename vector::iterator. T F

4. C++ type checks code even if it is unreachable. T F

5. Non-template functions that take variable number of arguments have precedence over base template functions that accepts any type T. T F

2. rm_const [5 marks]

Complete the implementation of rm_const, which remove const from type T if T is const-qualified (meaning that const is part of T, e.g. const int).

// becomes int cout << std::is_const::type>::value << endl;

// still int cout << std::is_const::type>::value << endl;

3. is_ptr [7 marks]

Complete the implementation of is_ptr, which checks whether the type T is a pointer or not. You must be able to handle a const pointer (e.g. int * const). Hint: rm_const may be helpful.

template is_ptr; cout << is_ptr::value << endl; // 0 cout << is_ptr::value << endl; // 1 cout << is_ptr::value << endl; // 1 cout << is_ptr::value << endl; // 0 cout << is_ptr::value << endl; // 1

4. can_equate [5 marks]

Write a C++ template, can_equate, which checks whether type T can be equal to type U. You must handle the situation when either T or U overloads the == operator.

ECE326 – Fall 2019: Week 10 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. It is not possible to cause infinite recursion when working with variadic template. T F

2. In general, arguments to variadic functions are not type-checked. T F

3. In Rust, name aliasing is not allowed. T F

4. Rust is strongly typed. T F

5. In Rust, ownership is a mechanism to check for memory leaks at runtime. T F

6. The major disadvantage of Rust is that it automatically adds runtime type safety checks, which negatively affects its runtime performance. T F

2. Short Answer [5 marks]

What’s the difference between the following two sets of statements?

// 1 let x = 5; let x = x + 2; let x = x * 3;

// set 2 let mut x = 5; x = x + 2; x = x * 3;

3. Variadic Template [10 marks]

Write a variadic template that calculates the population variance of a set of values. The return type of the template should always be double, but the template arguments can take any numeric type. https://en.wikipedia.org/wiki/Variance

ECE326 – Fall 2019: Week 11 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. In Rust, literals are first class citizens. T F

2. Box forces the contained object to be heap allocated. T F

3. A mutable object can be modified even if an immutable reference of it is in scope. T F

4. After transferring ownership, an can become mutable. T F

5. Generics in Rust supports duck typing. T F

2. Match [10 marks]

Create a function named hand_score which takes a tuple of two characters and returns the score of a blackjack hand using ONLY the match expression. You need to handle soft hands (e.g. A8 = 19) and hard hands. Return 21 for Blackjack. Assume the card values have been sanitized (do not check for invalid card). Hint: is_digit() and to_digit() may be helpful. https://doc.rust-lang.org/std/primitive.char.html

fn hand_score(hand: (char, char)) -> u32

3. Structure and Method [20 marks]

Write structure named Matrix which supports a 2x2 matrix of type f64, and implements the determinant method, the transpose method, and the inverse method. The transpose method should modify the existing matrix, but the inverse method should return a new matrix if the matrix is invertible, otherwise it should return None (Hint: use Option). Write a new static method which creates and initializes the matrix. Implement the Display trait for Matrix.

4. Generic Function [10 marks]

Write a generic function, sum_of_squares, which calculates the sum of squares of a generic array slice. Hint: you may need some trait bounds. ECE326 – Fall 2019: Week 12 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. Lifetime parameter must be added to all structures with non-static references. T F

2. Lifetime elision optimizes the binary by eliminating the need to copy parameters. T F

3. Concurrent programming helps reduce bugs by organizing code into independent threads of execution. T F

4. On a uniprocessor, it is safe to use Rc instead of Arc. T F

5. In Java, the synchronized operator enables synchronization between threads. T F

2. Channel [10 marks]

Use mpsc::channel and multiple threads to improve the performance of large square matrix multiplication.

3. Dining Philosopher [10 marks]

In the dining philosopher problem, there are N philosophers and N chopsticks in between each pair of philosophers. As you may know, you need a pair of chopsticks to be able to eat. A philosopher must successfully acquire both chopsticks to his/her left and right before proceeding to eat. Simulate this problem by creating one thread per philosopher, and use a monitor to synchronize the use of chopsticks.

4. Findall [10 marks]

Write a function that takes two string slices, text and word, and return a vector of all occurrences of the word in text in string slices. Note, you may need to “fix” the function signature. You may assume the text to consist of only ascii characters.

fn findall(text: &str, word: &str) -> Vec<&str>; ECE326 – Fall 2019: Week 13 Exercise Questions

1. True or False [1 mark each]

Circle T is true, otherwise circle F for false.

1. Trait objects can only be created on the heap. T F

2. Both C++ and Rust allows specifying the return type of arithmetic operations. T F

3. Generally speaking, a chain of iterator adapters should end in collect or fold. T F

4. In C++, closures and functions can be used interchangeably. T F

5. In a multithreaded setting, mutually recursive functions must implement mutual exclusion. T F

6. A generator cannot have the return statement. T F

2. Average of Shapes [10 marks]

Implement the Shape trait for Rectangle, Circle, and Triangle. The Shape trait has one method, area, which returns the area of the shape. Write a function which takes a list of shapes and returns the average area.

fn average_area(list: &Vec>) -> f64;

3. Coroutine [10 marks]

Write a Python function, ppmt, which returns the payment on principal for a given period for a loan based on periodic, constant payments and a constant interest rate. In addition, at any time, the user can make either lump sum payment or take out additional loan, which would cause the next payment to change based on remaining period.

# rate: interest rate (e.g. 0.0375 for 3.75% per period) # per: number of periods # pv: initial principal value on loan def ppmt(rate, per, pv)

loan = ppmt(0.0375, 240, 1000000) first_payment = next(loan) # e.g. taking out additional loan second_payment = loan.send(50000)