Skip to main content

Unit 5

ePortfolio Activity: Polymorphism

Assignment

An example of a Python program which uses polymorphism is shown below.

class Cat:
def __init__(self, name, age):
self.name = name
self.age = age

def info(self):
print(f"I am a cat. My name is {self.name}. I am {self.age} years old.")

def make_sound(self):
print("Meow")


class Dog:
def __init__(self, name, age):
self.name = name
self.age = age

def info(self):
print(f"I am a dog. My name is {self.name}. I am {self.age} years old.")

def make_sound(self):
print("Bark")


cat1 = Cat("Kitty", 2.5)
dog1 = Dog("Fluffy", 4)

for animal in (cat1, dog1):
animal.make_sound()
animal.info()
animal.make_sound()

Source: Programiz. (n.d.) Polymorphism in Python.

Write a Python program with polymorphism that is usable within the summative assessment for the humanoid robot.

The program below demonstrates how the use of polymorphism allows to define a base Robot class and its core behavior and then override it in the implementation classes to enable each robot type to perform specific tasks.

Polymorphism allows to specify the overall interface for interacting with a robot instance and also the common traits of a robot, thus reducing the amount of duplicated code and streamlining the implementation of the derived classes. It is therefore possible to interact with robots of different types using the same methods like greet(), report_status(), or perform_task(). Besides, core logic for performing a task (updating the status before and after a task is executed) is contained in the perform_task() method of the base class, whereas the type-specific behavior is specified in the overridable method _execute_task().

Polymorphism is a powerful tool that boosts the development process by facilitating code reuse.

from enum import Enum


class RobotStatus(Enum):
"""
Enum for robot status states
"""
IDLE = "IDLE"
BUSY = "BUSY"
OFFLINE = "OFFLINE"


class Task:
"""
Represents a task that can be assigned to any robot
"""

def __init__(self, task_id: int, description: str):
self.task_id = task_id
self.description = description

def get_details(self) -> str:
"""Returns formatted task details"""
return f"Task #{self.task_id}: {self.description}"


class Robot:
"""
Base class for all robot types

This class defines the common interface that all robot types will implement.
Each derived class will override these methods with its own implementation,
demonstrating polymorphism.
"""
__next_id = 1

def __init__(self, name: str):
"""Initialize a robot with a unique ID and default status"""
self.robot_id = Robot.__next_id
Robot.__next_id += 1
self.name = name
self.status = RobotStatus.IDLE
self.counter = 0 # Generic counter for tasks/activities

def greet(self) -> str:
"""
Returns a greeting message

This method will be overridden by subclasses to provide
type-specific greetings.
"""
return f"Hello, I am robot {self.name}."

def perform_task(self, task: Task) -> str:
"""
Performs a given task

This method handles the common status changes and counter increment,
while delegating the specific task implementation to _execute_task.
Subclasses should override _execute_task instead of this method.
"""
self.status = RobotStatus.BUSY
result = self._execute_task(task)
self.counter += 1
self.status = RobotStatus.IDLE
return result

def _execute_task(self, task: Task) -> str:
"""
Executes the specific task implementation

This protected method should be overridden by subclasses to provide
type-specific task handling.
"""
return f"Robot {self.name} is performing task: {task.get_details()}"

def report_status(self) -> str:
"""
Reports the current status of the robot

This method will be overridden by subclasses to provide
type-specific status reporting.
"""
return f"Robot {self.name} is currently {self.status.value}."


class ServiceRobot(Robot):
"""
Service robot for customer assistance
"""

def __init__(self, name: str, service_area: str):
"""Initialize with service area"""
super().__init__(name)
self.service_area = service_area

def greet(self) -> str:
return f"Hello! I'm {self.name}, your service assistant in the {self.service_area}."

def _execute_task(self, task: Task) -> str:
return f"Service robot {self.name} is assisting with: {task.get_details()}"

def report_status(self) -> str:
return f"Service robot {self.name} is {self.status.value}. Customers served: {self.counter}."


class SecurityRobot(Robot):
"""
Security robot for surveillance
"""

def __init__(self, name: str, security_clearance: int):
"""Initialize with security clearance level"""
super().__init__(name)
self.security_clearance = min(max(security_clearance, 1), 5)

def greet(self) -> str:
return f"Security unit {self.name} active. Clearance level: {self.security_clearance}."

def _execute_task(self, task: Task) -> str:
return f"Security robot {self.name} responding to: {task.get_details()}"

def report_status(self) -> str:
return f"Security robot {self.name} is {self.status.value}. Alerts handled: {self.counter}."


class MaintenanceRobot(Robot):
"""
Maintenance robot for repairs

Demonstrates polymorphism by overriding the base Robot class methods
with maintenance-specific implementations.
"""

def __init__(self, name: str, specialization: str):
"""Initialize with repair specialization"""
super().__init__(name)
self.specialization = specialization

def greet(self) -> str:
return f"Maintenance unit {self.name} online. Specialized in {self.specialization} repairs."

def _execute_task(self, task: Task) -> str:
return f"Maintenance robot {self.name} fixing: {task.get_details()}"

def report_status(self) -> str:
return f"Maintenance robot {self.name} is {self.status.value}. Repairs completed: {self.counter}."


def main():
robots = [
ServiceRobot("Servy", "Restaurant"),
SecurityRobot("Guard-X", 3),
MaintenanceRobot("Fixy", "Electrical")
]

tasks = [
Task(1, "Welcome guests and take orders"),
Task(2, "Investigate suspicious activity in sector 7"),
Task(3, "Repair malfunctioning light fixture")
]

# Demonstrate polymorphism by calling the same methods on different robot types
# Each robot will respond with its own implementation of the method

print("=== Robot Greetings ===")
for robot in robots:
# The same greet() method call works differently for each robot type
print(robot.greet())

print("\n=== Task Assignment ===")
for robot, task in zip(robots, tasks):
# The same perform_task() method call works differently for each robot type
print(robot.perform_task(task))

print("\n=== Status Reports ===")
for robot in robots:
# The same report_status() method call works differently for each robot type
print(robot.report_status())


if __name__ == "__main__":
main()