In [ ]:
#Today we will see more examples of functions
#calling each other.
#You have already seen an example of this
#in lecture 6.
#And at the very end, we will cover a new topic
#called recursion which we will cover tomorrow
#and next week. Read lecture 4 handout
#before class tomorrow.
#It will probably be confusing at first
#because it is a new topic.
#But you will understand it over time.

In [ ]:
#some other things that you might have forgotten.
#You can have a list of lists
#e.g.
x=[1,2,3,4,5] #what is x[0]
x=['a','b','c','d']
x=[[1,2],3,[4,5,6,7]]
#what is x[0]? [1,2]
#what is x[1]? 3
#what is x[2]? [4,5,6,7]
#what is len(x)? 3
#What is x[0][0]?
#  1 because x[0] is [1,2] and [1,2][0] is 1.
#what is x[0][1]? 2.
#what is len(x[0][0])?
#  Error because len(1) cannot use len on int.

In [104]:
#Say you want to swap the values of a and b.
#.e.g.
a=5
b=6

#a=b #now a is 6
#b=a #b=a now b is also 6
#new_a=a #new_a is 5
#a=b #now what is a? a is 6
#b=new_a #noew what is b? 5.

#and you want to have a=6 and b=5
#How would you do this?

a,b=b,a
print a
print b

6
5

In [ ]:
#Say you want to swap the values of a and b.
#.e.g.
a=5
b=6
#and you want to have a=6 and b=5
#How would you do this?
new_a=b
b=a
a=new_a

#an easy way to do this in python is
a,b=b,a

In [ ]:
#As we have seen before, one function can call another function.
#What does this function do?
#what is printed?
#Having more than one function
if h>50:
#print 'good'#True  <--Some people are confused by print Vs. return
return True
else:
return False

return 'candy'
else:
return 'no_candy'
#print y

#what is the value of y?

In [ ]:
#As we have seen before, one function can call another function.
#What does this function do?
#what is printed?
#Having more than one function
if h>50:
print 'good'#True  <--Some people are confused by print Vs. return
return True
else:
return False

return 'candy'
else:
return 'no_candy'
print y

#what is the value of y? Now? Rembmer
#whether or not we print something, this
#does not change
#the value of why.

In [ ]:
#In lab2, you have looked at the function
#isPalindrome which
#returns True if a given string is a palindrome.
#I.e., isPalindrome('abcde') returns False.
#returns False and isPalindrome('abcba')
#returns True.
#You have also seen a function called reverse
#that returns the reversed verion of a string.
#I give you a function called reverse. It takes in
#a string, and returns the reversed version of
#the string. So reverse('abcba') returns abcba.
#reverse('12345') returns '54321'.
#reverse(12345) gives an error.
#can you think of a way to create the function
#isPalindrom by using the function reverse?
#Like I said in lecture before,
#first try to write down in English
#how the function would work.
#.....

In [109]:
def Reverse(x):
y=''
for n in range(len(x)):
y += x[len(x)-n-1]
print y
return y

#def isPalindrome(x):
#    if Reverse(x)==x: #I am saying if None==x:
#        return True
#    else:
#        return False
#isPalindrome('abcba')

def isPalindrome(x):
return Reverse(x)==x
isPalindrome('abcba')

Out[109]:
True
In [111]:
5==5

Out[111]:
True
In [46]:
def isPalindrome(x):
if x==reverse(x):
return True
else:
return False

isPalindrome('123210')

Out[46]:
False
In [115]:
#Another way
def isPalindrome(x):
x=str(x)
return x==reverse(x)
#this does the same thing as the function
#isPalindrome above.
#why?
#if I give isPalindrome('12345') I want False
#if I give isPalindrome(12345) I want False
#if I give isPalindrome('abcba') I want True
#if I give isPalindrome(12321) I want True
#isPalindrome('12345')

Out[115]:
False
In [48]:
#Ok so now we want to have a function isPalindrome.
#However, we want it
#to be able to have a string or an int as an input.
#the function we wrote above can only take a string.
#what is the output of the code below?

def reverse(x):
y=''
for n in range(len(x)):
y += x[len(x)-n-1]
return y

def isPalindrome(x):
#x=str(x) #add this to use ints.
if x==reverse(x):
return True
else:
return False

isPalindrome(123210)

In [50]:
#We get a type error. Why? Because reverse only takes a string.
#where exactly is the error?
#1. We cannot use len on an int
#2. We cannot index into an int like this:
#       if x is an int we cannot say x[0]
#or x[1] etc...
#So how can we still have a function
#that takes a string or an int and returns
#whether or not that string or int is a palindrome?
#There are many ways of
#doing this. I will give you a few minutes to
#think of a few ways.

In [120]:
#One way to do this is to have 2 functions.
#One checks if a string is
#a palindrome. Another one checks if an int is
#a palindrome.
def reverse(x):
'''
This function takes a string. And returns
the reversed version of the string.
'''
y=''
for n in range(len(x)):
y += x[len(x)-n-1]
return y

def isStrPalindrome(x):
'''
This function takes a string and returns
True if the string is a palindrome. It returns
False otherwise.
'''
#return x==reverse(x)
#same as
if x==reverse(x):
return True
else:
return False

def isIntPalindrome(x):
'''
This function takes an int. And returns
True if the int is a plandrome. It returns
False otherwise.
'''
#what is I did x==reverse(x)
#return str(x)==reverse(str(x))
if str(x)==reverse(str(x)):
return True
else:
return False

def isPalindrome(x):
if type(x)==str:
#isStrPalindrome takes a string
#and returns True if the string is
#a palindrome. False if not.
return isStrPalindrome(x)

elif type(x)==int:
#isStrPalindrome takes a int
#and returns True if the int is
#a palindrome. False if not.
return isIntPalindrome(x)
else:
print 'Wrong data type'
return

y=isPalindrome(12.56)
print y

Wrong data type
None

In [ ]:
#Finally, we are going to cover recursion.
#This might be a hard concept to understand
#in the beginning. But with a little bit of
#practice,
#you'll get it.

In [ ]:
#Lets start with an example.
#consider the Fibonacci sequence
#1, 1, 2, 3, 5, 8, 13, . . ..
#This sequence is defined by the 0th and 1st
#Fibonacci numbers both being 1,
#and subsequent Fibonacci numbers being
#the sum of the previous two.

#The Fibonacci sequence is very well known in
#Math and
#appears frequently in nature.
#It also has applications
#in various computer science algorithms.

#We will not discuss the Fibonacci sequence
#in detail
#in this class but if you are interested in
#learning
#https://en.wikipedia.org/wiki/Fibonacci_number

In [ ]:
#The Fibonacci sequence is defined by the 0th
#and 1st
#Fibonacci numbers both being 1,
#and subsequent Fibonacci numbers being
#the sum of the previous two
#F(i) is 1 if i=0 or i=1
#
#F(i) is F(i−1) + F(i−2) otherwise

#So what is F(0)?
#    1 because i is 1
#What is F(1)?
#   1 because i is 1
#What is F(2)
#   It is F(i-1) + F(i-2)
#   which is 1+1=2
#F(3) is F(i-1)+F(i-2)=F(3-1)+F(3-2)
#   which is F(2)+F(1)=2+1=3
#F(4) is F(4-1)+F(4-2)=F(3)+F(2)=3+2=5
# ....And it continues this way

In [ ]:
##Now let us make a function that takes i and
#returns the ith Fibonacci number.
#We can do it the way we have learned how to.
#First we write in English how we want to create
#the function.

In [84]:
#Now let us make a function that takes i and
#returns the ith Fibonacci number.
#We can do it the way we have learned how to.
#lets call the function fibonacci
def fibonacci(i):
fib_i=1
fib_i_prev=1
fib_i_prev_prev=1

if i==0 or i==1:
return fib_i
for x in range(2,i+1):
fib_i = fib_i_prev + fib_i_prev_prev
fib_i_prev_prev=fib_i_prev
fib_i_prev=fib_i
return fib_i
fibonacci(3)

Out[84]:
3
In [60]:
#Although we could implement the Fibonacci sequence
#in a very complicated way without using recursion,
#the following function using recursion
#is very simple and easier to understand
def fibonacci(i):
if i<2:
return 1
return fibonacci(i-1) + fibonacci(i-2)
fibonacci(5)

#compare this function to the function we
#wrote above
#which is more complicated and hard to understand

Out[60]:
8
In [18]:
#Here is another example of a function that can
#be done recursively. Multiplying 2 numbers
a=5
b=3
a*b
#a*b gives 15 as you all know

Out[18]:
15
In [31]:
#We can implement the multiplication of 2 numbers
#a and b in as recursive function only using
#when you multiply 5*3, what do you do?
#5*3 is 5+5+5. The function below adds 5 to itself
#3 times. In genera, the function below takes
#inputs a and b and adds a to itself b times.
#This is the same as performing a*b.
def multiplyNumbers(a,b):
print a,b
if b == 0:
return 0
else:
return a + (multiplyNumbers(a,(b - 1)))
multiplyNumbers(5,3)
#we can print a and b to see how many times
#multiplyNumbers is called and what the inputs(a,b)
#are each time it is called.
#Remember printing something
#is different from returning something. We are
#printing all of these values to
#figure out what the function is doing.
#This does not change what the
#function is returning.

5 3
5 2
5 1
5 0

Out[31]:
15