473,386 Members | 1,924 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Recursion

Hi all. Need alittle help here. This is an example from "How to Think Like a
Computer Scientist: Learning with Python, Chapter 5". It's an open source
ebook, so if you feel like it you can find it here:
http://www.ibiblio.org/obp/thinkCSpy/

The example uses factorials to explain more complex recursion.

"Explanation From the Book Begins Here"++++++++++++++++++
def factorial(n):
if n == 0:
return 1
else:
recurse = factorial(n-1)
result = n * recurse
return result

The flow of execution is as follows.
If we call "factorial" with the value 3:

Since 3 is not 0, we take the second branch and calculate the factorial of n-1... Since 2 is not 0, we take the second branch and calculate the factorial of n-1... Since 1 is not 0, we take the second branch and calculate the factorial of n-1... Since 0 is 0, we take the first branch and return 1 without making any more recusive calls. The return value (1) is multiplied by n, which is 1, and the result is returned. The return value (1) is multiplied by n, which is 2, and the result is returned. The return value (2) is multiplied by n, which is 3, and the result, 6,

becomes the return value of the function that started the whole process.

"Example Ends Here"++++++++++++++++++++++++++++++++

I thought I understood what was going on untill "Since 0 is 0...", but after
that I get lost. Where are the variables being stored.
And how does 1*1=2 ---> The return value (1) is multiplied by n, which is 1,
and the result is returned. The return value (1) is multiplied by n, which
is 2, and the result is returned.
Sorry if I explained my problem oddly. You can see the example in the above
link, under chapter 5.
Jul 18 '05 #1
8 1868
> "Explanation From the Book Begins Here"++++++++++++++++++
def factorial(n):
if n == 0:
return 1
else:
recurse = factorial(n-1)
result = n * recurse
return result

The flow of execution is as follows.
If we call "factorial" with the value 3:

Since 3 is not 0, we take the second branch and calculate the
factorial of n-1...
Since 2 is not 0, we take the second branch and calculate
the factorial of n-1...
Since 1 is not 0, we take the second branch and calculate
the factorial of n-1...
Since 0 is 0, we take the first branch and return 1
without making any more recusive calls.
The return value (1) is multiplied by n, which is 1,
and the result is returned.
The return value (1) is multiplied by n, which is 2, and the
result is returned.
The return value (2) is multiplied by n, which is 3, and the
result, 6, becomes the return value of the function that started
the whole process.
"Example Ends Here"++++++++++++++++++++++++++++++++

On Mon, Sep 29, 2003 at 12:48:29AM +0000, Jakle wrote: I thought I understood what was going on untill "Since 0 is 0...", but after
that I get lost. Where are the variables being stored.


Each separate invocation of 'factorial' has an associated value for a
variable named 'n'. So on the 'Since 0 is 0' step, there are 4
invocations of 'factorial', one with n==0, one with n==1, etc. This is
what 3.10 "Variables and parameters are local" intends to explain:

| When you create a local variable inside a function, it only exists
| inside the function, and you cannot use it outside. For example:
|
| def catTwice(part1, part2):
| cat = part1 + part2
| printTwice(cat)
|
| This function takes two arguments, concatenates them, and then prints
| the result twice. We can call the function with two strings:
|
| >>> chant1 = "Pie Jesu domine, "
| >>> chant2 = "Dona eis requiem."
| >>> catTwice(chant1, chant2)
| Pie Jesu domine, Dona eis requiem. Pie Jesu domine, Dona eis requiem.
|
| When catTwice terminates, the variable cat is destroyed. If we try to
| print it, we get an error:
|
| >>> print cat
| NameError: cat
|
| Parameters are also local. For example, outside the function printTwice,
| there is no such thing as bruce. If you try to use it, Python will
| complain.

So not only do catTwice and printTwice have different local names, each
invocation of catTwice (or factorial) has its own values for local
names.

Jeff

Jul 18 '05 #2
>Subject: Recursion
From: "Jakle" ja****@hotmail.com
Date: 9/28/2003 7:48 PM Central Standard Time
Message-id: <xj******************@news1.news.adelphia.net>

Hi all. Need alittle help here. This is an example from "How to Think Like a
Computer Scientist: Learning with Python, Chapter 5". It's an open source
ebook, so if you feel like it you can find it here:
http://www.ibiblio.org/obp/thinkCSpy/

The example uses factorials to explain more complex recursion.

"Explanation From the Book Begins Here"++++++++++++++++++
def factorial(n):
if n == 0:
return 1
else:
recurse = factorial(n-1)
result = n * recurse
return result

The flow of execution is as follows.
If we call "factorial" with the value 3:

Since 3 is not 0, we take the second branch and calculate the factorialof n-1...
Since 2 is not 0, we take the second branch and calculate the

factorial of n-1...
Since 1 is not 0, we take the second branch and calculate the

factorial of n-1...
Since 0 is 0, we take the first branch and return 1 without

making any more recusive calls.
The return value (1) is multiplied by n, which is 1, and the

result is returned.
The return value (1) is multiplied by n, which is 2, and the result

is returned.
The return value (2) is multiplied by n, which is 3, and the result, 6,

becomes the return value of the function that started the whole process.

"Example Ends Here"++++++++++++++++++++++++++++++++

I thought I understood what was going on untill "Since 0 is 0...", but after
that I get lost. Where are the variables being stored.
And how does 1*1=2 ---> The return value (1) is multiplied by n, which is 1,


You've made a mistake here. 1*1=1, not 2. You can always modify the
program to add some debugging aids. Here, I added a second parameter
to the function so we can track the level of recursion via indenting:

# start

def factorial(n,t):
print '\t'*t,'factorial of',n
if n == 0:
print "\t"*t,'result =',1
return 1
else:
recurse = factorial(n-1,t+1)
result = n * recurse
print "\t"*t,'result =',n,' * ',recurse,' = ',result
return result

# always make the intial call with the second parameter = 1

print factorial(3,1)

# end

The sample run produced is

factorial of 3
factorial of 2
factorial of 1
factorial of 0
result = 1
result = 1 * 1 = 1
result = 2 * 1 = 2
result = 3 * 2 = 6
6

There are four variables named 'n', one at each level of recursion, that's
why the 'result = ' formula keeps changing. The first parameter is 'n'
(from the line 'factorial of' at the same level of indentation) and the
second parameter is the result of the lower level of recursion.
Note that at no point are we getting 1*1=2.

Once you understand how it works, restore the function to its original form.
and the result is returned. The return value (1) is multiplied by n, which
is 2, and the result is returned.
Sorry if I explained my problem oddly. You can see the example in the above
link, under chapter 5.


--
Mensanator
2 of Clubs http://members.aol.com/mensanator666...s/2ofclubs.htm
Jul 18 '05 #3

That's great. You guys have no idea how much that helped. And I love that
debugging tip. For some reason I thought that the 2 statements after the
recursion call, "result = n * recurse" and "return result" weren't executed
till n == 0. If you can't tell, I'm new to this. But I'm dedicated. I want
to thank you guys soooo much for taking the time to help out. I'm sitting
here jumping for joy because it's alittle more clear :-) I can't wait till
it's me helping out in the future. I'm still alittle confused about why the
flow of execution goes down then up again, but I now have the tools to look
at it in a better light. Time to get my nose in the book again, then write
another function using the same logic in order to make sure I understand.
Thanks again :-)
Jul 18 '05 #4
Jakle fed this fish to the penguins on Sunday 28 September 2003 08:28
pm:

That's great. You guys have no idea how much that helped. And I love
that debugging tip. For some reason I thought that the 2 statements
after the recursion call, "result = n * recurse" and "return result"
weren't executed till n == 0. If you can't tell, I'm new to this. But
They aren't executed until the "first" return from factorial() --
which only happens when n /is/ 0... At that point, the recursive calls
start returning and executing the statements under the factorial() call.

To reduce indentation, I'll use just 3!

Factorial(3)
n has value 3
n is NOT 0 so
res= Factorial(n-1)
Factorial(2)
n has value 2
n is not 0 so
res= Factorial(n-1)
Factorial(1)
n has value 1
n is not 0 so
res= Factorial(n-1)
Factorial(0)
n has value 0
n IS 0 so
return 1
res is now 1
return n * res (1 * 1)
res is now 1
return n * res (2 * 1)
res is now 2
return n * res (3 * 2)

Factorial(3) returns value 6
Each time Factorial makes a recursive call to itself (I know, that is
redundant phrasing) it creates a new "block" of local variables, the
variables in the previous block can not be seen. When a return
statement is encountered, the block of locals is deleted, leaving the
return value visible to the calling block.
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #5
On Mon, 29 Sep 2003 06:06:37 GMT, Dennis Lee Bieber
<wl*****@ix.netcom.com> wrote:
Each time Factorial makes a recursive call to itself (I know, that is
redundant phrasing) it creates a new "block" of local variables, the
variables in the previous block can not be seen. When a return
statement is encountered, the block of locals is deleted, leaving the
return value visible to the calling block.


I can't remember if the tutorial points it out, but for jakle's sake I
should mention that this means that the recursive implementation of
factorial uses a lot more memory than a simple loop implementation
(and is probably a lot slower too). Factorials are useful for
teaching recursion, but it's not usually the best way to implement a
factorial function [1]. There are some applications that are not so
easy to implement as a loop, though (traversing a tree structure is
usually one of the first that nascent programmers encounter) and then
recursion starts being actually useful.

[1] Some languages depend on recursion much more than Python does, but
they will typically spot cases that can be converted to simple loops
and do that behind the scenes for efficiency.
Jul 18 '05 #6
On Mon, 29 Sep 2003 06:06:37 GMT, Dennis Lee Bieber <wl*****@ix.netcom.com> wrote:
Jakle fed this fish to the penguins on Sunday 28 September 2003 08:28
pm:

That's great. You guys have no idea how much that helped. And I love
that debugging tip. For some reason I thought that the 2 statements
after the recursion call, "result = n * recurse" and "return result"
weren't executed till n == 0. If you can't tell, I'm new to this. But


They aren't executed until the "first" return from factorial() --
which only happens when n /is/ 0... At that point, the recursive calls
start returning and executing the statements under the factorial() call.

To reduce indentation, I'll use just 3!

Factorial(3)
n has value 3
n is NOT 0 so
res= Factorial(n-1)
Factorial(2)
n has value 2
n is not 0 so
res= Factorial(n-1)
Factorial(1)
n has value 1
n is not 0 so
res= Factorial(n-1)
Factorial(0)
n has value 0
n IS 0 so
return 1
res is now 1
return n * res (1 * 1)
res is now 1
return n * res (2 * 1)
res is now 2
return n * res (3 * 2)

Factorial(3) returns value 6
Each time Factorial makes a recursive call to itself (I know, that is
redundant phrasing) it creates a new "block" of local variables, the
variables in the previous block can not be seen. When a return
statement is encountered, the block of locals is deleted, leaving the
return value visible to the calling block.

You didn't type that out by hand, did you? ;-)

====< showfact.py >=======================================
def showfact(n, indent=0):
sind = len(' res= Factorial(')*' '*indent
print '%sFactorial(%s)'%(sind, n)
print '%s n has value %s' %(sind, n)
print '%s n %s 0 so'%(sind, ('is not', 'IS')[n==0])
if n==0:
print '%s return 1' %sind
return 1
print '%s res= Factorial(n-1)'% sind
res = showfact(n-1, indent+1)
print '%s res is now %s' %(sind, res)
print '%s return n * res (%s * %s)' % (sind, n, res)
return n * res

def test(n):
print '\nFactorial(%s) returns value %s' % (n, showfact(n))

if __name__ == '__main__':
import sys
try: test(int(sys.argv[1]))
except: print 'Usage: showfact.py <integer arg>'
================================================== ========

[ 8:16] C:\pywk\clp>showfact.py
Usage: showfact.py <integer arg>

[ 8:16] C:\pywk\clp>showfact.py 2
Factorial(2)
n has value 2
n is not 0 so
res= Factorial(n-1)
Factorial(1)
n has value 1
n is not 0 so
res= Factorial(n-1)
Factorial(0)
n has value 0
n IS 0 so
return 1
res is now 1
return n * res (1 * 1)
res is now 1
return n * res (2 * 1)

Factorial(2) returns value 2
Regards,
Bengt Richter
Jul 18 '05 #7
Bengt Richter fed this fish to the penguins on Monday 29 September 2003
08:07 am:

You didn't type that out by hand, did you? ;-)
Yes, I did... It was bedtime for me, and I was designing the "output"
while typing it... <G>

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #8
On Mon, 29 Sep 2003 16:37:23 GMT, rumours say that Dennis Lee Bieber
<wl*****@ix.netcom.com> might have written:
You didn't type that out by hand, did you? ;-)


Yes, I did... It was bedtime for me, and I was designing the "output"
while typing it... <G>


I am not sure if typing the text was 'harder' (that was Dennis), or
typing the program to produce the same text (that was Bengt, but anybody
would have guessed, right?)

PS I believe Bengt is one of the key persons in the newsgroup; somebody
tempts him enough, and his keyboard gets fire. It seems like 10Kloc are
but a piece of cake for Bengt, just a pass-time between lunch and
dinner... :) Maybe he *is* a Motie, after all.

Or perhaps I should someday post anonymously: "Hi, I'm a python newbie
and I want to write the perfect operating system, stable, easy and
free", and then try to lure Bengt. Hm... Hope Billy G. doesn't read
the newsgroup.
--
TZOTZIOY, I speak England very best,
Microsoft Security Alert: the Matrix began as open source.
Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Peri | last post by:
I'm trying to create Python parser/interpreter using ANTLR. Reading grammar from language refference I found: or_expr::= xor_expr | or_expr "|" xor_expr For me it looks like infinite recursion....
12
by: da Vinci | last post by:
Greetings. I want to get everyone's opinion on the use of recursion. We covered it in class tonight and I want a good solid answer from people in the "know" on how well recursion is accepted...
43
by: Lorenzo Villari | last post by:
I've tried to transform this into a not recursive version but without luck... #include <stdio.h> void countdown(int p) { int x;
2
by: Csaba Gabor | last post by:
I suppose spring fever has hit at alt.math.undergrad since I didn't get any rise from them when I posted this a week ago, so I am reposting this to some of my favorite programming groups: I'm...
75
by: Sathyaish | last post by:
Can every problem that has an iterative solution also be expressed in terms of a recursive solution? I tried one example, and am in the process of trying out more examples, increasing their...
19
by: Kay Schluehr | last post by:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691
18
by: MTD | last post by:
Hello all, I've been messing about for fun creating a trial division factorizing function and I'm naturally interested in optimising it as much as possible. I've been told that iteration in...
13
by: robert | last post by:
My code does recursion loops through a couple of functions. Due to problematic I/O input this leads sometimes to "endless" recursions and after expensive I/O to the Python recursion exception. What...
20
by: athar.mirchi | last post by:
..plz define it.
35
by: Muzammil | last post by:
int harmonic(int n) { if (n=1) { return 1; } else { return harmonic(n-1)+1/n; } } can any help me ??
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.