Learn Modern Ai Python 00 Python
Learn Modern Ai Python 00 Python
panaversity /
learn-modern-ai-python
main
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesso… 1/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
source: https://news.mit.edu/2016/scene-at-mit-margaret-hamilton-apollo-code-0817
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesso… 2/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
In 2003, a Tech researcher Ron Burkey uploaded a scanned copy of the Code online.
MIT Programmers created a “Special Assembly Language” for it. This language is
complicated to understand for humans but can be interpreted by computers very easily.
This complete Code consists of 145,000 lines that successfully landed Apollo 11 on
moon.
Source Code: Original Apollo 11 guidance computer (AGC) source code for Command
Module (Comanche055) and Lunar Module (Luminary099)
Source: https://medium.com/@sachinmittal24687/code-to-moon-apollo-11-mission-
f06468649d7c
She started working as MIT Programmer in 1959. Margaret Hamilton became the led
programmer of this project. She used to spent hours in the lab writing code and making
it error free. She often brought her 4 years old daughter Lauren to work at night
and on weekends.
This Code was written so perfectly that no bugs were founded in code at the time of
future Apollo missions. In 2003, NASA honored her achievements with the largest
financial award. She also got the Presidential Medal of Freedom.
Lesson for us: America is America because of these kind of hard working people,
with persistence and dedication we can also achieve greatness, whether it's
landing on the moon, exploring Mars, or tackling other seemingly insurmountable
(too great to be overcome) challenges.
1. What is OOP?
Object-Oriented Programming (OOP) is a programming paradigm that organizes
software design around objects and classes, rather than functions and logic. An object
is an instance of a class, which is a blueprint for creating objects. OOP focuses on
modeling real-world entities and their relationships in a more intuitive and
structured way.
For example, if you’re building a car simulation, you might create a Car class. Each car in
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesso… 3/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
p y g y g
your program would be an object (instance) of that class, with attributes like color,
speed, and model, and behaviors like accelerate() or brake().
2. Reusability: Classes and objects can be reused across different parts of a program
or in entirely different programs.
3. Maintainability: Code is easier to maintain and update because it’s organized into
logical units.
1. Encapsulation:
Encapsulation is the bundling of data (attributes) and methods (functions) that operate
on the data into a single unit (a class). It also restricts direct access to some of an
object’s components, which is a way of preventing unintended interference. Example:
In [ ]: class Car:
def __init__(self, color, speed):
self.color = color # Public attribute
self.__speed = speed # Private attribute (encapsulated)
def accelerate(self):
self.__speed += 10
def get_speed(self):
return self.__speed
Test Case:
In [ ]: car = Car("red", 0) # Provide values for color and speed
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesso… 4/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
print("Current speed: ", car.get_speed()) # Call the get_speed method
# speed up bro
for i in range(10):
car.accelerate()
Current speed: 0
Speed after acceleration: 100
2. Abstraction:
Abstraction means hiding complex implementation details and exposing only the
necessary features of an object. It helps reduce complexity and allows the programmer
to focus on interactions at a higher level.
Example:
You don’t need to know how a car’s engine works to drive it. Similarly, a Car class might
expose a drive() method without revealing the internal mechanics.
In [ ]: # Define a Car class with abstraction and idle stop engine feature
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
self._engine_status = False
self._idling_time = 0
self._traffic_signal = None
# Internal method to stop the engine if idling for 5 seconds (hidden from
def _idle_stop_engine(self):
import time
print("Engine is idling...")
for i in range(5):
print(f"Idling time: {i+1} seconds")
time.sleep(1)
self._idling_time += 1
if self._idling_time >= 5:
self._engine_status = False
print("Engine stopped (idle stop) to save fule.")
Traffic signal turned green. You can drive your Toyota Camry.
Engine started.
You are driving a Toyota Camry.
Traffic signal turned red. You stopped in a Toyota Camry.
Engine is idling...
Idling time: 1 seconds
Idling time: 2 seconds
Idling time: 3 seconds
Idling time: 4 seconds
Idling time: 5 seconds
Engine stopped (idle stop) to save fule.
Traffic signal turned green. You can drive your Toyota Camry.
Engine started.
You are driving a Toyota Camry.
Engine started.
2. The internal mechanics of the car (e.g., starting and stopping the engine, idling
time, and traffic signal logic) are hidden from the user and are handled by the
_start_engine and _idle_stop_engine methods.
3. The user doesn't need to know how the engine works or how the idle stop feature
is implemented; they just need to call the drive , stop , and
set_traffic_signal methods.
In [ ]: class ShoppingMall:
def basement_parking():
my_car = Car("Toyota", "Camry")
my_car._start_engine()
basement_parking();
Engine started.
In Python, methods that start with an underscore ( _ ) are considered private or internal
methods. This means they are not intended to be called directly from outside the class.
However, Python does not enforce this rule strictly, and you can still call these methods
directly if you want to.
3. Future changes: If the internal implementation of the Car class changes, the
_start_engine method may no longer be needed or may need to be modified.
By calling it directly, you are tightly coupling your code to the internal
implementation of the class, which can make it harder to maintain.
In [ ]: class BMW(Car):
def __init__(self, brand, model):
super(). init (brand, model)
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesso… 7/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
p () __ __( , )
def start_engine(self):
self._start_engine() # Car class private method is visible in child class
def _start_engine(self): # Overrides the parent method with the same name
print("BMW engine started") # Even you can override it
3. Inheritance:
Inheritance allows a class (child class) to inherit attributes and methods from another
class (parent class). This promotes code reuse and establishes a hierarchical relationship
between classes. Example:
In [ ]: class Vehicle:
def __init__(self, color, speed):
self.color = color
self.speed = speed
def drive(self):
print("Driving Speed = ", self.speed)
def accelerate(self):
self.speed += 10
Test Case:
In [ ]: car = Car("red", 120)
truck = Truck("blue", 80)
car.drive()
truck.drive()
In [ ]: for i in range(6):
car.accelerate()
car.drive()
# check truck speed
truck.drive()
4. Polymorphism:
Polymorphism allows objects of different classes to be treated as objects of a common
superclass. It enables flexibility and dynamic behavior in your code.
Example:
class Animal(ABC):
@abstractmethod
def speak(self) -> None:
pass
class Dog(Animal):
def speak(self) -> None:
print(type(self), ": Woof!")
class Cat(Animal):
def speak(self) -> None:
print(type(self), ": Meow!")
dog = Dog()
cat = Cat()
animal_sound(dog) # Output: Woof!
animal_sound(cat) # Output: Meow!
Conclusion
Object-Oriented Programming is a powerful paradigm that helps you write clean,
modular, and maintainable code. By mastering encapsulation, abstraction, inheritance,
and polymorphism, you’ll be well-equipped to tackle complex programming challenges.
Whether you’re building a small script or a large-scale application, OOP is an essential
tool in your programming toolkit.
Happy coding! 🚀
What is a Class?
A class is a blueprint or template for creating objects. It defines the attribute (data) and
methods (functions) that the objects created from the class will have. Think of a class as
a cookie cutter, and the objects as the cookies made from it.
For example, if you’re creating a program to manage vehicles, you might define a
Vehicle class with attributes like color, speed, and model, and methods like accelerate()
and brake().
What is an Object?
An object is an instance of a class. It’s a specific realization of the class, with its own
unique data. For example, if Vehicle is a class, then my_car and your_car could be
objects (instances) of that class, each with its own color, speed, and model.
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 10/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
In [ ]: class ClassName:
pass
# Class body
For example, in a Vehicle class, color and speed could be attributes, and accelerate() and
brake() could be methods.
Instantiating Objects
To create an object (instance) of a class, you call the class name like a function. This
invokes the __init__ method (the constructor) to initialize the object.
__ (double underscore)
# Access attributes
print(f"My car is {my_car.color}.") # Output: My car is Red.
# Call methods
my_car.accelerate(20) # Output: Accelerating! New speed: 80 km/h
my_car.brake(10) # Output: Braking! New speed: 70 km/h
my_car.display() # Output: Vehicle color: Red, Current speed: 70 km/h
My car is Red.
Accelerating! New speed: 80 km/h
Braking! New speed: 70 km/h
Vehicle color: Red, Current speed: 70 km/h
2. Attributes: The color and speed attributes are initialized in the constructor using
the self keyword.
3. Methods: The accelerate and brake methods modify the speed attribute, while the
display method prints the current state of the object.
4. Object Creation: An object my_car is created from the Vehicle class with the color
"Red" and speed 60.
5. Accessing Attributes and Methods: Attributes are accessed using dot notation
(my_car.color), and methods are called using parentheses (my_car.accelerate(20)).
Key Takeaways
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 12/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
Key Takeaways
A class is a blueprint for creating objects.
An object is an instance of a class.
Attributes define the state of an object, and methods define its behavior.
The self keyword is used to refer to the current instance of the class.
Objects are created by calling the class name like a function.
This example demonstrates the basics of creating and using classes and objects in
Python. As you progress, you’ll see how these concepts form the foundation of more
advanced OOP techniques! 🚀
What is a Constructor?
A constructor is a special method that is automatically called when an object of a class
is created. It’s used to initialize the object’s attributes or perform any setup required for
the object.
Syntax:
In [ ]: class ClassName:
def __init__(self, parameters):
pass
# Initialization code
Parameterized Constructors
A parameterized constructor takes parameters (arguments) when creating an object
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 13/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
A parameterized constructor takes parameters (arguments) when creating an object.
These parameters are used to initialize the object’s attributes.
Example:
In [ ]: class Person:
def __init__(self, name, age):
self.name = name
self.age = age
Alice
30
Default Constructors
If you don’t define an __init__ method in your class, Python provides a default
constructor that does nothing. However, you can define an init method without
parameters to act as a default constructor.
Example:
In [ ]: class Dog:
def __init__(self):
self.name = "Unknown"
self.age = 0
Unknown
0
Syntax:
In [ ]: class ClassName:
def __del__(self):
pass
# Cl d
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 14/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
# Cleanup code
In [ ]: class Car:
# Parameterized constructor
def __init__(self, brand, model):
self.brand = brand
self.model = model
print(f"A {self.brand} {self.model} has been created.")
# Destructor
def __del__(self):
print(f"The {self.brand} {self.model} has been destroyed.")
A Toyota Corolla has been created.
My car is a Toyota Corolla.
Car: Toyota Corolla
The Toyota Corolla has been destroyed.
2. Destructor (__del__): The __del__ method prints a message when the object is
destroyed. This is triggered automatically when the object goes out of scope or is
explicitly deleted using the del keyword.
3. Object Creation: An object my_car is created with the brand "Toyota" and model
"Corolla". The constructor is called automatically.
4. Object Deletion: The del keyword is used to explicitly delete the my_car object,
which triggers the destructor.
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 15/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
Key Takeaways
A constructor (__init__) is used to initialize an object when it is created.
A parameterized constructor takes arguments to initialize object attributes.
A default constructor is provided by Python if you don’t define an init method. A
destructor (__del__) is called when an object is about to be destroyed, and it’s used
for cleanup tasks.
The self keyword is used to refer to the current instance of the class.
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 16/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
In [ ]: class Dog:
# Class attribute (shared by all instances)
species = "Canis familiaris"
Dog species: Canis familiaris
Buddy's species: Canis familiaris
Max's species: Canis familiaris
Buddy's name: Buddy
Max's age: 3
Buddy's species after modification: Canis lupus
Max's species after modification: Canis lupus
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 17/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
p p
Buddy's species after shadowing: Canis aureus
Max's species remains: Canis lupus
Dog class attributes: {'__module__': '__main__', 'species': 'Canis lupus', '__in
it__': <function Dog.__init__ at 0x78cc0bdae0c0>, 'display': <function Dog.displ
ay at 0x78cc0bdae160>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__w
eakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}
dog1 instance attributes: {'name': 'Buddy', 'age': 5, 'species': 'Canis aureus'}
dog2 instance attributes: {'name': 'Max', 'age': 3}
The species attribute is defined at the class level and is shared by all instances of the
Dog class.
The name and age attributes are defined in the init method and are unique to each
instance of the Dog class.
3. Accessing Attributes:
Class attributes can be accessed using the class name (Dog.species) or an instance
(dog1.species).
Instance attributes are accessed using an instance (dog1.name).
4. Modifying Attributes:
Modifying a class attribute through the class (Dog.species = "Canis lupus") affects
all instances.
Modifying a class attribute through an instance (dog1.species = "Canis aureus")
creates a new instance attribute, shadowing the class attribute.
The dict attribute provides a dictionary of all attributes and their values for a class or
instance.
Key Takeaways
Class attributes are shared by all instances of a class, while instance attributes are
unique to each instance.
Class attributes can be accessed using the class name or an instance, but
modifying them through an instance creates a new instance attribute.
The __dict__ attribute is useful for inspecting the attributes of a class or object.
This example demonstrates how to work with class and instance attributes in Python
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 18/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
effectively. 🚀
1. Instance Methods
Definition: Instance methods are the most common type of methods. They operate
on an instance of the class and can access and modify instance attributes.
First Parameter: The first parameter is always self, which refers to the instance of
the class.
Usage: Used for methods that need to access or modify instance-specific data.
First Parameter: The first parameter is always cls, which refers to the class.
Usage: Used for methods that need to work with class-level data or perform
operations related to the class.
Usage: Used for utility functions that don’t depend on class or instance data.
In [ ]: class Person:
# Class attribute
species = "Homo sapiens"
# Constructor
def __init__(self, name, age):
self.name = name # Instance attribute
self.age = age # Instance attribute
# Instance method
def display(self):
print(f"{self.name} is {self.age} years old and is a {self.species}."
# Class method
@classmethod
def update_species(cls, new_species):
cls.species = new_species
print(f"Species updated to {cls.species}.")
# Static method
@staticmethod
def is_adult(age):
return age >= 18
Alice is 25 years old and is a Homo sapiens.
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 20/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
ce s 5 yea s o d a d s a o o sap e s.
Species updated to Homo sapiens sapiens.
Alice is 25 years old and is a Homo sapiens sapiens.
Is Alice an adult? True
2. Class Method (update_species): Operates on the class (cls) and modifies the class
attribute (species).
3. Static Method (is_adult): Doesn’t depend on the class or instance. It’s a utility
function that checks if a given age is 18 or older.
Key Takeaways
Instance methods are used for operations on instance data.
Static methods are used for utility functions that don’t depend on class or instance
data.
The self keyword refers to the instance, and the cls keyword refers to the class.
This example demonstrates how to implement and use different types of methods in
Python classes effectively. 🚀
6. Encapsulation
Encapsulation is one of the core principles of Object-Oriented Programming (OOP).
It refers to the bundling of data (attributes) and methods (functions) that operate on the
data into a single unit (a class). Encapsulation also involves restricting direct access to
some of an object’s components, which is a way of preventing unintended interference
and misuse of data.
1. Public:
2. Protected:
Attributes and methods are intended for internal use within the class and its
subclasses.
A single underscore _ is used as a prefix. Example: _age
3. Private:
Attributes and methods are accessible only within the class itself.
A double underscore __ is used as a prefix. Example: __salary
In [ ]: class BankAccount:
def __init__(self, account_holder, balance):
self.account_holder = account_holder # Public attribute
self._balance = balance # Protected attribute
self.__pin = "1234" # Private attribute
Account Holder: Alice
Balance: 1000
Access denied. PIN is private.
Initial Balance: 1000
Balance updated to 1500.
Invalid amount. Balance cannot be negative.
Account Holder: Alice
Balance: 1500
2. Protected Attribute (_balance): Intended for internal use but can still be accessed
directly (though not recommended). Getter and setter methods (get_balance and
set_balance) are provided for controlled access.
4. Getter and Setter Methods: get_balance retrieves the value of the protected
attribute _balance. set_balance updates the value of _balance after validating the
input.
Key Takeaways
Encapsulation bundles data and methods into a single unit (class) and restricts
direct access to some components.
Getter and setter methods provide controlled access to protected and private
attributes.
7. Inheritance
Inheritance is one of the core principles of Object-Oriented Programming (OOP). It
allows a class (called a child class or subclass) to inherit attributes and methods from
another class (called a parent class or superclass). This promotes code reuse and
establishes a hierarchical relationship between classes.
Types of Inheritance
1. Single Inheritance:
2. Multiple Inheritance:
Method Overriding
Method overriding occurs when a subclass provides a specific implementation of a
method that is already defined in its superclass. The subclass method overrides the
superclass method.
Single Inheritance
In [ ]: # Parent class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "Animal sound"
Multiple Inheritance
In [ ]: # First parent class
class Bird:
def fly(self):
return "Flying high!"
Flying high!
Swimming deep!
def display(self):
return f"{self.brand} {self.model}"
The Dog class inherits from the Animal class and overrides the speak method.
2. Multiple Inheritance:
The FlyingFish class inherits from both the Bird and Fish classes, gaining access to their
methods.
3. Using super():
The Car class uses super() to call the constructor of the Vehicle class and extends it with
an additional attribute (year).
4. Method Overriding:
The Car class overrides the display method of the Vehicle class to include the year
attribute
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 26/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
attribute.
Key Takeaways
Inheritance allows a class to inherit attributes and methods from another class.
Single inheritance involves one parent class and one child class.
Multiple inheritance involves multiple parent classes and one child class.
The super() function is used to call methods from the parent class.
8. Polymorphism
Polymorphism is one of the core principles of Object-Oriented Programming
(OOP). It refers to the ability of different classes to be treated as instances of the same
class through a common interface. In simpler terms, polymorphism allows objects of
different types to be used interchangeably if they share a common behavior.
2. Operator Overloading:
Customizing the behavior of operators (e.g., +, -, *, etc.) for user-defined classes using
special methods like add, sub, etc.
3. Duck Typing:
Python uses duck typing, which means that the type or class of an object is determined
by its behavior (methods and properties) rather than its inheritance. If an object behaves
like a duck, it’s treated as a duck.
Method Overriding
In [ ]: # Parent class
class Animal:
def speak(self):
return "Animal sound"
# Child classes
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
Woof!
Meow!
Operator Overloading
In [ ]: class Point:
def __init__(self, x, y):
self.x = x
self.y = y
Point(4, 6)
Duck Typing
In [ ]: class Duck:
def quack(self):
return "Quack!"
class Person:
def quack(self):
return "I can quack like a duck!"
Quack!
I can quack like a duck!
The Dog and Cat classes override the speak method of the Animal class. The
animal_sound function demonstrates polymorphism by accepting any object that has a
speak method.
2. Operator Overloading:
The Point class overloads the + operator using the add method. It also overrides the str
method to customize how the object is printed.
3. Duck Typing:
The make_it_quack function accepts any object that has a quack method, regardless of
its class. This demonstrates Python’s duck typing philosophy.
Key Takeaways
Polymorphism allows objects of different types to be treated as instances of the
same class through a common interface.
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 29/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
Method overriding enables a subclass to provide a specific implementation of a
method defined in its superclass.
9. Abstraction
Abstraction helps us focus on what something does, not how it does it. Think of it like a
TV remote—you press buttons without needing to know the internal circuits. In Python,
we use abstract classes to create blueprints for other classes.
What is Abstraction?
Abstraction simplifies complex systems by breaking them into manageable parts. For
example, all vehicles (cars, bikes) must have a start() method, but each vehicle starts
differently. Abstraction lets us enforce this rule without worrying about implementation
details.
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
Key components:
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 30/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
class Shape(ABC):
@abstractmethod
def calculate_area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def calculate_area(self):
return 3.14 * self.radius ** 2
class Square(Shape):
def __init__(self, side):
self.side = side
def calculate_area(self):
return self.side * self.side
Abstraction acts like a parenting agreement—"All my children must do these tasks, but I
don't care how they do them." This makes code more organized and prevents forgetting
important methods when creating new classes.
Test Case:
In [ ]: import pytest
#import Shape, Circle, Square # Replace with actual import path
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 31/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
def test_zero_radius_area(self):
assert Circle(0).calculate_area() == 0
def test_large_radius(self):
assert Circle(100).calculate_area() == 3.14 * 100**2
def test_zero_size_square(self):
assert Square(0).calculate_area() == 0
def test_negative_side(self):
"""Demonstrates handling of negative values (current code allows this
assert Square(-3).calculate_area() == 9 # (-3)² = 9
square = Square(4)
print("square.calculate_area(): ", square.calculate_area())
circle.calculate_area(): 78.5
square.calculate_area(): 16
2. Core calculations: Verifies area formulas using both normal and edge cases
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 32/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
object is the root of the class hierarchy. If you define a class without specifying a
base class, it implicitly inherits from object.
2. Default Methods:
The object class provides default implementations for several important methods
that are inherited by all other classes.
3. Universal Behavior:
Since all classes inherit from object, methods and attributes defined in object are
available to all objects in Python.
In Python, the object class is the root of the class hierarchy and provides default
implementations for many fundamental methods. While you cannot directly inspect the
internal structure of the object class (as it is implemented in C in CPython), you can
explore its methods and attributes using built-in functions like dir() and help().
Here’s an overview of the structure and key methods provided by the object class:
3. Attribute Access
__getattribute__(self, name) : Handles attribute access. It is called whenever
an attribute is accessed (e.g., obj.attr ).
__setattr__(self, name, value) : Handles attribute assignment. It is called
whenever an attribute is assigned (e.g., obj.attr = value ).
__delattr__(self, name) : Handles attribute deletion. It is called whenever an
attribute is deleted (e.g., del obj.attr ).
5. Other Methods
__dir__(self) : Returns a list of valid attributes for the object. The default
implementation includes all attributes in __dict__ and those defined in the class.
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 34/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
class object
| The base class of the class hierarchy.
|
| When called, it accepts no arguments and returns a new featureless
| instance that has no instance attributes and cannot be given any.
|
| Built-in subclasses:
| anext_awaitable
| async_generator
| async_generator_asend
| async_generator_athrow
| ... and 95 other subclasses
|
| Methods defined here:
|
| __delattr__(self, name, /)
| Implement delattr(self, name).
|
| __dir__(self, /)
| Default dir() implementation.
|
| __eq__(self, value, /)
| Return self==value.
|
| __format__(self, format_spec, /)
| Default object formatter.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getstate__(self, /)
| Helper for pickle.
|
| __gt__(self, value, /)
| Return self>value.
|
| __hash__(self, /)
| Return hash(self).
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __le__(self, value, /)
| Return self<=value.
|
| __lt__(self, value, /)
| Return self<value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __reduce__(self, /)
| Helper for pickle.
|
| __reduce_ex__(self, protocol, /)
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 35/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
| Helper for pickle.
|
| __repr__(self, /)
| Return repr(self).
|
| __setattr__(self, name, value, /)
| Implement setattr(self, name, value).
|
| __sizeof__(self, /)
| Size of object in memory, in bytes.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| __init_subclass__(...)
| This method is called when a class is subclassed.
|
| The default implementation does nothing. It may be
| overridden to extend subclasses.
|
| __subclasshook__(...)
| Abstract classes can override this to customize issubclass().
|
| This is invoked early on by abc.ABCMeta.__subclasscheck__().
| It should return True, False or NotImplemented. If it returns
| NotImplemented, the normal algorithm is used. Otherwise, it
| overrides the normal algorithm (and the outcome is cached).
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs)
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __class__ = <class 'type'>
| type(object) -> the object's type
| type(name, bases, dict, **kwds) -> a new type
M d l d h l
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 36/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
Modules and types themselves
This design ensures a consistent and predictable behavior across all objects in
Python.
For example, the integer 5 is an instance of the int class, and the string "hello" is an
instance of the str class.
In [ ]: print(type(5)) # Output:
print(type("hello")) # Output:
print(type(3.14)) # Output:
<class 'int'>
<class 'str'>
<class 'float'>
Since int, str, and float are classes, and all classes inherit from object, these types are
also objects.
2. Consistent Behavior:
Because all objects inherit from object, they share common methods and behaviors.
For example, all objects can be converted to a string using the str() method, and
their type can be checked using the type() function.
42
[1, 2, 3]
3. Dynamic Typing:
Python's unified type system allows for dynamic typing, meaning the type of a
variable is determined at runtime and can change.
For example, a variable can hold an integer at one point and a string at another.
In [ ]: x = 42 # x is an int
x = "hello" # x is now a str
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 37/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
All objects have attributes and methods that can be accessed in the same way,
regardless of their type.
For example, you can use the dir() function to list all attributes and methods of an
object.
This ensures that even custom classes have access to default methods like str, repr,
and eq.
In [ ]: class MyClass:
pass
obj = MyClass()
print(isinstance(obj, object)) # Output: True
True
B fit f th U ifi d T S t
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 38/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
2. Consistency:
Since all objects behave similarly, you can apply the same concepts (e.g., methods,
attributes, inheritance) across all types.
3. Extensibility:
You can create custom classes that behave like built-in types, thanks to the unified
object model.
4. Polymorphism:
The unified type system enables polymorphism, where objects of different types
can be used interchangeably if they share the same interface.
obj = MyClass()
print(isinstance(obj, object)) # Output: True
42
[1, 2, 3]
True
True
True
True
Conclusion
Python's unified type system ensures that everything in Python is an object, all derived
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 39/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
from the object class. This design provides consistency, simplicity, and flexibility,
making Python a powerful and user-friendly language. Whether you're working with
built-in types, functions, or custom classes, the same principles and behaviors apply,
creating a seamless programming experience.
In [ ]: class ToyShelf:
def __init__(self):
self.toys = []
In [ ]: class Puzzle:
def __init__(self, pieces):
self.pieces = pieces
def __str__(self):
return f"Puzzle with {self.pieces} fun pieces!"
def __repr__(self):
return f"Puzzle({self.pieces})"
puzzle = Puzzle(100)
print(str(puzzle)) # "Puzzle with 100 fun pieces!"
print(repr(puzzle)) # "Puzzle(100)"
In [ ]: l T B
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 40/41
5/17/25, 2:45 PM learn-modern-ai-python/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Lesson_12_OOP_Objects_&_…
In [ ]: class ToyBox:
def __init__(self):
self.toys = ["teddy", "car", "blocks"]
def __len__(self):
return len(self.toys)
box = ToyBox()
print(len(box)) # 3
print(box[1]) # "car"
3
car
In [ ]: class Doll:
def __init__(self, height):
self.height = height
https://github.com/panaversity/learn-modern-ai-python/blob/main/00_python_colab/12_traditional_oop_part_1/Agentic_AI_Traditional_Python_Less… 41/41