""" This module lets you practice BUILDING-UP a new SEQUENCE, one item at a time, using the ACCUMULATOR pattern. -- We will later see a more efficient way to build-up and/or modify sequences, namely by MUTATING their elements. Authors: David Mutchler, Vibha Alangar, Dave Fisher, Matt Boutell, Mark Hays, Mohammed Noureddine, Sana Ebrahimi, Sriram Mohan, their colleagues and PUT_YOUR_NAME_HERE. """ # TODO: 1. PUT YOUR NAME IN THE ABOVE LINE. import rosegraphics as rg def main(): """ Calls the various TEST functions in this module. """ run_test_make_simple_list() run_test_make_simple_string() run_test_make_less_simple_string() # ------------------------------------------------------------------------- # TODO: 8. Uncomment the tests below before working _TODO_ 9. # They launch annoying rg.RoseWindows on each run that you don't want # until you get to _TODO_ 9 and _TODO_ 10. # ------------------------------------------------------------------------- # run_test_draw_shapes() # run_test_rectangles_from_circles() def run_test_make_simple_list(): """ Tests the make_simple_list function. """ # ------------------------------------------------------------------------- # TODO: 2. Implement this TEST function. # It TESTS the make_simple_list function defined below. # Include at least ** 2 ** tests. # ___ # Use the same 4-step process as for previous TEST functions. # ------------------------------------------------------------------------- print() print("--------------------------------------------------") print("Testing the make_simple_list function:") print("--------------------------------------------------") # Test 1: expected = [5, 6, 7, 8, 9, 10, 11, 12, 13] actual = make_simple_list(5, 13) print("Expected:", expected) print("Actual: ", actual) # ------------------------------------------------------------------------- # TODO: 2 (continued) # Test 2: (YOU write THIS test) # ------------------------------------------------------------------------- def make_simple_list(m, n): """ What comes in: -- a positive integer m -- a positive integer n that is >= m What goes out: Returns the list [m, m+1, m+2, ... n], where m and n are the given arguments. Side effects: None. Examples: If m is 5 and n is 13, then this function returns: [5, 6, 7, 8, 9, 10, 11, 12, 13] If m and n are both 205, then this function returns: [205] Type hints: :type m: int :type n: int """ # ------------------------------------------------------------------------- # TODO: 3. Implement and test this function. # Note that you should write its TEST function first (above). # ------------------------------------------------------------------------- def run_test_make_simple_string(): """ Tests the make_simple_string function. """ # ------------------------------------------------------------------------- # TODO: 4. Implement this TEST function. # It TESTS the make_simple_string function defined below. # Include at least ** 2 ** tests. # ___ # Use the same 4-step process as for previous TEST functions. # ------------------------------------------------------------------------- print() print("--------------------------------------------------") print("Testing the make_simple_string function:") print("--------------------------------------------------") def make_simple_string(m, n): """ What comes in: -- a positive integer m -- a positive integer n that is >= m What goes out: Returns the STRING whose characters are m, m+1, m+2, ... n, each with a "-" character after it, where m and n are the given arguments. Side effects: None. Examples: If m is 5 and n is 13, then this function returns: "5-6-7-8-9-10-11-12-13-" If m and n are both 205, then this function returns: "205-" Type hints: :type m: int :type n: int """ # ------------------------------------------------------------------------- # TODO: 5. Implement and test this function. # Note that you should write its TEST function first (above). # ------------------------------------------------------------------------- def run_test_make_less_simple_string(): """ Tests the make_less_simple_string function. """ # ------------------------------------------------------------------------- # TODO: 6. Implement this TEST function. # It TESTS the make_less_simple_string function defined below. # Include at least ** 2 ** tests. # # Use the same 4-step process as for previous TEST functions. # ------------------------------------------------------------------------- print() print("--------------------------------------------------") print("Testing the make_less_simple_string function:") print("--------------------------------------------------") def make_less_simple_string(m, n): """ What comes in: -- a positive integer m -- a positive integer n that is >= m What goes out: The same as the previous problem, but WITHOUT the hyphen after the LAST number. That is, this function returns the STRING whose characters are m, m+1, m+2, ... n, with a "-" character BETWEEN each of the items and where m and n are the given arguments. Side effects: None. Examples: If m is 5 and n is 13, then this function returns: "5-6-7-8-9-10-11-12-13" If m and n are both 205, then this function returns: "205" Type hints: :type m: int :type n: int """ # ------------------------------------------------------------------------- # TODO: 7. Implement and test this function. # Note that you should write its TEST function first (above). # ------------------------------------------------------------------------- def run_test_draw_shapes(): """ Tests the draw_shapes function. """ print() print("-----------------------------------------------------------") print("Testing the draw_shapes function:") print("-----------------------------------------------------------") print("See the graphics window that pops up.") print("It should show 3 circles: red, white and blue.") print() print("Then it should ask the user to click the mouse to continue.") print("Then it should show 4 more shapes: a green circle,") print(" a yellow rectangle, a red circle and a thick black line.") # ------------------------------------------------------------------------- # Test 1 is ALREADY DONE (here). # ------------------------------------------------------------------------- window = rg.RoseWindow(500, 330, "draw_shapes, two tests") circles = [rg.Circle(rg.Point(50, 50), 50), rg.Circle(rg.Point(120, 50), 20), rg.Circle(rg.Point(250, 170), 130)] circles[0].fill_color = "red" circles[1].fill_color = "white" circles[2].fill_color = "blue" draw_shapes(circles, window) window.continue_on_mouse_click() # ------------------------------------------------------------------------- # Test 2 is ALREADY DONE (here). # It runs in the same window as Test 1. # The bottom circle should appear only PARTIALLY in the window; # that is purposeful. # ------------------------------------------------------------------------- rect_width = 100 rect_height = 160 rect_center = rg.Point(350, 100) various = [rg.Circle(rg.Point(400, 50), 30), 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)), rg.Circle(rg.Point(400, 300), 80), rg.Line(rg.Point(0, 0), rg.Point(100, 330))] various[0].fill_color = "green" various[1].fill_color = "yellow" various[2].fill_color = "red" various[3].thickness = 10 draw_shapes(various, window) window.close_on_mouse_click() def draw_shapes(shapes, window): """ What comes in: -- a sequence of rg.Shape objects Note: rg.Line, rg.Circle, rg.Point, ... are all rg.Shape objects. -- an rg.RoseWindow What goes out: Nothing (i.e., None). Side effects: See draw_shapes.pdf in this project for pictures that may help you better understand the following: For each rg.Shape in the given sequence of rg.Shape objects, 1. Attaches the rg.Shape to the given rg.RoseWindow. 2. Renders the rg.RoseWindow with a 0.3 second delay after the render. Examples: See the draw_shapes.pdf file in this project. Type hints: :type shapes: list | tuple of rg._Shape :type window: rg.RoseWindow """ # ------------------------------------------------------------------------- # TODO: 9. Implement and test this function. # *** Make sure you do _TODO_ 8 in main first! *** # The testing code is already written for you; # you enabled it via _TODO_ 8. # ######################################################################## # IMPORTANT: the same # attach_to # method works for ALL the rosegraphics shapes! # FWIW: The word for ideas like this is "polymorphism". # ######################################################################## # ------------------------------------------------------------------------- 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 rectangles_from_circles(circles): """ See rectangles_from_circles.pdf in this project for pictures that may help you better understand the following specification: What comes in: -- a sequence of rg.Circle objects What goes out: Returns a list of rg.Rectangles, where each rg.Rectangle circumscribes its corresponding rg.Circle in the given list of rg.Circles. Side effects: None. Examples: See rectangles_from_circles.pdf in this project. Type hints: :type circles: list | tuple of rg.Circle :rtype: list of rg.Rectangles """ # ------------------------------------------------------------------------- # TODO: 10. Implement and test this function. # The testing code is already written for you (above). # ######################################################################## # IMPORTANT: Examine the testing code above carefully. Be sure # that you understand WHY the tests are adequate tests! # ___ # IMPORTANT: The specification does NOT say to draw anything # in this function, so DON'T draw anything in here! # ######################################################################## # ------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Calls main to start the ball rolling. # ----------------------------------------------------------------------------- main()