Why is the recursion not working as expected when the start and end values are fine?

Question:

I am trying to use recursion to create the following effect:

FORWARD
ORWARD
RWARD
WARD
ARD
RD
D

But the python code below is producing some unexpected results:

def forward(string,start,end):
    if start>end:
        return
    start+=1
    print(string, start, end)
    return forward(string[start:end+1],start,end)
forward("FORWARD",0,6)

The output of the above code is:

FORWARD 0 6
FORWARD 1 6
ORWARD 2 6
WARD 3 6
D 4 6
 5 6
 6 6

I have also printed the start and end values and there seems to be no problem with them. What am I missing?

Asked By: Soumyadyuti Nandy

||

Answers:

The problem is that you pass only a part of the string. In the next iteration, you pass en even greater start value, which makes the string even smaller.

If you want the string to become smaller by 1 character, slice it only by one character, not start characters.

Passing end+1 as part of the slice might be problematic. You can leave that part empty, if you want the substring until the end.

Also, since the method does not return anything (return type is None basically), you don’t need the return statement.

forward(string[1:],start,end)

Another option would be to leave the string intact and print only a part of it:

print(string[start:], start, end)
forward(string,start,end)

It looks like you are at a point where you want to learn how to debug small programs and use a decent IDE with debugging capabilities, such as PyCharm. They offer a free community edition.

Answered By: Thomas Weller

One way to fix this is to pass the entire string in the recursive call, only incrementing the start value by one.

def forward(string,start,end):
    if start>end:
        return
    print(string[start:end+1], start, end)
    return forward(string,start+1,end)
Answered By: Unmitigated

When taking or removing substrings from the beginning or ending of a string python slice notation should look simple and clear, e.g.

def forward(string):
    if string:
        print(string)
        forward(string[1:])


if __name__ == '__main__':
    forward('forward')

string[n:] skips the first n characters and returns the remaining characters. string[:-n] returns everything but the last n characters. string[-n:] returns just the last n characters. Of course there are many more variations but getting a little bit of expertise and comfort with the slice concepts will go a long way toward producing clear python string manipulation code.

The problem is that reduce the string by the number which start is meaning, you don’t make the string one character smaller each time. Try this instead:

def forward(string):
    print(string)
    if len(string) == 1:
        return
    forward(string[1:])

forward("FORWARD")
Answered By: m-eriksen

What is the output/return of each iteration?

The only change over recursion is the printed output, not the return.
The return value is always None.

That’s why we only need to modify the print-statement’s argument string by slicing.

What changes with each iteration?

Put it other: What is the loop variable, what the recursive argument?

However, the string passed to the recursing function call stays unchanged. Here the start offset increases.

What is the exit-condition?

Also the stop- or exit-condition should be adjusted to "end reached" instead overlap.

def forward(string,start,end):
    print(string[start:], start, end)
    if start == end:  # not greater than, but equals means no char inbetween
        return
    return forward(string,start+1,end)  # string argument stays same, only start offset increases


forward("FORWARD",0,6)
print("---")
forward("FORWARD",1,6)
print("---")
forward("FORWARD",1,5)

Prints:

FORWARD 0 6
ORWARD 1 6
RWARD 2 6
WARD 3 6
ARD 4 6
RD 5 6
D 6 6
---
ORWARD 1 6
RWARD 2 6
WARD 3 6
ARD 4 6
RD 5 6
D 6 6
---
ORWARD 1 5
RWARD 2 5
WARD 3 5
ARD 4 5
RD 5 5

Input validation?

What happens when

  • start < 0 or start > len(string)-1 ?
  • end > len(string)-1 or end < start ?
  • string is None ?
Answered By: hc_dev
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.