def draw_circles_from_rectangle(m, n, rectangle, window): """ What comes in: Four arguments: -- Positive integers m and n. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_circles_from_rectangle.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangle on the given rg.RoseWindow. Then draws m rg.Circles on the given rg.RoseWindow, such that: -- The diameter of each rg.Circle is the same as the height of the given rg.Rectangle. -- The first rg.Circle is immediately to the left of the given rg.Rectangle -- Each subsequent rg.Circle is immediately to the left of the previous rg.Circle, so that the circles form a row that goes to the left. -- Each rg. Circle has the same fill_color as the given rg.Rectangle (and has no outline_color). Then draws n rg.Circles on the given RoseWindow, such that: -- The diameter of each rg.Circle is the same as the width of the given rg.Rectangle. -- The first rg.Circle is immediately above the given rg.Rectangle -- Each subsequent rg.Circle is immediately above the previous rg.Circle, so that the circles form a column that goes up. -- Each rg.Circle has the same outline_color as the given rg.Rectangle (and has no fill_color). Must ** render ** but ** NOT close ** the window. Type hints: :type m: int :type n: int :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ rectangle.attach_to(window) start_point = rectangle.get_center() x = start_point.x y = start_point.y corner1 = rectangle.corner_1 # corner 1 needs to be left most corner in # test case xC1 = corner1.x yC1 = corner1.y corner2 = rectangle.corner_2 # corner 2 needs to be right most corner # in test case xC2 = corner2.x yC2 = corner2.y radius_left = math.fabs(yC1 - yC2) / 2 radius_top = math.fabs(xC1 - xC2) / 2 xCL = xC1 - radius_left yCL = y xCT = x yCT = y - math.fabs((yC1 - yC2) / 2) - radius_top for k in range(m): center_left = rg.Point(xCL, yCL) circle1 = rg.Circle(center_left, radius_left) circle1.fill_color = rectangle.fill_color circle1.outline_color = rectangle.outline_color circle1.attach_to(window) xCL = xCL - (2 * radius_left) for k in range(n): center_top = rg.Point(xCT, yCT) circle = rg.Circle(center_top, radius_top) circle.outline_color = rectangle.outline_color circle.attach_to(window) yCT = yCT - (2 * radius_top) window.render()
def run_test_RETURN_circle(): """ Tests the RETURN_circle function. """ print() print('-----------------------------------------') print('Testing RETURN_circle:') print('-----------------------------------------') print() print('See the graphics window for this test.') print('If an error msg appears at any point,') print('then you have FAILED this test.') # ------------------------------------------------------------------ # Tests 1 and 2 (on one window): # ------------------------------------------------------------------ window = rg.RoseWindow(500, 400, 'Testing RETURN_circle') text = rg.Text(rg.Point(250, 125), '') text.attach_to(window.initial_canvas) circle = rg.Circle(rg.Point(200, 300), 50) circle.fill_color = 'blue' circle.attach_to(window.initial_canvas) msg = 'Note: If you see an error message at ANY point,\n' msg = msg + 'then you have failed this test.\n\n' msg = msg + 'I have drawn the original, blue circle.\n\n' msg = msg + 'So you should see a BLUE circle below\n' msg = msg + '(and nothing else).\n\n' msg = msg + 'Click the mouse to continue this test.\n' text.text = msg window.render(0.5) window.get_next_mouse_click() new_circle = RETURN_circle(circle, 'red') if new_circle: new_circle.attach_to(window.initial_canvas) msg = 'I have now called your RETURN_circle function\n' msg = msg + 'and drawn the CLONED, RED circle that your\n' msg = msg + 'RETURN_circle function should have returned.\n\n' msg = msg + 'So you should see a RED circle below\n' msg = msg + '(and nothing else, since the blue circle\n' msg = msg + 'is beneath the red circle).\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() if new_circle: new_circle.detach_from(window.initial_canvas) msg = 'I have now UN-drawn the CLONED, RED circle.\n\n' msg = msg + 'So you should see the original, BLUE circle below\n' msg = msg + '(and nothing else).\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() circle.detach_from(window.initial_canvas) msg = 'I have now UN-drawn the ORIGINAL, blue circle.\n\n' msg = msg + 'So you should see NO circles below.\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() if new_circle: new_circle.attach_to(window.initial_canvas) msg = 'Now I have RE-drawn the CLONED, RED circle\n' msg = msg + 'that your RETURN_circle function\n' msg = msg + 'should have returned.\n\n' msg = msg + 'So you should see a RED circle below\n' msg = msg + '(and nothing else).\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() # ------------------------------------------------------------------ # Note: The following statements make the variable new_circle # refer to a new, green circle. So we can no longer refer # to the RED circle (to which the variable new_circle once # referred). But the red circle still exists! # ------------------------------------------------------------------ new_circle = RETURN_circle(circle, 'green') if new_circle: new_circle.attach_to(window.initial_canvas) msg = 'Now I have ALSO drawn the CLONED, GREEN circle\n' msg = msg + 'that your RETURN_circle function\n' msg = msg + 'should have returned.\n\n' msg = msg + 'So you should see a GREEN circle below\n' msg = msg + '(and nothing else, since the red circle\n' msg = msg + 'is beneath the green circle).\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() if new_circle: new_circle.detach_from(window.initial_canvas) msg = 'I have now UN-drawn the CLONED, GREEN circle.\n\n' msg = msg + 'So you should see the cloned, RED circle below\n' msg = msg + '(and nothing else).\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() new_circle2 = RETURN_circle(rg.Circle(rg.Point(250, 350), 25), 'white') if new_circle: new_circle.attach_to(window.initial_canvas) if new_circle2: new_circle2.attach_to(window.initial_canvas) msg = 'I have now RE-drawn the CLONED, GREEN circle.\n' msg = msg + 'Additionally, I called your RETURN_circle function\n' msg = msg + 'again, asking it to return a smaller WHITE circle\n' msg = msg + 'that is below and to the right of the other circles.\n\n' msg = msg + 'So you should see a GREEN circle below\n' msg = msg + 'and a smaller WHITE circle below and to its right\n' msg = msg + '(but NOT the red circle, since it\n' msg = msg + 'is beneath the green circle).\n\n' msg = msg + 'Click the mouse to conclude this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() window.close()
def run_test_swap_colors(): """ Tests the swap_colors function. """ print() print('--------------------------------------------------') print('Testing the swap_colors function:') print('--------------------------------------------------') # ------------------------------------------------------------------ # Test 1: Note that it tests both: # -- what was SUPPOSED to be mutated (fill_color) and # -- what was NOT supposed to be mutated (all else). # The code passes this test if the expected value printed # is the same as the actual value printed. # ------------------------------------------------------------------ circle = rg.Circle(rg.Point(100, 150), 50) circle.fill_color = 'blue' rectangle = rg.Rectangle(rg.Point(200, 30), rg.Point(350, 150)) rectangle.fill_color = 'green' expected_c = 'Circle: center=(100, 150), radius=50,' expected_c += ' fill_color=green, outline_color=black,' expected_c += ' outline_thickness=1.' expected_r = 'Rectangle: corner_1=(200, 30), corner_2=(350, 150),' expected_r += ' fill_color=blue, outline_color=black,' expected_r += ' outline_thickness=1.' swap_colors(circle, rectangle) print() print('Expected circle after the function call:') print(expected_c) print('Actual circle after the function call:') print(circle) print() print('Expected rectangle after the function call:') print(expected_r) print('Actual rectangle after the function call:') print(rectangle) # ------------------------------------------------------------------ # Test 2: This is a VISUAL test. # The code passes this test if the objects are drawn per the test. # # Here, that means that when the window pauses and asks the user # to press any key to continue: # -- the circle is black_filled and # -- the rectangle is red_filled # and then when the user presses a key and the window pauses # again, now the reverse is true: # -- the circle is red_filled and # -- the rectangle is black_filled. # ------------------------------------------------------------------ title = 'The code passes the test if the fill colors of the circle' title += ' and rectangle get SWAPPED.' window = rg.RoseWindow(700, 400, title) circle = rg.Circle(rg.Point(100, 50), 40) circle.fill_color = 'black' circle.attach_to(window) rectangle = rg.Rectangle(rg.Point(200, 280), rg.Point(350, 350)) rectangle.fill_color = 'red' rectangle.attach_to(window) msg1 = 'At this point, the circle should be filled with BLACK\n' msg1 += 'and the rectangle should be filled with RED' message = rg.Text(rg.Point(400, 100), msg1) message.attach_to(window) # At this point, the CIRCLE should be filled with BLACK # and the RECTANGLE filled with RED. window.render() window.continue_on_mouse_click() swap_colors(circle, rectangle) # At this point, the CIRCLE should be filled with RED # and the RECTANGLE filled with BLACK. msg2 = 'Now, the circle should be filled with RED\n' msg2 += 'and the rectangle should be filled with BLACK.\n' msg2 += 'If so, and if nothing else changed,\n' msg2 += 'the code passed this test.' message.text = msg2 window.render() window.close_on_mouse_click()
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # done: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ center = rg.Circle(point, radius) center.attach_to(window) center.fill_color = color l = rg.Line(rg.Point(point.x - radius, point.y), rg.Point(point.x + radius, point.y)) l.attach_to(window) for k in range(-n + 1, n): for j in range(1, abs(k) + 1): ps = rg.Point(point.x - radius * abs(k), point.y + math.sqrt(3) * k * radius) c1 = rg.Circle(ps, radius) c1.fill_color = color c1.attach_to(window) l = rg.Line(rg.Point(ps.x - radius, ps.y), rg.Point(ps.x + radius, ps.y)) l.attach_to(window) c2 = rg.Circle(rg.Point(c1.center.x + 2 * radius * j, c1.center.y), radius) c2.fill_color = color c2.attach_to(window) l2 = rg.Line(rg.Point(c2.center.x - radius, c2.center.y), rg.Point(c2.center.x + radius, c2.center.y)) l2.attach_to(window) window.render()
def run_test_all(): """ Tests ALL the functions in this module. """ # Test broken_1: window = rg.RoseWindow(title='Testing BROKEN_1') circle1 = rg.Circle(rg.Point(50, 50), 15) circle1.fill_color = 'blue' broken_1(circle1, window) # Test 1 of broken_1 circle2 = rg.Circle(rg.Point(70, 150), 30) circle2.fill_color = 'red' broken_1(circle2, window) # Test 2 of broken_1 window.close_on_mouse_click() # Test broken_2: window = rg.RoseWindow(title='Testing BROKEN_2') broken_2(50, 75, window) # Test 1 of broken_2 broken_2(100, 150, window) # Test 2 of broken_2 window.close_on_mouse_click() # Test broken_3: window = rg.RoseWindow(title='Testing BROKEN_3') broken_3(5, rg.Point(100, 50), 80, 20, window) # Test 1 of broken_3 broken_3(3, rg.Point(50, 150), 40, 50, window) # Test 2 of broken_3 window.close_on_mouse_click() # Test broken_4: window = rg.RoseWindow(title='Testing BROKEN_4') broken_4(50, 75, 40, window) # Test 1 of broken_4 broken_4(100, 150, 75, window) # Test 2 of broken_4 window.close_on_mouse_click() # Test broken_5: window = rg.RoseWindow(title='Testing BROKEN_5') circle = rg.Circle(rg.Point(100, 50), 30) circle.fill_color = 'pink' broken_5(circle, window) # Test 1 of broken_5 circle = rg.Circle(rg.Point(250, 100), 80) circle.fill_color = 'red' broken_5(circle, window) # Test 2 of broken_5 window.close_on_mouse_click() # Test broken_6: expected = 1.8333333 actual = broken_6(3) # Test 1 of broken_6 print("Testing BROKEN_6:\n") print('Expected for BROKEN_6, Test 1:', expected, '(approximately)') print(' Actual for BROKEN_6, Test 1:', actual) expected = 5.1873775 actual = broken_6(100) # Test 2 of broken_6 print() print('Expected for BROKEN_6, Test 2:', expected, '(approximately)') print(' Actual for BROKEN_6, Test 2:', actual) print() # Test broken_7: window = rg.RoseWindow(title='Testing BROKEN_7') broken_7(5, rg.Point(100, 50), 80, 20, window) # Test 1 of broken_7 broken_7(3, rg.Point(50, 150), 40, 50, window) # Test 2 of broken_7 window.close_on_mouse_click()
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle (using its INSTANCE VARIABLES): -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. (Hint: For this, you'll need to use a METHOD that begins with "get".) -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ window = rg.RoseWindow() centerx = 100 centery = 150 circlecenter = rg.Point(centerx, centery) circleradius = 50 circle = rg.Circle(circlecenter, circleradius) circle.fill_color = "blue" circle.attach_to(window) rectanglecorner1 = rg.Point(200, 30) rectanglecorner2 = rg.Point(350, 50) rectangle = rg.Rectangle(rectanglecorner1, rectanglecorner2) rectangle.attach_to(window) window.render() window.close_on_mouse_click() print("for CIRCLE:") print(" outline thickness is", circle.outline_thickness) print(" fill color is", circle.fill_color) print(" center is", circle.center) print(" center x is", circle.center.x) print(" center y is", circle.center.y) print("for RECTANGLE:") print(" outline thickness is", rectangle.outline_thickness) print(" fill color is", rectangle.fill_color) print(" center is", rectangle.get_center()) print(" center x is", rectangle.get_center().x) print(" center y is", rectangle.get_center().y)
def draw_L(window, circle, r, c): """ See L.pdf in this project for pictures that may help you better understand the following specification: Draws an 'L' of circles on the given rg.RoseWindow. The 'column' part of the L should have r rows and 3 columns. (That is, it is r 'tall' and 3 'thick'.) The 'shared corner' part of the L should be 3 x 3. The 'row' part of the L should have c columns and 3 rows. (That is, it is c 'long' and 3 'thick'.) The given rg.Circle specifies: - The position of the upper-left circle drawn and also - The radius that all the circles have. - The fill_color that all the circles have. After drawing each circle, pauses briefly (0.1 second). Preconditions: :type window: rg.RoseWindow :type circle: rg.Circle :type r: int :type c: int and m and n are small, positive integers. """ original_x = circle.center.x original_y = circle.center.y radius = circle.radius x = original_x y = original_y for i in range(r): # Loop through the rows for j in range(3): # Loop through the columns new_circle = rg.Circle(rg.Point(x, y), radius) new_circle.fill_color = circle.fill_color new_circle.attach_to(window) window.render(0.1) x = x + (2 * radius) # Move x to the right, for next circle y = y + 2 * radius # Move y down, for the next row of circles x = original_x # Reset x to the left-edge, for the next row for i in range(3): # Loop through the rows for j in range(3): # Loop through the columns new_circle = rg.Circle(rg.Point(x, y), radius) new_circle.fill_color = circle.fill_color new_circle.attach_to(window) window.render(0.1) x = x + (2 * radius) # Move x to the right, for next circle y = y + 2 * radius # Move y down, for the next row of circles x = original_x # Reset x to the left-edge, for the next row original_x = original_x + 3 * (2 * radius) x = original_x y = y - 3 * (2 * radius) for i in range(3): # Loop through the rows for j in range(c): # Loop through the columns new_circle = rg.Circle(rg.Point(x, y), radius) new_circle.fill_color = circle.fill_color new_circle.attach_to(window) window.render(0.1) x = x + (2 * radius) # Move x to the right, for next circle y = y + 2 * radius # Move y down, for the next row of circles x = original_x # Reset x to the left-edge, for the next row
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------ # Done: 2. Implement and test this function. # We provided some tests for you (above). # ------------------------------------------------------------------ #################################################################### # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. #################################################################### # ------------------------------------------------------------------ # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------ center_x = point.x center_y = point.y x1 = center_x y1 = center_y for k in range(n): for m in range(k): center = rg.Point(x1 + m * radius * 2,y1) circle = rg.Circle(center, radius) circle.attach_to(window) circle.fill_color = color y = center.y x11 = center.x - radius x22 = center.x + radius line = rg.Line(rg.Point(x11,y), rg.Point(x22,y)) line.attach_to(window) x1 = center_x y1 = center_y x1 = x1 - radius * k y1 = y1 - math.sqrt(3 * radius * radius) * k x2 = center_x y2 = center_y for k in range(n): for m in range(k): center = rg.Point(x2 + m * radius * 2,y2) circle = rg.Circle(center, radius) circle.attach_to(window) circle.fill_color = color y = center.y x11 = center.x - radius x22 = center.x + radius line = rg.Line(rg.Point(x11, y), rg.Point(x22, y)) line.attach_to(window) x2 = center_x y2 = center_y x2 = x2 - radius * k y2 = y2 + math.sqrt(3 * radius * radius) * k window.render()
-- They have different radii. -- One is filled with some color and one is not filled. -- Waits for the user to press the mouse, then closes the window. """ # ------------------------------------------------------------------------- # DONE: 2. Implement this function, per its doc-string above. # -- ANY two rg.Circle objects that meet the criteria are fine. # -- File COLORS.txt lists all legal color-names. # Put a statement in main to test this function # (by calling this function). # ------------------------------------------------------------------------- window = rg.RoseWindow() c1 = rg.Circle(rg.Point(50, 50), 50) c2 = rg.Circle(rg.Point(100, 100), 25) c1.fill_color = 'maroon' c1.attach_to(window) c2.attach_to(window) window.render() window.close_on_mouse_click() def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow.
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle: -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ window = rg.RoseWindow(1500, 1500) center_x = 500 center_y = 500 rectangle_1_x = 0 rectangle_1_y = 0 rectangle_2_x = 250 rectangle_2_y = 360 center = rg.Point(center_x, center_y) point_1 = rg.Point(0, 0) point_2 = rg.Point(250, 360) rectangle = rg.Rectangle(point_1, point_2) circle = rg.Circle(center, 250) circle.fill_color = 'blue' thicc = 3 thicc_2 = 1 circle.pen = rg.Pen('black', thicc) rectangle.pen = rg.Pen('black', thicc_2) circle.attach_to(window) rectangle.attach_to(window) window.render() print(thicc) print('blue') print(center) print(center_x) print(center_y) print(thicc_2) print('None') rectangle_center_x = (rectangle_1_x + rectangle_2_x) / 2 rectangle_center_y = (rectangle_1_y + rectangle_2_y) / 2 rectangle_center = rg.Point(rectangle_center_x, rectangle_center_y) print(rectangle_center) print(rectangle_center_x) print(rectangle_center_y) window.close_on_mouse_click()
def draw_circles_from_rectangle(m, n, rectangle, window): """ What comes in: Four arguments: -- Positive integers m and n. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_circles_from_rectangle.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangle on the given rg.RoseWindow. Then draws m rg.Circles on the given rg.RoseWindow, such that: -- The diameter of each rg.Circle is the same as the height of the given rg.Rectangle. -- The first rg.Circle is immediately to the left of the given rg.Rectangle -- Each subsequent rg.Circle is immediately to the left of the previous rg.Circle, so that the circles form a row that goes to the left. -- Each rg. Circle has the same fill_color as the given rg.Rectangle (and has no outline_color). Then draws n rg.Circles on the given RoseWindow, such that: -- The diameter of each rg.Circle is the same as the width of the given rg.Rectangle. -- The first rg.Circle is immediately above the given rg.Rectangle -- Each subsequent rg.Circle is immediately above the previous rg.Circle, so that the circles form a column that goes up. -- Each rg.Circle has the same outline_color as the given rg.Rectangle (and has no fill_color). Must ** render ** but ** NOT close ** the window. Type hints: :type m: int :type n: int :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # DONE: 4. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # ########################################################################### # HINT: To figure out the code that computes the necessary # positions of each circle, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** ########################################################################### # ------------------------------------------------------------------------- rectangle.attach_to(window) window.render() print(rectangle) w = rectangle.corner_2.x - rectangle.corner_1.x h = rectangle.corner_2.y - rectangle.corner_1.y if w < 0: w = -w if h < 0: h = -h radius1 = (h / 2) radius2 = (w / 2) circle_left = 0 val1 = (h / 2) val2 = (w / 2) circle_up = 0 for k in range(m): if k == 0: circle_left = rg.Circle( rg.Point(rectangle.corner_1.x - radius1, rectangle.corner_2.y - radius2), radius1) circle_left.fill_color = rectangle.fill_color circle_left.outline_color = 0 if k > 0: circle_left = rg.Circle( rg.Point(rectangle.corner_1.x - val1, rectangle.corner_2.y - radius2), radius1) circle_left.fill_color = rectangle.fill_color circle_left.outline_color = 0 val1 = val1 + (radius1 * 2) circle_left.attach_to(window) window.render() for k in range(n): if k == 0: circle_up = rg.Circle( rg.Point(rectangle.corner_2.x - radius1, rectangle.corner_1.y - radius2), radius2) circle_up.outline_color = rectangle.outline_color if k > 0: circle_up = rg.Circle( rg.Point(rectangle.corner_2.x - radius1, rectangle.corner_1.y - val2), radius2) circle_up.outline_color = rectangle.outline_color val2 = val2 + (radius2 * 2) circle_up.attach_to(window) window.render()
def hourglass(window, n, point, radius, color): """ See hourglass_picture.pdf in this project for pictures that may help you better understand the following specification: Displays an "hourglass" shape of circles in the given window. -- Each circle has the given radius and given color. -- Each circle has a horizontal line drawn through it. -- The middlemost of the circles is centered at the given point. -- There is a single circle in that middlemost row. -- There are n rows (including the middlemost row) of circles going UP from the middlemost circle. -- There are n rows (including the middlemost row) of circles going DOWN from the middlemost circle. -- Each circle barely touches its neighbor circles. Preconditions: :type window: rg.RoseWindow :type n: int :type point: rg.Point :type radius: int :type color: str where n and radius are positive and color is a string that denotes a color that rosegraphics understands. """ # ------------------------------------------------------------------------- # DONE: 3. Implement and test this function. # We provided some tests for you (above). # ######################################################################## # BONUS: Avoid replicated code if you can. Hint: You are allowed # to define an additional function(s) if you wish. # ------------------------------------------------------------------------- # DIFFICULTY AND TIME RATINGS (see top of this file for explanation) # DIFFICULTY: 8 # TIME ESTIMATE: 25 minutes (warning: this problem is challenging) # ------------------------------------------------------------------------- og_point = point.clone() pt = rg.Point(og_point.x, og_point.y) for k in range(n): pt.y = og_point.y + 2 * radius * math.sin(60 * math.pi / 180) * k for j in range(-k, k + 1, 2): pt.x = og_point.x + radius * j circle = rg.Circle(pt, radius) circle.fill_color = color circle.attach_to(window) line = rg.Line(rg.Point(pt.x - radius, pt.y), rg.Point(pt.x + radius, pt.y)) line.attach_to(window) window.render() for k in range(n): pt.y = og_point.y - 2 * radius * math.sin(60 * math.pi / 180) * k for j in range(-k, k + 1, 2): pt.x = og_point.x + radius * j circle = rg.Circle(pt, radius) circle.fill_color = color circle.attach_to(window) line_pt1 = rg.Line(rg.Point(pt.x - radius, pt.y), rg.Point(pt.x + radius, pt.y)) line_pt1.attach_to(window) window.render()
def draw_circles_from_rectangle(m, n, rectangle, window): """ What comes in: Four arguments: -- Positive integers m and n. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_circles_from_rectangle.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangle on the given rg.RoseWindow. Then draws m rg.Circles on the given rg.RoseWindow, such that: -- The diameter of each rg.Circle is the same as the height of the given rg.Rectangle. -- The first rg.Circle is immediately to the left of the given rg.Rectangle -- Each subsequent rg.Circle is immediately to the left of the previous rg.Circle, so that the circles form a row that goes to the left. -- Each rg. Circle has the same fill_color as the given rg.Rectangle (and has no outline_color). Then draws n rg.Circles on the given RoseWindow, such that: -- The diameter of each rg.Circle is the same as the width of the given rg.Rectangle. -- The first rg.Circle is immediately above the given rg.Rectangle -- Each subsequent rg.Circle is immediately above the previous rg.Circle, so that the circles form a column that goes up. -- Each rg.Circle has the same outline_color as the given rg.Rectangle (and has no fill_color). Must ** render ** but ** NOT close ** the window. Type hints: :type m: int :type n: int :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 4. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # positions of each circle, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #################################################################### # ------------------------------------------------------------------ halfwidth = ((rectangle.corner_1.x - rectangle.corner_2.x) / 2) halfheight = ((rectangle.corner_1.y - rectangle.corner_2.y) / 2) widthcenter = ((rectangle.corner_1.x + rectangle.corner_2.x) / 2) heightcenter = ((rectangle.corner_1.y + rectangle.corner_2.y) / 2) if halfheight < 0: halfheight = -halfheight if halfwidth < 0: halfwidth = -halfwidth center = rg.Point(widthcenter - halfwidth - halfheight, heightcenter) for k in range(m): circle = rg.Circle(center, halfheight) circle.fill_color = rectangle.fill_color circle.attach_to(window) center = rg.Point(center.x - 2 * halfheight, heightcenter) center = rg.Point(widthcenter, heightcenter - halfwidth - halfheight) for k in range(n): circle2 = rg.Circle(center, halfwidth) circle2.outline_color = rectangle.outline_color circle2.attach_to(window) center = rg.Point( widthcenter, center.y - 2 * halfwidth, ) rectangle.attach_to(window) window.render()
def run_test_problem1(): """ Tests the problem1 function. """ print() print('--------------------------------------------------') print('Testing the problem1 function:') print(' See the graphics windows that pop up.') print('--------------------------------------------------') # TWO tests on ONE window. title = 'Tests 1 & 2 of problem 1: ' title += 'cyan/green fills, then black/magenta' window = rg.RoseWindow(450, 350, title) # Test 1: title = 'Tests 1 & 2 of problem 1: ' title += 'cyan/green fills, then black/magenta' window = rg.RoseWindow(450, 350, title) # Test 1: circle = rg.Circle(rg.Point(150, 50), 30) circle.fill_color = 'cyan' circle.outline_color = 'blue' circle.outline_thickness = 3 rect = rg.Rectangle(rg.Point(325, 50), rg.Point(365, 150)) rect.fill_color = 'green' rect.outline_color = 'black' rect.outline_thickness = 5 problem1(circle, rect, 'red', 50, window) window.continue_on_mouse_click() # Test 2: circle = rg.Circle(rg.Point(275, 200), 40) circle.fill_color = 'black' circle.outline_color = 'red' circle.outline_thickness = 15 rect = rg.Rectangle(rg.Point(40, 340), rg.Point(10, 300)) rect.fill_color = 'magenta' rect.outline_color = 'green' rect.outline_thickness = 4 problem1(circle, rect, 'blue', 140, window) window.close_on_mouse_click() # A third test on ANOTHER window. title = 'Test 3 of problem 1: purple/yellow fills' window = rg.RoseWindow(300, 200, title) # Test 3: circle = rg.Circle(rg.Point(50, 150), 20) circle.fill_color = 'purple' circle.outline_color = 'blue' circle.outline_thickness = 5 rect = rg.Rectangle(rg.Point(100, 20), rg.Point(140, 70)) rect.fill_color = 'yellow' rect.outline_color = 'grey' rect.outline_thickness = 10 problem1(circle, rect, 'green', 170, window) window.close_on_mouse_click()
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle: -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ window1 = rg.RoseWindow() point3 = rg.Point(100, 100) radius3 = 50 circle3 = rg.Circle(point3, radius3) circle3.fill_color = 'blue' circle3.attach_to(window1) point4 = rg.Point(200, 200) point5 = rg.Point(250, 250) rectangle = rg.Rectangle(point4, point5) rectangle.attach_to(window1) window1.render() print(circle3.outline_thickness) print(circle3.fill_color) print(circle3.center) print(point3.x) print(point3.y) print(rectangle.outline_thickness) print(rectangle.fill_color) rect_center = rectangle.get_center() print(rect_center) print(rect_center.x) print(rect_center.y) window1.close_on_mouse_click()
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle: -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ window = rg.RoseWindow() center = rg.Point(100, 100) radius = 30 circle = rg.Circle(center, radius) circle.fill_color = 'blue' circle.attach_to(window) corner1 = rg.Point(200, 200) corner2 = rg.Point(350, 100) rectangle = rg.Rectangle(corner1, corner2) rectangle.attach_to(window) window.render() print('Circle Outline Thickness:', circle.outline_thickness) print('Circle Fill Color:', circle.fill_color) print('Circle Center', center) print('Circle x-coordinate:', center.x) print('Circle y-coordinate', center.y) print('Rectangle Outline Thickness:', rectangle.outline_thickness) print('Rectangle Fill Color:', rectangle.fill_color) print('Rectangle Center:', rectangle.get_center()) print('Rectangle x-coordinate:', rectangle.get_center().x) print('Rectangle y-coordinate:', rectangle.get_center().y) window.close_on_mouse_click()
def draw_row_of_circles(n, starting_point, color, window): """ What comes in: The four arguments are: -- A positive integer n. -- An rg.Point. -- A color appropriate for rosegraphics (e.g. 'red') -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: Draws n rg.Circle objects in a row, all on the given rg.RoseWindow, such that: -- The first rg.Circle is centered at the given starting_point. -- Each rg.Circle just touches the previous one (to its left). -- Each rg.Circle has radius 20. -- Each rg.Circle is filled with the given color. Must ** render ** but ** NOT close ** the rg.RoseWindow. Type hints: :type n: int :type starting_point: rg.Point :type color: str :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # The example below shows one way to solve problems using # HELPER variables (aka AUXILIARY variables) # In this approach: # 1. You determine all the variables that you need # to construct/draw whatever the problem calls for. # We call these HELPER variables. # 2. You initialize them BEFORE the loop, choosing values that # make them just right for constructing and drawing the # FIRST object to be drawn, in the FIRST time through the loop. # For example, x = starting_point.x in the example below. # 3. You determine how many times the loop should run # (generally, however many objects you want to draw) # and write the FOR statement for the loop. # For example, for _ in range(n): in the example below. # 4. Inside the loop you write the statements to construct and # draw the FIRST object to be drawn, using your helper # variables. This is easy because you chose just the right # values for those helper variables for this FIRST object. # 5. Test: Make sure the FIRST object appears. # (It will be redrawn many times, that is OK). # 6. Add code at the BOTTOM of the loop that changes the helper # variables appropriately for the NEXT time through the loop. # For example, x = x + diameter in the example below. # 7. Test and fix as needed. # # Many students (and professionals) find this technique less # error-prone that using the loop variable to do all the work. # ------------------------------------------------------------------------- radius = 20 diameter = 2 * radius x = starting_point.x # Initialize x and y BEFORE the loop. Choose ... y = starting_point.y # ... values that make the FIRST object easy to draw. for _ in range(n): # Loop that does NOT use its index variable # --------------------------------------------------------------------- # Construct the relevant object(s), # based on the current x, y and other variables. # --------------------------------------------------------------------- center = rg.Point(x, y) circle = rg.Circle(center, radius) circle.fill_color = color # Attach the object(s) to the window. circle.attach_to(window) # --------------------------------------------------------------------- # Increment x (and in other problems, other variables) # for the thing(s) to draw in the NEXT iteration of the loop. # --------------------------------------------------------------------- x = x + diameter window.render()
def draw_circles_from_rectangle(m, n, rectangle, window): """ What comes in: Four arguments: -- Positive integers m and n. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_circles_from_rectangle.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangle on the given rg.RoseWindow. Then draws m rg.Circles on the given rg.RoseWindow, such that: -- The diameter of each rg.Circle is the same as the height of the given rg.Rectangle. -- The first rg.Circle is immediately to the left of the given rg.Rectangle -- Each subsequent rg.Circle is immediately to the left of the previous rg.Circle, so that the circles form a row that goes to the left. -- Each rg. Circle has the same fill_color as the given rg.Rectangle (and has no outline_color). Then draws n rg.Circles on the given RoseWindow, such that: -- The diameter of each rg.Circle is the same as the width of the given rg.Rectangle. -- The first rg.Circle is immediately above the given rg.Rectangle -- Each subsequent rg.Circle is immediately above the previous rg.Circle, so that the circles form a column that goes up. -- Each rg.Circle has the same outline_color as the given rg.Rectangle (and has no fill_color). Must ** render ** but ** NOT close ** the window. Type hints: :type m: int :type n: int :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # DONE: 4. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # positions of each circle, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #################################################################### # ------------------------------------------------------------------ rectangle_center = rectangle.get_center() rec_center_x = rectangle_center.x rec_center_y = rectangle_center.y height = rectangle.get_height() width = rectangle.get_width() fill_color = rectangle.fill_color outline_color = rectangle.outline_color radius1 = height / 2 row_center_x = rec_center_x - width / 2 - radius1 radius2 = width / 2 column_center_y = rec_center_y - height / 2 - radius2 for _ in range(m): rectangle.attach_to(window) row_center_y = rec_center_y row_center = rg.Point(row_center_x, row_center_y) circle_row = rg.Circle(row_center, radius1) circle_row.fill_color = fill_color circle_row.attach_to(window) row_center_x = row_center_x - height for _ in range(n): column_center_x = rec_center_x column_center = rg.Point(column_center_x, column_center_y) circle_column = rg.Circle(column_center, radius2) circle_column.outline_color = outline_color circle_column.attach_to(window) window.render() column_center_y = column_center_y - width
def draw_circles_from_rectangle(m, n, rectangle, window): """ What comes in: Four arguments: -- Positive integers m and n. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_circles_from_rectangle.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangle on the given rg.RoseWindow. Then draws m rg.Circles on the given rg.RoseWindow, such that: -- The diameter of each rg.Circle is the same as the height of the given rg.Rectangle. -- The first rg.Circle is immediately to the left of the given rg.Rectangle -- Each subsequent rg.Circle is immediately to the left of the previous rg.Circle, so that the circles form a row that goes to the left. -- Each rg. Circle has the same fill_color as the given rg.Rectangle (and has no outline_color). Then draws n rg.Circles on the given RoseWindow, such that: -- The diameter of each rg.Circle is the same as the width of the given rg.Rectangle. -- The first rg.Circle is immediately above the given rg.Rectangle -- Each subsequent rg.Circle is immediately above the previous rg.Circle, so that the circles form a column that goes up. -- Each rg.Circle has the same outline_color as the given rg.Rectangle (and has no fill_color). Must ** render ** but ** NOT close ** the window. Type hints: :type m: int :type n: int :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ corner1 = rectangle.corner_1 corner2 = rectangle.corner_2 midhor = ((corner1.x+corner2.x)/2) midver = ((corner1.y+corner2.y)/2) rectangle.attach_to(window) if corner1.x > corner2.x: leftbound = corner2.x else: leftbound = corner1.x if corner1.y > corner2.y: topbound = corner2.y else: topbound = corner1.y height = abs(corner1.y-corner2.y) for k in range(m): circle = rg.Circle(rg.Point(leftbound-(height/2)-(k*height/4), midver), height/2) circle.fill_color = rectangle.fill_color circle.attach_to(window) for k in range(n): circle = rg.Circle(rg.Point(midhor, (topbound-(height/2)-(k*height/4))), height/2) circle.outline_color = rectangle.outline_color circle.attach_to(window) window.render()
def problem1(square, thickness, window): """ See problem1_picture.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- An rg.Square. -- A positive integer -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: -- Draws, on the given rg.RoseWindow: -- The given rg.Square. -- An rg.Circle that: -- is directly below and touching the given rg.Square, -- has diameter the same as the length of each side of the given rg.Square, -- has fill color the same as the fill color of the given rg.Square, and -- has the given thickness as its outline thickness. (SEE THE PICTURES.) -- An rg.Line that: -- has one endpoint is at the center of the above rg.Circle, -- has another endpoint that is at the midpoint of the left side of the given rg.Square, -- has color the same as the outline color of the given rg.Square, and -- has the given thickness. (SEE THE PICTURES.) Note: Attach the rg.Line AFTER attaching the rg.Square and rg.Circle. Must render but ** NOT close ** the window. Type hints: :type square: rg.Square :type thickness: int :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # DONE: 3. Implement and test this function. SEE THE PICTURES in the PDF! # Tests have been written for you (above). # ------------------------------------------------------------------------- square.attach_to(window) window.render() # centerx = square.center.x centery = square.center.y + square.length_of_each_side center = rg.Point(centerx,centery) radius = square.length_of_each_side*0.5 circle = rg.Circle(center,radius) circle.fill_color = square.fill_color circle.outline_thickness = thickness circle.attach_to(window) window.render() # endpointx = square.center.x - square.length_of_each_side*0.5 endpointy = square.center.y endpoint = rg.Point(endpointx,endpointy) line = rg.Line(center,endpoint) line.color = square.outline_color line.thickness = thickness line.attach_to(window) window.render()
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle: -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ # ------------------------------------------------------------------ # DONE: 3. Implement this function, per its doc-string above. # -- ANY objects that meet the criteria are fine. # Put a statement in main to test this function # (by calling this function). # # IMPORTANT: Use the DOT TRICK to guess the names of the relevant # instance variables for outline thickness, etc. # ------------------------------------------------------------------ window = rg.RoseWindow() x1 = 300 y1 = 200 center1 = rg.Point(x1, y1) thickness = 20 color = "blue" circle = rg.Circle(center1, 50) circle.pen = rg.Pen('black', thickness) circle.fill_color = color circle.attach_to(window) print(thickness) print(color) print(center1) print(x1) print(y1) x2 = 50 y2 = 50 x3 = 140 y3 = 100 color2 = 'none' point1 = rg.Point(x2, y2) point2 = rg.Point(x3, y3) rectangle = rg.Rectangle(point1, point2) rectangle.pen = rg.Pen('black', thickness) rectangle.attach_to(window) print(thickness) print(color2) print('Point(', x2 + x3 / 2, ',', y2 + y3 / 2, ')') print(x2 + x3 / 2) print(y2 + y3 / 2) window.render() window.close_on_mouse_click()
def run_test_fill_from_colors(): """ Tests the fill_from_colors function. """ print("--------------------------------------------------") print("Testing the fill_from_colors function:") print("See the two graphics windows that pop up.") print("--------------------------------------------------") # ------------------------------------------------------------------------- # Test 1: Flashes red, white, blue -- 5 times. # ------------------------------------------------------------------------- title = "Red, white and blue, repeated 5 times!" window = rg.RoseWindow(400, 180, title, canvas_color="dark gray") circle = rg.Circle(rg.Point(150, 100), 40) circle.attach_to(window.initial_canvas) number_of_cycles = 5 window.continue_on_mouse_click("Click anywhere in here to start") for _ in range(number_of_cycles): fill_from_colors(window, circle, ["red", "white", "blue"]) window.close_on_mouse_click() # ------------------------------------------------------------------------- # Test 2: Flashes through a bunch of colors, looping through the # list forwards in a rectangle, then backwards in an ellipse. # ------------------------------------------------------------------------- colors = ["red", "white", "blue", "chartreuse", "chocolate", "DodgerBlue", "LightPink", "maroon", "yellow", "green", "SteelBlue", "black"] title = "Loop through 12 colors, forwards then backwards!" window = rg.RoseWindow(450, 250, title, canvas_color="yellow") rect_width = 100 rect_height = 40 rect_center = rg.Point(125, 100) rectangle = rg.Rectangle(rg.Point(rect_center.x - (rect_width / 2), rect_center.y - (rect_height / 2)), rg.Point(rect_center.x + (rect_width / 2), rect_center.y + (rect_height / 2))) oval_width = 70 oval_height = 160 oval_center = rg.Point(300, 100) ellipse = rg.Ellipse(rg.Point(oval_center.x - (oval_width / 2), oval_center.y - (oval_height / 2)), rg.Point(oval_center.x + (oval_width / 2), oval_center.y + (oval_height / 2))) rectangle.attach_to(window) ellipse.attach_to(window) window.render() window.continue_on_mouse_click("Click anywhere in here to start") # This function call iterates through the colors, # filling the rectangle with those colors: fill_from_colors(window, rectangle, colors) # The reverse method reverses its list IN PLACE # (i.e., it "mutates" its list -- more on that in future sessions). colors.reverse() window.continue_on_mouse_click() # This function call iterates through the colors, # filling the ellipse (oval) with those colors: fill_from_colors(window, ellipse, colors) window.close_on_mouse_click()
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle: -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ # ------------------------------------------------------------------------- # Done: 3. Implement this function, per its green doc-string above. # -- ANY objects that meet the criteria are fine. # Put a statement in main to test this function # (by calling this function). # # IMPORTANT: Use the DOT TRICK to guess the names of the relevant # instance variables for outline thickness, etc. # ------------------------------------------------------------------------- window = rg.RoseWindow(600, 600) c = rg.Circle(rg.Point(200, 200), 100) r = rg.Rectangle(rg.Point(300, 300), rg.Point(400, 550)) c.fill_color = 'blue' c.attach_to(window) r.attach_to(window) print() print('--------------------------------------------------') print('Circle Data:') print('--------------------------------------------------') print("Outline Thickness =", c.outline_thickness) print('Fill Color =', c.fill_color) print('Center =', c.center) print('X-center =', c.center.x) print('Y-center =', c.center.y) print() print('--------------------------------------------------') print('Rectangle Data:') print('--------------------------------------------------') print("Outline Thickness =", r.outline_thickness) print('Fill Color =', r.fill_color) center = r.get_center() print('Center =', center) print('X-center =', center.x) print('Y-center =', center.y) window.render() window.close_on_mouse_click()
def draw_circles_from_rectangle(m, n, rectangle, window, recFill, recOut): """ What comes in: Four arguments: -- Positive integers m and n. -- An rg.Rectangle. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See draw_circles_from_rectangle.pdf in this project for pictures that may help you better understand the following specification: First draws the given rg.Rectangle on the given rg.RoseWindow. Then draws m rg.Circles on the given rg.RoseWindow, such that: -- The diameter of each rg.Circle is the same as the height of the given rg.Rectangle. -- The first rg.Circle is immediately to the left of the given rg.Rectangle -- Each subsequent rg.Circle is immediately to the left of the previous rg.Circle, so that the circles form a row that goes to the left. -- Each rg. Circle has the same fill_color as the given rg.Rectangle (and has no outline_color). Then draws n rg.Circles on the given RoseWindow, such that: -- The diameter of each rg.Circle is the same as the width of the given rg.Rectangle. -- The first rg.Circle is immediately above the given rg.Rectangle -- Each subsequent rg.Circle is immediately above the previous rg.Circle, so that the circles form a column that goes up. -- Each rg.Circle has the same outline_color as the given rg.Rectangle (and has no fill_color). Must ** render ** but ** NOT close ** the window. Type hints: :type m: int :type n: int :type rectangle: rg.Rectangle :type window: rg.RoseWindow """ # ------------------------------------------------------------------ # Done: 4. Implement and test this function. # Tests have been written for you (above). # # CONSIDER using the ACCUMULATOR IN GRAPHICS pattern, # as in draw_row_of_circles in m1e, # instead of directly using the loop variable. # #################################################################### # HINT: To figure out the code that computes the necessary # positions of each circle, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** #################################################################### # ------------------------------------------------------------------ recWidth = float(rectangle.get_width()) recHeight = float(rectangle.get_height()) for k in range(m): circle_pos = rg.Point( rectangle.get_center().x - (recWidth / 2 + recHeight / 2 + (k * recHeight)), rectangle.get_center().y) circle = rg.Circle(circle_pos, recHeight / 2) circle.fill_color = recFill circle.attach_to(window) for j in range(n): circle_pos = rg.Point( rectangle.get_center().x, rectangle.get_center().y - (recHeight / 2 + recWidth / 2 + (j * recWidth))) circle = rg.Circle(circle_pos, recWidth / 2) circle.outline_color = recOut circle.attach_to(window) rectangle.outline_color = recOut rectangle.fill_color = recFill rectangle.attach_to(window) window.render()
def run_test_practice_problem3a(): """ Tests the practice_problem3a function. """ print() print('--------------------------------------------------') print('Testing the practice_problem3a function:') print('--------------------------------------------------') format_string = ' practice_problem3a( {} )' test_results = [0, 0] # Number of tests passed, failed. # Test 1: expected = 5 * 2 * 7 * 10 * 2 # which is 1400 circles = (rg.Circle(rg.Point(5, 10), 20), rg.Circle(rg.Point(2, 20), 20), rg.Circle(rg.Point(7, 30), 10), rg.Circle(rg.Point(10, 40), 20), rg.Circle(rg.Point(2, 50), 10)) print_expected_result_of_test([circles], expected, test_results, format_string) actual = practice_problem3a(circles) print_actual_result_of_test(expected, actual, test_results) # Test 2: expected = 58 circles = (rg.Circle(rg.Point(58, 10), 20),) print_expected_result_of_test([circles], expected, test_results, format_string) actual = practice_problem3a(circles) print_actual_result_of_test(expected, actual, test_results) # Test 3: expected = 84 * 28 * 10005 # which is 23531760 circles = (rg.Circle(rg.Point(84, 100), 200), rg.Circle(rg.Point(28, 200), 200), rg.Circle(rg.Point(10005, 300), 100)) print_expected_result_of_test([circles], expected, test_results, format_string) actual = practice_problem3a(circles) print_actual_result_of_test(expected, actual, test_results) # Test 4: expected = 1 circles = () print_expected_result_of_test([circles], expected, test_results, format_string) actual = practice_problem3a(circles) print_actual_result_of_test(expected, actual, test_results) # Test 5: expected = 5 * 0 * 7 * 10 * 2 # which is 0 circles = (rg.Circle(rg.Point(5, 10), 20), rg.Circle(rg.Point(0, 20), 20), rg.Circle(rg.Point(7, 30), 10), rg.Circle(rg.Point(10, 40), 20), rg.Circle(rg.Point(2, 50), 10)) print_expected_result_of_test([circles], expected, test_results, format_string) actual = practice_problem3a(circles) print_actual_result_of_test(expected, actual, test_results) # Test 6: circles = [] for k in range(1, 101): circles.append(rg.Circle(rg.Point(k, k + 20), 5 * k)) expected = math.factorial(100) print_expected_result_of_test([circles], expected, test_results, format_string) actual = practice_problem3a(circles) print_actual_result_of_test(expected, actual, test_results) # SUMMARY of test results: print_summary_of_test_results(test_results)
def run_test_rectangles_from_circles(): """ Tests the rectangles_from_circles function. """ print() print('-----------------------------------------------------------') print('Testing the rectangles_from_circles function:') print('-----------------------------------------------------------') print('See the graphics window that pops up.') print('It should show circles, then the circles circumscribed,') print('then more circles, then the new circles circumscribed too.') print() print('See rectangles_from_circles.pdf in this project') print('for pictures of the anticipated results.') # ------------------------------------------------------------------ # Test 1 is ALREADY DONE (here). # ------------------------------------------------------------------ window = rg.RoseWindow(650, 350, 'rectangles_from_circles, two tests') circles = [ rg.Circle(rg.Point(50, 80), 40), rg.Circle(rg.Point(150, 50), 30), rg.Circle(rg.Point(300, 100), 50), rg.Circle(rg.Point(220, 70), 60) ] circles[0].fill_color = 'red' circles[1].fill_color = 'white' circles[2].fill_color = 'blue' circles[3].fill_color = 'green' # ------------------------------------------------------------------ # This test calls the draw_shapes function that YOU write, # above. So if your draw_shapes breaks, so will this test. # ------------------------------------------------------------------ draw_shapes(circles, window) message = 'The circles to be circumscribed are shown above.' message = message + ' Click to continue.' window.continue_on_mouse_click(message) rectangles = rectangles_from_circles(circles) if rectangles is None: print() print('Either you have not yet gotten') print(' to the rectangles_from_circles problem (OK, no problem)') print(' or you have forgotten to return a result from that function.') window.close_on_mouse_click() return draw_shapes(rectangles, window) message = 'Now you should see the circumscribing rectangles too.' message = message + ' Click to continue.' window.continue_on_mouse_click(message) # ------------------------------------------------------------------ # Test 2 is ALREADY DONE (here). # It runs in the same window as Test 1. # ------------------------------------------------------------------ circles = [] center = rg.Point(50, 150) radius = 35 for _ in range(10): circle = rg.Circle(center, radius) circle.fill_color = 'magenta' circles = circles + [circle] center.x = center.x + 2 * radius center.y = center.y + 15 radius = radius - 3 draw_shapes(circles, window) message = 'More circles to be circumscribed are shown above.' message = message + ' Click to continue.' window.continue_on_mouse_click(message) rectangles = rectangles_from_circles(circles) draw_shapes(rectangles, window) message = 'Now you should see the circumscribing rectangles too.' message = message + ' Click to exit.' window.continue_on_mouse_click(message, close_it=True)
def run_test_MUTATE_circle(): """ Tests the MUTATE_circle function. """ print() print('-----------------------------------------') print('Testing MUTATE_circle:') print('-----------------------------------------') print() print('See the graphics window for this test.') print('If an error msg appears at any point,') print('you have failed this test.') # Tests 1 and 2 (on one window): window = rg.RoseWindow(500, 450, 'Testing MUTATE_circle') text = rg.Text(rg.Point(250, 125), '') text.attach_to(window.initial_canvas) circle = rg.Circle(rg.Point(250, 300), 50) circle.fill_color = 'yellow' circle.attach_to(window.initial_canvas) msg = 'Note: If you see an error message at ANY point,\n' msg = msg + 'then you have failed this test.\n\n' msg = msg + 'I have drawn the original, yellow circle.\n\n' msg = msg + 'So you should see a YELLOW circle below\n' msg = msg + '(and nothing else).\n\n' msg = msg + 'Click the mouse to continue this test.\n' text.text = msg window.render(0.5) window.get_next_mouse_click() result = MUTATE_circle(circle, 'pink', 200) msg = 'I have called your MUTATE_circle function.\n' msg = msg + 'It should have MUTATED the (sole) circle to be pink\n' msg = msg + 'and 200 units to the right of where it was.\n\n' msg = msg + 'So you should see (only) a PINK circle below,\n' msg = msg + 'almost touching the right side of the window.\n\n' msg = msg + 'Click the mouse to continue this test.' if result is not None: msg = msg + '\n\nERROR: You returned a value! Wrong!!!' text.text = msg window.render(0.5) window.get_next_mouse_click() circle.detach_from(window.initial_canvas) msg = 'I have now UN-drawn the (sole) circle.\n\n' msg = msg + 'So you should see NO circles below.\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() circle.attach_to(window.initial_canvas) msg = 'Now I have RE-drawn the (now pink) circle.\n\n' msg = msg + 'So you should see (only) a PINK circle below,\n' msg = msg + 'just touching the right side of the window.\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() result = MUTATE_circle(circle, 'black', -400) msg = 'I have called your MUTATE_circle function again.\n' msg = msg + 'It should have MUTATED the (sole) circle to be black\n' msg = msg + 'and 400 units to the left of where it was.\n\n' msg = msg + 'So you should see (only) a BLACK circle below,\n' msg = msg + 'just touching the left side of the window.\n\n' msg = msg + 'Click the mouse to continue this test.' if result is not None: msg = msg + '\n\nERROR: You returned a value! Wrong!!!' text.text = msg window.render(0.5) window.get_next_mouse_click() another_circle = rg.Circle(circle.center, 25) another_circle.fill_color = 'red' another_circle.attach_to(window.initial_canvas) msg = 'I have constructed and drawn another circle.\n' msg = msg + 'It is red and smaller than the black circle,\n' msg = msg + 'and currently centered on the black circle.\n\n' msg = msg + 'So you should now see a BLACK circle below,\n' msg = msg + 'just touching the left side of the window,\n' msg = msg + 'with a smaller red circle on top of the black circle.\n\n' msg = msg + 'Click the mouse to continue this test.' text.text = msg window.render(0.5) window.get_next_mouse_click() result = MUTATE_circle(another_circle, 'white', 65) msg = 'I have called your MUTATE_circle function again.\n' msg = msg + 'It should have MUTATED the small, red circle to be white\n' msg = msg + 'and 65 units to the left of where it was.\n\n' msg = msg + 'So you should see a BLACK circle below,\n' msg = msg + 'just touching the left side of the window,\n' msg = msg + 'with a WHITE circle slightly overlapping the black one.\n\n' msg = msg + 'Click the mouse to conclude this test.' if result is not None: msg = msg + '\n\nERROR: You returned a value! Wrong!!!' text.text = msg window.render(0.5) window.get_next_mouse_click() window.close()
def circle_and_rectangle(): """ -- Constructs an rg.RoseWindow. -- Constructs and draws a rg.Circle and rg.Rectangle on the window such that: -- They fit in the window and are easily visible. -- The rg.Circle is filled with 'blue' -- Prints (on the console, on SEPARATE lines) the following data associated with your rg.Circle: -- Its outline thickness. -- Its fill color. -- Its center. -- Its center's x coordinate. -- Its center's y coordinate. -- Prints (on the console, on SEPARATE lines) the same data but for your rg.Rectangle. -- Waits for the user to press the mouse, then closes the window. Here is an example of the output on the console, for one particular circle and rectangle: 1 blue Point(180.0, 115.0) 180 115 1 None Point(75.0, 150.0) 75.0 150.0 """ # ------------------------------------------------------------------------- # DONE: 3. Implement this function, per its green doc-string above. # -- ANY objects that meet the criteria are fine. # Put a statement in main to test this function # (by calling this function). # # IMPORTANT: Use the DOT TRICK to guess the names of the relevant # instance variables for outline thickness, etc. # ------------------------------------------------------------------------- window = rg.RoseWindow(height=400, width=400) x = rg.Point(300, 100) y = rg.Point(200, 100) z = rg.Point(250, 180) circle = rg.Circle(x, 20) circle.fill_color='red' rectangle = rg.Rectangle(y, z) circle.attach_to(window) rectangle.attach_to(window) window.render() print(circle.outline_thickness) print(circle.fill_color) print(circle.center) print(circle.center.x) print(circle.center.y) print(rectangle.outline_thickness) print(rectangle.fill_color) print(rectangle.get_center()) print(rectangle.get_center().x) print(rectangle.get_center().y) window.close_on_mouse_click()
def run_test_practice_problem3a(): """ Tests the practice_problem3a function. """ # ------------------------------------------------------------------ # 6 tests. # They use the imported simple_testing (st) module. # Each test is a SimpleTestCase with 3 arguments: # -- the function to test, # -- a list containing the argument(s) to send to the function, # -- the correct returned value. # For example, the first test below will call # practice_problem3a((rg.Circle(rg.Point(5, 10), 20), # rg.Circle(rg.Point(2, 20), 20), # rg.Circle(rg.Point(7, 30), 10), # rg.Circle(rg.Point(10, 40), 20), # rg.Circle(rg.Point(2, 50), 10))) # and compare the returned value against 1400 (the correct answer). # ------------------------------------------------------------------ tests = [st.SimpleTestCase(practice_problem3a, [(rg.Circle(rg.Point(5, 10), 20), rg.Circle(rg.Point(2, 20), 20), rg.Circle(rg.Point(7, 30), 10), rg.Circle(rg.Point(10, 40), 20), rg.Circle(rg.Point(2, 50), 10))], 5 * 2 * 7 * 10 * 2), st.SimpleTestCase(practice_problem3a, [(rg.Circle(rg.Point(58, 10), 20),)], 58), st.SimpleTestCase(practice_problem3a, [(rg.Circle(rg.Point(84, 100), 200), rg.Circle(rg.Point(28, 200), 200), rg.Circle(rg.Point(10005, 300), 100))], 84 * 28 * 10005), st.SimpleTestCase(practice_problem3a, [()], 1), st.SimpleTestCase(practice_problem3a, [(rg.Circle(rg.Point(5, 10), 20), rg.Circle(rg.Point(0, 20), 20), rg.Circle(rg.Point(7, 30), 10), rg.Circle(rg.Point(10, 40), 20), rg.Circle(rg.Point(2, 50), 10))], 5 * 0 * 7 * 10 * 2), ] circles = [] for k in range(1, 101): circles.append(rg.Circle(rg.Point(k, k + 20), 5 * k)) answer = math.factorial(100) tests.append(st.SimpleTestCase(practice_problem3a, [circles], answer)) # ------------------------------------------------------------------ # Run the 6 tests in the tests list constructed above. # ------------------------------------------------------------------ st.SimpleTestCase.run_tests('practice_problem3a', tests)
def draw_L(window, circle, r, c): """ See L.pdf in this project for pictures that may help you better understand the following specification: Draws an 'L' of circles on the given rg.RoseWindow. The 'column' part of the L should have r rows and 3 columns. (That is, it is r 'tall' and 3 'thick'.) The 'shared corner' part of the L should be 3 x 3. The 'row' part of the L should have c columns and 3 rows. (That is, it is c 'long' and 3 'thick'.) The given rg.Circle specifies: - The position of the upper-left circle drawn and also - The radius that all the circles have. - The fill_color that all the circles have. After drawing each circle, pauses briefly (0.1 second). Preconditions: :type window: rg.RoseWindow :type circle: rg.Circle :type r: int :type c: int and m and n are small, positive integers. """ # ------------------------------------------------------------------------- # DONE: 2. Implement and test this function. # The testing code is already written for you (above). # ------------------------------------------------------------------------- startx = circle.center.x starty = circle.center.y rad = circle.radius color = circle.fill_color x = startx y = starty #Stem for j in range(r): for k in range(3): stem = rg.Circle(rg.Point(x, y), rad) stem.fill_color = color stem.attach_to(window) window.render(0.1) x = x + (2 * rad) y = y + (2 * rad) x = startx #Corner for j in range(3): for k in range(3): stem = rg.Circle(rg.Point(x, y), rad) stem.fill_color = color stem.attach_to(window) window.render(0.1) x = x + (2 * rad) y = y + (2 * rad) x = startx x = (2 * 3 * rad) + startx y = (2 * r * rad) + starty #Leg for j in range(3): for k in range(c): stem = rg.Circle(rg.Point(x, y), rad) stem.fill_color = color stem.attach_to(window) window.render(0.1) x = x + (2 * rad) y = y + (2 * rad) x = (2 * 3 * rad) + startx