• API
• FAQ
• Tools
• Archive
SHARE
TWEET # Untitled a guest Feb 14th, 2020 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. import numpy
2. import pprint
3.
4.
5. class ImageLayer(object):
6.   """
7.   Represents a layer of an image
8.   """
9.   def __init__(self, x_shape, y_shape, fill_character, left_x, top_y, right_x, bottom_y):
10.     self.x_shape = x_shape
11.     self.y_shape = y_shape
12.     self.fill_character = fill_character
13.     self.canvas = self._build_canvas(left_x, top_y, right_x, bottom_y)
14.
15.   def _verify_coords(self, x, y):
16.     # Check that the co-ordinates are valid
17.     if x<0 or x>=self.x_shape or y<0 or y>=self.y_shape:
18.       raise ValueError(f'[{x}, {y}] is outside the bounds')
19.
20.   def _build_canvas(self, left_x, top_y, right_x, bottom_y):
21.     self._verify_coords(left_x, top_y)
22.     self._verify_coords(right_x, bottom_y)
23.     # Create the initial canvas for the layer
24.     canvas = numpy.zeros(shape=(self.x_shape, self.y_shape))
25.     canvas[left_x:right_x+1, top_y:bottom_y+1] = numpy.ones(shape=(right_x-left_x+1, bottom_y-top_y+1))
26.     return canvas
27.
28.   def erase_area(self, left_x, top_y, right_x, bottom_y):
29.     """
30.     Erase a section of the layer
31.     """
32.     self._verify_coords(left_x, top_y)
33.     self._verify_coords(right_x, bottom_y)
34.     self.canvas[left_x:right_x+1, top_y:bottom_y+1] = numpy.zeros(shape=(right_x-left_x+1, bottom_y-top_y+1))
35.
36.   def hit(self, select_x, select_y):
37.     """
38.     Check if the layer has any content at these co-ordinates
39.     """
40.     self._verify_coords(select_x, select_y)
41.     return self.canvas[select_x, select_y] == 1
42.
43.   def drag_and_drop(self, move_x, move_y):
44.     """
45.     Roll the canvas to move the position of the rectangle
46.     """
47.     # This will wrap rectanges around the maximums
48.     self.canvas = numpy.roll(self.canvas, move_x, axis=0)
49.     self.canvas = numpy.roll(self.canvas, move_y, axis=1)
50.
51.
52. class Image(object):
53.   """
54.   Represents an image with multiple layers
55.   """
56.   def __init__(self, x_shape=10, y_shape=6):
57.     self.x_shape = x_shape
58.     self.y_shape = y_shape
59.     self.layers = []
60.
61.   def draw_rectangle(self, fill_character, left_x, top_y, right_x, bottom_y):
62.     """
63.     Creates a new layer on top with the specified rectangle on it
64.     """
65.     new_layer = ImageLayer(
66.       self.x_shape,
67.       self.y_shape,
68.       fill_character,
69.       left_x,
70.       top_y,
71.       right_x,
72.       bottom_y
73.     )
74.     self.layers = [new_layer] + self.layers
75.
76.   def erase_area(self, left_x, top_y, right_x, bottom_y):
77.     """
78.     Erase the area on all layers
79.     """
80.     for layer in self.layers:
81.       layer.erase_area(left_x, top_y, right_x, bottom_y)
82.
83.   def drag_and_drop(self, select_x, select_y, release_x, release_y):
84.     """
85.     Move the top layer
86.     """
87.     for layer in self.layers:
88.       if layer.hit(select_x, select_y):
89.         layer.drag_and_drop(release_x-select_x, release_y-select_y)
90.         return
91.
92.   def bring_to_front(self, select_x, select_y):
93.     """
94.     Move the selected layer to the top of the stack
95.     """
96.     for i, layer in enumerate(self.layers):
97.       if layer.hit(select_x, select_y):
98.         self.layers.pop(i)
99.         self.layers = [layer] + self.layers
100.         return
101.
102.   def print_canvas(self):
103.     """
104.     Return an array of arrays with the rendered content
105.     """
106.     canvas = numpy.zeros(shape=(self.x_shape, self.y_shape)).tolist()
107.     for layer in reversed(self.layers):
108.       for i in range(self.x_shape):
109.         for j in range(self.y_shape):
110.           if layer.canvas[i, j] == 1:
111.             canvas[i][j] = layer.fill_character
112.
113.     # This can probably done when initializing the canvas.
114.     # The solution is somewhere in the numpy docs.
115.     for i in range(self.x_shape):
116.       for j in range(self.y_shape):
117.         if canvas[i][j] == 0:
118.           canvas[i][j] = ' '
119.     return canvas
120.
121.
122. def command_parser():
123.   # Parses the file in to the format:
124.   # ["COMMAND", [*command_args]]
125.   # BELOW IS HARDCODED EXAMPLE I USED FOR DEBUGGING:
126.   return [
127.     ['DRAW_RECTANGLE',['L',1,1,4,4]],
128.     ['DRAW_RECTANGLE',['R',2,1,4,4]],
129.     ['PRINT_CANVAS',[]],
130.     ['ERASE_AREA',[3,2,3,3]],
131.     ['PRINT_CANVAS',[]],
132.     ['DRAW_RECTANGLE',['#',1,3,8,4]],
133.     ['DRAG_AND_DROP',[2,2,6,2]],
134.     ['PRINT_CANVAS',[]],
135.     ['BRING_TO_FRONT',[1,2]],
136.     ['BRING_TO_FRONT',[6,2]],
137.     ['PRINT_CANVAS',[]],
138.     ['DRAG_AND_DROP',[3,3,3,2]],
139.     ['PRINT_CANVAS',[]],
140.   ]
141.
142.
143. def main():
144.   # Parse the command list
145.   command_list = command_parser()
146.   # create an empty image
147.   image = Image(10, 6)
148.
149.   # For each command apply it to the command list
150.   for command, command_args in command_list:
151.     if command == 'DRAW_RECTANGLE':
152.       image.draw_rectangle(*command_args)
153.     elif command == 'ERASE_AREA':
154.       image.erase_area(*command_args)
155.     elif command == 'DRAG_AND_DROP':
156.       image.drag_and_drop(*command_args)
157.     elif command == 'BRING_TO_FRONT':
158.       image.bring_to_front(*command_args)
159.     elif command == 'PRINT_CANVAS':
160.       pprint.pprint(image.print_canvas())
161.
162.
163. if __name__ == '__main__':
164.   main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.
Top