# We will draw some shapes without knowing too much about # either how the shapes are stored or how the drawing code works. # We only know their interfaces (APIs). # # For shapes, we need to know how to create them (constructor) # and get their bounding boxes (bounding_box method). # For drawing, we need to know how to create the drawing # (constructor), how to add rectangles (add_rectangle method), # how to add circles (add_circle method) and how to display (run method). # # The show_rectangles and show_shapes functions are polymorphic # in the sense that they process different types of shapes. # Because the functions are polymorphic, the main program is # very simple because it only needs to pass the shape list to # these functions without knowing anything about shapes at all. # # show_rectangles takes advantage of the fact that it only uses # a portion of the API (bounding_box) that is shared by all # shapes, and therefore needs no more information. # # show_shapes is distinguishes between quadrilaterals and circles # by checking whether an instance belongs to the Circle class. # The shape type determines which Drawing API to use for displaying # the shape. def show_rectangles(d, shapes): for s in shapes: llx, lly, urx, ury = s.bounding_box() d.add_rectangle(llx, lly, urx, ury, "red") def show_shapes(d, shapes): for s in shapes: llx, lly, urx, ury = s.bounding_box() if isinstance(s, Circle): d.add_circle(llx, lly, urx, ury, "green") else: d.add_rectangle(llx, lly, urx, ury, "red") if __name__ == "__main__": from rectangle import Rectangle from inheritance import Square, Circle from drawing import Drawing shape_list = [ Rectangle(40, 80, 120, 160), Square(160, 200, 80), Circle(40, 280, 60), ] d = Drawing(400, 400) show_rectangles(d, shape_list) d.run() d = Drawing(400, 400) show_shapes(d, shape_list) d.run()