# class representing a fraction class fraction: def __init__(self,n,d): # initialize numerator and denominator self.n = n if d==0: raise "zero denominator error" self.d = d # constructor # method to return string representation of class: def tostring(self): return str(self.n)+"/"+str(self.d) # tostring # method to simplify fraction by calculating the gcd def simplify(self): a = self.n # rename vars for convenience b = self.d while (a!=0 and b!=0): #find gcd of a and b if (a>b): a = a%b else: b = b%a # while gcd = a+b # gcd is the number that's not zero self.n = self.n / gcd # simplify numerator and denominator self.d = self.d /gcd #simplify def multiply(self,B): # multiply this fraction with another fraction B n = self.n * B.n d = self.d * B.d newobject = fraction(n,d) return newobject # multiply # is multiply a destructive or non-destructive function? # ----------- operator overloading ---------------- def __mul__(self,B): # overrides the * operator return self.multiply(B) # __mul__ def dmult(self,B): # destructive version of multiply: changes self self.n = self.n * B.n self.d = self.d * B.d # destructive multiplication def __add__(A,B): n = A.n*B.d + B.n*A.d d = A.d * B.d return fraction(n,d) # add def __eq__(A,B): return A.n*B.d == A.d*B.n # equals # class fraction ##### f1 = fraction(1,2) f2 = fraction(2,4) f3 = fraction(2,8) print f1 # don't expect to see 1/2 print f1.tostring() print f1 == f2 f4 = f1 + f3 # f1.add(f3) print f4.tostring() f4.simplify() print f4.tostring() ############# ### Summary: # In order to create a class of objects, I must first be clear as to: # 1. The attributes or "fields" of the object. That is, what are the # pieces of data that will make up the object. In the case of fractions, # these are the numerator and the denominator. # 2. What functions (methods) do I wish to be able to call on each object. # # Once I'm clear as to what needs to be done. I can now write a class # structure in Python. The first method I should write (usually) is the # "constructor" function, which must be called __init__. It is the job # of this function to assign initial values to the variables (fields) # representing each object. print "-------------- Class Excercise - Pun Intended -------------" # I want to have objects representing collections of coins (i.e., piggybanks). # The coin denominations are nickels, dimes, and quarters (we're snobs and # don't collect pennies). When the a coin-collection # object is first created, it will contain 0 nickels, 0 dimes and 0 quarters. # The methods that I want to call # are # addquarter(), adddime(), addnickel(), totalworth(), # # That is, the following code needs to be valid with your class: # mybank = piggybank() # mybank.adddime() # mybank.addquarter() # mybank.addnickel() # print mybank.totalworth() # should print 40 cents ## Now you're going to add another method to the class. You want to # *merge* the contents of two piggybanks into one: # yourbank = piggybank() # yourbank.addnickel() # yourbank.addquarter() # yourbank.merge(mybank) # add mybank's contents to yourbank # print yourbank.totalworth() # should print 70 cents # print mybank.totalworth() # should print 0 cents: you stole my money. ######################### ONE MORE IMPORTANT THING ########################### #You were first introduced to the concept of pointers with respect to arrays. #Arrays are special kinds of objects. Objects in Python are also referenced #through pointers. This means that if I do: # mybank = yourbank # it does not duplicate the yourbank object, rather it would just set mybank # to the memory address of where yourbank is stored. It doesn't copy the # object. So remember, when you assign a variable to an object, the variable # is actually only assigned to the memory address of the object. class demo: def __init__(this,a): this.x = a #init #demo def f(x,D): x = 2 D.x = 2 #f x = 1 D = demo(1) f(x,D) print x, D.x # prints 1, then 2 # x stays 1 because the x inside the function f is a local x. The D inside # the function f is also local to f (because it's a parameter), but it # points to the same object that the D outside points to. So when D.x is # changed to 2, it affects the same object that the other D points to as well. # Had I tried to do the following inside f: D = demo(2). Then the D inside # f will be set to a different object, but the D outside will still point to # the original object, which hasn't been changed. In this case it will still # print 1 for D.x