Antypas

shapes.py

May 22nd, 2020
791
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.15 KB | None | 0 0
  1. # This code requires Python 3 and tkinter (which is usually installed by default)
  2. # This code will NOT work on trinket.io as the tkinter module is not supported
  3. # Raspberry Pi Foundation 2017
  4. # CC-BY-SA 4.0
  5.  
  6. try:
  7.     from tkinter import Tk, Canvas, BOTH    
  8. except ImportError:
  9.     print("tkinter did not import successfully - check you are running Python 3 and that tkinter is available.")
  10.     exit(1)
  11.  
  12. # create the tkinter object which will used in the Paper class.
  13. try:
  14.     tk = Tk()
  15. except ValueError:
  16.     print("Error: could not instantiate Paper object")
  17.     exit(1)
  18.  
  19. import random
  20.  
  21. class Paper():
  22.  
  23.     def __init__(self, width=600, height=600):
  24.  
  25.         """Create a Paper object which allows shapes to be drawn onto it.
  26.        """
  27.         # Call the constructor from the superclass (tkinter's Tk)
  28.  
  29.         # Set some attributes
  30.         tk.title( "Drawing shapes" )
  31.         tk.geometry(str(width)+"x"+str(height))
  32.         tk.paper_width = width
  33.         tk.paper_height = height
  34.  
  35.         # Create a tkinter canvas object to draw on
  36.         tk.canvas = Canvas(tk)
  37.         tk.canvas.pack(fill=BOTH, expand=1)
  38.  
  39.     # return the instance of tk
  40.     def __get__(self, instance, owner):
  41.         return tk
  42.  
  43.     # allows Paper.display() to be called triggering the tk mainloop
  44.     @staticmethod
  45.     def display():
  46.         """
  47.        Displays the paper object
  48.        """
  49.         tk.mainloop()
  50.  
  51. class Shape():
  52.  
  53.     # Static class variable removing the need to pass in a Paper object
  54.     # to draw the shapes on
  55.     paper = Paper()
  56.  
  57.     # Constructor for Shape
  58.     def __init__(self, width=50, height=50, x=None, y=None, color="black"):
  59.  
  60.         """Creates a generic 'shape' which contains properties common to all
  61.        shapes such as height, width, x y coordinates and colour.
  62.        """
  63.  
  64.         # Set some attributes
  65.         self.height = height
  66.         self.width = width
  67.         self.color = color
  68.  
  69.         # Put the shape in the centre if no xy coords were given
  70.         if x is None:
  71.             self.x = (self.paper.paper_width/2) - (self.width/2)
  72.         else:
  73.             self.x = x
  74.         if y is None:
  75.             self.y = (self.paper.paper_height/2) - (self.height/2)
  76.         else:
  77.             self.y = y
  78.  
  79.     # This is an internal method not meant to be called by users
  80.     # (It has a _ before the method name to show this)
  81.     def _location(self):
  82.         """Internal method used by the class to get the location
  83.        of the shape. This shouldn't be called by users, hence why its
  84.        name begins with an underscore.
  85.        """
  86.  
  87.         x1 = self.x
  88.         y1 = self.y
  89.         x2 = self.x + self.width
  90.         y2 = self.y + self.height
  91.         return [x1, y1, x2, y2]
  92.  
  93.     # Randomly generate what the shape looks like
  94.     def randomize(self, smallest=20, largest=200):
  95.  
  96.         """Randomly generates width, height, position and colour for a shape. You can specify
  97.        the smallest and largest random size that will be generated. If not specified, the
  98.        generated shape will default to a random size between 20 and 200.
  99.        """
  100.  
  101.         self.width = random.randint(smallest, largest)
  102.         self.height = random.randint(smallest, largest)
  103.  
  104.         self.x = random.randint(0, self.paper.paper_width-self.width)
  105.         self.y = random.randint(0, self.paper.paper_height-self.height)
  106.  
  107.         self.color = random.choice(["red", "yellow", "blue", "green", "gray", "white", "black", "cyan", "pink", "purple"])
  108.  
  109.     # Getters and setters for Shape attributes
  110.     def set_width(self, width):
  111.         """Sets the width of the shape"""
  112.  
  113.         self.width = width
  114.  
  115.     def set_height(self,height):
  116.         """Sets the height of the shape"""
  117.  
  118.         self.height = height
  119.  
  120.     def set_x(self, x):
  121.         """Sets the x position of the shape"""
  122.  
  123.         self.x = x
  124.  
  125.     def set_y(self, y):
  126.         """Sets the y position of the shape"""
  127.  
  128.         self.y = y
  129.  
  130.     def set_color(self, color):
  131.         """Sets the colour of the shape"""
  132.  
  133.         self.color = color
  134.  
  135.     def get_color(self):
  136.         """Returns the colour of the shape"""
  137.  
  138.         return self.color
  139.  
  140.  
  141. # Rectangle class is a subclass of Shape
  142. class Rectangle(Shape):
  143.  
  144.     # This is how to draw a rectangle
  145.     def draw(self):
  146.  
  147.         """Draws a rectangle on the canvas. The properties of the rectangle
  148.        can be set using the getter and setter methods in Shape"""
  149.  
  150.         x1, y1, x2, y2 = self._location()
  151.  
  152.         # Draw the rectangle
  153.         self.paper.canvas.create_rectangle(x1, y1, x2, y2, fill=self.color)
  154.  
  155.  
  156. class Oval(Shape):
  157.  
  158.     def draw(self):
  159.  
  160.         """Draws an oval on the canvas. The properties of the oval
  161.        can be set using the getter and setter methods in Shape"""
  162.  
  163.         x1, y1, x2, y2 = self._location()
  164.  
  165.         # Draw the oval
  166.         self.paper.canvas.create_oval(x1, y1, x2, y2, fill=self.color)
  167.  
  168.  
  169. class Triangle(Shape):
  170.  
  171.     # Every constructor parameter has a default setting
  172.     # e.g. color defaults to "black" but you can override this
  173.     def __init__(self, x1=0, y1=0, x2=20, y2=0, x3=20, y3=20, color="black"):
  174.  
  175.         """Overrides the Shape constructor because triangles require three
  176.        coordinate points to be drawn, unlike rectangles and ovals."""
  177.  
  178.         try:
  179.             super().__init__(color=color)
  180.         except ValueError:
  181.             print("Error: could not instantiate Triangle")
  182.  
  183.         # Remove height and width attributes which make no sense for a triangle
  184.         # (triangles are drawn via 3 xy coordinates)
  185.         del self.height
  186.         del self.width
  187.  
  188.         # Instead add three coordinate attributes
  189.         self.x = x1
  190.         self.y = y1
  191.         self.x2 = x2
  192.         self.y2 = y2
  193.         self.x3 = x3
  194.         self.y3 = y3
  195.  
  196.     def _location(self):
  197.  
  198.         """Internal method used by the class to get the location
  199.        of the triangle. This shouldn't be called by users, hence why its
  200.        name begins with an underscore.
  201.        """
  202.  
  203.         return [self.x, self.y, self.x2, self.y2, self.x3, self.y3]
  204.  
  205.     def draw(self):
  206.  
  207.         """Draws a triangle on the canvas. The properties of the triangle
  208.        can be set using the getter and setter methods in Shape"""
  209.  
  210.         x1, y1, x2, y2, x3, y3 = self._location()
  211.         # Draw a triangle
  212.         self.paper.canvas.create_polygon(x1, y1, x2, y2, x3, y3, fill=self.color)
  213.  
  214.     def randomize(self):
  215.  
  216.         """Randomly chooses the location of all 3 triangle points as well
  217.        as the colour of the triangle"""
  218.  
  219.         # Randomly choose all the points of the triangle
  220.         self.x = random.randint(0, self.paper.paper_width)
  221.         self.y = random.randint(0, self.paper.paper_height)
  222.         self.x2 = random.randint(0, self.paper.paper_width)
  223.         self.y2 = random.randint(0, self.paper.paper_height)
  224.         self.x3 = random.randint(0, self.paper.paper_width)
  225.         self.y3 = random.randint(0, self.paper.paper_height)
  226.  
  227.         # Randomly choose a colour of this triangle
  228.         self.color = random.choice(["red", "yellow", "blue", "green", "gray", "white", "black", "cyan", "pink", "purple"])
  229.  
  230.     # Change the behaviour of set_width and set_height methods for a triangle
  231.     # because triangles are not drawn in the same way
  232.     def set_width(self, width):
  233.         """Overrides the setter method for width"""
  234.  
  235.         print("Width is not defined for Triangle objects")
  236.  
  237.     def set_height(self, height):
  238.         """Overrides the setter method for height"""
  239.  
  240.         print("Height is not defined for Triangle objects")
  241.  
  242.  
  243. # This if statement means
  244. # "if you run this file (rather than importing it), run this demo script"
  245. if __name__ == "__main__":
  246.  
  247.     # Random size and location triangle
  248.     tri = Triangle()
  249.     tri.randomize()
  250.     tri.draw()
  251.  
  252.     # Specific size and location rectangle
  253.     rect = Rectangle(height=40, width=90, x=110, y=20, color="yellow")
  254.     rect.draw()
  255.  
  256.     # Default oval
  257.     oval = Oval()
  258.     oval.draw()
  259.  
  260.     # Oval with setters
  261.     oval2 = Oval()
  262.     oval2.set_height(200)
  263.     oval2.set_width(100)
  264.     oval2.set_color("fuchsia")
  265.     oval2.set_x(30)
  266.     oval2.set_y(90)
  267.     oval2.draw()
  268.  
  269.     Paper.display()
Add Comment
Please, Sign In to add comment