Exercise 1

Recall that in the textbook, we created a class to model a multi-sided die. The code for the class is below.

from random import randrange

class MSDie:

    def __init__(self, sides):
        self.sides = sides
        self.value = 1

    def roll(self):
        self.value = randrange(1, self.sides+1)

    def getValue(self):
        return self.value

    def setValue(self, value):
        self.value = value

a. Before we experiment with the code, let’s play with the randrange function. Open up a REPL environment and run the following.

>>> from random import randrange
>>> randrange(0, 5)

b. Try repeatedly typing randrange(0, 5) to see what it generates. Does it ever generate the number 0? What about 5?

c. Try changing the parameters to other numbers to make sure you understand what it is doing.

d. Look at the roll() method of the MSDie class. Why are the parameters to randrange 1 and self.sides+1? Discuss this with your partner.

e. Copy and paste the above class into a file named classes.py and create a main() function that creates two six-sided dice, rolls them, and prints off their individual values and their sum. (Remember that to create an MSDie object, you must use do something like d = MSDie(4) which creates a single die with four sides. Initially the die has a value of 1, and to randomize its value you must call the roll() method. To do this, you would do something like d.roll().)

Exercise 2

Suppose we want to create a Rectangle class—not for working with Zelle’s graphics library but rather for doing various calculations.

The two basic parts every rectangle has is a width and height. Below is a partial implementation of a Rectangle class that contains two instance variables, width and height, to keep track of these values.

class Rectangle:

    def __init__(self, width, height):
        self.width = width
        self.height = height

    def getWidth(self):
        # Not yet implemented

    def getHeight(self):
        # Not yet implemented

    def getArea(self):
        # Not yet implemented

    def getPerimeter(self):
        # Not yet implemented

a. Copy and paste this class definition into your classes.py file.

b. Finish implementing the getWidth() and the getHeight() methods. Test that you can create objects of type Rectangle and get back their width and height components by updating your main() function, creating a few objects, and printing their width and height.

c. Finish implementing the getArea() and the getPerimeter() methods which return the area of the rectangle and the perimeter of the rectangle. Be sure to test them in your main() function and by running it via the terminal!

d. Create a new method called copy() which returns a new Rectangle object that has the save values for width and height as the one it is called on. (Note that this method takes no parameters but it will still have the special self parameter like the others.)

Exercise 3

Sometimes we want to track where a rectangle is located. If a rectangle is located at the point (x,y), we usually mean its upper left corner is at (x,y). (Zelle like to anchor rectangles by their center which can be confusing to other programmers.)

a. Add two more instance variables to the Rectangle class called x and y and update the initializer to take in the initial values of x and y.

b. Add methods getX() and getY() that return the values of these variables.

c. Test your updates in your main() function.

Exercise 4

It is sometimes useful to check if two rectangles are overlapping. Write a a method inside the Rectangle classes called overlapping(rect) that takes a single object of type Rectangle as a parameter and returns True if the rectangle rect is overlapping this rectangle and False otherwise. (Remember that you need to include the self parameter in the method definition and that you can use it to get the width and height of the self object.)

For example, here are a few examples of executing the method.

r1 = Rectangle(0, 50, 100, 50)      # x=0, y=50, width = 100, height = 50
r2 = Rectangle(25, 25, 50, 50)      # x=25, y=25, width=50, height=50
r3 = Rectangle(0, 100, 25, 25)      # x=0, y=100, width=25, height=25

print(r1.overlapping(r2))   # Prints True since they are overlapping
print(r2.overlapping(r3))   # Prints False since they are not

It may be helpful drawing the rectangles to see why they are overlapping or not overlapping to figure out how to write this method.