Python Assignment– 5

Object-Oriented Python

Basic Questions

  1. Define a class ‘Point’ with an ‘init(self, x, y)’ and create two objects; print their ‘x’ and ‘y’ attributes.
  2. Add an instance method ‘move(self, dx, dy)’ to ‘Point’ that updates coordinates; call it and print the new position.
  3. Add a class attribute ‘count’ to class ‘User’ that tracks how many objects were created in ‘init’; print ‘User.count’ after making three users.
  4. Add a ‘classmethod’ ‘from_fullname(cls, full)’ in ‘User’ that splits ‘full’ into ‘first’ and ‘last’ and returns an instance; demonstrate the call.
  5. Add a ‘staticmethod’ ‘is_valid_email(email)’ to ‘User’ that returns ‘True’ if ‘@’ is present; test it without creating an instance.
  6. Demonstrate encapsulation by creating class ‘BankAccount’ with public ‘owner’, protected ‘_balance’, and private ‘__pin’; print ‘owner’, read ‘_balance’, and show that ‘__pin’ is name-mangled by printing ‘dir(obj)’.
  7. In ‘BankAccount’, implement ‘deposit(self, amount)’ and ‘withdraw(self, amount)’ that change ‘_balance’; print the balance after each call.
  8. Create class ‘Animal’ with method ‘speak(self)’ that prints a generic message; subclass it as ‘Dog’ overriding ‘speak’ to print ‘woof’; call both.
  9. In ‘Dog.init’, call ‘super().init()’ from a base ‘Animal’ that sets ‘species’ and print ‘species’ from ‘Dog’ instance.
  10. Create a multilevel inheritance chain ‘A -> B -> C’; each has method ‘who(self)’ printing its class; show method resolution by calling ‘who’ on ‘C’.
  11. Create two base classes ‘Flyer’ and ‘Swimmer’ with methods ‘move(self)’; make ‘Duck(Flyer, Swimmer)’ and show which ‘move’ runs using ‘super()’ and MRO.
  12. Write a hierarchical inheritance: base ‘Shape’ with method ‘area(self)’; subclasses ‘Square’ and ‘Circle’ each implement ‘area’; call on both.
  13. Demonstrate duck typing: write function ‘make_sound(obj)’ that calls ‘obj.speak()’; pass instances of ‘Dog’ and a custom ‘Robot’ with a ‘speak’ method.
  14. Implement operator overloading for ‘Point’: define ‘add(self, other)’ to add coordinates and return a new ‘Point’; test ‘p3 = p1 + p2’.
  15. Add ‘str’ to ‘Point’ to return like ‘(x, y)’; print a point to see human-readable output.
  16. Create class ‘Bag’ that stores items list and implements ‘len’ to return item count; show ‘len(bag)’.
  17. In ‘Bag’, implement ‘getitem(self, idx)’ to index into internal list; show slicing also works by returning a new ‘Bag’ for slices.
  18. Build a class ‘Library’ that contains many ‘Book’ objects (composition); add method ‘add_book(self, book)’ and ‘list_titles(self)’; demonstrate usage.
  19. Show composition vs inheritance: make ‘Car’ with a ‘Engine’ object attribute and a method ‘start’ that delegates to ‘engine.start()’; print call flow.
  20. Implement simple private data: in ‘Profile’, store ‘__password’ and provide methods ‘set_password’ and ‘verify(password)’; prove that direct access to ‘__password’ fails.

Intermediate Questions

  1. Extend ‘BankAccount’ to print a warning from ‘withdraw’ if the result would be negative and prevent it; test with valid and invalid withdrawals.
  2. Add a ‘classmethod’ ‘from_dict(cls, data)’ to ‘User’ that builds an instance from a dictionary and increments ‘count’; test it.
  3. Implement multiple inheritance: ‘Logger’ with method ‘log’, ‘Timestamped’ with method ‘when’, and ‘Audit(Logger, Timestamped)’ that provides ‘record(self, msg)’ using both; show MRO with ‘Audit.mro’.
  4. Create ‘Vector’ with attributes ‘x’, ‘y’ and overload ‘add’, ‘sub’, and ‘eq’; write a small test that compares two sums for equality.
  5. In ‘Vector’, override ‘repr’ to return an unambiguous constructor-like string; show it in the REPL print.
  6. Implement ‘contains(self, value)’ for ‘Bag’ so that ‘value in bag’ checks membership; demo with two items present/absent.
  7. Add iteration to ‘Bag’ by defining ‘iter(self)’ that yields items; loop with ‘for item in bag’ and print all.
  8. Create ‘Config’ with class attribute ‘defaults’ (a dict) and method ‘get(self, key)’ that checks instance dict first, then class ‘defaults’; demonstrate precedence.
  9. Build an abstract base class ‘Repository’ using ‘abc.ABC’ with abstract methods ‘add(self, item)’ and ‘get(self, key)’; implement ‘MemoryRepo(Repository)’ and test.
  10. Show method overriding with ‘super()’ chaining: base ‘Notifiable.save(self)’ prints ‘base’; ‘LoggingMixin.save(self)’ prints ‘log’ then ‘super().save()’; ‘Model(LoggingMixin, Notifiable)’ calls ‘save’ and prints the order.
  11. Demonstrate hierarchical inheritance with three subclasses of ‘Employee’ (‘Manager’, ‘Engineer’, ‘Intern’) each overriding ‘role(self)’; iterate a mixed list and call ‘role’.
  12. Implement ‘Matrix’ with a nested list ‘data’ and define ‘len’ returning number of rows and ‘getitem’ supporting ‘matrix[i][j]’ access; print row count and an element.
  13. Add to ‘Matrix’ an operator overload ‘add’ that adds two matrices of same size; write a short test adding two 2×2 matrices.
  14. Create class ‘RangeLike’ that implements ‘iter’ and ‘len’ for numbers ‘start..stop’ (exclusive) using generator in ‘iter’; iterate and print items.
  15. Build ‘Cache’ with a private dict ‘__store’; provide ‘set’, ‘get’, and ‘has’ methods and prevent external direct mutation; verify privacy by checking attribute names.
  16. Implement a tiny domain: ‘Author’ and ‘Book’ where ‘Book’ has an ‘author’ attribute (composition); add ‘info(self)’ to print ‘<title> by <author.name>’; show printing.
  17. Create multilevel inheritance ‘Transport -> Vehicle -> Car’ where ‘Car’ overrides ‘move’ but also calls ‘super().move()’; print both messages in order.
  18. Add a ‘classmethod’ factory ‘zero()’ to ‘Vector’ returning the zero vector; use it in a small operation, then show ‘isinstance(Vector.zero(), Vector)’.
  19. Implement ‘call(self, x)’ on class ‘Multiplier’ to make instances callable and multiply ‘x’ by a preset factor; create ‘times3 = Multiplier(3)’ and call ‘times3(10)’.
  20. Build a minimal ORM-like model: base ‘Model’ with class attribute ‘table’, instance attribute ‘fields’ (dict), and method ‘to_row(self)’ returning a tuple; subclass ‘UserModel’ and show a row.

Advanced Questions

  1. Design a small hierarchy with operator overloading: ‘Money’ storing ‘amount’ and ‘currency’; implement ‘add’ to allow adding only when currencies match (raise ‘TypeError’ otherwise) and ‘str’ for display; test both success and failure.
  2. Implement ‘Polynomial’ that stores coefficients list and supports ‘call(self, x)’ to evaluate, ‘add’ to add polynomials, and ‘str’ to pretty-print; demonstrate with two polynomials.
  3. Create an abstract class ‘Shape’ with abstract methods ‘area(self)’ and ‘perimeter(self)’; implement ‘Rectangle’ and ‘Circle’ and show polymorphic iteration over a list of shapes calling both methods.
  4. Build a multiple-inheritance diamond: ‘Base’ -> ‘Left(Base)’, ‘Right(Base)’ -> ‘Child(Left, Right)’; give each a ‘who(self)’ that calls ‘super().who()’ then prints its own label; show linearization via printed order.
  5. Implement a container class ‘Deck’ that uses composition of a list of ‘Card’ objects and supports ‘len’, ‘getitem’, and ‘iter’; iterate, index, slice, and get its length.
  6. Create ‘SafeDict’ that inherits from ‘dict’ but overrides ‘getitem’ to return a default when key is missing while still allowing normal behavior; compare to a composed version ‘SafeDict2’ that holds an internal dict and forwards methods (composition vs inheritance).
  7. Write ‘Vector3’ with ‘add’, ‘sub’, ‘mul’ (scalar), ‘rmul’, and ‘abs’ (magnitude); demonstrate duck typing by using it anywhere a sequence of three numbers is expected in a function that only accesses ‘x’, ‘y’, ‘z’ attributes.
  8. Implement method chaining by returning ‘self’ from mutating methods: class ‘Query’ with ‘filter(self, **kw)’ and ‘order_by(self, key)’; show ‘Query().filter(a=1).order_by(“a”)’ and print internal state.
  9. Build a tiny plugin system: base abstract ‘Plugin’ with ‘run(self, data)’; a ‘Pipeline’ holds a list of plugins (composition) and calls each plugin’s ‘run’ in order; create two plugins and show the pipeline transforming input.
  10. Create ‘Tree’ nodes that support iteration over children via ‘iter’ and indexing via ‘getitem’; implement depth-first traversal as iteration and demonstrate ‘for child in node’ and ‘node[0]’.