Practice Questions — Inheritance and Polymorphism
← Back to NotesTopic-Specific Questions
Question 1
Easy
What is the output of the following code?
class Animal:
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return "Woof!"
d = Dog()
print(d.speak())Dog overrides the speak method from Animal.
Woof!Question 2
Easy
What is the output?
class Parent:
def __init__(self, name):
self.name = name
class Child(Parent):
pass
c = Child("Aarav")
print(c.name)Child inherits __init__ from Parent because it does not define its own.
AaravQuestion 3
Easy
What is the output?
class A:
x = 10
class B(A):
pass
class C(A):
x = 20
print(B.x)
print(C.x)B inherits x from A. C overrides x with its own value.
1020Question 4
Easy
What is the output?
class Vehicle:
def type(self):
return "Vehicle"
class Car(Vehicle):
def type(self):
return "Car"
c = Car()
print(isinstance(c, Car))
print(isinstance(c, Vehicle))isinstance checks if the object is an instance of the class or its parents.
TrueTrueQuestion 5
Easy
What is the output?
class Base:
def greet(self):
return "Hello from Base"
class Derived(Base):
def greet(self):
return "Hello from Derived"
b = Base()
d = Derived()
print(b.greet())
print(d.greet())Each object calls its own class's version of greet().
Hello from BaseHello from DerivedQuestion 6
Medium
What is the output?
class Person:
def __init__(self, name):
self.name = name
def info(self):
return self.name
class Student(Person):
def __init__(self, name, grade):
super().__init__(name)
self.grade = grade
def info(self):
return f"{super().info()} (Grade: {self.grade})"
s = Student("Priya", "A+")
print(s.info())super().info() calls Person's info method.
Priya (Grade: A+)Question 7
Medium
What is the output?
class A:
def method(self):
return "A"
class B(A):
def method(self):
return "B"
class C(A):
def method(self):
return "C"
class D(B, C):
pass
print(D().method())
print([cls.__name__ for cls in D.__mro__])D inherits from B first, then C. The MRO checks B before C.
B['D', 'B', 'C', 'A', 'object']Question 8
Medium
What is the output?
class X:
def show(self):
return "X"
class Y(X):
pass
class Z(X):
def show(self):
return "Z"
class W(Y, Z):
pass
print(W().show())Y does not define show(). Check the MRO to see where Python looks next.
ZQuestion 9
Medium
What is the output?
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
animals = [Dog("Rex"), Cat("Luna"), Dog("Buddy")]
for a in animals:
print(f"{a.name}: {a.speak()}")Each object calls its own class's speak() method.
Rex: Woof!Luna: Meow!Buddy: Woof!Question 10
Medium
What is the output?
class Base:
def __init__(self):
print("Base.__init__")
class Middle(Base):
def __init__(self):
print("Middle.__init__")
super().__init__()
class Child(Middle):
def __init__(self):
print("Child.__init__")
super().__init__()
c = Child()super() calls the next class in the MRO.
Child.__init__Middle.__init__Base.__init__Question 11
Hard
What is the output?
class A:
def __init__(self):
print("A", end=" ")
class B(A):
def __init__(self):
print("B", end=" ")
super().__init__()
class C(A):
def __init__(self):
print("C", end=" ")
super().__init__()
class D(B, C):
def __init__(self):
print("D", end=" ")
super().__init__()
d = D()
print()MRO: D -> B -> C -> A. super() follows the MRO, not the direct parent.
D B C A Question 12
Hard
What is the output?
class Animal:
def __init__(self, name):
self.name = name
class Pet:
def __init__(self, owner):
self.owner = owner
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
d = Dog("Rex", "Labrador")
print(d.name)
print(d.breed)
print(issubclass(Dog, Animal))
print(issubclass(Dog, Pet))Dog inherits from Animal only, not from Pet.
RexLabradorTrueFalseQuestion 13
Hard
What is the output?
class Validator:
def validate(self, value):
return True
class RangeValidator(Validator):
def __init__(self, low, high):
self.low = low
self.high = high
def validate(self, value):
return self.low <= value <= self.high
class TypeValidator(Validator):
def __init__(self, expected_type):
self.expected_type = expected_type
def validate(self, value):
return isinstance(value, self.expected_type)
validators = [RangeValidator(1, 100), TypeValidator(int)]
test_values = [50, 200, "hello"]
for val in test_values:
results = [v.validate(val) for v in validators]
print(f"{val!r}: {results}")Each validator checks independently. Follow the logic for each value.
50: [True, True]200: [False, True]'hello': [False, False]Question 14
Hard
What is the output?
class Base:
def method(self):
return self.value()
def value(self):
return 1
class Child(Base):
def value(self):
return 2
b = Base()
c = Child()
print(b.method())
print(c.method())self.value() calls the version of value() based on the actual type of self.
12Question 15
Hard
What is the output?
class Counter:
def __init__(self, start=0):
self.count = start
def __add__(self, other):
return Counter(self.count + other.count)
def __str__(self):
return f"Counter({self.count})"
a = Counter(10)
b = Counter(20)
c = a + b
print(c)
print(type(c).__name__)__add__ creates a new Counter with the sum of counts.
Counter(30)CounterQuestion 16
Medium
What is the Method Resolution Order (MRO) and why does it matter?
Think about multiple inheritance and which method Python calls when there are multiple options.
MRO is the order in which Python searches classes for a method when using inheritance. It is computed using the C3 linearization algorithm. MRO matters because in multiple inheritance, a method might exist in several parent classes, and the MRO determines which one is called. You can inspect it with
ClassName.__mro__ or ClassName.mro().Question 17
Hard
In the diamond problem, why does
super().__init__() in B's __init__ call C's __init__ instead of A's?super() follows the MRO, not the direct parent.
In a diamond inheritance (D -> B, C -> A), the MRO is D -> B -> C -> A. When B's __init__ calls
super().__init__(), Python looks at the MRO relative to the current object (which is a D instance). The next class after B in D's MRO is C, not A. So super() in B delegates to C, ensuring each class's __init__ is called exactly once.Mixed & Application Questions
Question 1
Easy
What is the output?
class Shape:
def area(self):
return 0
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
s = Square(5)
print(s.area())
print(isinstance(s, Shape))Square overrides area() and inherits from Shape.
25TrueQuestion 2
Easy
What is the output?
class Flyable:
def fly(self):
return f"{self.name} can fly"
class Swimmable:
def swim(self):
return f"{self.name} can swim"
class Duck(Flyable, Swimmable):
def __init__(self, name):
self.name = name
d = Duck("Donald")
print(d.fly())
print(d.swim())Duck inherits methods from both Flyable and Swimmable.
Donald can flyDonald can swimQuestion 3
Medium
What is the output?
class Logger:
def log(self, message):
print(f"[LOG] {message}")
class Database(Logger):
def save(self, data):
self.log(f"Saving: {data}")
return True
class Cache(Logger):
def store(self, key, value):
self.log(f"Caching: {key}={value}")
db = Database()
cache = Cache()
db.save("user_data")
cache.store("name", "Aarav")Both Database and Cache inherit log() from Logger.
[LOG] Saving: user_data[LOG] Caching: name=AaravQuestion 4
Medium
What is the output?
class A:
def __str__(self):
return "A"
class B(A):
pass
class C(A):
def __str__(self):
return "C"
class D(B, C):
pass
print(D())D does not define __str__. Follow the MRO: D -> B -> C -> A.
CQuestion 5
Medium
What is the output?
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def pay(self):
return self.salary
class Manager(Employee):
def __init__(self, name, salary, bonus):
super().__init__(name, salary)
self.bonus = bonus
def pay(self):
return super().pay() + self.bonus
m = Manager("Aarav", 50000, 10000)
print(m.pay())
print(m.name)Manager.pay() calls super().pay() which returns the base salary.
60000AaravQuestion 6
Hard
What is the output?
class Iterable:
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
def __getitem__(self, index):
return self.data[index]
class NameList(Iterable):
def __contains__(self, name):
return name.lower() in [n.lower() for n in self.data]
names = NameList(["Aarav", "Priya", "Rohan"])
print(len(names))
print(names[1])
print("PRIYA" in names)
print("Meera" in names)__contains__ does case-insensitive checking.
3PriyaTrueFalseQuestion 7
Hard
What is the output?
class Base:
count = 0
def __init__(self):
Base.count += 1
class ChildA(Base):
pass
class ChildB(Base):
pass
a1 = ChildA()
a2 = ChildA()
b1 = ChildB()
print(Base.count)
print(ChildA.count)
print(ChildB.count)All __init__ calls increment Base.count. It is a shared class variable.
333Question 8
Hard
What is the output?
class JsonMixin:
def to_dict(self):
return self.__dict__.copy()
class Person(JsonMixin):
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, grade):
super().__init__(name, age)
self.grade = grade
s = Student("Aarav", 16, "A")
print(s.to_dict())
print(isinstance(s, JsonMixin))Student inherits from Person which inherits from JsonMixin.
{'name': 'Aarav', 'age': 16, 'grade': 'A'}TrueQuestion 9
Medium
What is duck typing and how does it relate to polymorphism?
Think about what Python checks when you call a method on an object.
Duck typing is Python's approach to type checking: if an object has the right methods, it works, regardless of its actual class. 'If it walks like a duck and quacks like a duck, it is a duck.' This is a form of polymorphism that does not require inheritance. Any object with a
speak() method can be used where speak() is called, whether it inherits from a common base or not.Question 10
Hard
What is the difference between method overriding and method overloading? Does Python support both?
Overriding: same method name in parent and child. Overloading: same name with different parameter lists.
Method overriding is when a child class defines a method with the same name as the parent's, replacing its behavior. Python fully supports this. Method overloading is when multiple methods have the same name but different parameter lists (common in Java). Python does NOT support traditional overloading -- defining a method twice replaces the first definition. Python achieves similar flexibility through default parameters, *args, and **kwargs.
Multiple Choice Questions
MCQ 1
What does class Dog(Animal) mean?
Answer: B
B is correct. The parentheses indicate inheritance: Dog is a subclass of Animal. It inherits all attributes and methods from Animal.
B is correct. The parentheses indicate inheritance: Dog is a subclass of Animal. It inherits all attributes and methods from Animal.
MCQ 2
What does super() do?
Answer: B
B is correct.
B is correct.
super() returns a proxy object that delegates method calls to the parent (or next class in the MRO). Most commonly used as super().__init__().MCQ 3
What is method overriding?
Answer: A
A is correct. Method overriding occurs when a child class defines a method with the same name as the parent's. The child's version is used for objects of the child class.
A is correct. Method overriding occurs when a child class defines a method with the same name as the parent's. The child's version is used for objects of the child class.
MCQ 4
What is polymorphism?
Answer: B
B is correct. Polymorphism means 'many forms.' The same method name (e.g., area()) works differently for different object types (Circle, Rectangle, Triangle).
B is correct. Polymorphism means 'many forms.' The same method name (e.g., area()) works differently for different object types (Circle, Rectangle, Triangle).
MCQ 5
In Python, all classes implicitly inherit from which class?
Answer: C
C is correct. In Python 3, all classes implicitly inherit from
C is correct. In Python 3, all classes implicitly inherit from
object (lowercase). class MyClass: is equivalent to class MyClass(object):.MCQ 6
What is the MRO for class D(B, C) where B and C both inherit from A?
Answer: C
C is correct. C3 linearization gives D -> B -> C -> A -> object. B is listed before C in the class definition, so it comes first. A comes after both B and C because it is their common parent.
C is correct. C3 linearization gives D -> B -> C -> A -> object. B is listed before C in the class definition, so it comes first. A comes after both B and C because it is their common parent.
MCQ 7
What does isinstance(obj, cls) check?
Answer: B
B is correct.
B is correct.
isinstance(obj, cls) returns True if obj is an instance of cls or any class that inherits from cls. It checks the full inheritance chain.MCQ 8
What is duck typing?
Answer: C
C is correct. Duck typing means Python does not check an object's class to determine if it has the right interface. If the required methods exist, Python uses them. 'If it walks like a duck and quacks like a duck, it is a duck.'
C is correct. Duck typing means Python does not check an object's class to determine if it has the right interface. If the required methods exist, Python uses them. 'If it walks like a duck and quacks like a duck, it is a duck.'
MCQ 9
What happens if you try to instantiate a class with an unimplemented @abstractmethod?
Answer: B
B is correct. You cannot instantiate a class that has unimplemented abstract methods. Python raises
B is correct. You cannot instantiate a class that has unimplemented abstract methods. Python raises
TypeError: Can't instantiate abstract class X with abstract method Y.MCQ 10
What is a mixin?
Answer: B
B is correct. A mixin is a small class that provides specific functionality (like serialization, logging) and is designed to be inherited alongside a main class. Mixins typically do not have __init__ and are not meant to be used alone.
B is correct. A mixin is a small class that provides specific functionality (like serialization, logging) and is designed to be inherited alongside a main class. Mixins typically do not have __init__ and are not meant to be used alone.
MCQ 11
What does super().__init__() call in a diamond inheritance D(B, C) when called from B?
Answer: B
B is correct. super() follows the MRO, not the direct parent. For a D instance, the MRO is D->B->C->A->object. When B calls super().__init__(), the next class after B in the MRO is C, so C's __init__ is called.
B is correct. super() follows the MRO, not the direct parent. For a D instance, the MRO is D->B->C->A->object. When B calls super().__init__(), the next class after B in the MRO is C, so C's __init__ is called.
MCQ 12
What is the purpose of returning NotImplemented from __add__?
Answer: B
B is correct. Returning
B is correct. Returning
NotImplemented tells Python that this operand does not support the operation. Python then tries the right operand's __radd__ method. This is different from raising NotImplementedError.MCQ 13
What is the difference between issubclass() and isinstance()?
Answer: B
B is correct.
B is correct.
issubclass(Dog, Animal) checks if the Dog class inherits from Animal. isinstance(d, Animal) checks if the object d is an instance of Animal or its subclasses.MCQ 14
What is the __add__ method used for?
Answer: B
B is correct.
B is correct.
__add__(self, other) defines what happens when you use the + operator with objects of the class: a + b calls a.__add__(b).MCQ 15
If a child class does not define __init__, what happens when you create an instance?
Answer: B
B is correct. If the child does not define __init__, it inherits the parent's __init__. The parent's initialization code runs as if you were creating a parent instance, setting all the parent's attributes.
B is correct. If the child does not define __init__, it inherits the parent's __init__. The parent's initialization code runs as if you were creating a parent instance, setting all the parent's attributes.
MCQ 16
What does the abc module provide?
Answer: B
B is correct. The
B is correct. The
abc module provides ABC class and @abstractmethod decorator for creating Abstract Base Classes. ABCs define interfaces that subclasses must implement.MCQ 17
Can a class inherit from multiple abstract base classes?
Answer: B
B is correct. A class can inherit from multiple ABCs. It must implement every @abstractmethod from every abstract parent. If any are missing, the class itself becomes abstract and cannot be instantiated.
B is correct. A class can inherit from multiple ABCs. It must implement every @abstractmethod from every abstract parent. If any are missing, the class itself becomes abstract and cannot be instantiated.
MCQ 18
What special method enables the len() function on custom objects?
Answer: C
C is correct. Defining
C is correct. Defining
__len__(self) allows len(obj) to work on custom objects. It should return a non-negative integer.Coding Challenges
Challenge 1: Shape Hierarchy
EasyCreate a Shape base class with an area() method returning 0. Create Circle(radius), Rectangle(width, height), and Triangle(base, height) subclasses, each overriding area(). Write a function total_area(shapes) that returns the sum of all areas.
Sample Input
(No input required)
Sample Output
Circle: 78.54
Rectangle: 24
Triangle: 12.0
Total: 114.54
Use inheritance and method overriding. The function should work with any list of Shape objects.
class Shape:
def area(self):
return 0
def __str__(self):
return f"{type(self).__name__}: {self.area()}"
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return round(3.14159 * self.radius ** 2, 2)
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Triangle(Shape):
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return 0.5 * self.base * self.height
def total_area(shapes):
return sum(s.area() for s in shapes)
shapes = [Circle(5), Rectangle(4, 6), Triangle(6, 4)]
for s in shapes:
print(s)
print(f"Total: {total_area(shapes)}")Challenge 2: Employee Pay System
EasyCreate an Employee base class with name and base_salary. Create Manager (with bonus), Developer (with overtime_hours at 500/hr), and Intern (gets 50% of base). Each overrides calculate_pay(). Print payroll for a team.
Sample Input
(No input required)
Sample Output
Aarav (Manager): Rs.60000
Priya (Developer): Rs.45000
Rohan (Intern): Rs.10000
Total payroll: Rs.115000
Use super().__init__() in all subclasses.
class Employee:
def __init__(self, name, base_salary):
self.name = name
self.base_salary = base_salary
def calculate_pay(self):
return self.base_salary
def role(self):
return type(self).__name__
class Manager(Employee):
def __init__(self, name, base_salary, bonus):
super().__init__(name, base_salary)
self.bonus = bonus
def calculate_pay(self):
return self.base_salary + self.bonus
class Developer(Employee):
def __init__(self, name, base_salary, overtime_hours):
super().__init__(name, base_salary)
self.overtime_hours = overtime_hours
def calculate_pay(self):
return self.base_salary + self.overtime_hours * 500
class Intern(Employee):
def calculate_pay(self):
return int(self.base_salary * 0.5)
team = [Manager("Aarav", 50000, 10000), Developer("Priya", 40000, 10), Intern("Rohan", 20000)]
total = 0
for emp in team:
pay = emp.calculate_pay()
total += pay
print(f"{emp.name} ({emp.role()}): Rs.{pay}")
print(f"Total payroll: Rs.{total}")Challenge 3: Animal Sound Polymorphism
EasyCreate an Animal base class and at least 4 animal subclasses (Dog, Cat, Cow, Duck), each with a sound() method. Write a function animal_chorus(animals) that calls sound() on each. Demonstrate duck typing by adding a Robot class (not inheriting from Animal) that also has sound().
Sample Input
(No input required)
Sample Output
Rex the Dog says: Woof!
Luna the Cat says: Meow!
Gauri the Cow says: Moo!
Daisy the Duck says: Quack!
R2D2 the Robot says: Beep!
Demonstrate polymorphism and duck typing.
class Animal:
def __init__(self, name):
self.name = name
def sound(self):
return "..."
def __str__(self):
return f"{self.name} the {type(self).__name__} says: {self.sound()}"
class Dog(Animal):
def sound(self): return "Woof!"
class Cat(Animal):
def sound(self): return "Meow!"
class Cow(Animal):
def sound(self): return "Moo!"
class Duck(Animal):
def sound(self): return "Quack!"
class Robot: # Not an Animal!
def __init__(self, name):
self.name = name
def sound(self):
return "Beep!"
def __str__(self):
return f"{self.name} the Robot says: {self.sound()}"
def animal_chorus(things):
for thing in things:
print(thing)
animal_chorus([Dog("Rex"), Cat("Luna"), Cow("Gauri"), Duck("Daisy"), Robot("R2D2")])Challenge 4: Sortable Collection with Operator Overloading
MediumCreate a Student class with name and gpa. Implement __lt__ (for sorting), __eq__, __str__, and __repr__. Create a list of students and sort them by GPA (descending). Also implement __add__ that merges two student lists.
Sample Input
(No input required)
Sample Output
Sorted by GPA (desc):
1. Priya (GPA: 9.8)
2. Aarav (GPA: 9.2)
3. Meera (GPA: 8.5)
4. Rohan (GPA: 7.9)
Use __lt__ for comparisons. sorted() should work with Student objects.
class Student:
def __init__(self, name, gpa):
self.name = name
self.gpa = gpa
def __lt__(self, other):
return self.gpa < other.gpa
def __eq__(self, other):
return isinstance(other, Student) and self.gpa == other.gpa
def __str__(self):
return f"{self.name} (GPA: {self.gpa})"
def __repr__(self):
return f"Student('{self.name}', {self.gpa})"
students = [
Student("Aarav", 9.2),
Student("Priya", 9.8),
Student("Rohan", 7.9),
Student("Meera", 8.5),
]
sorted_students = sorted(students, reverse=True)
print("Sorted by GPA (desc):")
for i, s in enumerate(sorted_students, 1):
print(f"{i}. {s}")Challenge 5: Plugin System with Abstract Base Class
MediumCreate an abstract Plugin class with abstract methods: name(), version(), and execute(data). Create three concrete plugins: UpperCasePlugin, ReversePlugin, and CountPlugin. Write a PluginManager that registers plugins and runs all of them on given data.
Sample Input
(No input required)
Sample Output
Running UpperCase v1.0: HELLO WORLD
Running Reverse v1.0: dlrow olleh
Running Counter v1.0: 11 characters
Use ABC and @abstractmethod. PluginManager should work with any Plugin subclass.
from abc import ABC, abstractmethod
class Plugin(ABC):
@abstractmethod
def name(self): pass
@abstractmethod
def version(self): pass
@abstractmethod
def execute(self, data): pass
class UpperCasePlugin(Plugin):
def name(self): return "UpperCase"
def version(self): return "1.0"
def execute(self, data): return data.upper()
class ReversePlugin(Plugin):
def name(self): return "Reverse"
def version(self): return "1.0"
def execute(self, data): return data[::-1]
class CountPlugin(Plugin):
def name(self): return "Counter"
def version(self): return "1.0"
def execute(self, data): return f"{len(data)} characters"
class PluginManager:
def __init__(self):
self.plugins = []
def register(self, plugin):
self.plugins.append(plugin)
def run_all(self, data):
for plugin in self.plugins:
result = plugin.execute(data)
print(f"Running {plugin.name()} v{plugin.version()}: {result}")
pm = PluginManager()
pm.register(UpperCasePlugin())
pm.register(ReversePlugin())
pm.register(CountPlugin())
pm.run_all("hello world")Challenge 6: MRO Explorer
MediumCreate a diamond inheritance hierarchy: class A at the top, B and C inheriting from A, and D inheriting from both B and C. Each class should have a method who_am_i() that returns its class name plus super().who_am_i(). Print the MRO and the chain of who_am_i() calls.
Sample Input
(No input required)
Sample Output
MRO: D -> B -> C -> A -> object
D -> B -> C -> A
Use super() in each class. Handle the base case in A.
class A:
def who_am_i(self):
return "A"
class B(A):
def who_am_i(self):
return "B -> " + super().who_am_i()
class C(A):
def who_am_i(self):
return "C -> " + super().who_am_i()
class D(B, C):
def who_am_i(self):
return "D -> " + super().who_am_i()
d = D()
mro_names = [cls.__name__ for cls in D.__mro__]
print(f"MRO: {' -> '.join(mro_names)}")
print(d.who_am_i())Challenge 7: Mixin-Based Logging System
HardCreate TimestampMixin (adds timestamp to __str__), SerializableMixin (to_dict method), and ValidatableMixin (abstract validate method). Create a User class using all three mixins. The User should validate that name is non-empty and age is between 0 and 150.
Sample Input
(No input required)
Sample Output
[2026-04-06] User: Aarav, 16
{'name': 'Aarav', 'age': 16}
Valid: True
Invalid name: Name cannot be empty
Invalid age: Age must be between 0 and 150
Each mixin should provide one specific feature. User combines all three.
from abc import ABC, abstractmethod
class TimestampMixin:
def timestamped_str(self):
return f"[2026-04-06] {str(self)}"
class SerializableMixin:
def to_dict(self):
return {k: v for k, v in self.__dict__.items() if not k.startswith('_')}
class ValidatableMixin(ABC):
@abstractmethod
def validate(self):
pass
class User(TimestampMixin, SerializableMixin, ValidatableMixin):
def __init__(self, name, age):
self.name = name
self.age = age
def validate(self):
errors = []
if not self.name or not self.name.strip():
errors.append("Name cannot be empty")
if not isinstance(self.age, int) or self.age < 0 or self.age > 150:
errors.append("Age must be between 0 and 150")
return (len(errors) == 0, errors)
def __str__(self):
return f"User: {self.name}, {self.age}"
u1 = User("Aarav", 16)
print(u1.timestamped_str())
print(u1.to_dict())
valid, errors = u1.validate()
print(f"Valid: {valid}")
u2 = User("", 16)
valid, errors = u2.validate()
print(f"Invalid name: {errors[0]}")
u3 = User("Rohan", 200)
valid, errors = u3.validate()
print(f"Invalid age: {errors[0]}")Challenge 8: Custom Collection with Full Operator Support
HardCreate a SortedList class that maintains a sorted list of numbers. Implement __len__, __getitem__, __contains__, __add__ (merge two SortedLists), __eq__, __str__, __iter__, and an insert method that maintains sorted order.
Sample Input
(No input required)
Sample Output
SortedList([1, 3, 5, 7, 9])
Length: 5
Index 2: 5
5 in list: True
Merged: SortedList([1, 2, 3, 4, 5, 6, 7, 9])
The list must always remain sorted. insert() should place the element in the correct position.
class SortedList:
def __init__(self, items=None):
self._data = sorted(items) if items else []
def insert(self, value):
for i, item in enumerate(self._data):
if value <= item:
self._data.insert(i, value)
return
self._data.append(value)
def __len__(self):
return len(self._data)
def __getitem__(self, index):
return self._data[index]
def __contains__(self, value):
for item in self._data:
if item == value:
return True
if item > value:
return False
return False
def __add__(self, other):
return SortedList(self._data + other._data)
def __eq__(self, other):
return isinstance(other, SortedList) and self._data == other._data
def __iter__(self):
return iter(self._data)
def __str__(self):
return f"SortedList({self._data})"
s1 = SortedList([5, 1, 9, 3, 7])
print(s1)
print(f"Length: {len(s1)}")
print(f"Index 2: {s1[2]}")
print(f"5 in list: {5 in s1}")
s2 = SortedList([2, 4, 6])
merged = s1 + s2
print(f"Merged: {merged}")Need to Review the Concepts?
Go back to the detailed notes for this chapter.
Read Chapter NotesWant to learn Python with a live mentor?
Explore our Python course