# ex10PhillConrad.py Example submission for ex10, CS5nm, 08F # Phill Conrad for CS5nm, Fall 2008 10/20/2008 # Load up the TurtleWorld Software import sys sys.path.append("/Users/pconrad/CS5NM/swampy.1.1") # change this if needed from TurtleWorld import * import math # we need this for math.fabs, math.pi, and math.tan # check_expect_within_tolerance # checks whether a function produces the expected result # but allows some degree of inaccuracy (a "tolerance") # in cases where calculating the exact result may not be feasible # (e.g. quantities involving pi, square roots, etc.) # consumes: # test: a string describing the test # check: the value we are testing (typically result of a function call) # expect: the value we are expecting (typically a literal value) # toleranace: the largest inaccuracy that is permitted # produces: # nothing (there is no return value) # side effect: # prints a message indicating whether the test passed or failed def check_expect_within_tolerance(test,check,expect,tolerance): if (math.fabs(check-expect) <= tolerance): print "Test " + test + " passed (with tolerance " + \ str(tolerance) + ")" else: print "Test " + test + " failed: expected " + str(expect) + \ " but I got " + str(check) + " (tolerance of " + \ str(tolerance) + " exceeded)" # radiansToDegrees converts degrees to radians # consumes: radians, the number of radians in some angle # produces: degrees, the number of degrees in an equivalent angle def radiansToDegrees(radians): return radians / math.pi * 180.0; check_expect_within_tolerance("radiansToDegrees test 1", radiansToDegrees(math.pi), 180.0, 0.0001) # 180 degrees is "pi" radians check_expect_within_tolerance("radiansToDegrees test 2", radiansToDegrees(2 * math.pi), 360.0, 0.0001) # 360 degrees is "2*pi" radians check_expect_within_tolerance("radiansToDegrees test 3", radiansToDegrees(0.5 * math.pi), 90.0, 0.0001) # 90 degrees is "pi/2.0" radians # house: draws a house using a turtle # consumes: t, a turtle # precondition: turtle is facing right, at the lower left hand corner # of where the house will be drawn def drawHouse(t,width,height): # Calculate the various dimensions of the house heightHousePart = height * (2.0/3.0) heightRoofPart = height * (1.0/3.0) lengthHalfRoof = math.sqrt( (width * 0.5)**2 + (heightRoofPart**2)) # the angle that the roof make with the house can be computed # by the inverse of the tangent function # (tangent is "opposite over adjacent") # (arctangent is "what angle makes this ratio of opposite over adjacent?") roofAngleRadians = math.atan(heightRoofPart/(width * 0.5)) # convert from radians to degrees roofHouseAngleDegrees = radiansToDegrees(roofAngleRadians) print "roofHouseAngleDegrees = ", print roofHouseAngleDegrees # the sum of the angles in a triangle is 180, so the point of the roof # can be found by subtracting the other two angles roofPointDegrees = 180 - (2.0 * roofHouseAngleDegrees) # Now we can start drawing fd(t,width) # draw the bottom edge lt(t) fd(t,heightHousePart) # draw the right edge lt(t) fd(t,width) # draw the line between the house and the roof lt(t) fd(t,heightHousePart) # draw the left edge lt(t,180) # turn around fd(t,heightHousePart) # draw back up the left edge # draw the roof rt(t,90-roofHouseAngleDegrees) # turn to the right fd(t,lengthHalfRoof) # left half of the roof # to make the "inside" of the angle be roofPointDegrees, we have to # "turn right" 180 - roofPointDegrees rt(t,180 - roofPointDegrees) # the point at the top of the house fd(t,lengthHalfRoof) # right half of the roof # to be tidy, let's put the turtle back at the starting point # we could probably make this more efficient rt(t,90-roofHouseAngleDegrees) # shoudl point turtle back down towards ground fd(t,heightHousePart) rt(t) fd(t,width) # draw back along the bottom rt(t,180) # turn back around world = TurtleWorld() # create a world (a screen) bob = Turtle() # create a turtle, and call him bob # bob.delay is the delay between moves. bob.delay = 1.0 # make a slow turtle (1.0 makes him slow, 0.01 is fast) #bob.delay = 0.01 # make a fast turtle drawHouse(bob,40,50) pu(bob) # pick up the pen bk(bob,100) pd(bob) # put down the pen drawHouse(bob,30,20) pu(bob) # pick up the pen rt(bob) fd(bob,50) lt(bob) pd(bob) # put down the pen drawHouse(bob,20,30) wait_for_user() # keep the screen open til we click the red X or circle to quit