Classes and Objects (Part II)¶

Outline¶

  • Reminders
  • Programmer-Defined Types
  • Attributes
  • Mutable Objects
  • Copying Objects
  • Exercises

In [1]:
# import packages
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns; sns.set()

Important Notes/Reminders ¶

  • Project proposals due today!
  • Quiz 6 on Fri., Nov. 15th (last quiz!)
  • If you are interested in Fresno State's Department of Math Day (DMD), go here.
  • Math Club will have tutoring today from 4PM - 6PM.

Programmer-defined Types ¶

A program-defined type is also called a class . A class definition looks like this:

In [6]:
class Point:
    """Represents a point in 2-D space."""

Attributes ¶

Named elements of an object that are assigned values are known as attributes. In other words, they belong to the object.

In [7]:
class Rectangle:
    """Represents a rectangle.
    attributes: width, height, (lower left) corner.
    """
In [20]:
# create an instance of a rectangle
box = Rectangle()
# assign width and height to box
box.width = 100.0
box.height = 200.0
# assign a corner as an instance of a point
box.corner = Point()
# assing x, y to the the corner of the box
box.corner.x = 0.0
box.corner.y = 0.0
In [21]:
def print_point(p):
    print('(%g, %g)' % (p.x, p.y))
In [ ]:
def print_time(t):
    print('%.2d:' % t.hour)
In [22]:
def find_center(rect):
    p = Point()
    p.x = rect.corner.x + rect.width/2
    p.y = rect.corner.y + rect.height/2
    return print_point(p)
    # return p
In [23]:
find_center(box)
(50, 100)

Mutable Objects ¶

You can change the state of an object by making an assignment to one of its attributes. For example, what happens if you try to increase the width of a rectangle?

In [24]:
box.width = box.width*2
In [25]:
box.width
Out[25]:
200.0
In [28]:
def grow_rectangle(rect, dwidth, dheight):
    ''' Modifies the width and length of a rectangle by dwidth and dheight 
     rect: Rectangle object '''
    rect.width = rect.width + dwidth
    rect.height = rect.height + dheight
In [29]:
grow_rectangle(box, 2, 2)
In [32]:
box.height
Out[32]:
202.0

NOTE! Inside the function, rect is an alias for box, so when the function modifies rect, box changes.

Practice!

  • Write a function named move_rectangle that takes a Rectangle and two numbers named dx and dy. It should change the location of the rectangle by adding dx to the x coordinate of corner and adding dy to the y coordinate of corner.
In [33]:
def move_rectangle(rect, dx, dy):
    rect.corner.x = rect.corner.x + dx
    rect.corner.y = rect.corner.y + dy
In [34]:
move_rectangle(box, 0,0)
In [36]:
print_point(box.corner)
(0, 0)

Copying Objects ¶

Aliasing can make a program difficult to read because changes in one place might have unexpected effects in another place. It is hard to keep track of all the variables that might refer to a given object. Copying an object is often an alternative to aliasing.

In [37]:
import copy
p1 = Point()
p2 = copy.copy(p1)
In [38]:
p1 == p2
Out[38]:
False
In [39]:
p1
Out[39]:
<__main__.Point at 0x1a1e9c4da0>
In [40]:
p2
Out[40]:
<__main__.Point at 0x1a1e9c4dd8>

In order to duplicate an object and embeddings, we want to use deepcopy. Otherwise, we might accidentally affect multiple objects' embeddings.

In [41]:
box2 = copy.deepcopy(box)

Practice!

  • Write a version of move_rectangle that creates and returns a new Rectangle instead of modifying the old one.
In [42]:
def move_rectangle2(rect1, dx, dy):
    rect = copy.deepcopy(rect1)
    rect.corner.x = rect.corner.x + dx
    rect.corner.y = rect.corner.y + dy
    return rect
In [44]:
print_point(box.corner)
(0, 0)
In [45]:
box2 = move_rectangle2(box,1,1)
In [46]:
print_point(box2.corner)
(1, 1)

Exercises ¶

Note: This participation assignment (all parts) is due Wed, Nov. 12th at 11:59PM.


1. The `Circle` Class

  • Write a definition for a class named Circle with attributes center and radius, where center is a Point object and radius is a number.
  • Instantiate a Circle object that represents a circle with its center at (150, 100) and radius 75. Write a function named point_in_circle that takes a Circle and a Point and returns True if the Point lies in or on the boundary of the circle.
  • Write a function named rect_in_circle that takes a Circle and a Rectangle and returns True if the Rectangle lies entirely in or on the boundary of the circle.
  • Write a function named rect_circle_overlap that takes a Circle and a Rectangle and returns True if any of the corners of the Rectangle fall inside the circle. **Or as a more challenging version, return True if any part of the Rectangle falls inside the circle.
In [ ]:
 

2. Debugging

Investigate the following functions and their uses as they relate to Classes (you may refer to the thinkpython2 book or the interwebs). Briefly give an example of each using the Circle class you came up with above.

- `type`
- `isinstance`
- `hasattr`