473,324 Members | 2,531 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,324 software developers and data experts.

Adding through recursion

There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None

Martin

Nov 22 '05 #1
26 1476
any change you want to have :

"return add(x,y)" in the else ?
ma************@gmail.com wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None

Martin


Nov 22 '05 #2
any change you want to have :

"return add(x,y)" in the else ?
ma************@gmail.com wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None

Martin


Nov 22 '05 #3
On 18 Nov 2005 05:22:47 -0800, ma************@gmail.com
<ma************@gmail.com> wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None


Every function returns a value. If you don't use an explicit return
keyword, None is returned implicitly. You print the answer that you
are looking for from within your function, then print the return value
from that function, which, as I've explained, will be None.

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Nov 22 '05 #4
On 18 Nov 2005 05:22:47 -0800, ma************@gmail.com
<ma************@gmail.com> wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None


Every function returns a value. If you don't use an explicit return
keyword, None is returned implicitly. You print the answer that you
are looking for from within your function, then print the return value
from that function, which, as I've explained, will be None.

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Nov 22 '05 #5
"ma************@gmail.com" <ma************@gmail.com> writes:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None


Perhaps this hint will help:
print add(0,6)

6
6

--
Mark Jackson - http://www.alumni.caltech.edu/~mjackson
Of course a weed-puller isn't of much *use* in the Garden
of Eden, but it takes a while to figure that out.
- Tim Peters
Nov 22 '05 #6
"ma************@gmail.com" <ma************@gmail.com> writes:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None


Perhaps this hint will help:
print add(0,6)

6
6

--
Mark Jackson - http://www.alumni.caltech.edu/~mjackson
Of course a weed-puller isn't of much *use* in the Garden
of Eden, but it takes a while to figure that out.
- Tim Peters
Nov 22 '05 #7
basically the other two points :-)

you create a string of add functions

add(2,4)--add(1,5)--add(0,6)

only in the last ( add(0,6) ) explicitly returns y, in the else of
add(1,5) you ignor it. If you want the starting add to return something
sensible you need to find a way to pass it back up the function chain.

not tested
def add(x, y):
if x == 0:
sum = y
print sum
else:
x -= 1
y += 1
sum = add(x, y)
return sum

print add(2, 4)

ma************@gmail.com wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None

Martin

Nov 22 '05 #8
basically the other two points :-)

you create a string of add functions

add(2,4)--add(1,5)--add(0,6)

only in the last ( add(0,6) ) explicitly returns y, in the else of
add(1,5) you ignor it. If you want the starting add to return something
sensible you need to find a way to pass it back up the function chain.

not tested
def add(x, y):
if x == 0:
sum = y
print sum
else:
x -= 1
y += 1
sum = add(x, y)
return sum

print add(2, 4)

ma************@gmail.com wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)

result:
6
None

Martin

Nov 22 '05 #9
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?

Nov 22 '05 #10
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?

Nov 22 '05 #11
On 18 Nov 2005 06:30:58 -0800, ma************@gmail.com
<ma************@gmail.com> wrote:
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?


There is no return statement in your else block. That's where the
Nones are coming from.

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Nov 22 '05 #12
On 18 Nov 2005 06:30:58 -0800, ma************@gmail.com
<ma************@gmail.com> wrote:
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?


There is no return statement in your else block. That's where the
Nones are coming from.

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Nov 22 '05 #13

ma************@gmail.com wrote:
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?

Martin,

-a function should either return something or not. Your function has
two exit points, one explicitly returns a value, one doesn't (and so
defaults to returning None).

- trace through the function with pencil and paper for small values of
x and y

def add(x, y):
if x:
x -= 1
y += 1
add(x,y)
else:
print y
def ADD(x, y):
if x:
x -= 1
y += 1
return ADD(x,y)
else:
return y
add(5,6) 11ADD(5,6) 11
z = add(5,6) 11print z Nonez = ADD(5,6)
print z

11
Gerard

Nov 22 '05 #14

ma************@gmail.com wrote:
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?

Martin,

-a function should either return something or not. Your function has
two exit points, one explicitly returns a value, one doesn't (and so
defaults to returning None).

- trace through the function with pencil and paper for small values of
x and y

def add(x, y):
if x:
x -= 1
y += 1
add(x,y)
else:
print y
def ADD(x, y):
if x:
x -= 1
y += 1
return ADD(x,y)
else:
return y
add(5,6) 11ADD(5,6) 11
z = add(5,6) 11print z Nonez = ADD(5,6)
print z

11
Gerard

Nov 22 '05 #15
ma************@gmail.com wrote:
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?


because you're not returning the value to the print statement;
you're returning it to your own function, which throws it away.

if you add "raise Exception" to the "x == 0" path, you get this
traceback:

$ python add.py
6
Traceback (most recent call last):
File "add.py", line 10, in ?
print add(2, 4)
File "add.py", line 8, in add
add(x, y)
File "add.py", line 8, in add
add(x, y)
File "add.py", line 4, in add
raise Exception
Exception

which shows that you're a couple of levels down when you find
the right value. and since the "add(x, y)" call at line 8 throws
away the result, the "print" statement at line 10 will never see
it.

</F>

Nov 22 '05 #16
ma************@gmail.com wrote:
I still don't get it. I tried to test with x = 0 and found that to
work. How come since the value of y is right and it is printed right it
"turns into" None when returned by the return statement ?


because you're not returning the value to the print statement;
you're returning it to your own function, which throws it away.

if you add "raise Exception" to the "x == 0" path, you get this
traceback:

$ python add.py
6
Traceback (most recent call last):
File "add.py", line 10, in ?
print add(2, 4)
File "add.py", line 8, in add
add(x, y)
File "add.py", line 8, in add
add(x, y)
File "add.py", line 4, in add
raise Exception
Exception

which shows that you're a couple of levels down when you find
the right value. and since the "add(x, y)" call at line 8 throws
away the result, the "print" statement at line 10 will never see
it.

</F>

Nov 22 '05 #17
ma************@gmail.com wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)


One of the best things to do when you don't understand how a function is
working is to geneously sprinkle the code with tracing print statements:
def add(x, y): params = (x, y)
print "Starting Function", params
if x == 0:
print "x is zero", params
print y
return y
print "After Return", params
else:
print "Non-zero x", params
x -= 1
y += 1
print "Updated x & y", params, '->', (x,y)
add(x, y)
print "Should I be here?", params
print "Falling off end.", params

print add(2, 4)

Starting Function (2, 4)
Non-zero x (2, 4)
Updated x & y (2, 4) -> (1, 5)
Starting Function (1, 5)
Non-zero x (1, 5)
Updated x & y (1, 5) -> (0, 6)
Starting Function (0, 6)
x is zero (0, 6)
6
Should I be here? (1, 5)
Falling off end. (1, 5)
Should I be here? (2, 4)
Falling off end. (2, 4)
None
Nov 22 '05 #18
ma************@gmail.com wrote:
There is problaly a really simple answer to this, but why does this
function print the correct result but return "None":

def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)

print add(2, 4)


One of the best things to do when you don't understand how a function is
working is to geneously sprinkle the code with tracing print statements:
def add(x, y): params = (x, y)
print "Starting Function", params
if x == 0:
print "x is zero", params
print y
return y
print "After Return", params
else:
print "Non-zero x", params
x -= 1
y += 1
print "Updated x & y", params, '->', (x,y)
add(x, y)
print "Should I be here?", params
print "Falling off end.", params

print add(2, 4)

Starting Function (2, 4)
Non-zero x (2, 4)
Updated x & y (2, 4) -> (1, 5)
Starting Function (1, 5)
Non-zero x (1, 5)
Updated x & y (1, 5) -> (0, 6)
Starting Function (0, 6)
x is zero (0, 6)
6
Should I be here? (1, 5)
Falling off end. (1, 5)
Should I be here? (2, 4)
Falling off end. (2, 4)
None
Nov 22 '05 #19
ma************@gmail.com <ma************@gmail.com> wrote:
def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)


To add to the other good advice in this thread:

This is just one of many reasons why I advocate always having a
*single* return statement, at the *end* of the function. I usually
start out writing my function setting a default return value, and the
return statement immediately below.

In your case, the default return value is None, so let's make that
explicit.

def recursive_add(x, y):
result = None
return result

Then, the rest of the function's responsibility is about changing that
default value if necessary.

def recursive_add(x, y):
result = None
if x == 0:
print y
result = y
else:
x -= 1
y += 1
recursive_add(x, y)
return result

With this structure, it becomes quickly obvious what's gone wrong: one
of the branches is not changing the default return value.

def recursive_add(x, y):
if x == 0:
print y
result = y
else:
x -= 1
y += 1
result = recursive_add(x, y)
return result

I find this much less error-prone than hiding return statements in
branches throughout the function; if the only return statement is at
the very end of the function, it becomes much easier to read.

--
\ "If you go to a costume party at your boss's house, wouldn't |
`\ you think a good costume would be to dress up like the boss's |
_o__) wife? Trust me, it's not." -- Jack Handey |
Ben Finney
Nov 22 '05 #20
ma************@gmail.com <ma************@gmail.com> wrote:
def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)


To add to the other good advice in this thread:

This is just one of many reasons why I advocate always having a
*single* return statement, at the *end* of the function. I usually
start out writing my function setting a default return value, and the
return statement immediately below.

In your case, the default return value is None, so let's make that
explicit.

def recursive_add(x, y):
result = None
return result

Then, the rest of the function's responsibility is about changing that
default value if necessary.

def recursive_add(x, y):
result = None
if x == 0:
print y
result = y
else:
x -= 1
y += 1
recursive_add(x, y)
return result

With this structure, it becomes quickly obvious what's gone wrong: one
of the branches is not changing the default return value.

def recursive_add(x, y):
if x == 0:
print y
result = y
else:
x -= 1
y += 1
result = recursive_add(x, y)
return result

I find this much less error-prone than hiding return statements in
branches throughout the function; if the only return statement is at
the very end of the function, it becomes much easier to read.

--
\ "If you go to a costume party at your boss's house, wouldn't |
`\ you think a good costume would be to dress up like the boss's |
_o__) wife? Trust me, it's not." -- Jack Handey |
Ben Finney
Nov 22 '05 #21
On Nov 19, Ben Finney wrote:
...
This is just one of many reasons why I advocate always having a
*single* return statement, at the *end* of the function.


Agreed that it's a good *general* practice, but sometimes early exit
is useful and clear.

This is somewhat of a religious topic. A good discussion is:
http://c2.com/cgi/wiki?SingleFunctionExitPoint

pychecker warns of fall-off-the-end functions.

--
_ _ ___
|V|icah |- lliott <>< md*@micah.elliott.name
" " """
Nov 22 '05 #22
On Nov 19, Ben Finney wrote:
...
This is just one of many reasons why I advocate always having a
*single* return statement, at the *end* of the function.


Agreed that it's a good *general* practice, but sometimes early exit
is useful and clear.

This is somewhat of a religious topic. A good discussion is:
http://c2.com/cgi/wiki?SingleFunctionExitPoint

pychecker warns of fall-off-the-end functions.

--
_ _ ___
|V|icah |- lliott <>< md*@micah.elliott.name
" " """
Nov 22 '05 #23
In article <dl**********@rose.polar.local>,
Ben Finney <bi****************@benfinney.id.au> wrote:
ma************@gmail.com <ma************@gmail.com> wrote:
def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)
.... def recursive_add(x, y):
if x == 0:
print y
result = y
else:
x -= 1
y += 1
result = recursive_add(x, y)
return result

I find this much less error-prone than hiding return statements in
branches throughout the function; if the only return statement is at
the very end of the function, it becomes much easier to read.


Well, it's sure clearer where it returns. On the other
hand, now you have to analyze the block structure to
know that the 3rd line assignment is still going to be
in effect when you get to the return. That's easy in
this case, of course, but make the structure more complex
and add a loop or too, and it can be hard. Where if you
see a return statement, you know for sure.

State variables are analogous to goto in a way, similar
sort of spaghetti potential. It may or may not help to
have all the strands come out at the same spot, if the
route to that spot could be complicated.

Donn Cave, do**@u.washington.edu
Nov 22 '05 #24
In article <dl**********@rose.polar.local>,
Ben Finney <bi****************@benfinney.id.au> wrote:
ma************@gmail.com <ma************@gmail.com> wrote:
def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)
.... def recursive_add(x, y):
if x == 0:
print y
result = y
else:
x -= 1
y += 1
result = recursive_add(x, y)
return result

I find this much less error-prone than hiding return statements in
branches throughout the function; if the only return statement is at
the very end of the function, it becomes much easier to read.


Well, it's sure clearer where it returns. On the other
hand, now you have to analyze the block structure to
know that the 3rd line assignment is still going to be
in effect when you get to the return. That's easy in
this case, of course, but make the structure more complex
and add a loop or too, and it can be hard. Where if you
see a return statement, you know for sure.

State variables are analogous to goto in a way, similar
sort of spaghetti potential. It may or may not help to
have all the strands come out at the same spot, if the
route to that spot could be complicated.

Donn Cave, do**@u.washington.edu
Nov 22 '05 #25

Ben Finney wrote:
ma************@gmail.com <ma************@gmail.com> wrote:
def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)


To add to the other good advice in this thread:

This is just one of many reasons why I advocate always having a
*single* return statement, at the *end* of the function. I usually
start out writing my function setting a default return value, and the
return statement immediately below.

In your case, the default return value is None, so let's make that
explicit.

def recursive_add(x, y):
result = None
return result

Then, the rest of the function's responsibility is about changing that
default value if necessary.

def recursive_add(x, y):
result = None
if x == 0:
print y
result = y
else:
x -= 1
y += 1
recursive_add(x, y)
return result

With this structure, it becomes quickly obvious what's gone wrong: one
of the branches is not changing the default return value.

def recursive_add(x, y):
if x == 0:
print y
result = y
else:
x -= 1
y += 1
result = recursive_add(x, y)
return result

I find this much less error-prone than hiding return statements in
branches throughout the function; if the only return statement is at
the very end of the function, it becomes much easier to read.


I don't see this as clearer than multiple return. But then it I believe
it is really preference or style, rather than obvious
advantage/disadvantage.

Interestingly, this kind of error is easy to spot by the compiler in C.

Nov 22 '05 #26

Ben Finney wrote:
ma************@gmail.com <ma************@gmail.com> wrote:
def add(x, y):
if x == 0:
print y
return y
else:
x -= 1
y += 1
add(x, y)


To add to the other good advice in this thread:

This is just one of many reasons why I advocate always having a
*single* return statement, at the *end* of the function. I usually
start out writing my function setting a default return value, and the
return statement immediately below.

In your case, the default return value is None, so let's make that
explicit.

def recursive_add(x, y):
result = None
return result

Then, the rest of the function's responsibility is about changing that
default value if necessary.

def recursive_add(x, y):
result = None
if x == 0:
print y
result = y
else:
x -= 1
y += 1
recursive_add(x, y)
return result

With this structure, it becomes quickly obvious what's gone wrong: one
of the branches is not changing the default return value.

def recursive_add(x, y):
if x == 0:
print y
result = y
else:
x -= 1
y += 1
result = recursive_add(x, y)
return result

I find this much less error-prone than hiding return statements in
branches throughout the function; if the only return statement is at
the very end of the function, it becomes much easier to read.


I don't see this as clearer than multiple return. But then it I believe
it is really preference or style, rather than obvious
advantage/disadvantage.

Interestingly, this kind of error is easy to spot by the compiler in C.

Nov 22 '05 #27

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: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.