# Recursion Lab Solutions # Spring 2020 # recursiveTurtles.py from turtle import * from turtleBeads import * # Tests are at the bottom in the run function. # ------------------------------------ # Task 1 # ------------------------------------ # Provided function. Version A: No loops, no recursion def square(length): ''' Draws a square of size length maintains heading and position invariant ''' fd(length) lt(90) fd(length) lt(90) fd(length) lt(90) fd(length) # back to starting location lt(90) # heading in same direction as start # Provided function. Version B: For loop, no recursion def square(length): ''' Draws a square of size length maintains heading and position invariant ''' for i in range(1,5): # or for i in range(4) fd(length) lt(90) # ------------------------------------ # Task 2 # ------------------------------------ def row(number, size): ''' Recursively draw a row of squares (like asteriskLine), maintains a position invariant ''' if (number > 0): square(size) fd(size) row(number-1,size) # recursive call bk(size) # maintain position invariant # ------------------------------------ # Task 3 # ------------------------------------ def spacedRow(number, size): ''' Recursively draw a row of squares with a constant space in between squares and maintians a posiion invariant ''' if (number > 0): square(size) # move to position to draw the next one pu() fd(size + size/4) pd() spacedRow(number-1,size)# recursive call # move back to original starting position (maintain position invariant) pu() bk(size+ size/4) pd() # ------------------------------------ # Task 4 # ------------------------------------ def decreasingRow(number, size): ''' Recursively draw a row of squares that get progressively smaller by 1/2 each time and maintains a position invariant ''' if (number > 0): square(size) fd(size) decreasingRow(number-1,size/2.)# recursive call bk(size) # maintain position invariant # ------------------------------------ # Task 5 -- omitted in Spring 19, but good extra practice! # ------------------------------------ def nestedSquares(number, size): ''' Recursively draw nested squares that get progressively smaller by 1/2 each time anchored in the lower left corner ''' if (number > 0): square(size) nestedSquares(number-1,size/2.)# recursive call # ------------------------------------ # Task 6 # ------------------------------------ def diagonal(number, size): ''' Recursively draw a diagonal row of squares that get progressively smaller by 1/2 each time where each successive square is anchored on the upper right corner of the previous square. Maintains a position invariant ''' if (number > 0): square(size) # move to position to draw next one fd(size) lt(90) fd(size) rt(90) diagonal(number-1,size/2.)# recursive call # move back: maintain position invariant -- # this block of 4 lines undo # the block of 4 lines (fd, lt, fd, rt) before the recursive call bk(size) lt(90) bk(size) rt(90) # ------------------------------------ # Task 6.5 # ------------------------------------ def doubleDiagonal(number, size): ''' Recursively draw a diagonal row of squares that get progressively smaller by 1/2 each time where each successive pair of squares is anchored on the upper right corner and the lower left corner of the previous square. Maintains a position invariant ''' if (number > 0): square(size) # move to position to draw next one from upper right corner fd(size) lt(90) fd(size) rt(90) doubleDiagonal(number-1,size/2.)# recursive call # move back: maintain position invariant -- this block of 4 lines undoes # the block of 4 lines (fd, lt, fd, rt) before the recursive call bk(size) lt(90) bk(size) rt(90) # Second recursive call from bottom left corner doubleDiagonal(number-1, size/2.) # No need to worry about position invariant, bc already back at # starting location, facing Right. # ------------------------------------ # Task 7 # ------------------------------------ def superDiagonal(number, size): ''' Recursively draw a row of squares that get progressively smaller by 1/2 each time where each successive square is anchored on the upper right corner of the previous square and the upper left corner of the previous square ''' if (number > 0): square(size) # back at lower left starting point # get into position for recursive call fd(size) lt(90) fd(size) rt(90) # recursive call for diagonal stemming from upper right corner # Note the 2. allows for more precision, e.g. if size is odd # then we get a more accurate half size. superDiagonal(number-1,size/2.) # first recursive call # maintain position invariant by undoing the steps before # the recursive call lt(90) bk(size) rt(90) bk(size) # back at lower left corner, facing East # draw the diagonal in the SouthWest direction lt(180) superDiagonal(number-1,size/2.) # second recursive call rt(180) def run(): setupTurtle() # move to lower left corner of canvas to draw teleport(-200,-200) pencolor('red') # Tests #square(100) #row(5, 100) #spacedRow(5, 100) #decreasingRow(5, 100) #nestedSquares(5, 100) doubleDiagonal(2, 200) #superDiagonal(5, 100) if __name__ == "__main__": run()