Python Object Oriented Programming
Python Object Oriented Programming
freeCodeCamp Class
OOP Constructor
import csv
class Item:
rate = 0.8
all = []
def __init__(self,name, price, qty=0):
# print("I am Created! {}".format(name))
# print(f"I am a class of type, {name}")
# assert price >=0, f"Price {price} must be greater than 0"
# assert qty >=0, f"Qty {qty} must be greater than 0"
self.name = name
self.price = price
self.qty = qty
Item.all.append(self)
def calculate_price(self):
return self.price * self.qty
def empty_item(self):
return self.qty ** 2
def apply_discount(self):
self.price = self.price * Item.rate
def __repr__(self):
return(f"Item({self.name},{self.price}, {self.qty}")
@classmethod
def instantiate_from_csv(cls):
with open('items.csv', 'r') as f:
reader = csv.DictReader(f)
items = list(reader)
for item in items:
#print(item)
Item(
name=item.get('name'),
price=item.get('price'),
qty=item.get('qty')
)
Item.instantiate_from_csv()
print(Item.all)
# item1 = Item("MacOS", 150, 5)
# item2 = Item("Windows", -1500)
# print(Item.all)
# for instance in Item.all:
# print(instance.name)
# print(instance.price)
#item1.apply_discount()
# print(item1.price)
# item2.rate = 0.7
#item2.apply_discount()
# print(item2.price)
# print(Item.rate)
# print(item1.rate)
# print(item2.rate)
# print(Item.__dict__)
# print(item1.__dict__)
# print(item1.name)
# print(item2.name)
# print(item1.calculate_price())
# print(item2.calculate_price())
# print(item1.empty_item())
# print(item2.empty_item())
# item1.name = "Phone"
# item1.price = 150
# item1.qty = 5
# print(item1.calculate_price(item1.price, item1.qty))
# print(type(item1))
# print(type(item1.name))
# print(type(item1.qty))
# name = "pradeep"
# print(type(name))
# print(name.upper())
# item2 = Item()
# item2.name = "Laptop"
# item2.price = 1500
# item2.qty = 3
# print(type(item2))
# print(item2.calculate_price(item2.price, item2.qty))
# print(item1.empty_item(item1.qty))
# print(item2.empty_item(item2.qty))
Polymorphism
name = "Pradeep" # str
print(len(name))
my_list = ["pradeep","python"] # list
print(len(my_list))
# That's polymorphism in action, a single function does now
# how to handle different kinds of objects as expected!
(Python4Networking) (base) pradeep:~$/Users/pradeep/LearnPython/Python4Networking/bin/python /Use
rs/pradeep/LearnPython/poly.py
7
2
(Python4Networking) (base) pradeep:~$
Class Methods and Static Methods
import csv
class Item:
pay_rate = 0.8 # The pay rate after 20% discount
all = []
def __init__(self, name: str, price: float, quantity=0):
# Run validations to the received arguments
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
assert quantity >= 0, f"Quantity {quantity} is not greater or equal to zero!"
# Assign to self object
self.name = name
self.price = price
self.quantity = quantity
# Actions to execute
Item.all.append(self)
def calculate_total_price(self):
return self.price * self.quantity
def apply_discount(self):
self.price = self.price * self.pay_rate
@classmethod
def instantiate_from_csv(cls):
with open('items.csv', 'r') as f:
reader = csv.DictReader(f)
items = list(reader)
for item in items:
Item(
name=item.get('name'),
price=float(item.get('price')),
quantity=int(item.get('quantity')),
)
@staticmethod
def is_integer(num):
# We will count out the floats that are point zero
# For i.e: 5.0, 10.0
if isinstance(num, float):
# Count out the floats that are point zero
return num.is_integer()
elif isinstance(num, int):
return True
else:
return False
def __repr__(self):
return f"Item('{self.name}', {self.price}, {self.quantity})"
item1 = Item("phone",150,4)
print(item1.is_integer(7))
class Item:
@staticmethod
def is_integer():
'''
This should do something that has a relationship
with the class, but not something that must be unique
per instance!
'''
@classmethod
def instantiate_from_something(cls):
'''
This should also do something that has a relationship
with the class, but usually, those are used to
manipulate different structures of data to instantiate
objects, like we have done with CSV.
'''
# THE ONLY DIFFERENCE BETWEEN THOSE:
# Static methods are not passing the object reference as the first argument in the background!
# NOTE: However, those could be also called from instances.
item1 = Item()
item1.is_integer()
item1.instantiate_from_something()
Class Inheritance
import csv
class Item:
pay_rate = 0.8 # The pay rate after 20% discount
all = []
def __init__(self, name: str, price: float, quantity=0):
# Run validations to the received arguments
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
assert quantity >= 0, f"Quantity {quantity} is not greater or equal to zero!"
# Assign to self object
self.name = name
self.price = price
self.quantity = quantity
# Actions to execute
Item.all.append(self)
def calculate_total_price(self):
return self.price * self.quantity
def apply_discount(self):
self.price = self.price * self.pay_rate
def __repr__(self):
return f"{self.__class__.__name__}('{self.name}', {self.price}, {self.quantity})"
class Phone(Item):
def __init__(self, name: str, price: float, quantity=0, broken_phones=0):
# Call to super function to have access to all attributes / methods
super().__init__(
name, price, quantity
)
# Run validations to the received arguments
assert broken_phones >= 0, f"Broken Phones {broken_phones} is not greater or equal to zero!"
# Assign to self object
self.broken_phones = broken_phones
phone1 = Phone("iPhone15Pro", 500, 5, 1)
print(Item.all)
(Python4Networking) (base) pradeep:~$/Users/pradeep/LearnPython/Python4Networking/bin/python /Use
rs/pradeep/LearnPython/inheritance.py
[Phone('iPhone15Pro', 500, 5)]
(Python4Networking) (base) pradeep:~$
import csv
class Item:
pay_rate = 0.8 # The pay rate after 20% discount
all = []
def __init__(self, name: str, price: float, quantity=0):
# Run validations to the received arguments
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
assert quantity >= 0, f"Quantity {quantity} is not greater or equal to zero!"
# Assign to self object
self.name = name
self.price = price
self.quantity = quantity
# Actions to execute
Item.all.append(self)
def calculate_total_price(self):
return self.price * self.quantity
def apply_discount(self):
self.price = self.price * self.pay_rate
def __repr__(self):
return f"{self.__class__.__name__}('{self.name}', {self.price}, {self.quantity})"
class Phone(Item):
def __init__(self, name: str, price: float, quantity=0, broken_phones=0):
# Call to super function to have access to all attributes / methods
super().__init__(
name, price, quantity
)
# Run validations to the received arguments
assert broken_phones >= 0, f"Broken Phones {broken_phones} is not greater or equal to zero!"
# Assign to self object
self.broken_phones = broken_phones
phone1 = Phone("iPhone15Pro", 500, 5, 1)
class Laptop(Item):
def __init__(self, name: str, price: float, quantity=0, broken_laptops=0):
super().__init__(
name, price, quantity
)
assert broken_laptops >=0, f"Broken Laptops {broken_laptops} is not greater or equal to zero!"
self.broken_laptops = broken_laptops
laptop1 = Laptop("MacbookAir", 1100, 3,1)
print(Item.all)
(Python4Networking) (base) pradeep:~$/Users/pradeep/LearnPython/Python4Networking/bin/python /Use
rs/pradeep/LearnPython/inheritance.py
[Phone('iPhone15Pro', 500, 5), Laptop('MacbookAir', 1100, 3)]
(Python4Networking) (base) pradeep:~$
Getters and Setters
item.py
import csv
class Item:
pay_rate = 0.8 # The pay rate after 20% discount
all = []
def __init__(self, name: str, price: float, quantity=0):
# Run validations to the received arguments
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
assert quantity >= 0, f"Quantity {quantity} is not greater or equal to zero!"
# Assign to self object
self.__name = name
self.price = price
self.quantity = quantity
# Actions to execute
Item.all.append(self)
@property
# Property Decorator = Read-Only Attribute
def name(self):
return self.__name
@name.setter
def name(self, value):
if len(value) > 10:
raise Exception("The name is too long!")
else:
self.__name = value
def calculate_total_price(self):
return self.price * self.quantity
def apply_discount(self):
self.price = self.price * self.pay_rate
@classmethod
def instantiate_from_csv(cls):
with open('items.csv', 'r') as f:
reader = csv.DictReader(f)
items = list(reader)
for item in items:
Item(
name=item.get('name'),
price=float(item.get('price')),
quantity=int(item.get('quantity')),
)
@staticmethod
def is_integer(num):
# We will count out the floats that are point zero
# For i.e: 5.0, 10.0
if isinstance(num, float):
# Count out the floats that are point zero
return num.is_integer()
elif isinstance(num, int):
return True
else:
return False
def __repr__(self):
return f"{self.__class__.__name__}('{self.name}', {self.price}, {self.quantity})"
phone.py
from item import Item
class Phone(Item):
def __init__(self, name: str, price: float, quantity=0, broken_phones=0):
# Call to super function to have access to all attributes / methods
super().__init__(
name, price, quantity
)
# Run validations to the received arguments
assert broken_phones >= 0, f"Broken Phones {broken_phones} is not greater or equal to zero!"
# Assign to self object
self.broken_phones = broken_phones
main.py
from item import Item
item1 = Item("MyItem", 750)
# Setting an Attribute
item1.name = "OtherItem"
# Getting an Attribute
print(item1.name)
Output
(Python4Networking) (base) pradeep:~$/Users/pradeep/LearnPython/Python4Networking/bin/python /Use
rs/pradeep/LearnPython/main.py
OtherItem
If we try to set a longer name, then an exception will be raised!
from item import Item
item1 = Item("MyItem", 750)
# Setting an Attribute
item1.name = "OtherItemslonger"
# Getting an Attribute
print(item1.name)
(Python4Networking) (base) pradeep:~$/Users/pradeep/LearnPython/Python4Networking/bin/python /Use
rs/pradeep/LearnPython/main.py
Traceback (most recent call last):
File "/Users/pradeep/LearnPython/main.py", line 6, in <module>
item1.name = "OtherItemslonger"
File "/Users/pradeep/LearnPython/item.py", line 28, in name
raise Exception("The name is too long!")
Exception: The name is too long!
(Python4Networking) (base) pradeep:~$