operators and abstraction announcements for today two
play

Operators and Abstraction Announcements for Today Two Weeks Out! - PowerPoint PPT Presentation

Lecture 20 Operators and Abstraction Announcements for Today Two Weeks Out! Assignments Prelim, Nov 21 st at 7:30 A4 graded by Saturday Will cover survey next week Same rooms as last time Day after A6 is due A5 also


  1. Lecture 20 Operators and Abstraction

  2. Announcements for Today Two Weeks Out! Assignments • Prelim, Nov 21 st at 7:30 • A4 graded by Saturday § Will cover survey next week § Same rooms as last time § Day after A6 is due • A5 also graded by Saturday § Returned via Gradescope • Material up to Nov. 12 § Similar policies to A2 § Study guide this weekend • Need to be working on A6 § Recursion + Loops + Classes § Finish Image this weekend • Conflict with Prelim? § Finish Filter by next Thurs § Prelim 2 Conflict on CMS § Best way to study for exam § SDS students must submit! 11/7/19 Operators and Abstraction 2

  3. Case Study: Fractions class Fraction(object): • Want to add a new type """Instance is a fraction n/d""" § Values are fractions: ½ , ¾ # INSTANCE ATTRIBUTES: § Operations are standard # _numerator: an int multiply, divide, etc. # _denominator: an int > 0 § Example : ½ * ¾ = ⅜ • Can do this with a class def __init__(self,n=0,d=1): § Values are fraction objects """Init: makes a Fraction""" § Operations are methods self._numerator = n self._denominator = d • Example : frac1.py 11/7/19 Operators and Abstraction 3

  4. Case Study: Fractions class Fraction(object): • Want to add a new type """Instance is a fraction n/d""" § Values are fractions: ½ , ¾ # INSTANCE ATTRIBUTES: § Operations are standard Reminder : Hide # _numerator: an int multiply, divide, etc. attributes, use # _denominator: an int > 0 § Example : ½ * ¾ = ⅜ getters/setters • Can do this with a class def __init__(self,n=0,d=1): § Values are fraction objects """Init: makes a Fraction""" § Operations are methods self._numerator = n self._denominator = d • Example : frac1.py 11/7/19 Operators and Abstraction 4

  5. Problem: Doing Math is Unwieldy What We Want What We Get 1 2 + 1 3 + 1 4 ∗ 5 >>> p = Fraction(1,2) >>> q = Fraction(1,3) 4 >>> r = Fraction(1,4) >>> s = Fraction(5,4) >>> (p.add(q.add(r))).mult(s) This is confusing! 11/7/19 Operators and Abstraction 5

  6. Problem: Doing Math is Unwieldy What We Want What We Get 1 2 + 1 3 + 1 4 ∗ 5 >>> p = Fraction(1,2) >>> q = Fraction(1,3) 4 >>> r = Fraction(1,4) >>> s = Fraction(5,4) Why not use the >>> (p.add(q.add(r))).mult(s) standard Python math operations? This is confusing! 11/7/19 Operators and Abstraction 6

  7. Special Methods in Python class Point3(object): • Have seen three so far """Instances are points in 3D space""" § __init__ for initializer … § __str__ for str() def __init__(self,x=0,y=0,z=0): § __repr__ for repr() """Initializer: makes new Point3""" • Start/end with 2 underscores … § This is standard in Python def __str__(self,q): § Used in all special methods """Returns: string with contents""” § Also for special attributes … • We can overload operators def __repr__(self,q): § Give new meaning to +, *, - """Returns: unambiguous string""” … 11/7/19 Operators and Abstraction 7

  8. Operator Overloading • Many operators in Python a special symbols § + , - , / , * , ** for mathematics § == , != , < , > for comparisons • The meaning of these symbols depends on type § 1 + 2 vs 'Hello' + 'World' § 1 < 2 vs 'Hello' < 'World' • Our new type might want to use these symbols § We overload them to support our new type 11/7/19 Operators and Abstraction 8

  9. Returning to Fractions What We Want Operator Overloading 1 2 + 1 3 + 1 4 ∗ 5 • Python has methods that correspond to built-in ops 4 § __ add__ corresponds to + § __mul__ corresponds to * § __eq__ corresponds to == Why not use the § Not implemented by default standard Python • To overload operators you math operations? implement these methods 11/7/19 Operators and Abstraction 9

  10. Operator Overloading: Multiplication class Fraction(object): >>> p = Fraction(1,2) """Instance is a fraction n/d""" >>> q = Fraction(3,4) # _numerator: an int >>> r = p*q # _denominator: an int > 0 def __mul__(self,q): Python """Returns: Product of self, q converts to Makes a new Fraction; does not modify contents of self or q >>> r = p.__mul__(q) Precondition: q a Fraction""" assert type(q) == Fraction Operator overloading uses top= self._numerator*q._numerator bot= self._denominator*q._denominator method in object on left. return Fraction(top,bot) 11/7/19 Operators and Abstraction 10

  11. Operator Overloading: Addition class Fraction(object): >>> p = Fraction(1,2) """Instance is a fraction n/d""” >>> q = Fraction(3,4) # _numerator: an int >>> r = p+q # _denominator: an int > 0 def __add__(self,q): Python """Returns: Sum of self, q converts to Makes a new Fraction Precondition: q a Fraction""" >>> r = p.__add__(q) assert type(q) == Fraction bot= self._denominator*q._denominator Operator overloading uses top= (self._numerator*q._denominator+ self._denominator*q._numerator) method in object on left. return Fraction(top,bot) 11/7/19 Operators and Abstraction 11

  12. Comparing Objects for Equality class Fraction(object): • Earlier in course, we saw == """Instance is a fraction n/d""" compare object contents # _numerator: an int § This is not the default # _denominator: an int > 0 § Default : folder names • Must implement __eq__ def __eq__(self,q): """Returns: True if self, q equal, § Operator overloading! False if not, or q not a Fraction""" § Not limited to simple if type(q) != Fraction: attribute comparison return False § Ex : cross multiplying left = self._numerator*q._denominator rght = self._denominator*q._numerator 4 1 2 4 return left == rght 2 4 11/7/19 Operators and Abstraction 12

  13. is Versus == • p is q evaluates to False • p == q evaluates to True § Compares folder names § But only because method __eq__ compares contents § Cannot change this id2 id2 id3 id3 p q Point Point x 2.2 x 2.2 y 5.4 y 5.4 z 6.7 z 6.7 Always use (x is None) not (x == None) 11/7/19 Operators and Abstraction 13

  14. Structure of a Proper Python Class class Fraction(object): Docstring describing class """Instance is a fraction n/d""" Attributes are all hidden # _numerator: an int # _denominator: an int > 0 def getNumerator(self): Getters and Setters. """Returns: Numerator of Fraction""" … def __init__(self,n=0,d=1): Initializer for the class. """Initializer: makes a Fraction""" Defaults for parameters. … def __add__(self,q): Python operator overloading """Returns: Sum of self, q""" … def normalize(self): Normal method definitions """Puts Fraction in reduced form""" … 11/7/19 Operators and Abstraction 14

  15. Recall: Overloading Multiplication class Fraction(object): >>> p = Fraction(1,2) """Instance is a fraction n/d""" >>> q = 2 # an int # _numerator: an int >>> r = p*q # _denominator: an int > 0 def __mul__(self,q): Python """Returns: Product of self, q converts to Makes a new Fraction; does not modify contents of self or q >>> r = p.__mul__(q) # ERROR Precondition: q a Fraction""" assert type(q) == Fraction Can only multiply fractions. top = self._numerator*q._numerator bot= self._denominator*q._denominator But ints “make sense” too. return Fraction(top,bot) 11/7/19 Operators and Abstraction 15

  16. Solution: Look at Argument Type class Fraction(object): • Overloading use left type … § p*q => p.__mul__(q) def __mul__(self,q): § Done for us automatically """Returns: Product of self, q Precondition: q a Fraction or int""" § Looks in class definition if type(q) == Fraction: • What about type on right ? return self._mulFrac(q) § Have to handle ourselves elif type(q) == int: return self._mulInt(q) • Can implement with ifs … § Write helper for each type def _mulInt(self,q): # Hidden method return Fraction(self._numerator*q, § Check type in method self._denominator) § Send to appropriate helper 11/7/19 Operators and Abstraction 16

  17. A Better Multiplication class Fraction(object): >>> p = Fraction(1,2) … >>> q = 2 # an int def __mul__(self,q): >>> r = p*q """Returns: Product of self, q Precondition: q a Fraction or int""" Python if type(q) == Fraction: converts to return self._mulFrac(q) elif type(q) == int: return self._mulInt(q) >>> r = p.__mul__(q) # OK! … def _mulInt(self,q): # Hidden method See frac3.py for a full return Fraction(self._numerator*q, example of this method self._denominator) 11/7/19 Operators and Abstraction 17

Recommend


More recommend