In [ ]:
# https://github.com/tuxfux-hlp/Python-examples/blob/master/opps/Good_links.txt
In [ ]:
# programming
# functional programming.
# object oriented programming.
In [ ]:
# A P I E
# A - Abstraction - how do you define your class object.
# P - Polymorphism - Many forms
# I - Inheritance
# E - Encapsulation
In [ ]:
# All the below are examples of abstaraction.
# example 1:
# bankaccount - class/classobj
# - balance
# + deposit()
# + withdraw()
# + Sintrest()
# vipin - 100,000 -> instance/object
# madan - 10,000
# harshita - 1000
In [ ]:
# example 2:
# villas ( blueprints) - class
# villa1 -> yellow -> instance/objects
# villa2 -> pink
# villa3 -> green
In [ ]:
# Example 3:
# automobiles
# car (generic term) - class
# - color
# - body
# - wheels
# + break
# + accleration
# + clutch
# car models
# bmw - instance/object
# skoda
# maruti
# audi
# benz
# nano
In [1]:
# Polymorphism
print 2 + 3 # 5
print '2' + '3' # 23
# banks
# intrest ( poly - many , morphism - forms)
# home loan intrest
# education loan intrest
# saving loan intrest
# personal loan intrest
# ulip intrest.
In [ ]:
# Inheritance
# the features or advantages u get from your parents
# father( lefthanded,brownhair,blackeyes)
# mother( righthanded,blondhair,blueeyes)
# child is inheriting features from both mother and father.
# child( lefhanded,blackhair,blueeyes)
In [ ]:
# Encapsulation
# hiding of data. But we don't have it in python
# getting the people to use function rather than data.
# bankaccount
# balance
# deposit()
# withdraw()
# add money - i should not modify the balance account direclty, i should use the deposit() function.
# withdraw money - i should not modify balance account direclty , i should use the withdraw() function.
# we are more concerned with the functionality rather than the data.
# pendrive - you plugin and see data. reading and writing data into the pendrive.
In [3]:
# bankaccount for learning object oriented programming.
# basic functional programming.
balance = 0
def deposit(amount):
global balance
balance = balance + amount
def withdraw(amount):
global balance
balance = balance - amount
# Main
# ramanji
print "balance of ramanji before deposit- {}".format(balance)
print "depositing the amount into account - 1000"
deposit(1000)
print "withdraw the amount from the account - 300"
withdraw(300)
print "balance of ramanji after all transactions - {}".format(balance)
# Sunil
print "balance of sunil before deposit- {}".format(balance)
In [6]:
# dictionary
def account():
return {'balance':0}
def deposit(account,amount):
account['balance'] = account['balance'] + amount
def withdraw(account,amount):
account['balance'] = account['balance'] - amount
# Main
ramji = account() # ramji = {balance:0} , ramji['balance']
print ramji
print "balance of ramji is {}".format(ramji['balance'])
print "depositing the amount into account - 1000"
deposit(ramji,1000)
print "withdraw then amount from the account - 300"
withdraw(ramji,300)
print "balance of ramanji after all transactions - {}".format(ramji['balance'])
sunil = account()
print sunil
print "balance of sunil is {}".format(sunil['balance'])
In [ ]:
# object oriented concept.
In [21]:
# self represents the object itself.
# Abstraction of a class account.
# class is a keyword to begin your object oriented programming.
# bal -> variables/sdata
# deposit,withdraw,my_balance -> methods of class.
# Madhav,Madan -> objects/instances
# self -> represents the objects itself.
# class account(object):
class account: # class
bal = 0
def deposit(self,amount): # methods
self.bal = self.bal + amount
def withdraw(self,amount): # methods
self.bal = self.bal - amount
def my_balance(self): # methods
print "my balance is {}".format(self.bal)
print type(account) # 'classobj'/class
print type(account()) # 'instance'/object
# Madhav - instance/object
Madhav=account()
print dir(Madhav)
Madhav.deposit(1000)
# Madan - instance/object
Madan=account()
print dir(Madan)
Madan.deposit(2000)
In [15]:
Madhav.my_balance()
In [19]:
Madhav.my_balance()
In [22]:
Madan.my_balance()
In [23]:
# Methods
# important method - constructor. __init__
# The first function to get into action, when you create an object is called constructor.
# class account(object):
class newaccount:# class
def __init__(self,minbal): # Method/constructor
self.bal = minbal
def deposit(self,amount): # methods
self.bal = self.bal + amount
def withdraw(self,amount): # methods
self.bal = self.bal - amount
def my_balance(self): # methods
print "my balance is {}".format(self.bal)
In [27]:
# Anil
# salaried
# constructor is the first function/method which gets called when you try to access the Anil account.
Anil = newaccount(minbal=0)
print dir(Anil)
Anil.my_balance()
# Harshita
# student
Harshita = newaccount(minbal=10000)
print dir(Harshita)
Harshita.my_balance()
In [31]:
# Inheritance
# the features or advantages u get from your parents
# father( lefthanded,brownhair,blackeyes)
# mother( righthanded,blondhair,blueeyes)
# child is inheriting features from both mother and father.
# child( lefhanded,blackhair,blueeyes)
class Father:
hand="lefty"
hair="brown"
class Mother:
hand="right"
hair="blond"
eyes="blue"
class child(Father,Mother):
hair="black"
# Main
Kumar = child()
print dir(Kumar)
print Kumar.hair
print Kumar.hand
print Kumar.eyes
In [36]:
raise santosh
In [37]:
# santosh is inherting the features of the Exception class.
class santosh(Exception):
pass
raise santosh,"I am back"
In [33]:
# example
# Movies
# A,U,A/U 18yrs and above.
age = input("please enter your age:")
class InvalidAgeError(Exception):
def __init__(age):
self.age = age
def validate_age(age):
if age < 18:
raise InvalidAgeError(age)
else:
return "you are old enough to see the movie- {}".format(age)
try:
validate_age(age)
except Exception as e:
print "you are not allowed to watch the movie {}".format(e.age)
else:
print validate_age(age)
In [35]:
# example
# Movies
# A,U,A/U 18yrs and above.
age = input("please enter your age:")
# i created a custome exception called InvalidAgeError
# parent exception is Exception.
# child is InvalidAgeError
class InvalidAgeError(Exception):
def __init__(self,age):
self.age = age
def validate_age(age):
if age < 18:
raise InvalidAgeError(age)
else:
return "you are old enough to see the movie- {}".format(age)
try:
validate_age(age)
except Exception as e:
print "you are not allowed to watch the movie {}".format(e.age)
else:
print validate_age(age)
In [45]:
# inheritance example on the bank
# ICICI account
# for salaried people - you can keep a zero balance or you can get a overdraft.
# for non-salaried people - we need to maintain a minimum balance.
# class account(object):
class account: # class
def __init__(self): # special method - constructor
self.bal = 0
def deposit(self,amount): # methods
self.bal = self.bal + amount
def withdraw(self,amount): # methods
self.bal = self.bal - amount
def my_balance(self): # methods
print "my balance is {}".format(self.bal)
# you can inherit data and method from parents class but , you need to import the constructor(__init__) explicity.
class minaccount(account):
def __init__(self):
account.__init__(self)
def withdraw(self,amount):
if self.bal - amount < 1000:
return "buddy!!! you need to call your daddy"
else:
account.withdraw(self,amount)
# inheritance - minaccount is child of account class.
# Polymorphism - so we have withdraw() both in account and also minaccount.
# both function have different functionlities , its called as polymorphic
# There is an order of looking for functions.
# Harshita.my_balance() , first its looks into the minaccount class and later it looks into the account class
# kumar
kumar = account()
kumar.my_balance()
kumar.withdraw(1000)
kumar.my_balance()
# Harshita - you have to manage a min balance of 1000 rupees
Harshita = minaccount()
Harshita.my_balance()
Harshita.deposit(2000)
Harshita.my_balance()
Harshita.withdraw(1500)
Out[45]:
In [46]:
Harshita.withdraw(800)
In [47]:
Harshita.my_balance()
In [48]:
# Polymorphism
# magic methods : https://github.com/RafeKettler/magicmethods
# https://github.com/RafeKettler/magicmethods/blob/master/magicmethods.pdf
print 3 + 2
print '3' + '2'
In [54]:
a = 3
b = 2
print type(a),type(b) # a,b are instances/objects of 'int' class
print dir(a)
print a + b
print a.__add__(b)
In [56]:
c = '3'
b = '2'
print type(c),type(b) # c,b are instances/objects of 'str' class
print c.__add__(b)
In [57]:
# Adding two Rational number
# 1/5 + 1/2 = 7/10 = (1 * 2 ) + (5 * 1) / 5 * 2 = 7/10
# http://anandology.com/python-practice-book/object_oriented_programming.html#special-class-methods
In [59]:
print 1/5 + 1/2
print 1/5.0 + 1/2.0
In [60]:
class RationalNumber:
"""
Rational Numbers with support for arthmetic operations.
>>> a = RationalNumber(1, 2)
>>> b = RationalNumber(1, 3)
>>> a + b
5/6
>>> a - b
1/6
>>> a * b
1/6
>>> a/b
3/2
"""
def __init__(self, numerator, denominator=1): # constructor
self.n = numerator
self.d = denominator
def __add__(self, other):
if not isinstance(other, RationalNumber):
other = RationalNumber(other)
n = self.n * other.d + self.d * other.n
d = self.d * other.d
return RationalNumber(n, d)
def __str__(self):
return "%s/%s" % (self.n, self.d)
__repr__ = __str__
In [62]:
a = RationalNumber(1,5) # a.n = 1,a.d=5
b = RationalNumber(1,2) # b.n = 1,b.d=2
print a + b # + is calling __add__ by default
# a.__add__(b)
In [63]:
c = RationalNumber(1,5)
d = 2
print c + d
In [64]:
e = 12
f = 13
print e + f
In [ ]:
# encapsulation
# http://radek.io/2011/07/21/private-protected-and-public-in-python/
# https://importantshock.wordpress.com/2006/11/03/adventures-in-pythonic-encapsulation/
# encapsulation is all about functionality rather than directly accessing the data.
# public,protected,private
# Python doesn’t have any mechanisms, that would effectively restrict you from accessing a
# variable or calling a member method. All of this is a matter of culture and convention.
In [12]:
# Cup class containts only public variables.Everyone can access them.
class Cup:
def __init__(self): # methods
self.content = None # data
self.color = None # data
def fill(self,drink): # mothods
self.content = drink
def empty(self): # methods
self.content=None
In [14]:
RedCup = Cup()
In [3]:
print dir(RedCup)
In [4]:
RedCup.content="cofee"
RedCup.color="Red"
In [6]:
print RedCup.content
print RedCup.color
In [7]:
RedCup.fill("tea")
In [9]:
print RedCup.content
In [15]:
RedCup.empty()
print RedCup.content
In [16]:
# Protected
# putting a _ before a variable literally makes it private.
# you should access the private variable only from within a class or subclass.
# using of a _<variable> literally changes nothing. Its just a convention to use the private variables only using method of the
# class.
class Cup:
def __init__(self): # methods
self._content = None # Protected
self.color = None # data
def fill(self,drink): # mothods
self._content = drink
def empty(self): # methods
self._content=None
In [17]:
BlueCup = Cup()
In [18]:
print dir(BlueCup)
In [19]:
# _content is declared a private variable and should not be touched directly.
In [20]:
# what i expect others(collegus/programmes) to do.
BlueCup.color = "blue"
In [21]:
BlueCup.fill('boost')
In [22]:
BlueCup._content
Out[22]:
In [23]:
BlueCup.empty()
print BlueCup._content
In [24]:
# fun part
BlueCup._content = "pepsi"
In [25]:
print BlueCup._content
In [31]:
# Private
# A private variable can have a two underscores before the variable : __variable
class Cup:
def __init__(self): # methods
self.__content = None # Private
self.color = None # data
def fill(self,drink): # mothods
self.__content = drink
def empty(self): # methods
self.__content=None
def contains(self):
return self.__content
In [36]:
YellowCup = Cup()
In [37]:
YellowCup.fill("horlicks")
In [38]:
YellowCup.__content
In [39]:
print YellowCup.contains()
In [40]:
# Name Mangling
print dir(YellowCup)
In [42]:
# _Cup__content
print YellowCup._Cup__content # Accessing a private variable in not so nice way.
In [51]:
YellowCup._Cup__content = "bournvita"
print YellowCup._Cup__content
In [52]:
print YellowCup.contains()
In [ ]: