Dobz
Dobz

Reputation: 1213

Loop keeps going after being carried out

def Help(string):
    while True:
        if string == 'Manifest':
            return Manifest()
            break
        elif string == 'Intent':
            return Intent()
            break
        else:
            print('The options available are: \n')
            for i in andHelp:
                print(i)
            print('Type Q to Quit \n')
            x = input('What option do you choose: ')
            print('\n')
            if x == 'Q':
                break
            else:
                Help(x)

How come if it goes into the else statement it will keep looping? for example:

"The options available are:

Intent

Manifest

Type Q to Quit

What option do you choose: " <-- this will keep coming up aswell as the function I choose.

Upvotes: 0

Views: 344

Answers (2)

kojiro
kojiro

Reputation: 77059

Your actual problem is due to your recursion not actually returning the inner frame's value, but eliminating the recursion seems a more straightforward solution.

What's goofy about this is doing a recursion inside a loop. Both the recursion and the loop serve the same purpose: To make the option choice keep happening until a valid option is given. So you can definitely eliminate one:

def Help(string):
    while True:
        if string == 'Manifest':
            return Manifest()
            break
        elif string == 'Intent':
            return Intent()
            break
        else:
            print('The options available are: \n')
            for i in andHelp:
                print(i)
            print('Type Q to Quit \n')
            string = input('What option do you choose: ') # Change `x` to `string` so next iteration will change behavior
            print('\n')
            if string == 'Q':
                break

As Inbar Rose's answer points out, you can shorten this quite a bit with recursion, but since Python requires a recursion limit, you can make the program crash by forcing it to recur beyond that limit. So perhaps sticking with the loop is better. Anyway, you can clean it up further by having the validation of string be the condition of the loop itself:

def Help(string):
    validOptions = ('Manifest', 'Intent', 'Q')

    while string not in validOptions:
        print('The options available are: \n')
        for i in andHelp:
            print(i)
        print('Type Q to Quit \n')
        string = input('What option do you choose: ')
        print('\n')

    # Now you have a guaranteed-valid string, so you don't need this part in the loop.
    if string == 'Manifest':
        return Manifest() # No need for a 'break' after a return. It's [dead code](http://en.wikipedia.org/wiki/Dead_code)
    elif string == 'Intent':
        return Intent()
    elif string == 'Q':
        return

Upvotes: 1

Inbar Rose
Inbar Rose

Reputation: 43437

You don't even need a while loop for what you are checking. Use this instead:

def Help(string):
    if string == 'Manifest':
        return Manifest()
    elif string == 'Intent':
        return Intent()
    else:
        print('The options available are:\n%s\nType Q to Quit\n' % '\n'.join(andHelp))
        x = input('What option do you choose: ')
        print('\n')
        if x != 'Q':
            Help(x)

note: I modified your prints a bit to reduce extra lines that really, didn't need to be there.
note2: As you may see in the comments, it may be dangerous to do this recursively without a limitation because you may reach a maximum depth level.

Upvotes: 1

Related Questions