Python OOP Exercises
Python OOP Exercises
Object Oriented
Programming Exercises Become a
Pro Developer
Python
Object Oriented
Programming Exercises
Become a Pro Developer
Edcorner Learning
Table of Contents
Introduction
1 Overview of Python OOPS
2 What in Python is OOPS?
3 Some of the Major Advantages of OOPS are:
4 Difference between procedural and object-oriented programming
5 Python's Class and Objects
6 What is a Class Definition in Python?
7 An __init__ method: What is it?
8 Creating a Class Object
9 What is Instance Methods with Example
10 The four core ideas of object-oriented programming are:
11 Inheritance
12 Super()
13 Polymorphism
14 Class Methods and polymorphism
15 Inheritance and Polymorphism
16 Encapsulation
17 A getter and a setter
18 Modifiers of Access
19 Abstraction
20 Important aspects of abstract classes
21 Certain noteworthy aspects of Abstract classes are:
22 OOPS's benefits in Python
Lets starts Python OOPS Programming Exercises
Module 1 Class Method - Decorator
Module 2 Static Method - Decorator
Module 3 Special Methods
Module 4 Inheritance
Module 5 Abstract Classes
Module 6 Miscelleanuoes Exercises
Introduction
4. Programming approach
POP adheres to programming from the top down. The top-down
method of programming focuses on dissecting a complex issue into
manageable units of code. The minor portions of the problems are
then resolved.
OOPS principles adhere to the Bottom-up method of programming.
The Bottom-Up method prioritises resolving the smaller issues at
their most fundamental level before incorporating them into a
comprehensive and entire solution.
Let's say you want to keep track of how many books you own. You
can easily do that by utilising a variable. Also possible is to
compute the sum of five numbers and save the result in a variable.
Simple values are intended to be stored in a variable using
primitive data structures like numbers, characters, and lists.
Consider your name, the square root of a number, or the quantity of
marbles (say).
But what if you need to keep a record of every employee in your
business? For instance, if you try to put all of your employees in a
list, you can later become confused about which index of the list
corresponds to which individual details (e.g. which is the name
field, or the empID or age etc.)
Even if you try to keep them in a dictionary, the entire codebase
will eventually become too complicated to manage. Therefore, we
employ Python Classes in these situations.
To create user-defined data structures in Python, use a class.
Classes set up functions, called "methods," that describe how an
object made from a class can behave and what actions it can take.
Classes and objects are the main topics covered by Python's OOPS
ideas.
Classes simplify the code by avoiding complicated codebases. It
accomplishes this by developing a model or design for how
everything ought to be defined. Any object that derives from the
class should have the characteristics or capabilities specified by this
clause.
Note:
Simple structural definition is all that a class does. It makes no
specific reference to anything or anyone. For instance, the class
HUMAN has attributes like name, age, gender, and city. It does not
identify any particular HUMAN, but it does describe the qualities
and capabilities that a HUMAN or an object of the HUMAN class
ought to have.
The term "object" refers to a class instance. It is the class's actual
implementation and is real.
A collection of data (variables) and methods (functions) that access
the data is referred to as an object. It is the actual class
implementation.
Take this example where Human is a class. This class only serves
as a template for what Human should be, not an actual
implementation. You could argue that the "Human" class only
makes logical sense.
However, "Edcorner" is a Human class object (please refer the
image given above for understanding). It follows that Edcorner was
built using the blueprint for the Human class, which holds the
actual data. Unlike "Human," "Edcorner" is a real person (which
just exists logically). He is a genuine person who embodies all the
characteristics of the class Human, including having a name, being
male, being 32 years old, and residing in Newyork. Additionally,
Edcorner uses all of the methods included in the Human class; for
example, Edcorner can walk, speak, eat, and sleep.
And many humans can be produced utilising the class Human
blueprint. For instance, by leveraging objects and the blueprint for
the class Human, we could generate many more persons.
Short Tip:
class = draught (suppose an architectural drawing). The Object is a
real item that was created using the "blueprint" (suppose a house).
An instance is a representation of the item that is virtual but not a
true copy.
No memory is allotted to a class when it is defined; just the object's
blueprint is produced. Memory allocation only takes place during
object or instance creation. The actual data or information is
contained in the object or instance.
6 What is a Class Definition in Python?
Python classes are defined using the word class, which is then
followed by the class name and a colon.
Syntax:
Below the class definition, indented code is regarded as a
component of the class body.
In a method named init, the qualities that all Human objects must
possess are specified (). When a new Human object is formed,
__init__() assigns the values we supply inside the object's
properties to set the object's initial state. In other words, each new
instance of the class is initialised via __init__(). Any number of
parameters can be passed to __init__(), but self is always the first
parameter.
The self parameter contains a reference to the active class instance.
This means that we can access the data of an object's variables by
using the self argument, which corresponds to the address of the
current object of a class.
Since this self points to the address of each individual object and
returns its corresponding value, even if there are 1000 instances
(objects) of a class, we can always access each of their unique data.
Let's look at how the Human class defines __init__():
We use the self variable three times in the body of. init__() for the
following purposes:
self.name = 'name' creates the name attribute and sets the name
parameter's value as its value.
self.age = The age attribute is created and given the value of the
age parameter that was supplied.
self.gender = The gender parameter value is produced and assigned
to the gender attribute.
In Python, there are two categories of attributes:
Class attribute number 1:
These variables apply to all instances of the class equally. For each
new instance that is created, they do not have new values. Just after
the class definition, they are defined.
In this case, whatever object we create will have a fixed value for
the species.
2. Instance Information:
The variables that are defined inside of any class function are
known as instance attributes. Every instance of the class has a
unique value for the instance attribute. These values rely on the
value that was supplied when the instance was created.
The instance attributes in this case are name, age, and gender.
When a new instance of the class is created, they will have
different values.
8 Creating a Class Object
Inheritance
Encapsulation
Polymorphism
Abstraction of data.
People frequently tell newborns that they have face features that
resemble those of their parents or that they have inherited particular
traits from their parents. It's possible that you've also observed that
you share a few characteristics with your parents.
The real-world situation is fairly similar to inheritance as well.
However, in this case, the "parent classes"' features are passed
down to the "child classes." They are referred to as "properties" and
"methods" here, along with the qualities they inherit.
A class can derive its methods and attributes from another class's
by using the process known as inheritance. Inheritance is the
process of a child class receiving the properties of a parent class.
The Parent class is the class from which the properties are
inherited, and the Child class is the class from which the properties
are inherited.
As we did in our previous examples, we define a typical class.
After that, we may declare the child class and provide the name of
the parent class it is descended from in parenthesis.
The parent class Human is inherited by the child class Boy in the
example above. Because Boy is inheriting from Human, we can
access all of its methods and properties when we create an instance
of the Boy class.
In the Boy class, a method called schoolName has also been
defined. The parent class object is unable to access the method
schoolName. The schoolName method can, however, be called by
making a child class object (Boy).
Let's look at the problem we run into if we try to use the object
from the parent class to invoke the methods of a child class.
Therefore, the AttributeError: 'Human' object has no
attribute'schoolName' is returned in this case. because it is not
possible for child classes to access parent class data and properties.
12 Super()
The parent class is referred to in the inheritance-related method
super(). It can be used to locate a certain method in a superclass of
an object. It serves a very important purpose. Let's examine its
operation —
The super function's syntax is as follows. After the super()
keyword, we write the name of the parent class function we want to
refer to.
Here, the classes Human and Girl have definitions for the Code()
method. But as you can see, each method has a separate
implementation. The Code technique in Human class reads "I can
Code," whereas the Code method in Girl class reads "I can teach."
So let's call the Code technique from the child class to the parent
class.
As you can see, we are using super to call the Code method at line
19. ().
Code(). This will invoke the Human class' Code method. Thus, "I
can Code" is printed. Nevertheless, Code() was already
implemented in Girl (at line 15).
If a method with the same name already exists in the subclass,
super() will still call the method in the superclass.
13 Polymorphism
Let's say you are using your phone to browse the Instagram feeds.
You opened Spotify and began playing your favourite song because
you suddenly had the urge to listen to some music as well. After a
while, you received a call, so you paused whatever you were doing
in the background to answer it. Your friend called and requested
that you text them a certain person's phone number. So you sent
him the phone number through SMS and carried on with your
tasks.
Have you picked up on anything? With just one device—your
mobile phone—you could surf through feeds, listen to music, take
and make phone calls, and message.
Therefore, polymorphism is comparable to that. Poly means
numerous, and morph denotes different forms. Therefore,
polymorphism as a whole refers to something with various forms.
Or "something" that, depending on the circumstance, can exhibit a
variety of behaviours.
In OOPS, polymorphism describes functions with the same names
but different behaviours. Alternatively, a different function
signature with the same function name (parameters passed to the
function).
All of a child class's properties are inherited from the parent class's
methods. But occasionally, it tries to change the techniques by
adding its own implementation. In Python, there are many different
ways to use polymorphism.
An illustration of an inbuilt polymorphic function
An example of an inbuilt polymorphism function is len(). It will
just compute the value and return because we can use it to calculate
the length of various kinds like strings, lists, tuples, and
dictionaries.
Here, the len function was given a string, list, and dictionary, and it
computed the answer. It serves as an illustration of an inbuilt
polymorphic function.
You must have encountered pill forms for medications where the
entire contents are kept sealed inside the capsule’s lid. In essence, a
capsule contains many drug combinations.
In programming, the variables and the methods are similarly kept
in a container known as a “class”! Yes, we have learned a lot about
classes in Python, and we are already aware that every variable and
function we create in OOP stays inside the class.
Encapsulation is the term used in Python to describe the act of
combining data with the matching methods (behaviour) into a
single entity.
Encapsulation, then, is a programming approach that ties the class’s
variables and methods together and makes it impossible for other
classes to access them. It is an example of an OOPS concept in
Python.
Security is possible via encalpsulation. It protects the data from
outside access. By encapsulating an object or piece of information,
a company can prevent clients or other unauthorised individuals
from accessing it without permission.
17 A getter and a setter
You most likely use a laptop, phone, or tablet to read this book.
While reading it, you are also presumably taking notes, underlining
key passages, and possibly saving some information to your
personal files. All you can see when you read this is a "screen" with
the data that is being displayed to you. You just see the keyboard's
keys as you type, so you don't have to worry about internal
subtleties like how pushing a key can cause that word to appear
onscreen. Alternatively, how pressing a button on your screen may
launch a new tab!
Therefore, whatever we may see in this situation is abstract. We
can only see the outcome it is producing and not the inside details
(which actually matters to us).
Similar to this, abstraction only reveals the functions that anything
possesses while concealing any implementations or internal details.
Abstraction's major objective is to conceal background information
and any extraneous data implementation so that people only see
what they need to see. It aids in managing the codes' complexity.
20 Important aspects of abstract classes
Python's support for OOPS ideas has many benefits that make
it suitable for the development of significant software. Let's
examine a couple of them:
Effective problem-solving is possible because we create
classes that do the necessary actions for each mini-problem.
The next problem can be solved even more quickly because
we can reuse those classes.
flexibility in having different versions of the same class
thanks to polymorphism
high level of code complexity was reduced through
abstraction.
By encapsulating, high security and data privacy are achieved.
code reuse caused by a child class's inheritance of parent class
properties.
Instead than sifting through hundreds of lines of code to locate
a single problem, modularity of programming makes
debugging simple.
Lets starts Python OOPS Programming Exercises
Module 1 Class Method - Decorator
1. Using the classmethod class (do it in the standard way) implement a class
named Person that has a class method named show_details() which displays
the following text to the console:
'Running from Person class.'
Try to pass the class name using the appropriate attribute of the Person class.
In response, call the show_details() class method.
Expected result:
Running from Person class.
class Container:
@classmethod
def show_details(cls):
print(f'Running from {cls.__name__} class.')
class Person:
instances = []
def __init__(self):
Person.instances.append(self)
@classmethod
def count_instances(cls):
return len(Person.instances)
Module 2 Static Method - Decorator
Solution:
import time
class Container:
def get_current_time():
return time.strftime('%H:%M:%S', time.localtime())
get_current_time = staticmethod(get_current_time)
7. Define a Container class that has a static method (use the @staticmethod
decorator) named get_current_time() returning the current time in the format
'%h:%m:%s' , e.g. '09:45:10' .
Tip: Use the built-in time module.
Solution :
import time
class Container:
@staticmethod
def get_current_time():
return time.strftime('%H:%M:%S', time.localtime())
import uuid
class Book:
import uuid
class Book:
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
Expected result:
Book(title=' Python Object Oriented Programming Exercises Volume 2',
author='Edcorner Learning')
import uuid
class Book:
Solution:
import uuid
class Book:
def __repr__(self):
return f"Book(title='{self.title}', author='{self.author}')"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
book1 = Book(' Python Object Oriented Programming Exercises
Volume 2', author='Edcorner Learning')
print(book1)
Module 3 Special Methods
10. Define a Person class that takes two bare attributes: fname (first
name) and Iname (last name).
Then implement the _repr_ ( ) special method to display a
formal representation of the
Person object as shown below:
[IN]: person = Person('John', 'Doe')
[IN]: print(person)
[OUT]: Person(fname='John', lname=’Doe’)
Create an instance of the Person class with the given attributes:
fname = 'Mike'
• lname = 'Smith'
and assign it to the variable person. In response, print the person
instance to the console.
Expected result:
Person(fname='Mike’, lname='Smith')
Solution:
def __repr__(self):
return f"Person(fname='{self.fname}', lname='{self.lname}')"
Solution:
Solution:
class Vector:
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
v1 = Vector(-3, 4, 2)
print(v1)
14. An implementation of the Vector class is given. Implement the
_len_ ( ) special method to return the number of vector
coordinates.
Example:
[IN]: vl = Vector(3, 4, 5)
[IN]: print(len(vl))
[Out]: 3
Create a vector from the RA3 space with coordinates: (-3,4,2) and
assign it to the variable v7. In response, print the number of coordinates
of this vector using the built-in len() function.
Expected result:
3
class Vector:
def __init__(self, *components):
self.components = components
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
15. An implementation of the Vector class is given. Implement the
_bool_( ) special method to return the logical value of vector:
• False in case the first coordinate is zero
• on the contrary True
If the user doesn't pass any argument, return the logical value False.
Example
[IN]: vl = Vector(0, 4, 5)
[IN]: print(bool(vl))
[Out]: False
Then create the following instances:
• vl = Vector()
• v2 = Vector(3, 2)
v3 = Vector(0, -3, 2)
v4 = Vector(5, 0, -1)
In response, print the logical value of the given instances to the console.
Expected result:
False
True
False
True
class Vector:
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
16. An implementation of the Vector class is given. Create the following
instances of this class:
• vl = Vector(4, 2)
• v2 = Vector(-l, 3)
Then try to add these instances, i.e. perform the operation v1 + v2 . If there is
an error, print the error message to the console. Use a try ... except ... clause
in your solution.
Expected result:
unsupported operand type(s) for +: 'Vector' and 'Vector'
class Vector:
def __repr__(self):
return f"Vector{self.components}"
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
17. An implementation of the Vector class is given. Implement the _add_( ) special method to
add Vector instances (by coordinates). For simplicity, assume that the user adds vectors of the same
length. Then create two instances of the Vector class:
vl = Vector(4, 2)
v2 = Vector(-l, 3)
and perform the addition of these vectors. Print the result to the console.
Expected result:
(3,5)
class Vector:
def __init__(self, *components):
self.components = components
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
18. An implementation of the Vector class is given. Create the following
instances of this class:
• vl = Vector(4, 2)
• v2 = Vector(-l, 3)
Then try to subtract these instances (perform the v1 - v2 operation). If there is
an error, print the error message to the console. Use a try ... except ... clause
in your solution.
Expected result:
unsupported operand type(s) for 'Vector' and 'Vector'
class Vector:
def __repr__(self):
return f"Vector{self.components}"
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
def __add__(self, other):
components = tuple(x + y for x, y in zip(self.components,
other.components))
return Vector(*components)
Soluton:
20. An implementation of the Vector class is given. Implement the
_mui ( ) special method that allows you to multiply Vector
instances (by coordinates). For simplicity, assume that the user
multiplies vectors of the same length. Then create two instances of this
class:
• vl = Vector(4, 2)
• v2 = Vector(-l, 3)
and perform the multiplication of these vectors. Print the result to the
console.
Expected result:
(-4,6)
class Vector:
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
v1 = Vector(4, 2)
v2 = Vector(-1, 4)
print(v1 / v2)
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
Solution:
class Vector:
def __repr__(self):
return f'Vector{self.components}'
def __str__(self):
return f'{self.components}'
def __len__(self):
return len(self.components)
v1 = Vector(4, 2)
v2 = Vector(-1, 4)
print(v1 // v2)
23. The following Doc class is implemented for storing text documents.
Implement the _add_ ( ) special method to add Doc instances with a
space character.
Example:
[IN]: docl = Doc('Object')
[IN]: doc2 = Doc('Oriented')
[IN]: print(docl + doc2)
def __repr__(self):
return f"Doc(string='{self.string}')"
def __str__(self):
return f'{self.string}'
24. The following Hashtag class is implemented for storing text
documents - hashtags. Implement the _add_ () special method
to add (concatenate) Hashtag instances using a space character as
shown below (take into account the appropriate number of ■ # ■
characters at the beginning of the new object).
Example:
[IN]: hashtagl = Hashtag('sport')
[IN]: hashtag2 = Hashtag('travel1) [IN]: print(hashtagl + hashtag2)
[OUT]: »sport »travel
Then create three Hashtag instances for the following text documents:
• python
• developer
• oop
In response, print the result of adding these instances.
Expected result:
#python #developer #oop
class Hashtag:
def __repr__(self):
return f"Hashtag(string='{self.string}')"
def __str__(self):
return f'{self.string}'
Solution:
25. The following Doc class is implemented for storing text documents.
Implement the _eq_( )special method to compare Doc instances. Class
instances are equal when they have identical string attribute values.
Example:
[IN]: docl = Doc('Finance')
[IN]: doc2 = Doc('Finance')
[IN]: print(docl == doc2)
[OUT]: True
Then create two instances of the Doc class for the following
documents:
• 'Python'
• '3.8'
In response, print the result of comparing these instances.
Expected result:
False
class Doc:
def __repr__(self):
return f"Doc(string='{self.string}')"
def __str__(self):
return f'{self.string}'
26. The following Doc class is implemented for storing text documents.
Implement the _it_( )
special method to compare Doc instances. A class instance is 'smaller1
than another instance when the string attribute is shorter.
Example:
[IN]: docl = Doc('Finance')
[IN]: doc2 = Doc('Education')
[IN]: print(docl < doc2)
[OUT]: True
Then create two instances of the Doc class for the following
documents:
• 'sport'
• 'activity'
and assign to the variables:
doc1
doc2
In response, print the result of comparing these instances (perform
doc1 < doc2 ).
Expected result:
True
class Doc:
def __repr__(self):
return f"Doc(string='{self.string}')"
def __str__(self):
return f'{self.string}'
Solution:
27. The following Doc class is implemented for storing text documents.
Implement the _iadd_() special method to perform extended
assignments. Concatenate two instances with the string ‘ & ‘
Example:
[IN]:
[IN]:
[IN]:
docl = Doc(1 Finance')
doc2 = Doc('Accounting1)
docl += doc2
[IN]: print(docl)
[OUT]: Finance & Accounting
Then create two instances of the Doc class for the following
documents:
• 'sport'
• 'activity'
and assign according to the variables:
• docl
doc2
Perform extended assignment
• docl + = doc2
Expected result:
sport & activity
class Doc:
def __repr__(self):
return f"Doc(string='{self.string}')"
def __str__(self):
return f'{self.string}'
Solution:
28. The Book class is given. Implement the _str _() method to display
an informal
representation of a Book instance (see below).
Example:
[IN]: bookl = Book('Python OOPS Vol2', 'Edcorner Learning’)
[IN]: print(bookl)
[OUT]: Book ID: 214522 | Title: Python OOPS Vol2 | Author:
Edcorner Learning
Then create an instance named book with arguments:
• title= ‘Python OOPS Vol2’
• author='Edcorner Learning’
In response, print the instance to the console.
Expected result:
Book ID: 1234 | Title: Python OOPS Vol2 | Author: Edcorner
Learning
Note: The Book ID value may vary.
import uuid
class Book:
def __repr__(self):
return f"Book(title='{self.title}', author='{self.author}')"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
Solution:
Module 4 Inheritance
29. The Container class was implemented. Implement two simple classes
inheriting from the class Container with names respectively:
• PlasticContainer
• MetalContainer
class Container:
pass
Solution:
class Container:
pass
class PlasticContainer(Container):
pass
class MetalContainer(Container):
pass
class Container:
pass
class PlasticContainer(Container):
pass
class MetalContainer(Container):
pass
class CustomContainer:
pass
Solution:
class Container:
pass
class PlasticContainer(Container):
pass
class MetalContainer(Container):
pass
class CustomContainer:
pass
print(issubclass(PlasticContainer, Container))
print(issubclass(MetalContainer, Container))
print(issubclass(CustomContainer, Container))
Expected result:
Vehicle(category='land vehicle')
LandVehicle(category='land vehicle1)
AirVehicle(category='air vehicle1)
class Vehicle:
Expected result:
Vehicle -> land vehicle
LandVehlcle -> land vehicle
AlrVehlcle -> air vehicle
class Vehicle:
def __init__(self, category=None):
self.category = category if category else 'land vehicle'
class LandVehicle(Vehicle):
pass
class AirVehicle(Vehicle):
class Vehicle:
34. The Vehicle and Car classes are listed below. Implement a method named
dispiay_attrs() in the base class Vehicle, which displays the instance
attributes and their values. For example, for the Vehicle class:
vehicle = Vehlcle('BMW', 'red', 2020) vehicle.dlsplay_attrs()
brand -> BMW
color -> red
year -> 2020
And for the Car class:
car = Car(‘BMW’, 'red', 2020, 190) car.dlsplay_attrs()
brand -> BMW color -> red
year -> 2020
horsepower -> 190
Then create an instance of the Car class named car with the attribute values: 1
Opel ', 'black', 2018, 160
In response, call dispiay_attrs( ) on the car instance.
Expected result:
brand -> Opel
color -> black
year -> 2018
horsepower -> 160
class Vehicle:
class Car(Vehicle):
def __init__(self, brand, color, year, horsepower):
super().__init__(brand, color, year)
self.horsepower = horsepower
Solution:
35. The Vehicle and Car classes are listed below. Extend the
dispiay_attrs() method in the Car class so that the following
information is displayed before displaying the attributes: ' calling from
class: Car' and then the rest of the attributes with their values. Use super
() for this. For example, for the Car class:
car = Car('BMW', 'red', 2020, 190) car.dlsplay_attrs()
returns:
Calling from class: Car brand -> BMW
color -> red
year -> 2020
horsepower ->
190
Then create an instance of the class Car named car with the attribute
values: ' BMW’
'black', 2018, 260
In response, call display_attrs( ) on the car instance.
Expected result:
Calling from class: Car
brand -> BMW
color -> black
year -> 2018
horsepower -> 260
class Vehicle:
def display_attrs(self):
for attr, value in self.__dict__.items():
print(f'{attr} -> {value}')
class Car(Vehicle):
Solution:
36. Implement simple classes with the following structure:
• Container
• TemperatureControlledContainer • RefrigeratedContainer
The TemperatureControlledContainer class inherits from the Container class
and the RefrigeratedContainer class inherits from
TemperatureControlledContainer.
Solution:
class Container:
pass
class TemperatureControlledContainer(Container):
pass
class RefrigeratedContainer(TemperatureControlledContainer):
pass
class Department:
pass
40. The following classes are defined. Add the _init_() method to the Person
class, which sets three attributes:
• firstname
• lastname
• age
Then create an instance of the Worker class passing the following arguments:
• 'John'
'Doe'
• 35
In response, print the value of the _dict_ attribute of this instance.
Expected result:
{‘first_name’ : 'John', 'last_name': 'Doe', 'age': 35}
class Person:
pass
class Department:
pass
class Worker(Person, Department):
pass
Solution:
41. The following classes are defined. Add a init ( ) method to the
Department class that sets
the following attributes:
• deptname (department name)
• short_dept_name (department short name)
Then create an instance of the Department class with arguments:
• 'Information Technology'
• 'IT'
In response, print the value of the _dict_ attribute of this instance.
Expected result:
{'dept_name': 'Information Technology', 'short_dept_name': 'IT'}
class Person:
Solution:
42. The following classes are defined. Add the _init_( ) method to the Worker
class to set all the attributes from the Person and Department classes.
Then create an instance of the Worker class passing the following arguments:
• 'John'
• 'Doe'
• 30
• 'Information Technology’
• 'IT'
In response, print the value of the _dict_ attribute of this instance.
•
Expected Result:
{'first_name': 'John', 'last_name': 'Doe', 'age': 30, 'dept_name':
'Information Technology', 'short_dept_name': 'IT'}
class Person:
self.short_dept_name = short_dept_name
class Worker(Person, Department):
pass
Solution:
class Person:
Solution:
43. The following classes are defined. Display the MRO - Method
Resolution Order for the Worker class.
Note: The solution that the user passes is in a file named exercise.py,
while the checking code (which is invisible to the user) is executed
from a file named evaluate.py from the level where the classes are
imported. Therefore, instead of the name of the module
_main_ , the response will be the name of the module in which
this class is implemented, in this case exercise .
Expected result:
[<class 'exercise.Worker’>, <class 'exercise.Person'>, <class
'exercise.Departnent’, <class 'object’>]
class Person:
Solution:
class Person:
def __init__(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
self.age = age
class Department:
def __init__(self, dept_name, short_dept_name):
self.dept_name = dept_name
self.short_dept_name = short_dept_name
class Worker(Person, Department)
Solution:
def area(self):
return self.a * self.a
Solution:
from abc import ABC, abstractmethod
class Figure(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Square(Figure):
def area(self):
return self.a * self.a
def perimeter(self):
return 4 * self.a
square = Square(10)
print(square.area())
print(square.perimeter())
46. Create an abstract class named Taxpayer. In the _init_() method set an
instance attribute
(without validation) called salary. Then add an abstract method called
calculate_tax() (use the @abstractmethod decorator).
Solution:
from abc import ABC, abstractmethod
class TaxPayer(ABC):
def __init__(self, salary):
self.salary = salary
@abstractmethod
def calculate_tax(self):
pass
class TaxPayer(ABC):
def __init__(self, salary):
self.salary = salary
@abstractmethod
def calculate_tax(self):
pass
Solution:
from abc import ABC, abstractmethod
class TaxPayer(ABC):
@abstractmethod
def calculate_tax(self):
pass
class StudentTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.15
student = StudentTaxPayer(40000)
print(student.calculate_tax())
@abstractmethod
def calculate_tax(self):
pass
class StudentTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.15
Solution:
from abc import ABC, abstractmethod
class TaxPayer(ABC):
@abstractmethod
def calculate_tax(self):
pass
class StudentTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.15
class DisabledTaxPayer(TaxPayer):
def calculate_tax(self):
return min(self.salary * 0.12, 5000.0)
disabled = DisabledTaxPayer(50000)
print(disabled.calculate_tax())
49. An implementation of the Taxpayer abstract class is given.
Create a class derived from the TaxPayer class named WorkerTaxPayer
that implements the caicuiate_tax( ) method that calculates the tax
value according to the rule:
• up to the amount of 80,000 -> 17% tax rate
• everything above 80,000 -> 32% tax rate
Then create two instances of WorkerTaxPayer named workerl and
worker2 and salaries of 70,000 and 95,000 respectively. In response, by
calling caicuiate_tax() print the calculated tax for both instances to the
console.
Expected result:
11900.0
18400.0
from abc import ABC, abstractmethod
class TaxPayer(ABC):
def __init__(self, salary):
self.salary = salary
@abstractmethod
def calculate_tax(self):
pass
class StudentTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.15
class DisabledTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.12
Solution:
from abc import ABC, abstractmethod
class TaxPayer(ABC):
@abstractmethod
def calculate_tax(self):
pass
class StudentTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.15
class DisabledTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.12
class WorkerTaxPayer(TaxPayer):
def calculate_tax(self):
if self.salary < 80000:
return self.salary * 0.17
else:
return 80000 * 0.17 + (self.salary - 80000) * 0.32
worker1 = WorkerTaxPayer(70000)
worker2 = WorkerTaxPayer(95000)
print(worker1.calculate_tax())
print(worker2.calculate_tax())
def calculate_tax(self):
if self.salary < 80000:
return self.salary * 0.17
else:
return 80000 * 0.17 + (self.salary - 80000) * 0.32
Solution:
from abc import ABC, abstractmethod
class TaxPayer(ABC):
def __init__(self, salary):
self.salary = salary
@abstractmethod
def calculate_tax(self):
pass
class StudentTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.15
class DisabledTaxPayer(TaxPayer):
def calculate_tax(self):
return self.salary * 0.12
class WorkerTaxPayer(TaxPayer):
def calculate_tax(self):
if self.salary < 80000:
return self.salary * 0.17
else:
return 80000 * 0.17 + (self.salary - 80000) * 0.32
tax_payers = [StudentTaxPayer(50000),
DisabledTaxPayer(70000),
WorkerTaxPayer(68000), WorkerTaxPayer(120000)]
for tax_payer in tax_payers:
print(tax_payer.calculate_tax())
Module 6 Miscelleanuoes Exercises
51. The people list is given. Sort the objects in the people list ascending by
age. Then print the name and age to the console as shown below.
Expected result:
Alice-> 19
Tom ->25
Mike -27
John -> 29
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
people = [Person('Tom', 25), Person('John', 29),
Person('Mike', 27), Person('Alice', 19)]
Solution:
52. The following Point class is given. Implement a reset ( ) method that
allows you to set the values of the x and y attributes to zero. Then create an
instance of the Point class with coordinates (4, 2) and print it to the console.
Call the reset ( ) method on this instance and print the instance to the console
again.
Expected result:
Point(x=4, y=2)
Point(x=0, y=0)
class Point:
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
Solution:
def __repr__(self):
return f"Point(x={self.x}, y={self.y})"
def reset(self):
self.x = 0
self.y = 0
Solution:
54. Implement a class called Note that describes a simple note. When creating
Note objects, an instance attribute called content will be set with the contents
of the note. Also add instance attribute called creationjime that stores the
creation time (use the given date format: '%m-%d- %Y %H:%M:%S' ).
Next, create two instances of the Note class named notel and note2, and
assign the following contents:
'My first note.'
'My second note.'
Solution:
import datetime
class Note:
55. The Note class is given. Implement a find( ) method that checks if a
given word is in the note (case sensitive). The method should return
True or False, respectively.
Then create an instance named notel with the contents of the note:
'Object Oriented Programming in Python.'
On the notel instance call the find() method to check if the note
contains the following words:
• 'python'
• 'Python'
Print the result to the console.
Expected result:
False
True
import datetime
class Note:
Solution:
56. The Note class is given. Implement a find( ) method that checks if a
given word is in the note (case insensitive). The method should return
True or False, respectively.
Then create an instance named notel with the contents of the note:
'Object Oriented Programming in Python.'
On the note7 instance call the find() method to check if the note
contains the following words:
'python'
'Python'
Print the result to the console.
Expected result:
True
True
import datetime
class Note:
def __init__(self, content):
self.content = content
self.creation_time = datetime.datetime.now().strftime('%m-%d-%Y
%H:%M:%S')
Solution:
Solution:
58. Implementations of the Note and Notebook class are given.
Implement a method named dispiay_notes( ) in the Notebook class to
display the content of all notes of the notes instance attribute to the
console.
Create an instance of the Notebook class named notebook. Then, using
the new_note() method add two notes to the notebook with the
following content:
• 'My first note.'
• 'My second note.'
In response, call dispiay_notes() method on the notebook instance.
Expected result:
My first note.
My second note.
import datetime
class Note:
def __init__(self, content):
self.content = content
self.creation_time = datetime.datetime.now().strftime('%m-%d-
%Y %H:%M:%S')
def __repr__(self):
return f"Note(content='{self.content}')"
def find(self, word):
return word.lower() in self.content.lower()
class Notebook:
def __init__(self):
self.notes = []
def new_note(self, content):
self.notes.append(Note(content))
Solution:
Solution:
59. Implementations of the Note and Notebook class are given. Implement a
method called search() in the Notebook class that allows you to return a list
of notes containing a specific word (passed as an argument to the method,
case insensitive). You can use the Note.find method for this.
Create an instance of the Notebook class named notebook. Then, using the
new_note() method add notes to the notebook with the following content:
• 'Big Data'
• 'Data Science'
• 'Machine Learning'
In response, call the search() method on the notebook instance looking for
notes that contain the Word 'data' .
Expected result:
[Note(content='Big Data'), Note(content='Data Science')]
import datetime
class Note:
def __repr__(self):
return f"Note(content='{self.content}')"
def __init__(self):
self.notes = []
def new_note(self, content):
self.notes.append(Note(content))
def display_notes(self):
for note in self.notes:
print(note.content)
def search(self, value):
return [note for note in self.notes if note.find(value)]
notebook = Notebook()
notebook.new_note('Big Data')
notebook.new_note('Data Science')
notebook.new_note('Machine Learning')
print(notebook.search('data'))
60. Implement a class named Client which has a class attribute named
all_clients (as a list). Then the _init_( ) method sets two instance
attributes (no validation):
• name
• email
Add this instance to the alLclients list (Client class attribute). Also add a
_repr_( ) method
the Client class (see below).
Create three clients by executing the following code:
Clientl = Client(‘Tom’, ‘[email protected]’)
client2 = Client(‘Donald', ‘[email protected]’)
client3 = Client('Mike’, ‘[email protected]’)
In response, print the all_cients attribute of the Client class.
Expected Result:
[Client(name='Tom', email='[email protected]'),
Client(name='Donald', email='[email protected]'), Client(name='Mike',
email='[email protected]')]
Solution:
class Client:
all_clients = []
61. The Client class is implemented. Note the class attribute all_clients. Try
to implement a special class extending the built-in list class called ClientList,
which in addition to the standard methods for the built-in class list will have a
search_emaii() method that allows you to return a list of Client class
instances containing the text (value argument) in the email address.
For example, the following code:
Clientl = Client(‘Tom’, ‘[email protected]’)
client2 = Client(‘Donald', ‘[email protected]’)
client3 = Client('Mike’, ‘[email protected]’)
client4 = Client(1 Lisa1, '[email protected]' )
print(Client.all_clients.search_email('sales'))
class ClientList(list)
def search_email(self, value):
pass
class Client:
all_clients = ClientList()
def __init__(self, name, email):
self.name = name
self.email = email
Client.all_clients.append(self)
def __repr__(self):
return f"Client(name='{self.name}', email='{self.email}')"
Solution:
class ClientList(list):
class Client:
all_clients = ClientList()
def __init__(self, name, email):
self.name = name
self.email = email
Client.all_clients.append(self)
def __repr__(self):
return f"Client(name='{self.name}', email='{self.email}')"
class ClientList(list):
class Client:
all_clients = ClientList()
def __repr__(self):
return f"Client(name='{self.name}', email='{self.email}')"
Solution:
63. The Client class is implemented. The following four instances of the
Client class:
class ClientList(list):
class Client:
all_clients = ClientList()
def __repr__(self):
return f"Client(name='{self.name}', email='{self.email}')"
client1 = Client('Tom', '[email protected]')
client2 = Client('Donald', '[email protected]')
client3 = Client('Mike', '[email protected]')
client4 = Client('Lisa', '[email protected]')
Solution:
64. Create a class named CustomDict that extends the built-in diet
class. Add a method named is_any_str_vaiue() that returns a boolean
value:
• True in case the created dictionary contains at least one value of
str type
• otherwise False.
Example I:
[IN]: cd = CustonDict(python=’mid')
[IN]: print(cd.ls_any_str_value())
returns:
[OUT]: True
Example II:
[IN]: cd = CustomDict(price=119.99)
[IN]: print(cd.ls_any_str_value())
returns:
[OUT]: False
You only need to implement the CustomDict class.
Solution:
class CustomDict(dict):
def is_any_str_value(self):
flag = False
for key in self:
if isinstance(self[key], str):
flag = True
break
return flag
65. Create a class named StringListOnly that extends the built-in list
class. Modify the behavior of the append () method so that only objects
of str type can be added to the list. If you try to add a different type of
object raise TypeE rror with message:
'Only objects of type str can be added to the list.'
Then create an instance of the StringListOnly class and add the
following objects with the append() method:
'Data'
'Science'
In response, print result to the console.
Expected result:
['Data', 'Science']
Solution:
66. Create a class named StringListOnly that extends the built-in list
class. Modify the behavior of the append() method so that only objects
of str type an be added to the list. Replace all uppercase letters with
lowercase before adding the object to the list. If you try to add a
different type of object raise TypeE rror with message:
'Only objects of type str can be added to the list.'
Then create an instance of the StringListOnly class and add the
following objects with the append() method:
'Data'
• 'Science'
• 'Machine Learning'
In response, print result to the console.
Expected result:
['data', 'science', 'machine learning']
Solution:
67. An implementation of the Product class is given. Implement a class
named Warehouse which in the init ( ) method sets an
instance attribute of the Warehouse class named products to
an empty list.
Then create an instance of the Warehouse class named warehouse and
display the value of the products attribute to the console.
Expected result:
[]
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
Solution:
68. The implementation of the classes: Product and Warehouse is given. To
the Warehouse class, add a method named add_product( ) that allows you to
add an instance of the Product class to the products list. If the product name
is already in the products list, skip adding the product.
Next, create an instance of the Warehouse class named warehouse. Using the
add_product() method add the following products:
'Laptop', 3900.0
'Mobile Phone', 1990.0
'Mobile Phone', 1990.0
Note that the second and third products are duplicates. The add_product()
method should avoid adding duplicates. Print the products attribute of the
warehouse instance to the console.
Expected result:
[Product(product_name='Laptop', price=3900.0),
Product(product_name='Mobile Phone', price=1990.0)]
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
Solution:
import uuid
class Product:
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
warehouse = Warehouse()
warehouse.add_product('Laptop', 3900.0)
warehouse.add_product('Mobile Phone', 1990.0)
print(warehouse.products)
69. The implementation of the classes: Product and Warehouse is given. To
the Warehouse class, add a method named remove_product( ) that allows you
to remove an instance of the Product class from the products list with a given
product name. If the product name is not in the products list, just skip.
Next, create an instance of the Warehouse class named warehouse. Using the
add_product() method add the following products:
'Laptop', 3900.0
'Mobile Phone', 1990.0
• 'Camera', 2900.0
Then, using the remove_product() method, remove the product named
'Mobile Phone' . In response, print the products attribute of the warehouse
instance to the console.
Expected result:
[Product(product_name='Laptop', price=3900.0),
Product(product_name='Camera', price=2900.0)]
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
Solution:
import uuid
class Product:
def __init__(self, product_name, price):
self.product_id = self.get_id()
self.product_name = product_name
self.price = price
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
def __str__(self):
return f'Product Name: {self.product_name} | Price: {self.price}'
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
71. The implementation of the classes: Product and Warehouse is given. Add
a method to the Warehouse class named dispiay_products() that displays all
products in the products attribute of the Warehouse class.
Then create an instance of the Warehouse class named warehouse and
execute the following code:
warehouse.add_product(1 Laptop', 3900.0)
warehouse.add_product('Mobile Phone', 1990.0)
warehouse.add_product('Cañera', 2900.0)
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
def __str__(self):
return f'Product Name: {self.product_name} | Price: {self.price}'
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
def __str__(self):
return f'Product Name: {self.product_name} | Price: {self.price}'
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
def display_products(self):
for product in self.products:
print(product)
warehouse = Warehouse()
warehouse.add_product('Laptop', 3900.0)
warehouse.add_product('Mobile Phone', 1990.0)
warehouse.add_product('Camera', 2900.0)
warehouse.display_products()
72. The implementation of the classes: Product and Warehouse is
given. Add a method called sort_by_price( ) to the Warehouse class
that returns an alphabetically sorted list of products. The sort_by_price(
) method also takes an argument ascending set to True by default,
which means an ascending sort. If False is passed, reverse the sort
order.
Then create an instance of the Warehouse class named warehouse and
execute the following code:
warehouse.add_product(1 Laptop', 3900.0)
warehouse.add_product('Mobile Phone', 1990.0)
warehouse.add_product('Cañera', 2900.0)
warehouse.add_product('USB Cable', 24.9)
warehouse.add_product('House', 49.0)
In response, use the sort_by_price( ) method to print a sorted list of
products to the console as shown below.
Expected result:
Product(product_name='USB Cable', price=24.9)
Product(product_name='Mouse', price=49.0)
Product(product_name='Mobile Phone', price=1990.0)
Product(product_name='Camera', price=2900.O)
Product(product_name='Laptop', price=3900.0)
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}',
price={self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
def display_products(self):
for product in self.products:
print(f'Product ID: {product.product_id} | Product name: '
f'{product.product_name} | Price: {product.price}')
Solution:
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
def display_products(self):
for product in self.products:
print(f'Product ID: {product.product_id} | Product name: '
f'{product.product_name} | Price: {product.price}')
warehouse = Warehouse()
warehouse.add_product('Laptop', 3900.0)
warehouse.add_product('Mobile Phone', 1990.0)
warehouse.add_product('Camera', 2900.0)
warehouse.add_product('USB Cable', 24.9)
warehouse.add_product('Mouse', 49.0)
for product in warehouse.sort_by_price():
print(product)
73. The implementation of the classes: Product and Warehouse
is given. Complete the implementation of the method named
search_product( ) of the Warehouse class that allows you to return a list
of products containing the specified name ( query argument).
Then create an instance of the Warehouse class named warehouse and
execute the following code:
warehouse.add_product(1 Laptop', 3900.0)
warehouse.add_product('Mobile Phone', 1990.0)
warehouse.add_product('Cañera', 2900.0)
warehouse.add_product(1 USB Cable', 24.9)
warehouse.add_product(1 Mouse1, 49.0)
In response, call search_product() method and find all products that
contain the letter 'm'.
Expected Result:
[Product(product_name='Mobile Phone', price=1990.0),
Product(product_name='Mouse', price=49.0)]
import uuid
class Product:
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
def display_products(self):
for product in self.products:
print(f'Product ID: {product.product_id} | Product name: '
f'{product.product_name} | Price: {product.price}')
def __repr__(self):
return f"Product(product_name='{self.product_name}', price=
{self.price})"
@staticmethod
def get_id():
return str(uuid.uuid4().fields[-1])[:6]
class Warehouse:
def __init__(self):
self.products = []
def add_product(self, product_name, price):
product_names = [product.product_name for product in
self.products]
if not product_name in product_names:
self.products.append(Product(product_name, price))
def display_products(self):
for product in self.products:
print(f'Product ID: {product.product_id} | Product name: '
f'{product.product_name} | Price: {product.price}')
Edcredibly App –
https://play.google.com/store/apps/details?id=com.edcredibly.courses