Chapter 25

Related Classes

Classes may also be related to each other through a mechanism called inheritance. When one class inherits from another, it inherits all the state and behavior of the original class, and then has the opportunity to define additional new state and behavior.

The Sierpinski triangle is an interesting mathematical object (a fractal, like the Mandelbrot set) that is constructed by repeatedly removing the middle from a solid triangle.

Listing 25.1: Sierpinski Triangle

 1 # sierpinski.py
 2
 3 from turtle import Turtle, setworldcoordinates, exitonclick
 4
 5 class SierpinskiTriangle(Turtle):
 6 size = 2
 7 def __init__(self, n, x, y):
 8  Turtle.__init__(self, visible=False)
 9  self.n = n
10  self.speed(0)
11  self.penup()
12  self.goto(x, y)
13
14 def draw(self):
15  if self.n == 0:
16    self.begin_fill()
17    for i in range(3):
18    self.forward(SierpinskiTriangle.size)
19    self.left(120)
20    self.end_fill()
21  else:
22    for i in range(3):
23    SierpinskiTriangle(self.n − 1,
24        self.xcor(),
25        self.ycor()).draw()
26    self.forward(SierpinskiTriangle.size ** self.n)
27    self.left(120)
28
29 def main():
30 setworldcoordinates(0, 0, 75, 75)
31 SierpinskiTriangle(5, 5, 5).draw()
32 exitonclick()
33
34 if __name__ == "__main__":
35 main()

If this program takes too long to complete, try reducing the first parameter to the constructor in main().

The Turtle Class

The turtle module provides both procedural and object-oriented versions of its functionality. Part I only used procedural code (Python functions) because we had not used objects at that point in the course. Listing 25.1 introduces object-oriented turtle module code via the Turtle class. The Turtle class defines turtle objects that draw and move using method calls that are exactly the same as the function calls we used earlier. In fact, the function calls are implemented in the background by calling the corresponding method on a single internal Turtle object. One advantage of using Turtle objects explicitly is that your program can then work with more than one turtle at a time.

Some of the methods available on a Turtle object t are:

t.pendown()

Start drawing the turtle’s path.

t.penup()

Stop drawing the turtle’s path.

t.dot()

Draw a dot at current location.

t.goto(x, y)

Move to position (x, y).

t.forward(n)

Move forward n units.

t.left(theta)

Turn left angle theta (default degrees).

t.xcor()

Current position’s x coordinate.

t.ycor()

Current position’s y coordinate.

t.speed(s)

Set speed (1=slow to 10=fast; 0 is “instantly”).

t.begin_fill()

Turn filling on.

t.end_fill()

Stop filling.

You can find the description of other methods in the Python library documentation.

Inheritance

When we define a new class using inheritance, the new class inherits all of the state and behavior of the original class, known as the base class. The new class is called an extension of the base class, and it may define additional new state and behavior. Base classes are also known as parent classes or superclasses; extensions are also known as child classes or subclasses.

Inheritance is said to model an “is-a” relationship because an instance of the extension is an instance of the base class.

The syntax to define a class as an extension of a base class in Python is:

class <ClassName>(<BaseClass>):
 <body>

Thus, in Listing 25.1, the SierpinskiTriangle class extends the Turtle base class. Because of this, all of the methods defined in the Turtle class are available to be called on any SierpinskiTriangle object. We say that a SierpinskiTriangle object “is a” Turtle. In addition, SierpinskiTriangle objects have additional state and behavior that Turtle objects do not.

Superclass Initializer

If you define an .__init__() method for a class extension, it is usually a good idea to call the base class’s .__init__() method first to make sure that the state defined for the base class is initialized to reasonable values before trying to set additional state for the extension. The syntax to make this call is:

<BaseClass>.__init__(self, <other parameters>)

Class Variables

Recall that objects store data in instance variables (fields) and that the syntax to access a particular object’s field is <object>.<field>. Every object has its own storage for instance variables and thus different objects may store different values in their fields.

Occasionally, it is helpful for a class to store data that is shared among all instances of the class; in this case, a class variable is appropriate. For example, in Listing 25.1, the size variable of the SierpinskiTriangle class is shared by all instances of that class and controls the size of the triangles that are drawn.

There is no special syntax for declaring class variables in Python. Instead, any variable that is assigned a value inside of a class definition but outside all method definitions of the class (as on line 6) is automatically a class variable. The syntax to access the value of a class variable is:

<ClassName>.<variable>

This is analogous to using <object>.<variable> to access an instance variable.

Class variables are public and may be accessed by code outside of the class using the same syntax.

Exercises

  1. 25.1 Use the SierpinskiTriangle class from Listing 25.1 to answer these questions:
    1. (a) List the new state and behavior that SierpinskiTriangle adds to Turtle.
    2. (b) Explain why the size variable is better as a class variable than an instance variable.
    3. (c) Explain why .penup() is called in the initializer without any later call to .pendown().
    4. (d) Describe as specifically as you can where all drawing is done in this program.
  2. 25.2 Use Listing 25.1 to answer these questions:
    1. (a) Determine the total number of turtle objects that are created.
    2. (b) Determine the starting position and orientation of a new turtle that is initialized by Turtle.__init__().
    3. (c) One of the three vertices is used as the starting point for drawing each triangle. Which vertex does this code use?
  3. 25.3 Modify Listing 25.1 to draw the lower-right triangle first.
  4. 25.4 Modify Listing 25.1 to use a Screen object instead of direct function calls. Use the Python documentation if you need it.
  5. 25.5 Modify Listing 25.1 to ask the user for the initial value of n. Adjust the screen coordinates so that the image fits the screen appropriately.
  6. 25.6 Write a program to implement the following algorithm that uses any three noncolinear points in the plane A, B, and C:
     Set p randomly to one of A, B, or C.
     Repeat:
      Set q randomly to one of A, B, or C.
      Set p to the midpoint between p and q.
      Put a dot at p.

    Describe the result. You do not need to write any classes.

  7. 25.7 Implement the previous exercise using a class that inherits from Turtle.
  8. 25.8 Write a program dicepoker.py to play dice poker. The game is played by rolling five dice. The user then chooses to either stay or re-roll some of the dice. After two options to re-roll or the player stays, the hand is evaluated. Scoring hands are five of a kind, a straight, four of a kind, a full house, three of a kind, or two pair. Give each of these an appropriate value, and keep track of the amount of money held by the player. Use appropriate classes.
  9. 25.9 Write a program pig.py to play the dice game Pig. Turns alternate between two players. During a player’s turn, the player rolls one die repeatedly until either a 1 is rolled or the player decides to stand. If a 1 appears at any time, the turn is over and the player scores 0. Otherwise, when a player stands, the turn is over and the player receives the sum of all of his or her rolls during that turn. The first player to reach 100 wins. Design appropriate classes.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.18.104.213