Session 8

πŸ—οΈ Object-Oriented Programming

Building with classes and objects

πŸ“š 8 Topics ⏱️ 55 min read 🎯 Intermediate Level

πŸ—ΊοΈ What You'll Learn

πŸ—οΈ What is OOP?
πŸ“¦ Classes & Objects
🎭 The self Parameter
πŸ”§ __init__ Constructor
πŸ“ Instance Methods
🎯 __repr__ Method

πŸ“˜ Same topic in the course notebook

Session_8 OOPs in Python covers classes, __init__, self, inheritanceβ€”same as this lesson. Use the OOPs notebook to code along.

🏠

Classes are Like Blueprints!

    πŸ“ BLUEPRINT (Class)          🏠 HOUSES (Objects)
    ─────────────────           ─────────────────────
    
    class House:                house1 = House("Blue")
      color                     house2 = House("Red")
      rooms                     house3 = House("Green")
      door_count
                               Each house is a UNIQUE OBJECT
    Defines the structure       created from the SAME BLUEPRINT
    
    One blueprint β†’ Many houses! 🏘️
          

A Class is a template, Objects are the actual things built from that template!

❓ What is OOP?

8.1

🎯 Why Object-Oriented Programming?

πŸ”„ Programming Paradigms

    PROCEDURAL                      OBJECT-ORIENTED
    ────────────                    ────────────────
    Step-by-step instructions       Objects with data + behavior
    
    Functions work on data          Data and functions bundled together
    
    # Procedural                    # OOP
    name = "Alice"                  class Person:
    age = 25                            def __init__(self, name, age):
    def greet(name):                        self.name = name
        print(f"Hi {name}")                 self.age = age
                                        def greet(self):
                                            print(f"Hi {self.name}")
          
πŸ’‘ Benefits of OOP
  • Organization: Group related data and functions together
  • Reusability: Create objects from the same class
  • Modularity: Changes in one class don't affect others
  • Real-world modeling: Model real things as objects

πŸ“¦ Classes & Objects

8.2

πŸ—οΈ Creating Your First Class

A class defines the structure. An object (instance) is created from that class.

Python From Source
# Creating a simple class from Session 8
class Dog:
    """A simple Dog class"""
    pass  # Empty class for now

# Create objects (instances) of the class
dog1 = Dog()
dog2 = Dog()

print("dog1:", dog1)
print("dog2:", dog2)
print("Same object?", dog1 == dog2)  # False - different objects!
print("Type:", type(dog1))
Output
dog1: <__main__.Dog object at 0x...>
dog2: <__main__.Dog object at 0x...>
Same object? False
Type: <class '__main__.Dog'>

πŸ”§ The __init__ Constructor

8.3

🎬 Initializing Objects

__init__ is a special method that runs automatically when you create a new object. It's called the constructor!

🎬 __init__ = The Birth of an Object

    dog1 = Dog("Buddy", 3)
              β”‚
              β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  __init__(self, name, age)      β”‚
    β”‚                                 β”‚
    β”‚  1. Creates empty object (self) β”‚
    β”‚  2. Sets self.name = "Buddy"    β”‚
    β”‚  3. Sets self.age = 3           β”‚
    β”‚  4. Returns the object          β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
              β–Ό
    dog1 is now ready to use! πŸ•
          
Python From Source
# __init__ method from Session 8
class Dog:
    """A Dog class with attributes"""
    
    def __init__(self, name, age, breed):
        """Initialize a new Dog object"""
        self.name = name      # Instance attribute
        self.age = age        # Instance attribute
        self.breed = breed    # Instance attribute
        print(f"A new dog '{name}' has been created! πŸ•")

# Create dog objects
buddy = Dog("Buddy", 3, "Golden Retriever")
max = Dog("Max", 5, "German Shepherd")

# Access attributes
print(f"\\n{buddy.name} is a {buddy.age}-year-old {buddy.breed}")
print(f"{max.name} is a {max.age}-year-old {max.breed}")
Output
A new dog 'Buddy' has been created! πŸ•
A new dog 'Max' has been created! πŸ•

Buddy is a 3-year-old Golden Retriever
Max is a 5-year-old German Shepherd

🎭 The self Parameter

8.4

πŸͺž What is self?

self refers to the current object instance. It's how the object refers to itself!

πŸͺž self = "Me, Myself"

    When you call: buddy.bark()
    
    Python secretly does: Dog.bark(buddy)
                                    β”‚
                                    └── This becomes 'self'
    
    Inside the method:
        self.name = buddy's name
        self.age = buddy's age
    
    'self' is a reference to the object calling the method!
          
Python From Source
# Understanding self from Session 8
class Person:
    def __init__(self, name):
        print(f"self is: {self}")
        self.name = name
    
    def introduce(self):
        print(f"Hi, I'm {self.name}!")
        print(f"self inside method: {self}")

# Create objects
alice = Person("Alice")
print(f"alice variable: {alice}")
print()
alice.introduce()

print("\\n--- Another person ---")
bob = Person("Bob")
bob.introduce()
Output
self is: <__main__.Person object at 0x...>
alice variable: <__main__.Person object at 0x...>

Hi, I'm Alice!
self inside method: <__main__.Person object at 0x...>

--- Another person ---
self is: <__main__.Person object at 0x...>
Hi, I'm Bob!
πŸ’‘ Key Point

self is just a convention - you could use any name, but always use self for readability!

πŸ“ Instance Methods

8.5

🎬 Methods = Object Actions

Methods are functions that belong to a class. They define what objects can do!

Python From Source
# Instance methods from Session 8
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.energy = 100
    
    def bark(self):
        """Make the dog bark"""
        print(f"{self.name} says: Woof! Woof! πŸ•")
    
    def sleep(self):
        """Make the dog sleep"""
        self.energy = 100
        print(f"{self.name} is sleeping... πŸ’€")
        print(f"Energy restored to {self.energy}!")
    
    def play(self, minutes):
        """Play and use energy"""
        energy_used = minutes * 2
        if energy_used <= self.energy:
            self.energy -= energy_used
            print(f"{self.name} played for {minutes} minutes! 🎾")
            print(f"Energy left: {self.energy}")
        else:
            print(f"{self.name} is too tired to play! 😴")
    
    def birthday(self):
        """Increase dog's age by 1"""
        self.age += 1
        print(f"πŸŽ‚ Happy Birthday {self.name}! Now {self.age} years old!")

# Create a dog and use methods
buddy = Dog("Buddy", 3)
buddy.bark()
buddy.play(30)
buddy.play(20)
buddy.sleep()
buddy.birthday()
Output
Buddy says: Woof! Woof! πŸ•
Buddy played for 30 minutes! 🎾
Energy left: 40
Buddy played for 20 minutes! 🎾
Energy left: 0
Buddy is sleeping... πŸ’€
Energy restored to 100!
πŸŽ‚ Happy Birthday Buddy! Now 4 years old!

🎯 The __repr__ Method

8.6

πŸ“‹ String Representation

__repr__ defines how an object is displayed when printed. Without it, you get something like <Dog object at 0x...>!

Python From Source
# __repr__ method from Session 8
class Dog:
    def __init__(self, name, age, breed):
        self.name = name
        self.age = age
        self.breed = breed
    
    def __repr__(self):
        """Return a nice string representation"""
        return f"Dog(name='{self.name}', age={self.age}, breed='{self.breed}')"

# Without __repr__: <Dog object at 0x...>
# With __repr__: Dog(name='Buddy', age=3, breed='Golden Retriever')

buddy = Dog("Buddy", 3, "Golden Retriever")
print(buddy)

# Also works in lists!
dogs = [
    Dog("Max", 5, "German Shepherd"),
    Dog("Luna", 2, "Labrador")
]
print("\\nList of dogs:", dogs)
Output
Dog(name='Buddy', age=3, breed='Golden Retriever')

List of dogs: [Dog(name='Max', age=5, breed='German Shepherd'), Dog(name='Luna', age=2, breed='Labrador')]

🎯 Practical Example: Bank Account

8.7

🏦 Building a Bank Account Class

Python From Source
# Bank Account class from Session 8
class BankAccount:
    """A simple bank account"""
    
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance
        print(f"Account created for {owner} with ${balance:.2f}")
    
    def deposit(self, amount):
        """Add money to account"""
        if amount > 0:
            self.balance += amount
            print(f"βœ… Deposited ${amount:.2f}. New balance: ${self.balance:.2f}")
        else:
            print("❌ Deposit amount must be positive!")
    
    def withdraw(self, amount):
        """Remove money from account"""
        if amount > self.balance:
            print(f"❌ Insufficient funds! Balance: ${self.balance:.2f}")
        elif amount <= 0:
            print("❌ Withdrawal amount must be positive!")
        else:
            self.balance -= amount
            print(f"βœ… Withdrew ${amount:.2f}. New balance: ${self.balance:.2f}")
    
    def get_balance(self):
        """Return current balance"""
        return self.balance
    
    def __repr__(self):
        return f"BankAccount(owner='{self.owner}', balance=${self.balance:.2f})"

# Test the bank account
account = BankAccount("Alice", 1000)
print()
account.deposit(500)
account.withdraw(200)
account.withdraw(2000)  # Insufficient funds
print(f"\\nCurrent balance: ${account.get_balance():.2f}")
print(account)
Output
Account created for Alice with $1000.00

βœ… Deposited $500.00. New balance: $1500.00
βœ… Withdrew $200.00. New balance: $1300.00
❌ Insufficient funds! Balance: $1300.00

Current balance: $1300.00
BankAccount(owner='Alice', balance=$1300.00)

β­• Another Example: Circle Class

8.8

πŸ“ Geometric Calculations

Python From Source
# Circle class from Session 8
import math

class Circle:
    """A class to represent a circle"""
    
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        """Calculate the area of the circle"""
        return math.pi * self.radius ** 2
    
    def circumference(self):
        """Calculate the circumference"""
        return 2 * math.pi * self.radius
    
    def diameter(self):
        """Return the diameter"""
        return self.radius * 2
    
    def __repr__(self):
        return f"Circle(radius={self.radius})"

# Create circles and calculate
circle1 = Circle(5)
circle2 = Circle(10)

print(f"Circle 1: {circle1}")
print(f"  Area: {circle1.area():.2f}")
print(f"  Circumference: {circle1.circumference():.2f}")
print(f"  Diameter: {circle1.diameter()}")

print(f"\\nCircle 2: {circle2}")
print(f"  Area: {circle2.area():.2f}")
Output
Circle 1: Circle(radius=5)
  Area: 78.54
  Circumference: 31.42
  Diameter: 10

Circle 2: Circle(radius=10)
  Area: 314.16

πŸ“‹ Quick Reference

Concept Syntax Description
Define Class class MyClass: Create a new class (blueprint)
Create Object obj = MyClass() Instantiate an object
Constructor def __init__(self): Initialize new objects
self self.attribute Reference to current object
Method def method(self): Function inside a class
String Rep def __repr__(self): How object displays

🚫 Common Mistakes (OOP)

πŸ’­ Short reflection

In one sentence: why do we use self as the first parameter in every instance method?

βœ… CORE (Must know)

πŸ“š NON-CORE (Good to know)

Complete code from course notebook: OOPs.ipynb

Every line of code from the course notebook (verbatim).

# --- Code cell 2 ---
# python language----intrepreted,high-level language and object oriented programming language

# --- Code cell 3 ---
# oops---- object oriented programming language
# oops---  classes and objects

# --- Code cell 4 ---
# classes and objects are bascially used in other programming like java,c++----organized and reusable code

# --- Code cell 5 ---
# class--is a blue print for creating objects
# it has a set of attributes(variables) and methods(functions)  that are instances(created objects) of a classes

# --- Code cell 6 ---
# object----is an instance of a class
# when you create an object,you use the class as a templete
# attributes(variables) and methods(functions)  that are instances(created objects) of a classes

# --- Code cell 7 ---
#syntax

class class_name:
  attributes=34
  def function_name(self):
    print("my name is aravind")

# --- Code cell 8 ---
object=class_name() # instance of a class
object.attributes
object.function_name()

# --- Code cell 9 ---
# basic program
# define a class
#feature="mammel"
class dog:
  # attributes
  species="carlies"

  # methods
  def bark(self):
    return "wolf"

# --- Code cell 10 ---
dog1=dog() # instance of a class

# --- Code cell 11 ---
dog1.species

# --- Code cell 12 ---
dog1.bark()

# --- Code cell 13 ---
def bark():
    return "wolf"

bark()

# --- Code cell 14 ---
# basic program
# define a class
#feature="mammel"
class dog:
  # attributes
  species="carlies"

  # methods
  def bark(aravind,ryujj,fhhj):
    return "wolf"

# --- Code cell 15 ---
yellow=dog()

# --- Code cell 16 ---
yellow.species

# --- Code cell 17 ---
yellow.bark()

# --- Code cell 18 ---
class dog1:
  species="carlies"
  def bark(self):
    return "wolf"

# --- Code cell 19 ---
dog2=dog1()

# --- Code cell 20 ---

dog2.bark()

# --- Code cell 21 ---
# self----refrence to the current instance of a class and also used to acess variables in a class

# --- Code cell 22 ---
#__init__----constructor to intialize a attributes --
#    is a special method in oops

# --- Code cell 23 ---
class student:
  def __init__(priya,name,age):
    # initalizing the attributes
    priya.name=name
    priya.age=age

  # methods
  def introduce(priya):
    return f"my name is{priya.name} and i am {priya.age} years old"

# --- Code cell 24 ---
student1=student("rahul",33)

# --- Code cell 25 ---
student1.name

# --- Code cell 26 ---
student1.age

# --- Code cell 27 ---
student1.introduce()

# --- Code cell 28 ---
student2=student("aravind",33)

# --- Code cell 29 ---
student2.introduce1()

# --- Code cell 30 ---
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
            return f"I'm {self.name}, and I'm {self.age} years old."

# --- Code cell 31 ---
person1=Person("tarun",33)
print(person1)

# --- Code cell 32 ---
person2=Person("rahul",36)
person2

# --- Code cell 33 ---
class person:
  def __init__(goor,name,age=30):
    goor.name=name
    goor.age=age
  def introduce(goor):
    return f"Hi I'm {goor.name}and my {goor.age}"

door=person("aravind")
door.introduce()

# --- Code cell 35 ---
class Book:
    def __init__(self, title, author, copies):
        self.title = title
        self.author = author
        self.copies = copies

    def display_details(self):
        print(f"Title: {self.title}, Author: {self.author}, Available Copies: {self.copies}")

    def borrow(self):
        if self.copies > 0:
            self.copies -= 1
            print(f"You borrowed '{self.title}'. Remaining copies: {self.copies}")
        else:
            print(f"Sorry, '{self.title}' is not available right now.")

    def return_book(self):
        self.copies += 1
        print(f"You returned '{self.title}'. Available copies: {self.copies}")


class Library:
    def __init__(self):
        self.books = []

    # add new book
    def add_book(self, book):
        self.books.append(book)
        print(f"Book '{book.title}' added to the library.")

    # search for a book
    def search_book(self, title):
        for book in self.books:
            if book.title.lower() == title.lower():
                print("Book found:")
                book.display_details()
                return book
        print("Book not found in the library.")
        return None

    # display all books
    def display_all_books(self):
        print("\n--- Library Books ---")
        if not self.books:
            print("No books available.")
        else:
            for book in self.books:
                book.display_details()

# --- Code cell 36 ---
# ---------------- Real-time usage ----------------
library = Library()

# Adding books to library
book1 = Book("The Alchemist", "Paulo Coelho", 3)
book2 = Book("Python Programming", "Guido van Rossum", 2)
book3 = Book("Clean Code", "Robert C. Martin", 4)

library.add_book(book1)
library.add_book(book2)
library.add_book(book3)

# --- Code cell 37 ---
# Display all books
library.display_all_books()

# --- Code cell 38 ---
library.search_book("The Alchemist")

# --- Code cell 39 ---
# Search and borrow
found_book = library.search_book("The Alchemist")
if found_book:
    found_book.return_book()