469,916 Members | 1,924 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,916 developers. It's quick & easy.

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 1364
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 discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Peri | last post: by
12 posts views Thread by da Vinci | last post: by
43 posts views Thread by Lorenzo Villari | last post: by
2 posts views Thread by Csaba Gabor | last post: by
75 posts views Thread by Sathyaish | last post: by
19 posts views Thread by Kay Schluehr | last post: by
18 posts views Thread by MTD | last post: by
13 posts views Thread by robert | last post: by
20 posts views Thread by athar.mirchi | last post: by
35 posts views Thread by Muzammil | last post: by
reply views Thread by Salome Sato | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.