""" This module lets you practice one form of the ACCUMULATOR pattern, namely, the "IN GRAPHICS" form which features: -- DRAWING OBJECTS via ACCUMULATING positions and/or sizes, as in: x = x + pixels Additionally, it emphasizes that you must ** DO A CONCRETE EXAMPLE BY HAND ** before you can implement a solution to the problem in Python. 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 # ----------------------------------------------------------------------------- # Students: As you work each of these problems, ask yourself: # 1. Do I need a loop? # If so, HOW MANY LOOPS? # # 2. Where I need a loop, what needs to happen: # -- BEFORE the loop? # -- IN the loop? # -- AFTER the loop? # ----------------------------------------------------------------------------- ############################################################################## # TODO: 2. Read the following, then change its _TODO_ to DONE. # Throughout these exercises, you must use RANGE statements. # At this point of the course, you are restricted to the SINGLE-ARGUMENT # form of RANGE statements, like this: # range(blah): # There is a MULTIPLE-ARGUMENT form of RANGE statements (e.g. range(a, b)) # but you are NOT permitted to use the MULTIPLE-ARGUMENT form yet, for # pedagogical reasons. Change the above _TODO_ to DONE after reading this. ############################################################################### def main(): """ Calls the TEST functions in this module. """ print("-----------------------------------------------") print("Un-comment each of the following TEST functions") print("as you implement the functions that they test.") print("-----------------------------------------------") # run_test_draw_parallel_lines() # run_test_draw_lines() def run_test_draw_parallel_lines(): """ Tests the draw_parallel_lines function. """ print() print("--------------------------------------------------") print("Testing the draw_parallel_lines function:") print(" See the graphics windows that pop up.") print("--------------------------------------------------") # ------------------------------------------------------------------------- # TWO tests on ONE window. # ------------------------------------------------------------------------- title = "Tests 1 and 2 of DRAW_PARALLEL_LINES:" title = title + " 4 long lines, 7 short lines" window1 = rg.RoseWindow(600, 350, title) # Test 1: left_most_point = rg.Point(400, 50) draw_parallel_lines(7, left_most_point, 100, window1) # Test 2: left_most_point = rg.Point(50, 200) draw_parallel_lines(4, left_most_point, 300, window1) window1.close_on_mouse_click() # ------------------------------------------------------------------------- # A third test on ANOTHER window. # ------------------------------------------------------------------------- title = "Test 3 of DRAW_PARALLEL_LINES: 12 very long lines!" window2 = rg.RoseWindow(500, 400, title) # Test 3: left_most_point = rg.Point(20, 20) draw_parallel_lines(12, left_most_point, 470, window2) window2.close_on_mouse_click() def draw_parallel_lines(n, point, length, window): """ What comes in: The four arguments are: -- A positive integer n. -- An rg.Point. -- A positive integer length. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See 1_draw_parallel_lines.pdf in this project for pictures that may help you better understand the following specification: Draws n rg.Lines parallel to each other, all on the given rg.RoseWindow, such that: -- The first rg.Line has its left-most end at the given rg.Point. -- Each rg.Line is a horizontal line (i.e., parallel to the x-axis). -- Each rg.Line has the given length. -- Each rg.Line is 30 pixels below the previous rg.Line. Must ** render ** but ** NOT close ** the window. Type hints: :type n: int :type point: rg.Point :type length: int :type window: rg.RoseWindow :rtype: None """ # ------------------------------------------------------------------------- # TODO: 3. 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 # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** # ######################################################################## # ------------------------------------------------------------------------- def run_test_draw_lines(): """ Tests the draw_lines function. """ print() print("--------------------------------------------------") print("Testing the draw_lines function:") print(" See the graphics windows that pop up.") print("--------------------------------------------------") # TWO tests on ONE window. title = "Tests 1 & 2 of DRAW_LINES: 4 lines, 12 lines!" window1 = rg.RoseWindow(350, 400, title) draw_lines(4, rg.Point(20, 120), window1) draw_lines(12, rg.Point(150, 230), window1) window1.close_on_mouse_click() # A third test on ANOTHER window. window2 = rg.RoseWindow(350, 300, "Test 3 of DRAW_LINES: 7 lines!") draw_lines(7, rg.Point(50, 120), window2) window2.close_on_mouse_click() def draw_lines(n, point, window): """ What comes in: The three arguments are: -- A integer n that is at least 2. -- An rg.Point. -- An rg.RoseWindow. What goes out: Nothing (i.e., None). Side effects: See 2_draw_lines.pdf in this project for pictures that may help you better understand the following specification: Draws n rg.Lines on the given rg.RoseWindow, such that: -- The leftmost point of each of the rg.Lines is the given rg.Point. -- For the rightmost point of each of the lines: -- Its x-coordinate is (pX + 100), where pX is the x-coordinate of the given rg.Point. -- The y-coordinates of the lines vary evenly from (pY - 100) to (pY + 100), where pY is the y-coordinate of the given rg.Point. Must ** render ** but ** NOT close ** the window. Type hints: :type n: int :type point: rg.Point :type window: rg.RoseWindow :rtype: None """ # ------------------------------------------------------------------------- # TODO: 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 # endpoints for each line, # ** FIRST DO A CONCRETE EXAMPLE BY HAND! ** # ######################################################################## # ------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Calls main to start the ball rolling. # ----------------------------------------------------------------------------- main()