Lecture 18 - More Python Class Methods
Lecture 18 - More Python Class Methods
METHODS
(download slides and .py files to follow along)
6.100L Lecture 18
Ana Bell
1
IMPLEMENTING USING
THE CLASS vs THE CLASS
6.100L Lecture 18
RECALL THE COORDINATE CLASS
class Coordinate(object):
""" A coordinate made up of an x and y value """
def __init__(self, x, y):
""" Sets the x and y values """
self.x = x
self.y = y
def distance(self, other):
""" Returns euclidean dist between two Coord obj """
x_diff_sq = (self.x-other.x)**2
y_diff_sq = (self.y-other.y)**2
return (x_diff_sq + y_diff_sq)**0.5
6.100L Lecture 18
ADDING METHODS TO THE
COORDINATE CLASS
Methods are functions that only work with objects of this type
class Coordinate(object):
""" A coordinate made up of an x and y value """
def __init__(self, x, y):
""" Sets the x and y values """
self.x = x
self.y = y
def distance(self, other):
""" Returns euclidean dist between two Coord obj """
x_diff_sq = (self.x-other.x)**2
y_diff_sq = (self.y-other.y)**2
return (x_diff_sq + y_diff_sq)**0.5
def to_origin(self):
""" always sets self.x and self.y to 0,0 """
self.x = 0
self.y = 0
4
6.100L Lecture 18
MAKING COORDINATE INSTANCES
c = Coordinate(3,4)
origin = Coordinate(0,0)
c.to_origin()
print(c.x, c.y)
5
6.100L Lecture 18
CLASS DEFINITION INSTANCE
OF AN OBJECT TYPE vs OF A CLASS
6.100L Lecture 18
USING CLASSES TO BUILD OTHER
CLASSES
Example: use Coordinates to build Circles
Our implementation will use 2 data attributes
Coordinate object representing the center
int object representing the radius
radius
Center
coordinate
6.100L Lecture 18
CIRCLE CLASS:
DEFINITION and INSTANCES
class Circle(object):
def __init__(self, center, radius):
self.center = center
self.radius = radius
center = Coordinate(2, 2)
my_circle = Circle(center, 2)
6.100L Lecture 18
YOU TRY IT!
Add code to the init method to check that the type of center is
a Coordinate obj and the type of radius is an int. If either are
not these types, raise a ValueError.
6.100L Lecture 18
CIRCLE CLASS:
DEFINITION and INSTANCES
class Circle(object):
def __init__(self, center, radius):
self.center = center
self.radius = radius
def is_inside(self, point):
""" Returns True if point is in self, False otherwise """
return point.distance(self.center) < self.radius
center = Coordinate(2, 2)
my_circle = Circle(center, 2)
p = Coordinate(1,1)
print(my_circle.is_inside(p))
10
6.100L Lecture 18
YOU TRY IT!
Are these two methods in the Circle class functionally equivalent?
class Circle(object):
def __init__(self, center, radius):
self.center = center
self.radius = radius
11
6.100L Lecture 18
EXAMPLE:
FRACTIONS
12
6.100L Lecture 18
NEED TO CREATE INSTANCES
class SimpleFraction(object):
def __init__(self, n, d):
self.num = n
self.denom = d
13
6.100L Lecture 18
MULTIPLY FRACTIONS
class SimpleFraction(object):
def __init__(self, n, d):
self.num = n
self.denom = d
def times(self, oth):
top = self.num*oth.num
bottom = self.denom*oth.denom
return top/bottom
14
6.100L Lecture 18
ADD FRACTIONS
class SimpleFraction(object):
def __init__(self, n, d):
self.num = n
self.denom = d
………
def plus(self, oth):
top = self.num*oth.denom + self.denom*oth.num
bottom = self.denom*oth.denom
return top/bottom
15
6.100L Lecture 18
LET’S TRY IT OUT
f1 = SimpleFraction(3, 4)
f2 = SimpleFraction(1, 4)
print(f1.num) 3
print(f1.denom) 4
print(f1.plus(f2)) 1.0
print(f1.times(f2)) 0.1875
16
6.100L Lecture 18
YOU TRY IT!
Add two methods to invert fraction object according to the specs below:
class SimpleFraction(object):
""" A number represented as a fraction """
def __init__(self, num, denom):
self.num = num
self.denom = denom
def get_inverse(self):
""" Returns a float representing 1/self """
pass
def invert(self):
""" Sets self's num to denom and vice versa.
Returns None. """
pass
# Example:
f1 = SimpleFraction(3,4)
print(f1.get_inverse()) # prints 1.33333333 (note this one returns value)
f1.invert() # acts on data attributes internally, no return
print(f1.num, f1.denom) # prints 4 3
17
6.100L Lecture 18
LET’S TRY IT OUT WITH MORE
THINGS
f1 = SimpleFraction(3, 4)
f2 = SimpleFraction(1, 4)
print(f1.num) 3
print(f1.denom) 4
print(f1.plus(f2)) 1.0
print(f1.times(f2)) 0.1875
18
6.100L Lecture 18
SPECIAL OPERATORS IMPLEMENTED
WITH DUNDER METHODS
19
6.100L Lecture 18
SPECIAL OPERATORS IMPLEMENTED
WITH DUNDER METHODS
6.100L Lecture 18
PRINTING OUR OWN
DATA TYPES
21
6.100L Lecture 18
PRINT REPRESENTATION OF AN
OBJECT
>>> c = Coordinate(3,4)
>>> print(c)
<__main__.Coordinate object at 0x7fa918510488>
>>> print(c)
<3,4>
22
6.100L Lecture 18
DEFINING YOUR OWN PRINT
METHOD
class Coordinate(object):
def __init__(self, xval, yval):
self.x = xval
self.y = yval
def distance(self, other):
x_diff_sq = (self.x-other.x)**2
y_diff_sq = (self.y-other.y)**2
return (x_diff_sq + y_diff_sq)**0.5
def __str__(self):
return "<"+str(self.x)+","+str(self.y)+">"
23
6.100L Lecture 18
WRAPPING YOUR HEAD AROUND
TYPES AND CLASSES
24
6.100L Lecture 18
EXAMPLE: FRACTIONS WITH
DUNDER METHODS
25
6.100L Lecture 18
CREATE & PRINT INSTANCES
class Fraction(object):
def __init__(self, n, d):
self.num = n
self.denom = d
def __str__(self):
return str(self.num) + "/" + str(self.denom)
26
6.100L Lecture 18
LET’S TRY IT OUT
f1 = Fraction(3, 4)
f2 = Fraction(1, 4)
f3 = Fraction(5, 1)
print(f1) 3/4
print(f2) 1/4
print(f3) 5/1
Ok, but looks weird!
27
6.100L Lecture 18
YOU TRY IT!
Modify the str method to represent the Fraction as just the
numerator, when the denominator is 1. Otherwise its
representation is the numerator then a / then the denominator.
class Fraction(object):
def __init__(self, num, denom):
self.num = num
self.denom = denom
def __str__(self):
return str(self.num) + "/" + str(self.denom)
# Example:
a = Fraction(1,4)
b = Fraction(3,1)
print(a) # prints 1/4
print(b) # prints 3
28
6.100L Lecture 18
IMPLEMENTING
+-*/
float()
29
6.100L Lecture 18
COMPARING METHOD vs.
DUNDER METHOD
30
6.100L Lecture 18
LETS TRY IT OUT
a = Fraction(1,4)
b = Fraction(3,4)
print(a) 1/4
c = a * b
print(c) 3/16
31
6.100L Lecture 18
CLASSES CAN HIDE DETAILS
32
6.100L Lecture 18
BIG IDEA
Special operations we’ve
been using are just
methods behind the
scenes.
Things like:
print, len
+, *, -, /, <, >, <=, >=, ==, !=
[]
and many others!
33
6.100L Lecture 18
CAN KEEP BOTH OPTIONS BY ADDING
A METHOD TO CAST TO A float
class Fraction(object):
def __init__(self, n, d):
self.num = n
self.denom = d
………
def __float__(self):
return self.num/self.denom
c = a * b
print(c) 3/16
print(float(c)) 0.1875
34
6.100L Lecture 18
LETS TRY IT OUT SOME MORE
a = Fraction(1,4)
b = Fraction(2,3)
c = a * b
print(c) 2/12
35
6.100L Lecture 18
ADD A METHOD
class Fraction(object):
………
def reduce(self):
def gcd(n, d):
while d != 0:
(d, n) = (n%d, d)
return n
if self.denom == 0:
return None
elif self.denom == 1:
return self.num
else:
greatest_common_divisor = gcd(self.num, self.denom)
top = int(self.num/greatest_common_divisor)
bottom = int(self.denom/greatest_common_divisor)
return Fraction(top, bottom)
c = a*b
print(c) 2/12
print(c.reduce()) 1/6 36
6.100L Lecture 18
WE HAVE SOME IMPROVEMENTS TO MAKE
class Fraction(object):
…………
def reduce(self):
def gcd(n, d):
while d != 0:
(d, n) = (n%d, d)
return n
if self.denom == 0:
return None
elif self.denom == 1:
s
return self.num
else:
greatest_common_divisor = gcd(self.num, self.denom)
top = int(self.num/greatest_common_divisor)
bottom = int(self.denom/greatest_common_divisor)
return Fraction(top, bottom)
37
6.100L Lecture 18
CHECK THE TYPES, THEY’RE DIFFERENT
a = Fraction(4,1)
b = Fraction(3,9)
ar = a.reduce() 4
br = b.reduce() 1/3
38
6.100L Lecture 18
YOU TRY IT!
Modify the code to return a Fraction object when denominator
is 1
class Fraction(object):
def reduce(self):
def gcd(n, d):
while d != 0:
(d, n) = (n%d, d)
return n
if self.denom == 0:
return None
elif self.denom == 1:
return self.num
else:
greatest_common_divisor = gcd(self.num, self.denom)
top = int(self.num/greatest_common_divisor)
bottom = int(self.denom/greatest_common_divisor)
return Fraction(top, bottom)
# Example:
f1 = Fraction(5,1)
print(f1.reduce()) # prints 5/1
39
not 5
6.100L Lecture 18
WHY OOP and BUNDLING THE
DATA IN THIS WAY?
Code is organized and modular
Code is easy to maintain
It’s easy to build upon objects to make more complex objects
40
6.100L Lecture 18
MITOpenCourseWare
https://ocw.mit.edu
For information about citing these materials or our Terms ofUse,visit: https://ocw.mit.edu/terms.
41