""" A simple Line class. NOTE: This is NOT rosegraphics -- it is your OWN Line class. 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 math import m1t_test_Line as m1t ############################################################################### # IMPORTANT: # Your instructor will help you get started on this exercise. ############################################################################### # ----------------------------------------------------------------------------- # TODO: 2. Right-click on the src folder and # Mark Directory as ... Sources Root, # if you have not already done so. # _ # Then, with your instructor, READ THE INSTRUCTIONS in file # m0_INSTRUCTIONS.txt # asking questions as needed. Once you understand the instructions, # mark this _TODO_ as DONE. # ----------------------------------------------------------------------------- ############################################################################### # NOTE: For ALL of the methods that you implement, the method is allowed # to have additional side effects as needed by it and/or other methods. ############################################################################### def main(): """ Calls the TEST functions in this module, but ONLY if the method to be tested has at least a partial implementation. That is, a TEST function will not be called until you begin work on the code that it is testing. """ if m1t.is_implemented("__init__"): run_test_init() if m1t.is_implemented("clone"): run_test_clone() if m1t.is_implemented("reverse"): run_test_reverse() if m1t.is_implemented("slope"): run_test_slope() if m1t.is_implemented("length"): run_test_length() if m1t.is_implemented("get_number_of_clones"): run_test_get_number_of_clones() if m1t.is_implemented("line_plus"): run_test_line_plus() if m1t.is_implemented("line_minus"): run_test_line_minus() if m1t.is_implemented("midpoint"): run_test_midpoint() if m1t.is_implemented("is_parallel"): run_test_is_parallel() if m1t.is_implemented("reset"): run_test_reset() ############################################################################### # Students: # Do NOT touch the following Point class - it has no TO DO. # Do NOT copy code from the methods in this Point class. # # DO ** READ ** this Point class, # asking questions about any of it that you do not understand. # # DO ** CALL ** methods in this Point class as needed # in implementing and testing the methods of the ** Line ** class. # # IMPORTANT, IMPORTANT, IMPORTANT: # *** In your ** Line ** class methods, you should NEVER have code # *** that a ** Point ** class method could do for you. ############################################################################### # The Point class (and its methods) begins here. ############################################################################### class Point: """ Represents a point in 2-dimensional space. """ def __init__(self, x, y): """ Sets instance variables x and y to the given coordinates. """ self.x = x self.y = y def __repr__(self): """ Returns a string representation of this Point. For each coordinate (x and y), the representation: - Uses no decimal points if the number is close to an integer, - Else it uses 2 decimal places after the decimal point. Examples: Point(10, 3.14) Point(3.01, 2.99) """ decimal_places = 2 # Use 2 places after the decimal point formats = [] numbers = [] for coordinate in (self.x, self.y): if abs(coordinate - round(coordinate)) < (10 ** -decimal_places): # Treat it as an integer: formats.append("{}") numbers.append(round(coordinate)) else: # Treat it as a float to decimal_places decimal places: formats.append("{:." + str(decimal_places) + "f}") numbers.append(round(coordinate, decimal_places)) format_string = "Point(" + formats[0] + ", " + formats[1] + ")" return format_string.format(numbers[0], numbers[1]) def __eq__(self, p2): """ Defines == for Points: a == b is equivalent to a.__eq__(b). Treats two numbers as "equal" if they are within 6 decimal places of each other for both x and y coordinates. """ return (round(self.x, 6) == round(p2.x, 6) and round(self.y, 6) == round(p2.y, 6)) def clone(self): """ Returns a new Point at the same (x, y) as this Point. """ return Point(self.x, self.y) def distance_from(self, p2): """ Returns the distance this Point is from the given Point. """ dx_squared = (self.x - p2.x) ** 2 dy_squared = (self.y - p2.y) ** 2 return math.sqrt(dx_squared + dy_squared) def halfway_to(self, p2): """ Given another Point object p2, returns a new Point that is half-way between this Point and the given Point (p2). """ return Point((self.x + p2.x) / 2, (self.y + p2.y) / 2) def plus(self, p2): """ Returns a Point whose coordinates are those of this Point PLUS the given Point. For example: p1 = Point(500, 20) p2 = Point(100, 13) p3 = p1.plus(p2) print(p3) would print: Point(600, 33) """ return Point(self.x + p2.x, self.y + p2.y) def minus(self, p2): """ Returns a Point whose coordinates are those of this Point MINUS the given Point. For example: p1 = Point(500, 20) p2 = Point(100, 13) p3 = p1.minus(p2) print(p3) would print: Point(400, 7) """ return Point(self.x - p2.x, self.y - p2.y) ############################################################################### # The Line class (and its methods) begins here. ############################################################################### class Line: """ Represents a line segment in 2-dimensional space. """ def __init__(self, start, end): """ What comes in: -- self -- a Point object named start -- a Point object named end where the two Points are to be the initial start and end points, respectively, of this Line. What goes out: Nothing (i.e., None). Side effects: MUTATEs this Line by setting two instance variables named: -- start -- end to CLONES of the two Point arguments, respectively. Other methods must maintain those instance variables as needed so that they always indicate the CURRENT start and end points of this Line. Also, initializes other instance variables as needed by other Line methods. Example: This __init__ method runs when one constructs a Line. So the 3rd of the following statements invokes the __init__ method of this Line class: p1 = Point(30, 17) p2 = Point(50, 80) line = Line(p1, p2) # Causes __init__ to run print(line.start) # Should print Point(30, 17) print(line.end) # Should print Point(50, 80) print(line.start == p1) # Should print True print(line.start is p1) # Should print False Type hints: :type start: Point :type end: Point """ # --------------------------------------------------------------------- # TODO: 3. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def __repr__(self): """ What comes in: -- self What goes out: Returns a string representation of this Line, in the form: Line[(x1, y1), (x2, y2)] Side effects: None. Note: print(BLAH) causes BLAH's __repr__ to be called. BLAH's __repr__ returns a string, which the print function then prints. Example: Since the print function calls __repr__ on the object to be printed: p1 = Point(30, 17) p2 = Point(50, 80) line = Line(p1, p2) # Causes __init__ to run # The following statement causes __repr__ to run, # hence should print: Line[(30, 17), (50, 80)] print(line) Type hints: :rtype: str """ # --------------------------------------------------------------------- # We have already implemented this __repr__ function for you. # Do NOT modify it. # --------------------------------------------------------------------- start = repr(self.start).replace("Point", "") end = repr(self.end).replace("Point", "") return "Line[{}, {}]".format(start, end) def __eq__(self, line2): """ What comes in: -- self -- a Line object What goes out: Returns True if: this Line's start point is equal to line2's start point AND this Line's end point is equal to line2's end point. Returns False otherwise. Side effects: None. Note: a == b is equivalent to a.__eq__(b). Examples: p1 = Point(30, 17) p2 = Point(50, 80) line1 = Line(p1, p2) line2 = Line(p1, p2) line3 = Line(p2, p1) print(line1 == line1) # Should print: True print(line1 == line2) # Should print: True print(line1 == line3) # Should print: False line1.start = Point(0, 0) print(line1 == line2) # Should now print: False Type hints: :type line2: Line :rtype: bool """ # --------------------------------------------------------------------- # We have already implemented this __eq__ function for you. # Do NOT modify it. # --------------------------------------------------------------------- return (self.start == line2.start) and (self.end == line2.end) def clone(self): """ What comes in: -- self What goes out: Returns a new Line whose START is a clone of this Line's START and whose END is a clone of this Line's END. Side effects: None. Example: p1 = Point(30, 17) p2 = Point(50, 80) line1 = Line(p1, p2) line2 = line1.clone() print(line1) # Should print: Line[(30, 17), (50, 80)] print(line2) # Should print: Line[(30, 17), (50, 80)] print(line1 == line2) # Should print: True print(line1 is line2) # Should print: False print(line1.start is line2.start) # Should print: False print(line1.end is line2.end) # Should print: False line1.start = Point(11, 12) print(line1) # Should print: Line[(11, 12), (50, 80)] print(line2) # Should print: Line[(30, 17), (50, 80)] print(line1 == line2) # Should now print: False Type hints: :rtype: Line """ # --------------------------------------------------------------------- # TODO: 4. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def reverse(self): """ What comes in: -- self What goes out: Nothing (i.e., None). Side effects: MUTATES this Line so that its direction is reversed (that is, its start and end points are swapped). ** Must NOT mutate its start and end points -- just SWAP them. ** Examples: p1 = Point(30, 17) p2 = Point(50, 80) line1 = Line(p1, p2) line2 = line1.clone() print(line1) # Should print: Line[(30, 17), (50, 80)] line1.reverse() print(line1) # Should print: Line[(50, 80), (30, 17)] print(line1 == line2) # Should print: False line1.reverse() print(line1 == line2) # Should now print: True """ # --------------------------------------------------------------------- # TODO: 5. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def slope(self): """ What comes in: -- self What goes out: Returns the slope of this Line, or math.inf if the line is vertical (i.e., has "infinite" slope). Side effects: None. Examples: p1 = Point(30, 3) p2 = Point(50, 8) line1 = Line(p1, p2) # Since the slope is (8 - 3) / (50 - 30) , which is 0.25: print(line1.slope()) # Should print [approximately]: 0.25 line2 = Line(Point(10, 10), Point(10, 5)) print(line2.slope()) # Should print: inf # math.inf is NOT the STRING "inf", so: print(line2.slope() == "inf") # Should print False Type hints: :rtype: float """ # --------------------------------------------------------------------- # TODO: 6. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def length(self): """ What comes in: -- self What goes out: Returns the length of this Line. Side effects: None. Example: p1 = Point(166, 10) p2 = Point(100, 10) line1 = Line(p1, p2) # Since the distance from p1 to p2 is 66: print(line1.length()) # Should print: 66.0 p3 = Point(0, 0) p4 = Point(3, 4) line2 = Line(p3, p4) print(line2.length()) # Should print about 5.0 Type hints: :rtype: float """ # --------------------------------------------------------------------- # TODO: 7. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def get_number_of_clones(self): """ What comes in: -- self What goes out: -- Returns the number of times that this Line has been cloned (via the clone method). Side effects: None. Example: line1 = Line(Point(500, 20), Point(100, 8)) line2 = line1.clone() line3 = line1.clone() line4 = line3.clone() line5 = line1.clone() print(line1.get_number_of_clones()) print(line2.get_number_of_clones()) print(line3.get_number_of_clones()) print(line4.get_number_of_clones()) print(line5.get_number_of_clones()) would print: 3 [since there are three line1.clone() statements] 0 [since there are no line2.clone() statements] 1 [since there is one line3.clone() statement] 0 [since there are no line4.clone() statements] 0 [since there are no line5.clone() statements] Type hints: :rtype: int: """ # --------------------------------------------------------------------- # TODO: 8. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def line_plus(self, other_line): """ What comes in: -- self -- another Line object What goes out: -- Returns a Line whose: -- start is the sum of this Line's start (a Point) and the other_line's start (another Point). -- end is the sum of this Line's end (a Point) and the other_line's end (another Point). Side effects: None. Example: line1 = Line(Point(500, 20), Point(100, 8)) line2 = Line(Point(100, 13), Point(400, 8)) line3 = line1.line_plus(line2) print(line3) would print: Line[(600, 33), (500, 16)] Type hints: :type other_line: Line :rtype: Line: """ # --------------------------------------------------------------------- # TODO: 9. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def line_minus(self, other_line): """ What comes in: -- self -- another Line object What goes out: -- Returns a Line whose: -- start is this Line's start (a Point) minus the other_line's start (another Point). -- end is this Line's end (a Point) minus the other_line's end (another Point). Side effects: None. Example: line1 = Line(Point(500, 20), Point(100, 8)) line2 = Line(Point(100, 13), Point(400, 8)) line3 = line1.line_minus(line2) print(line3) would print: Line[(400, 7), (-300, 0)] Type hints: :type other_line: Line :rtype: Line: """ # --------------------------------------------------------------------- # TODO: 10. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def midpoint(self): """ What comes in: -- self What goes out: returns a Point at the midpoint of this Line. Side effects: None. Example: p1 = Point(3, 10) p2 = Point(9, 20) line1 = Line(p1, p2) print(line1.midpoint()) # Should print: Point(6, 15) Type hints: :rtype: Point """ # --------------------------------------------------------------------- # TODO: 11. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- def is_parallel(self, line2): """ What comes in: -- self -- another Line object (line2) What goes out: Returns True if this Line is parallel to the given Line (line2). Returns False otherwise. *** SEE THE IMPORTANT NOTE BELOW, re ROUNDING numbers. Side effects: None. Examples: line1 = Line(Point(15, 30), Point(17, 50)) # slope is 10.0 line2 = Line(Point(10, 10), Point(15, 60)) # slope is 10.0 line3 = Line(Point(10, 10), Point(80, 80)) # slope is 7.0 line4 = Line(Point(10, 10), Point(10, 20)) # slope is inf print(line1.is_parallel(line2)) # Should print: True print(line2.is_parallel(line1)) # Should print: True print(line1.is_parallel(line3)) # Should print: False print(line1.is_parallel(line4)) # Should print: False print(line1.is_parallel(line1)) # Should print: True print(line4.is_parallel(line4)) # Should print: True Type hints: :type line2: Line :rtype: bool """ # --------------------------------------------------------------------- # TODO: 12. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # ################################################################### # IMPORTANT: When you test whether two FLOATING POINT numbers # are "equal", you must deal with the imprecision # of floating-point arithmetic. For example, in REAL arithmetic, # 1 / (24 * math.pi - 20 * math.pi) # and # 3 / (72 * math.pi - 60 * math.pi) # are equal. But in FLOATING point arithmetic, they are: # 0.07957747154594767 # and # 0.07957747154594765 # respectively (hence NOT equal). # Try it out if you don't believe me! # _ # IMPORTANT BOTTOM-LINE: When you want to test whether two # FLOATING POINT numbers a and b are the same, # as in this method, DON'T use: a == b # INSTEAD use: round(a, 12) == round(b, 12) # _ # The latter compares the numbers rounded to 12 decimal places. # In the context of this exercise, doing so is adequate to ignore # floating-point errors while distinguishing numbers that really # are different from each other. ####################################################################### def reset(self): """ What comes in: -- self What goes out: Nothing (i.e., None). Side effects: MUTATES this Line so that its start and end points revert to what they were when this Line was constructed. Examples: p1 = Point(-3, -4) p2 = Point(3, 4) line1 = Line(p1, p2) line2 = Line(Point(0, 1), Point(10, 20)) ... [various actions, including some like these:] line1.start = Point(100, 300) line2.end = Point(99, 4) line1.reverse() # Should print: Line[(x1, y1), (x2, y2)] where (x1, y1) and # (x2, y2) are the CURRENT coordinates of line1's endpoints. print(line1) print(line2) # Similarly for line2 line1.reset() line2.reset() print(line1) # Should print: Line[(-3, -4), (3, 4)] print(line2) # Should print: Line[(0, 1), (10, 20)] """ # --------------------------------------------------------------------- # TODO: 13. # a. READ the above specification, including the Example. # ** ASK QUESTIONS AS NEEDED. ** # ** Be sure you understand it, ESPECIALLY the Example. # b. Implement and test this method. # The tests are already written (below). # They include the Example in the above doc-string. # --------------------------------------------------------------------- ############################################################################### # The TEST functions for the Line class begin here. # # We have already written the TEST functions. They all take the form: # -- m1t.run_test_BLAH() # This runs OUR tests. # -- One more test (or set of tests) that came directly from the Example # in the specification. ############################################################################### def run_test_init(): """ Tests the __init__ method of the Line class. """ m1t.run_test_init() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(30, 17) p2 = Point(50, 80) line = Line(p1, p2) # Causes __init__ to run print(line.start) # Should print Point(30, 17) print(line.end) # Should print Point(50, 80) print(line.start == p1) # Should print True print(line.start is p1) # Should print False print("The above should print:") print(" Point(30, 17)") print(" Point(50, 80)") print(" True") print(" False") def run_test_clone(): """ Tests the clone method of the Line class. """ m1t.run_test_clone() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(30, 17) p2 = Point(50, 80) line1 = Line(p1, p2) line2 = line1.clone() print(line1) # Should print: Line[(30, 17), (50, 80)] print(line2) # Should print: Line[(30, 17), (50, 80)] print(line1 == line2) # Should print: True print(line1 is line2) # Should print: False print(line1.start is line2.start) # Should print: False print(line1.end is line2.end) # Should print: False line1.start = Point(11, 12) print(line1) # Should print: Line[(11, 12), (50, 80)] print(line2) # Should print: Line[(30, 17), (50, 80)] print(line1 == line2) # Should now print: False print("The above should print:") print(" Line[(30, 17), (50, 80)]") print(" Line[(30, 17), (50, 80)]") print(" True") print(" False") print(" False") print(" False") print(" Line[(11, 12), (50, 80)]") print(" Line[(30, 17), (50, 80)") print(" False") def run_test_reverse(): """ Tests the reverse method of the Line class. """ m1t.run_test_reverse() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(30, 17) p2 = Point(50, 80) line1 = Line(p1, p2) line2 = line1.clone() print(line1) # Should print: Line[(30, 17), (50, 80)] line1.reverse() print(line1) # Should print: Line[(50, 80), (30, 17)] print(line1 == line2) # Should print: False line1.reverse() print(line1 == line2) # Should now print: True print("The above should print:") print(" Line[(30, 17), (50, 80)]") print(" Line[(50, 80), (30, 17)") print(" False") print(" True") def run_test_slope(): """ Tests the slope method of the Line class. """ m1t.run_test_slope() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(30, 3) p2 = Point(50, 8) line1 = Line(p1, p2) # Since the slope is (8 - 3) / (50 - 30) , which is 0.25: print(line1.slope()) # Should print [approximately]: 0.25 line2 = Line(Point(10, 10), Point(10, 5)) print(line2.slope()) # Should print: inf # math.inf is NOT the STRING "inf", so: print(line2.slope() == "inf") # Should print False print("The above should print:") print(" 0.25 (approximately)") print(" inf") print(" False") def run_test_length(): """ Tests the length method of the Line class. """ m1t.run_test_length() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(166, 10) p2 = Point(100, 10) line1 = Line(p1, p2) # Since the distance from p1 to p2 is 66: print(line1.length()) # Should print: 66.0 p3 = Point(0, 0) p4 = Point(3, 4) line2 = Line(p3, p4) print(line2.length()) # Should print about 5.0 print("The above should print:") print(" 66.0") print(" 5.0 (approximately)") def run_test_get_number_of_clones(): """ Tests the get_number_of_clones method of the Line class. """ m1t.run_test_get_number_of_clones() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- line1 = Line(Point(500, 20), Point(100, 8)) line2 = line1.clone() line3 = line1.clone() line4 = line3.clone() line5 = line1.clone() print(line1.get_number_of_clones()) print(line2.get_number_of_clones()) print(line3.get_number_of_clones()) print(line4.get_number_of_clones()) print(line5.get_number_of_clones()) print("The above should print 3, then 0, then 1, then 0, then 0.") def run_test_line_plus(): """ Tests the line_plus method of the Line class. """ m1t.run_test_line_plus() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- line1 = Line(Point(500, 20), Point(100, 8)) line2 = Line(Point(100, 13), Point(400, 8)) line3 = line1.line_plus(line2) print(line3) print("The above should print: Line[(600, 33), (500, 16)]") def run_test_line_minus(): """ Tests the line_minus method of the Line class. """ m1t.run_test_line_minus() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- line1 = Line(Point(500, 20), Point(100, 8)) line2 = Line(Point(100, 13), Point(400, 8)) line3 = line1.line_minus(line2) print(line3) print("The above should print: Line[(400, 7), (-300, 0)]") def run_test_midpoint(): """ Tests the midpoint method of the Line class. """ m1t.run_test_midpoint() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(3, 10) p2 = Point(9, 20) line1 = Line(p1, p2) print(line1.midpoint()) # Should print: Point(6, 15) print("The above should print: Point(6, 15)") def run_test_is_parallel(): """ Tests the is_parallel method of the Line class. """ m1t.run_test_is_parallel() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- line1 = Line(Point(15, 30), Point(17, 50)) # slope is 10.0 line2 = Line(Point(10, 10), Point(15, 60)) # slope is 10.0 line3 = Line(Point(10, 10), Point(80, 80)) # slope is 7.0 line4 = Line(Point(10, 10), Point(10, 20)) # slope is inf print(line1.is_parallel(line2)) # Should print: True print(line2.is_parallel(line1)) # Should print: True print(line1.is_parallel(line3)) # Should print: False print(line1.is_parallel(line4)) # Should print: False print(line1.is_parallel(line1)) # Should print: True print(line4.is_parallel(line4)) # Should print: True print("The above should print:") print(" True, True, False, False, True, True") def run_test_reset(): """ Tests the reset method of the Line class. """ m1t.run_test_reset() # This runs OUR tests. # ------------------------------------------------------------------------- # One ADDITIONAL test (or set of tests). # ------------------------------------------------------------------------- p1 = Point(-3, -4) p2 = Point(3, 4) line1 = Line(p1, p2) line2 = Line(Point(0, 1), Point(10, 20)) line1.start = Point(100, 300) line2.end = Point(99, 4) line1.reverse() # Should print: Line[(x1, y1), (x2, y2)] where (x1, y1) and # (x2, y2) are the CURRENT coordinates of line1's endpoints. print(line1) print(line2) # Similarly for line2 line1.reset() line2.reset() print(line1) # Should print: Line[(-3, -4), (3, 4)] print(line2) # Should print: Line[(0, 1), (10, 20)] print("The above should print:") print(" Line[(3, 4), (100, 300)]") print(" Line[(0, 1), (99, 4)]") print(" Line[(-3, -4), (3, 4)]") print(" Line[(0, 1), (10, 20)]") # ----------------------------------------------------------------------------- # If this module is running at the top level (as opposed to being # imported by another module), then call the "main" function. # It is necessary here to enable the automatic testing in m1t_test_Line.py. # ----------------------------------------------------------------------------- if __name__ == "__main__": main()