<jupyter_start><jupyter_text>Python is a multi-paradigm programming language. Meaning, it supports different programming approach.One of the popular approach to solve a programming problem is by creating objects. This is known as Object-Oriented Programming (OOP).An object has two characteristics:attributesbehavior The concept of OOP in Python focuses on creating reusable codeParrot is an object,name, age, color are attributessinging, dancing are behavior ClassA class is a blueprint for the object.We can think of class as an sketch of a parrot with labels. It contains all the details about the name, colors, size etc. Based on these descriptions, we can study about the parrot ObjectAn object (instance) is an instantiation of a class. When class is defined, only the description for the object is defined. Therefore, no memory or storage is allocated.<jupyter_code>class Parrot:

    # class attribute
    species = "bird"

    # instance attribute
    def __init__(self, name, age):
        self.name = name
        self.age = age

# instantiate the Parrot class
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)

# access the class attributes
print("Blu is a", blu.__class__.species)
print("Woo is also a", woo.__class__.species)

# access the instance attributes
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))<jupyter_output>Blu is a bird
Woo is also a bird
Blu is 10 years old
Woo is 15 years old<jupyter_text>MethodsMethods are functions defined inside the body of a class. They are used to define the behaviors of an object.<jupyter_code>class Parrot:
    
    # instance attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    # instance method
    def sing(self, song):
        return "{} sings {}".format(self.name, song)

    def dance(self):
        return "{} is now dancing".format(self.name)

# instantiate the object
blu = Parrot("Blu", 10)

# call our instance methods
print(blu.sing("'Happy'"))
print(blu.dance())<jupyter_output>Blu sings 'Happy'
Blu is now dancing<jupyter_text>nheritanceInheritance is a way of creating new class for using details of existing class without modifying it. The newly formed class is a derived class (or child class). Similarly, the existing class is a base class (or parent class).<jupyter_code># parent class
class Bird:
    
    def __init__(self):
        print("Bird is ready")

    def whoisThis(self):
        print("Bird")

    def swim(self):
        print("Swim faster")

# child class
class Penguin(Bird):

    def __init__(self):
        # call super() function
        super().__init__()
        print("Penguin is ready")

    def whoisThis(self):
        print("Penguin")

    def run(self):
        print("Run faster")

peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()<jupyter_output>Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster<jupyter_text>EncapsulationUsing OOP in Python, we can restrict access to methods and variables. This prevent data from direct modification which is called encapsulation.In Python, we denote private attribute using underscore as prefix i.e single “ _ “ or double “ __“.<jupyter_code>class Computer:

    def __init__(self):
        self.__maxprice = 900

    def sell(self):
        print("Selling Price: {}".format(self.__maxprice))

    def setMaxPrice(self, price):
        self.__maxprice = price

c = Computer()
c.sell()

# change the price
c.__maxprice = 1000
c.sell()

# using setter function
c.setMaxPrice(1000)
c.sell()<jupyter_output>Selling Price: 900
Selling Price: 900
Selling Price: 1000<jupyter_text>PolymorphismPolymorphism is an ability (in OOP) to use common interfacefor multiple form (data types).Suppose, we need to color a shape, there are multiple shape option (rectangle, square, circle). However we could use same method to color any shape. This concept is called Polymorphism.<jupyter_code>class Parrot:

    def fly(self):
        print("Parrot can fly")
    
    def swim(self):
        print("Parrot can't swim")

class Penguin:

    def fly(self):
        print("Penguin can't fly")
    
    def swim(self):
        print("Penguin can swim")

# common interface
def flying_test(bird):
    bird.fly()

#instantiate objects
blu = Parrot()
peggy = Penguin()

# passing the object
flying_test(blu)
flying_test(peggy)<jupyter_output>Parrot can fly
Penguin can't fly
{'fraction_non_alphanumeric': 0.08922520894510956, 'fraction_numerical': 0.007002484752654168, 'mean_word_length': 3.8287895310796074, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '249722', 'license': 'MIT', 'n_tokens_mistral': 1383, 'n_tokens_neox': 1307, 'n_words': 508, 'path': 'module-1/OOP/.ipynb_checkpoints/Object Oriented Programming Basics -checkpoint.ipynb', 'repo_name': 'ruesaintdenis/Ironhack-Labs', 'size': '4427'}