Lec 10,11,12
'''nOTES for classestypes&objects in python each data = an object object = data/value + how to interact object is an instance of a type you can define your new type e.g. 1234 - object of an int, can intereact with '+,-,*,/,...'example - a lift, a car, a list - to drive a car, you do not need car manufacturing knowledgeprocess:create a class: name, data, interfaceuse it: create an instance, and operatedot notation <class instance>.<attributes or methods>syntax:see below'''import math#how to create a classclasscoordinate(object):#in fact, in python 3,#automatically inherit from objectdef__init__(self,x,y):#init - used to create an instance#self is the created object it"self"#other params - passed from outside when initself.x=x #create an attributeself.y=ydefdistance(other, a):#a very bad example not using "self"return((a.x-other.x)**2+(a.y-other.y)**2)**0.5c=coordinate(1,1)d=coordinate(3,2)print(format(c.distance(d),".02f"))print(format(coordinate.distance(c,d),".02f"))'''that is OOP, packing data and proceduresbetter when developing and testing by breaking task down to several modulesclass objects can used asattributes of another class object'''classCircle:def__init__(self,center,radius):#center coordinate, radius intself.center=centerself.radius=radiuspassdefis_inside(self,p):return p.distance(self.center)<self.radiuscenter=coordinate(0,0)mycirc=Circle(center,1)print(mycirc.is_inside(c),mycirc.is_inside(d))'''operator overloading - rewriting dunder methods'''import mathclassfraction:def__init__(self,num,denum):self.num=numself.denum=denumpassdef__add__(self,other): t=fraction(self.num*other.denum +other.num*self.denum,self.denum*other.denum)return tdef__sub__(self,other): t=fraction( -other.num, other.denum )returnself.__add__(t)def__mul__(self,other):ifisinstance(other,fraction): t=fraction(self.num*other.num,self.denum*other.denum)else: t=fraction(self.num*other,self.denum)return tdef__truediv__(self,other):ifisinstance(other,fraction): t=fraction( other.denum, other.num)else: t=fraction(1, other)returnself.__mul__(t)def__str__(self):defgcd(p,q):while(q!=0): (p,q)=(q,p%q)return p frac_gcd=gcd(self.num,self.denum)self.num//=frac_gcdself.denum//=frac_gcdreturnstr(self.num)+'/'+str(self.denum)def__float__(self):returnself.num/self.denuma=fraction(1,3)b=fraction(3,5)print(a+b,a,b);print(a-b,a,b);print(a*b,a,b);print(a/b,a,b);print(a*2,a,b);print(a/2,a,b)print(format(float(a),(".02f")),float(b))'''remember: always access attributes through methods--------inheritance: copy, override, additionaccess parent via super()e.g. inside __init__, super().init(...) self.a=a self.b=b ...Child Class can be passed to where Parent Class is expectedbut NOT vice versa"All squares are rectangles, but not vice versa."'''