WEEK10: recursion
---------------------------------------------------------------
 M: recursive functions

GETTING USER INPUT:

def getChar():
  c = raw_input("char: ")
  if len(c) == 1:
    return c
  else:
    print "please enter just one character..."
    return getChar()


- uses recursion instead of for loop or while loop
- base case: if len(c) == 1  (stops the recursion!)


FACTORIAL EXAMPLE:

math definition:

 n! = 1 if n is 0, n*(n-1)! if n is greater than 0

easy to express this using recursion:

def factorial(n):
  if n == 0:
    return 1
  else:
    return n * factorial(n-1)

 - try running /home/jk/inclass/factorialstack.py to see the stack
   for the recursive factorial function:

$ python factorialstack.py

please enter a positive integer...
           n: 4
-------------------------------
  in factorial...stacknum = 1, n = 4
  calling 4 * factorial(3)
    in factorial...stacknum = 2, n = 3
    calling 3 * factorial(2)
      in factorial...stacknum = 3, n = 2
      calling 2 * factorial(1)
        in factorial...stacknum = 4, n = 1
        calling 1 * factorial(0)
          in factorial...stacknum = 5, n = 0
          returning 1
        returning 1 
      returning 2 
    returning 6 
  returning 24 
factorial(n): 24


REVERSE A STRING:

 - can you write a recursive function to reverse a string?

$ python revstr.py 
  string: we love computer science
  reversed: ecneics retupmoc evol ew

 Hint: if you have a string, s, and a working recursive revstr 
 function, what will revstr(s[1:]) + s[0] give you??

 What is the base case/stop-the-recursion condition for this one??

def revstr(str):
  """ Use recursion to reverse a given string.  """
  if len(str) <= 1:
    return str
  else:
    return revstr(str[1:]) + str[0]

 and just for fun, here is the non-recursive version:

def NRrevstr(str):
  """ Non-Recursive version """
  rs = ""
  for i in range(len(str)-1, -1, -1):
    rs = rs + str[i]
  return rs


GRAPHICS:

 - can you write a recursive function to draw concentric circles?
   here's how it would be called from main: 

    reccircle(cenpt, size, color, win)

   your function should draw a circle at the given center point,
   with the given size and color, then call itself again with a
   smaller size.

   when should the recursion end? 


def reccircle(p, radius, color, w):
  """ draw recursive circles """
  if radius > 1:
    c = Circle(p, radius)
    c.setOutline(color)
    c.draw(w)
    reccircle(p, radius*0.45, color, w)

So far all of the recursive functions we have looked at could easily be written without recursion. How about the following image? Can you think of ways to create it with and without recursion?

circles pic