## Program Source Code 9.1, page no: 246¶

In [1]:
def gcd(a,b):  #function gcd
if a>b:
c=a
a=b
b=c
c=b%a

while c!=0:
b=a
a=c
c=b%a
return a

def lcm(a,b):  #function lcm
g=gcd(a,b)
l=g*(a/g)*(b/g)
return l

class Fraction: #class

def __init__(self,a=0,b=1,anotherfraction=None):
if anotherfraction==None:               #normal constructor
self.__num=a
self.__denom=b
print 'fraction object (',self.__num,'/',self.__denom,') created'
else:                          #copy constructor
self.__num=aanotherfraction.self.__num
self.__denom=anotherfraction.self.__denom
print 'fraction object (',self.__num,'/',self.__denom,')created(copy)'

def __del__(self):       #destructor
print 'fraction object (',self.__num,'/',self.__denom,') destroyed'

tmp=Fraction()
l=lcm(self.__denom,operand2.__denom)
tmp.__num=self.__num*(l/self.__denom)+operand2.__num*(l/operand2.__denom)
tmp.__denom=l
g=gcd(tmp.__num,tmp.__denom)
tmp.__num/=g
tmp.__denom/=g
print 'In overloaded Fraction::operator + : ( ',self.__num,'/',self.__denom,') + (',operand2.__num,'/',operand2.__denom,') = (',tmp.__num,'/',tmp.__denom,')'
return tmp

def __assign__(self,rval):
self.__num=rval.self.__num
self.__denom=rval.self.__denom
print 'In overloaded Fraction::operator = : ( ',rval.self.__num,'/',rval.self.__denom,') -> (',self.__num,'/',self.__denom,')'
return self

print 'Please enter values of numerator and denominator:'
n=input()
d=input()
f1=Fraction(n,d)

print 'Please enter another set of numerator and denominator: '
n=input()
d=input()
f2=Fraction(n,d)
b=f2
f3=Fraction()
f3=f1+f2
f3=f2=f1


Please enter values of numerator and denominator:
3
4
fraction object ( 3 / 4 ) created
Please enter another set of numerator and denominator:
5
6
fraction object ( 5 / 6 ) created
fraction object ( 0 / 1 ) created
fraction object ( 0 / 1 ) created
In overloaded Fraction::operator + : (  3 / 4 ) + ( 5 / 6 ) = ( 19 / 12 )
fraction object ( 0 / 1 ) destroyed
fraction object ( 19 / 12 ) destroyed


## Program Source Code 9.2, page no: 265¶

In [20]:
class Integer: #class defined
def __init__(self,a=None,arg=None):          #constructor
if arg==None:
self.__i=a
else:
self.__i=arg.__i

def __del__(self):
pass

tmp=Integer()
tmp.__i=self.__i + arg.__i         #These are integer additions
return tmp

def __assign__(self,arg):
self.__i=arg.__i                  #These are integer assignments
return self

#Overload the increment operator
tmp=Integer()
tmp=self
self.__i+=arg
return self

def __int(self):
return self.__i
a=5
b=Integer() #object of integer class
b=5
a+=1
a=a+a
a+=1
b=b+1
b=b+b
print 'a=',a
print 'b=',b


a= 13
b= 12


## Program Source Code 9.3, page no: 269¶

In [6]:
class Fraction:
__num=None
__denom=None
def __init__(self,a=0,b=1): #constructor
self.__num=a
self.__denom=b
print 'Constructor call: Fraction object (',self.__num,'/',self.__denom,') created'

def __del__(self):
print 'Fraction object (',self.__num,'/',self.__denom,') destroyed'

# Python doesn't have >> operator for input so we are just using input function
def input(self):
self.__num = int(raw_input())
self.__denom = int(raw_input())

#Python does not use << operator for printing. So here we are just declaring function name as print_
def _repr_(self):
print 'The fraction is ',
print self.__num , '/', self.__denom

f1=Fraction()
print 'Please enter the values of numerator and denominator: '
f1.input()
f1._repr_()


Constructor call: Fraction object ( 0 / 1 ) created
Please enter the values of numerator and denominator:
3
4
The fraction is  3 / 4


## Program Source Code 9.4, page no: 272¶

In [28]:
class Fraction:

def __init__(self,a=0,b=1):
#normal constructor
self.__num=a
self.__denom=b
print 'Constructor Call : fraction object (',self.__num,'/',self.__denom,') created'

def __del__(self):       #destructor
print 'fraction object (',self.__num,'/',self.__denom,') destroyed'

def __new__(typ, sz):
print 'Fraction:: operator new called to'
print 'allocate ',sz,'bytes'
return AllocateMem(sz)

def AllocateMem(sz):
if pm==NULL:
print 'failed to allocate memory'
exit(0)
else:
print 'Memory successfully allocated '
return pm

def FreeMem(m):
pass
def __new__(typ, *args, **kwargs):
obj = object.__new__(typ, *args, **kwargs)
print 'Global operator new called to'
print 'allocate ',sz,'bytes'
return AllocateMem(sz)

pf1=[]*4
pf2=[]

print 'Memory succesfully allocated'
for i in xrange(4): #allocate array
pf1.append(Fraction())
print 'Memory succesfully allocated'
for i in range(1):
pf2.append(Fraction())

del pf2[0] #delete object
print 'Fraction::operator delete called'

for i in range(3,-1,-1):
del pf1[i] #delete array

print 'Global operator delete called'

Memory succesfully allocated
Constructor Call : fraction object ( 0 / 1 ) created
Constructor Call : fraction object ( 0 / 1 ) created
Constructor Call : fraction object ( 0 / 1 ) created
Constructor Call : fraction object ( 0 / 1 ) created
Memory succesfully allocated
Constructor Call : fraction object ( 0 / 1 ) created
fraction object ( 0 / 1 ) destroyed
Fraction::operator delete called
fraction object ( 0 / 1 ) destroyed
fraction object ( 0 / 1 ) destroyed
fraction object ( 0 / 1 ) destroyed
fraction object ( 0 / 1 ) destroyed
Global operator delete called

In [ ]: