operators and abstraction announcements
play

Operators and Abstraction Announcements Reading Regrades Today - PowerPoint PPT Presentation

Lecture 19 Operators and Abstraction Announcements Reading Regrades Today is last day to request Tuesday : Chapter 18 Show it to me after class Thursday reading online I will verify if it is valid Then request regrade in


  1. Lecture 19 Operators and Abstraction

  2. Announcements Reading Regrades • Today is last day to request • Tuesday : Chapter 18 § Show it to me after class • Thursday reading online § I will verify if it is valid • Then request regrade in CMS Assignments • Prelim, Nov 9 th 7:30-9:00 § Material up to November 2nd • A4 due tonight at Midnight § Recursion + Loops + Classes § 10 pts per day late • S/U Students are exempt § Consultants available tonight • Conflict with Prelim time? • A5 posted today, A6 on Sat. § Prelim 2 Conflict on CMS § See included micro -deadlines 10/26/17 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: top [int] multiply, divide, etc. _denominator: bottom [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 10/26/17 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: top [int] multiply, divide, etc. attributes, use _denominator: bottom [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 10/26/17 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) 4 >>> q = Fraction(1,3) >>> r = Fraction(1,4) >>> s = Fraction(5,4) >>> (p.add(q.add(r))).mult(s) This is confusing! 10/26/17 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) 4 >>> q = Fraction(1,3) >>> 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! 10/26/17 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""” … 10/26/17 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 10/26/17 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 10/26/17 Operators and Abstraction 9

  10. Operator Overloading: Multiplication class Fraction(object): >>> p = Fraction(1,2) """Instance attributes: >>> q = Fraction(3,4) _numerator: top [int] >>> r = p*q _denominator: bottom [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) 10/26/17 Operators and Abstraction 10

  11. Operator Overloading: Addition class Fraction(object): >>> p = Fraction(1,2) """Instance attributes: >>> q = Fraction(3,4) _numerator: top [int] >>> r = p+q _denominator: bottom [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 top= (self._numerator*q._denominator+ Operator overloading uses self._denominator*q._numerator) method in object on left. return Fraction(top,bot) 10/26/17 Operators and Abstraction 11

  12. Comparing Objects for Equality class Fraction(object): • Earlier in course, we saw == """Instance attributes: compare object contents _numerator: top [int] § This is not the default _denominator: bottom [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 10/26/17 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) 10/26/17 Operators and Abstraction 13

  14. Structure of a Proper Python Class class Fraction(object): Docstring describing class """Instances represent a Fraction Attributes are all hidden Attributes: _numerator: [int] _denominator: [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""" … 10/26/17 Operators and Abstraction 14

  15. Recall: Overloading Multiplication class Fraction(object): >>> p = Fraction(1,2) """Instance attributes: >>> q = 2 # an int _numerator [int]: top >>> r = p*q _denominator [int > 0]: bottom """ 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) 10/26/17 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 10/26/17 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) 10/26/17 Operators and Abstraction 17

Recommend


More recommend