python programming in context chapter 12. objectives to introduce the concept of inheritance to...

32
Python Programming in Context Chapter 12

Upload: june-little

Post on 02-Jan-2016

225 views

Category:

Documents


10 download

TRANSCRIPT

Python Programming in Context

Python Programming in ContextChapter 12ObjectivesTo introduce the concept of inheritanceTo create a working object-oriented graphics packageTo provide another example of object-oriented design

GoalThis is what we want to be able to doDraw on a canvasListing 12.1def drawHouse():myCanvas = Canvas(800,600)house = Rectangle(Point(-100,-100),Point(100,100))house.setFill('blue')door = Rectangle(Point(-50,-100),Point(0,75))door.setFill('brown')roof1 = Line(Point(-100,100),Point(0,200))roof2 = Line(Point(0,200),Point(100,100))roof1.setWidth(3)roof2.setWidth(3)myCanvas.draw(house)myCanvas.draw(door)myCanvas.draw(roof1)myCanvas.draw(roof2)sun = Circle(Point(-150,250),20)sun.setFill('yellow')myCanvas.draw(sun)for i in range(-150,150): # move the sun across the skysun.move(1,0)Figure 12.1Inheritance HierarchyIS-A RelationshipOne object is a more specific instance of anotherHAS-A RelationshipOne object uses another objectExamplesA rectangle is-a polygonA square is-a rectangleFigure 12.2Figure 12.3Listing 12.2myCanvas = Canvas(800,600)myLine = Line(Point(-100,-100),Point(100,100))myCanvas.draw(myLine)Figure 12.4Implementing the Canvas ClassA canvas will have a width and a heightA turtle will do all the drawing

Listing 12.3class Canvas: def __init__(self,w,h): self.turtle = turtle.Turtle() self.screen = turtle.Screen() self.width = w self.height = h

self.screen.setup(width=self.width,height=self.height) self.turtle.hideturtle()

def draw(self,gObject): self.turtle.up() self.screen.tracer(0) gObject._draw(self.turtle) self.screen.tracer(1)

Geometric ObjectLine colorLine widthDrawGeometric objects dont really know how to draw themselvesSubclasses will know how to draw themselvesCall the _draw method from each objectListing 12.4class GeometricObject: def __init__(self): self.lineColor = 'black' self.lineWidth = 1

def getColor(self): return self.lineColor

def getWidth(self): return self.lineWidth

def setColor(self,color): self.lineColor = color

def setWidth(self,width): self.lineWidth = width

def _draw(self,someturtle): print("Error: You must define _draw in subclass")PointX and Y locationInherits color and widthDraw makes a dot

Listing 12.5class Point(GeometricObject): def __init__(self, x,y): super().__init__() self.x = x self.y = y

def getCoord(self): return (self.x,self.y)

def getX(self): return self.x

def getY(self): return self.y

def _draw(self,aturtle): aturtle.goto(self.x,self.y) aturtle.dot(self.lineWidth,self.lineColor) LineHas two pointsColor and width are inheritedDraws a line between by placing turtle on one point and moving to the otherListing 12.6class Line(GeometricObject): def __init__(self, p1,p2): super().__init__() self.p1 = p1 self.p2 = p2 def getP1(self): return self.p1 def getP2(self): return self.p2 def _draw(self,aturtle): aturtle.color(self.getColor()) aturtle.width(self.getWidth()) aturtle.goto(self.p1.getCoord()) aturtle.down() aturtle.goto(self.p2.getCoord())Figure 12.5Figure 12.6RedesignCurrent design works wellThe following example shows a problemChanging the color of the line after the line has been drawnNew color will not be shownNeed to redraw the lineBut, then it will be out of place with respect to all the other objectsNeed to redraw ALL OF THEMNeed to keep track of all object on canvas in the order they were createdListing 12.7 def test2(): myCanvas = Canvas(500,500) myLine = Line(Point(-100,-100),Point(100,100)) myOtherLine = Line(Point(-100,100),Point(100,-100)) myLine.setWidth(4) myOtherLine.setWidth(4) myCanvas.draw(myLine) myCanvas.draw(myOtherLine) myLine.setColor('red')Figure 12.7Listing 12.8class Canvas: def __init__(self,w,h): self.width = w self.height = h self.visibleObjects = [] self.turtle = turtle.Turtle() self.screen = turtle.Screen() self.screen.setup(width=self.width,height=self.height) self.turtle.hideturtle()

def drawAll(self): self.screen.reset() self.screen.tracer(0) for shape in self.visibleObjects: shape._draw(self.turtle) self.screen.tracer(1) self.turtle.hideturtle()

def addShape(self,shape): self.visibleObjects.append(shape)

def draw(self,gObject): gObject.setCanvas(self) gObject.setVisible(True) self.turtle.up() self.screen.tracer(0) gObject._draw(self.turtle) self.screen.tracer(1) self.addShape(gObject)Listing 12.9 (Part 1)class GeometricObject:

def __init__(self): self.lineColor = 'black' self.lineWidth = 1 self.visible = False self.myCanvas = None

def setColor(self,color): self.lineColor = color if self.visible: self.myCanvas.drawAll()

def setWidth(self,width): self.lineWidth = width if self.visible:Listing 12.9 (Part 2) self.myCanvas.drawAll()

def getColor(self): return self.lineColor

def getWidth(self): return self.lineWidth

def _draw(self): print ("Error: You must define _draw in subclass")

def setVisible(self,vFlag): self.visible = vFlag

def setCanvas(self,theCanvas): self.myCanvas = theCanvas

PolygonPolygons are defined by a list of pointsDraw the polygon by moving the turtle from point to pointConnect the last point back to the firstFigure 12.8Figure 12.9RectangleNeeds two opposing diagonal pointsCan compute the other two pointsDraw as polygonFigure 12.10Figure 12.11

Shape

Circle

Square

Ellipse Polygon

Rectangle Triangle

GeometricObject

ShapePointLine

Canvas

Circle Rectangle

Square

Triangle

Ellipse Polygon

Circle Rectangle

Square

Triangle

Ellipse

x y

Polygon

Shape

CanvasGeometricObject

Point

getX getY getCoord

Line

getP1 getP2

p1 p2

lineColor lineWidth

turtle objectsdrawsetWidth

setColor

__class__

__dict__

__bases__

__bases__

__dict__

__dict__

__bases__

__dict__

{p2, lineWidth, p1, lineColor}

black

1

(2)

(6)(7)

(4)

(5)

(3)

(1)

myLine

Line

GeometricObject

object

{getP1, __module__, getP2 _draw, __doc__, __init__}

{__module__, setColor, getColor, _draw, getWidth, __weakref__, __dict__, setWidth, __doc__, __init__}

__class__ black

__dict__

myLine global

1

{p2, lineWidth, p1, lineColor}

selflocal(getWidth)

Circle Rectangle

Square

Triangle

Ellipse

x y

Polygon

Shape

CanvasGeometricObject

Point

getX getY getCoord _draw

Line

getP1 getP2 _draw

p1 p2

lineColor lineWidth visible myCanvas

turtle visibleObjectsdraw drawAll getTurtlesetWidth

setColor setCanvas setVisible move

fillColor

setFill

p3

p0 p1

p2

p3

p0 p1

p2

(II.x, ur.y) ur = (20, 10)

(ur.x, II.y)II = (0, 0)

Circle

Ellipse

x y

Shape

Square

CanvasGeometricObject

Point

getX getY getCoord _draw

Line

getP1 getP2 _draw

p1 p2

lineColor lineWidth visible myCanvas

turtle Objectsdraw drawAll getTurtlesetWidth

setColor setCanvas setVisible move

fillColor

setFill

Polygoncorners

_draw move

RectanglelowerLeft upperRightgetLowerLeft getUpperRight

Trianglep1 p2 p3getP1 getP2 getP3