ObjectOriented Programming in Python Goldwasser and Letscher Chapter

Object-Oriented Programming in Python Goldwasser and Letscher Chapter 6 Defining Our Own Classes Terry Scott University of Northern Colorado 2007 Prentice Hall

Introduction: Chapter 6 Topics • • • Simple point class. Robust point class. Television class. Fraction class. advanced lessons. 2

Predefined versus User Defined Classes • Why do classes? It supports reuse of code. • Some predefined classes are int, float, list, tuple, boolean, and file. • By being able to create our own classes we can configure Python to handle new data types. 3

Point Class • class Point: • __init__ called the constructor. Executed when a new object is created from a class. • self lets Python know that a method or data is a member of the class. – For a data member it should be; self. _x where _x is the class data attribute. Without the self a variable is only a local variable inside a class method. – For a method the self is the first parameter in the parameter list. __init__(self, . . . ) 4

Indentation Pattern for a Class 5

Connection Between a Method (set. X) for the object corner and set. X definition in the class. 6

Two Perspectives • Left: perspective from outside the Point class. • Right: perspective from inside the Point class. 7

Accessors and Mutators • Accessors and mutators let users of the class access data member and change data member values. • get. X(self) can return the X data member. • set. X(self, val) will change the X data member to be val. 8

Creating a point class Point: def __init__(self): self. _x = 0 self. _y = 0 def get. X(self, val): return self. _x 9

Point Class (Continued) def set. X(self, val): self. _x = val def set. Y(self. val): self. _y = val def set. Y(self, val): self. _y = val 10

Using the Point Class #create a new object corner of type Point from Simple. Point import Point corner = Point() corner. set. X(8) #8 is value of _x in object corner. set. Y(6) #6 is value of _y in object corner 11

Improved Point class #if no values are specified for x and y then #the values are set to 0. def __init__(self, init. X = 0, init. Y = 0) self. _x = init. X self. _y = init. Y #Scales the point by a value factor. def scale(self, factor): self. _x *= factor self. _y *= factor 12

Improved Point Class (continued) def distance(self, other): dx = self. _x - other. _x dy = self. _y – other. _y return sqrt(dx*dx + dy*dy) #using the distance method point 1 = Point(5, 20) point 2 = Point(45, 60) apart. Amt = point 1. distance(point 2) 13

Improved Point Class (continued) #normalize point – make its distance to the #origin 1 def normalize(self): mag = self. distance(Point()) #Point() creates new point at origin if mag > 0: #don't scale if point is at origin self. scale(1/mag) 14

Improved Point Class (continued) #allow print to be able to print a point object. def __str__(self): return '<'+str(self. _x)+', '+str(self. _y)+ '>' #using __str__ method new = Point(3, 5) print new #output <3, 5> 15

Improved Point Class (continued) • Can not use <3, 5> to initialize an object. point = <3, 5> #this is an error • Can overload most operators so that they have a new meaning when used with new objects. • An example is + operator when used with int and float does addition. When used with str it does concatenation (sticks the two strings together). 16

Improved Point Class (continued) #overloading operators: + overloading def __add__(other): return Point(self. _x +other. _x, self. _y+other. _y #using the __add__ method new = Point(3, 5) old = Point(4, 7) total = new + old print total #output <7, 12> 17

Polymorphism • Operator may do a different operation depending on the type that is passed into the operator. • Multiplication operator: int or float multiply each component by the value, point do a dot product. • isinstance(variable, Type) returns True if variable is of type Type. 18

Polymorphism #if val is an int or float it does the if code #if a Point it does the elif code. def __mul__(self, val): if isinstance(val, (int, float)): #performs regular multiplication operation. return Point(self. _x*val, self. _y*val) elif isinstance(val, Point): #performs dot product operation. return self. _x*val. _x + self. _y*val. _y 19

Television Class • Create a user class to emulate the way television controls work. • General principles – On-off and mute are both toggle switches – All controls only work when the TV is on. – Volume control goes from 1 to 10 inclusive. – Channels range from 2 – 99 inclusive. It wraps around. – Can change channel by entering a channel number. 20

Television Class #initializes television object class Television: def __init__(self): self. _power. On = False self. muted = False self. _volume = 5 self. _channel = 2 self. _prev. Chan = 2 21

Television Class Diagram 22

Television Class (continued) #Clicking flips if on then off and off then on def toggle. Power(self): self. _power. On = not self. _power. On #Clicking flips between muted and unmuted. def toggle. Mute(self): if self. _power. On: self. _muted = not self. _muted 23

Television Class (continued) #volume can range from 1 upto including 10 def volume. Up(self): if self. _power. On: if self. _volume < 10: self. _volume += 1 self. _muted = False return self_volume #volume is #displayed on tv when it is changed. 24

Television Class (continued) #channel increases by one and wraps back to 2 def channel. Up(self): if self. _power. On: self. _prev. Chan = self. _channel if self. _channel == 99: self. _channel = 2 else: self. _channel += 1 return self. _channel 25

Television Class (continued) • volume. Down is similar to volume. Up just replace test self. _volume < 10 with self. _volume > 1 and replace self. _volume += 1 with self. _volume -= 1 • channel. Down is similar to channel. Up just replace test self. _channel == 99 with self. _channel == 2 and replace self. _channel += 1 with self. _channel -= 1. 26

Television Class (continued) #Channel is set to number. def set. Channel(self, number): if self. _power. On: if 2 <= number <= 99: self. _prev. Chan = self. _channel = number return self. _channel 27

Trace of set. Channel(7) Tuned to Channel 5 and Was Previously on Channel 2 28

Television Class (continued) #Flip to previous channel. def jump. Prev. Channel(self): if self. _power. On: incoming = self. _channel = self. _prev. Chan = incoming return self. _channel 29

Flawed Swap of Channels #Left picture is starting situation self. _channel = self. _prev. Chan = self. _channel #both variables end up at 5 30

One Way to Do This in Python self. _channel, self. _prev. Chan=self. prev. Chan, self. _channel 31

Television Class (continued) # previous code #using swap from previous slide incoming = self. _channel = self. _prev. Chan = incoming # in Python can do the following: can assign #simultaneously so no need to set to a #tempory value. self. _channel, self. _prev. Chan=self. prev. Chan, self. _channel 32

Fraction Class • Fraction consists of two numbers: a numerator and a denominator. • Must be in lowest terms. • Denominator must be non-negative. • Denominator must be non-zero. • Method types: – constructor. – arithmetic operators. – comparison operators. – type conversion operators. 33

Fraction Class Code def __init__(self, numer=0, denom= 0): if denom == 0: self. _num = 0 self. _den = 0 else: factor = gcd(abs(numer), abs(denom)) if denom < 0: factor = -factor self. _num = numer // factor self. _den = denom // factor 34

Fraction Class Code (continued) #overloads + operator fraction objects. def __add__(self, other): return Fraction(self. _num*other. _den + self. _den*other. _num, self. _den*other. _den) #overload < operator fraction objects. def __lt__(self, other): return self. _num*other. _den<self. _den*other. _num 35

Fraction Class Code (continued) # Overloads == operator fraction objects def __eq__(self, other): return self. _num == other. _num and self. _den == other. _den # Overloads float operator fraction object def __float__(self): return float(self. _num) / self. _den 36

Fraction Class Code (continued) # overloads int function def __init__(self): return int(float(self)) # overload str function def __str__(self): if self. _den == 0: return 'undefined' elif self. _den == 1 return str(self. _num) else: return str(self. _num) + '/' + str(self. _den) 37

Complete Fraction Class from gcd import gcd class Fraction: def __init__(self, . . . ) #include constructor code def __add__(self, . . . ) #include + operator code def __sub__(self, . . . ): #similar to __add__ code just - instead 38

Complete Fraction Class (continued) def __mul__(self, other): return Fraction(self. _num*other. _num, self. _den * other. _den def __mul__(self, other): return Fraction(self. _num*other. _den, self. _den * other. _num #include other comparison operators #include float, int, and str conversion operators. 39

Advanced Lessons #Class-Level Attributes # don't hardwire values such as 0 and 10 # volume and 2 and 99 for channels class Television: #class level attributes will be shared by all _min. Volume = 0 _max. Volume = 10 _min. Channel = 2 _max. Channel = 99 #use. Television. _min. Volume etc instead of hardwired #values that were used before. 40

Advanced Lessons (continued) # Methods that call other methods # By using previously defined set. Channel method can # simplify the code. def channel. Up(self): if self. _power. On: if self. _channel == Television. _max. Channel: goto = Television. _min. Channel else: goto = self. _channel + 1 return self. set. Channel(goto) 41

Advanced Lessons (continued) # By separating the wrap-around character# istics from the actual channel changing the # code is simplified. # Revised jump. Prev. Channel using a # previously defined method. def jump. Prev. Channel(self): return self. set. Channel(self. _prev. Chan) 42
- Slides: 42