Python Forum
Why not getting return on line #16?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why not getting return on line #16?
#1
I have a small python code (https://ideone.com/fc2MNb), but it on one line (line #16) returns None. While on another line (line #27) returns value.
Reply
#2
Hello, please post the code here in the thread. Also, enclose the code in python tags.
Reply
#3
Without following the link my guess is you have a code branch inside your function that doesn't end in a return. Do you have any if statements?
Reply
#4
(Feb-10-2021, 03:45 PM)deanhystad Wrote: Without following the link my guess is you have a code branch inside your function that doesn't end in a return. Do you have any if statements?

No, rechecked it before. There is no if or any other conditional to prevent return at line #16. Even the line #13 prints the list 'new', i.e. one line before the return statement.
The code is stated below:
n = 4562; 
rev = 0
new= []
m = 0
 
def convert(n,m):
    print "round #:", m,"n :", n
    a = ((n+1) % 3)-1
    if n:
        new.append(a); print 'new :', new
        convert((n+1)//3,m+1)
    else:
        print 'n==',n, 'new: ::: ', new
        return new
 
print  convert(n,m), "<<---- None returned ? "
 
sum = 0
 
def value(l):
    sum = 0
    for i in range(0, len(new),1):
        sum += new[i]*(3**i)
        print "sum :" , sum
    return sum
 
print value(new),  "<<---- Value is returned "
Reply
#5
The return statement in the convert function is indented too far. Align it with the if/else and it will work as expected.
jahuja73 likes this post
Reply
#6
I don't know if there is an error in you logic or your code. As written, the code only returns a value if n == 0. This occurs only one time and is followed by the recursion unwinding. This is easier to see if I move the print statements around.
n = 4562; 
new= []
m = 0
  
def convert(n,m):
    print(f'convert({n}, {m})')
    a = ((n+1) % 3)-1
    if n:
        new.append(a)
        convert((n+1)//3,m+1)
        print('a', new)
    else:
        print('b', new)
        return new
  
print(convert(n ,m))
Output:
convert(4562, 0) convert(1521, 1) convert(507, 2) convert(169, 3) convert(56, 4) convert(19, 5) convert(6, 6) convert(2, 7) convert(1, 8) convert(0, 9) b [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] a [-1, 0, 0, 1, -1, 1, 0, -1, 1] None
Notice that after line 13 (print('b', new) is executed once followed by line 11 (print('a', new)) executing 9 times. There is no return after line 11.

Should convert look like this?
def convert(n,m):
    print(f'convert({n}, {m})')
    a = ((n+1) % 3)-1
    if n:
        new.append(a)
        convert((n+1)//3,m+1)
        print('a', new)
    else:
        print('b', new)
    return new
Reply
#7
(Feb-10-2021, 10:34 PM)deanhystad Wrote: I don't know if there is an error in you logic or your code. As written, the code only returns a value if n == 0. This occurs only one time and is followed by the recursion unwinding. This is easier to see if I move the print statements around.

[output]convert(4562, 0)
convert(1521, 1)
convert(507, 2)
convert(169, 3)
convert(56, 4)
convert(19, 5)
convert(6, 6)
convert(2, 7)
convert(1, 8)
convert(0, 9)
b [-1, 0, 0, 1, -1, 1, 0, -1, 1]
a [-1, 0, 0, 1, -1, 1, 0, -1, 1]
...
Notice that after line 13 (print('b', new) is executed once followed by line 11 (print('a', new)) executing 9 times. There is no return after line 11.

Should convert look like this?
def convert(n,m):
    print(f'convert({n}, {m})')
    a = ((n+1) % 3)-1
    if n:
        new.append(a)
        convert((n+1)//3,m+1)
        print('a', new)
    else:
        print('b', new)
    return new

But, control enters only one time in the else part.
Then there is a print of correct 'new', on line #13.
Seemingly, if line#13 gives correct output, then inside that else conditional will get on line #14 correct return too.

But, that doesn't occur and it behaves as if line #14 is not having updated value of new.

However, your modification to move return at end of all recursive calls works.

Not sure still why need return at the end of all recursive calls, when return at n==0 should give correct output, particularly when line #13 works correctly.

>> There can be only one reason, that in a recursion there can be no 'return call' till last case is executed.
But, know nothing like that. As per me, can exit by return anytime.
Reply
#8
(Feb-10-2021, 09:37 PM)BashBedlam Wrote: The return statement in the convert function is indented too far. Align it with the if/else and it will work as expected.

Thanks, but request some sort of proof by code or otherwise that in a recursive set of calls cannot return till the program control has returned back to the first call.
Reply
#9
This is your code solving for n = 6, but instead of recursively calling convert() it calls a different version of convert for each value of n. So convert6() calls convert2() calls conver1() which calls convert0().
def convert0():
    return new

def convert1():
    new.append(2 % 3 - 1)
    convert0()

def convert2():
    new.append(3 % 3 - 1)
    convert1()

So while you are correct that return will jump you out of a function, it will not jump you back out of 9 levels of function calls.  It only jumps you back to the function's caller, where execution resumes with the next command.

def convert6():
    new.append(7 % 3 - 1)
    convert2()
Is it now clear why convert() is returning None? convert6() does not have a return statement, and when you call convert(6), it doesn't have a return statement either. Just because convert() returns "new" when n == 0, this does not mean that value is returned by all the other calls to convert(). That is not how function calls work. Each function call will return a value or not return a value based on the code IN THE FUNCTION. Your function convert() will return a value if the argument n == 0, otherwise it does not return a value.

So while it is true that return will jump you out of a function, it does not jump you out of 9 levels of function calls. Return jumps you back to the function's caller, and execution resumes at the next line.
Reply
#10
(Feb-11-2021, 05:00 AM)deanhystad Wrote: Is it now clear why convert() is returning None? convert6() does not have a return statement, and when you call convert(6), it doesn't have a return statement either. Just because convert() returns "new" when n == 0, this does not mean that value is returned by all the other calls to convert(). That is not how function calls work. Each function call will return a value or not return a value based on the code IN THE FUNCTION. Your function convert() will return a value if the argument n == 0, otherwise it does not return a value.

Return jumps you back to the function's caller, and execution resumes at the next line.

Have modified your code to show that 'None' is returned in your code too.

Please explain that.

# https://ideone.com/m51fsf
new = []

def convert0():
    print 'convert0:', new
    return new
    print 'After convert0:', new #program control never reaches here
 
def convert1():
    new.append(2 % 3 - 1)
    print 'convert1:', new
    convert0()
    print 'After convert1:', new
 
def convert2():
    new.append(3 % 3 - 1)
    print 'convert2:', new
    convert1()
    print 'After convert2:', new
 
"""
So while you are correct that return will jump you out of a function, it will not jump you back out of 9 levels of function calls.  It only jumps you back to the function's caller, where execution resumes with the next command.
"""
 
def convert6():
    new.append(7 % 3 - 1)
    print 'convert6:', new
    convert2()
    print 'After convert6:', new

print "convert6()", convert6() # <--- prints: None
Output:

convert6() convert6: [0]
convert2: [0, -1]
convert1: [0, -1, 1]
convert0: [0, -1, 1]
After convert1: [0, -1, 1]
After convert2: [0, -1, 1]
After convert6: [0, -1, 1]
None
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Read characters of line and return positions Gizzmo28 2 887 Nov-04-2020, 09:27 AM
Last Post: perfringo
  Return JSON records in single line using python 2.7 anandmn85 0 1,788 May-14-2018, 09:16 AM
Last Post: anandmn85

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020