Flashiota
Flashiota

Reputation: 23

Is it possible to stop a loop from another function in Python?

I want a program that starts with the main menu that branches off to different functions. At the end of each function I want the user to be asked 'Do you want to go back to the main menu?' if the user says no I want the program to terminate by stopping the main loop (I don't want to use sys.exit() or anything similar). Example code:

#Issue is almost at the bottom
#Feel free to comment on the rest of the code as well,
#Always looking to improve
def main():
    loop = True
    while loop:
        print('''MENU CHOICE''')
        print('''1: go here''')
        print('''2: go there''')
        print('''3: You get the point''')
        print('''0: Terminate program''')
        print()

        try:
            answer = int(input('''I want to go to program: '''))
        except:
            print('''Not a valid menu choice, please try again''')
            print()

        if answer != 1 and answer != 2 and answer != 3 and answer != 0:
            print('''Not a valid menu choice, please try again''')
            print()
        elif answer == 1:
            program1()
        elif answer == 2:
            program2()
        elif answer == 3:
            program3()
        else:
            loop = False

def program1():
    print('''This is program 1''')
    itdontwork = input('''Do you want to go back to the menu? Y/N''')

    if itdontwork == 'Y' or itdontwork == 'y':
        print()
    else:
        print('''SHUTTING DOWN''')
        loop = False #Here is the issue

#The rest of the programs would be the same

main()

Upvotes: 2

Views: 4985

Answers (5)

rth
rth

Reputation: 3106

The simplest way is to make your variable loop global

loop = True
def main():
    global loop
    while loop:
        print('''MENU CHOICE''')
        print('''1: go here''')
        print('''2: go there''')
        print('''3: You get the point''')
        print('''0: Terminate program''')
        print()

        try:
            answer = int(input('''I want to go to program: '''))
        except:
            print('''Not a valid menu choice, please try again''')
            print()

        if answer != 1 and answer != 2 and answer != 3 and answer != 0:
            print('''Not a valid menu choice, please try again''')
            print()
        elif answer == 1:
            program1()
        elif answer == 2:
            program2()
        elif answer == 3:
            program3()
        else:
            loop = False

def program1():
    global loop
    print('''This is program 1''')
    itdontwork = input('''Do you want to go back to the menu? Y/N''')

    if itdontwork == 'Y' or itdontwork == 'y':
        print()
    else:
        print('''SHUTTING DOWN''')
        loop = False #Here is the issue

#The rest of the programs would be the same

main()

Global will allow you to have the same w/r variable everywhere. Without global all variables a local.

Upvotes: 0

Cesar Canassa
Cesar Canassa

Reputation: 20173

The problem is that you are trying to change a variable that was defined outside the scope of the program1 function. loop was defined inside main therefore only main can access it. There are several ways to fix this, you could declare loop outside (make it a global) or just make your program1 return a boolean to the caller function, e.g.:

def main():
    loop = True
    while loop:
        loop = program1()

def program1():
    itdontwork = input('''Do you want to go back to the menu? Y/N''')
    if itdontwork == 'Y' or itdontwork == 'y':
        print()
    else:
        print('''SHUTTING DOWN''')
        return False

Upvotes: 3

AlmightyWhy
AlmightyWhy

Reputation: 474

I think what you want to try to do is have the different programs return a value.

The problem is that the functions get executed but return nothing. Your main function returns nothing; therefore the loop variable can never be updated to break the loop.

#Issue is almost at the bottom
#Feel free to comment on the rest of the code as well,
#Always looking to improve
def main():
    loop = True
    while loop:
        print('''MENU CHOICE''')
        print('''1: go here''')
        print('''2: go there''')
        print('''3: You get the point''')
        print('''0: Terminate program''')
        print()

        try:
            answer = int(input('''I want to go to program: '''))
        except:
            print('''Not a valid menu choice, please try again''')
            print()

        if answer != 1 and answer != 2 and answer != 3 and answer != 0:
            print('''Not a valid menu choice, please try again''')
            print()
        elif answer == 1:
            return program1() # Return the output of this function
        elif answer == 2:
            return program2() # Return the output of this function
        elif answer == 3:
            return program3() # Return the output of this function
        else:
            loop = False

def program1():
    print('''This is program 1''')
    itdontwork = input('''Do you want to go back to the menu? Y/N''')

    if itdontwork == 'Y' or itdontwork == 'y':
        print()
    else:
        print('''SHUTTING DOWN''')
        return False # Return the output of this function

#The rest of the programs would be the same

main()

Upvotes: 1

UtahJarhead
UtahJarhead

Reputation: 2217

You can raise ValueError('Words and stuff') and then trap on it.

if answer != 1 and answer != 2 and answer != 3 and answer != 0:
    print('''Not a valid menu choice, please try again''')
    print()
elif answer == 1:
    try:
        program1()
    except ValueError:
        break
elif answer == 2:
    try:
        program2()
    except ValueError:
        break
elif answer == 3:
    try:
        program3()
    except ValueError:
        break
else:
    loop = False


def program1():
    print('''This is program 1''')
    itdontwork = input('''Do you want to go back to the menu? Y/N''')

    if itdontwork == 'Y' or itdontwork == 'y':
        print()
    else:
        print('''SHUTTING DOWN''')
        # loop = False #Here is the issue
        raise ValueError('BOOM SHAKA LAKA!')

Upvotes: -2

Mike
Mike

Reputation: 73

...
        elif answer == 1:
            loop = program1()
        elif answer == 2:
            loop = program2()
        elif answer == 3:
            loop = program3()
        else:
            loop = False

def program1():
    print('''This is program 1''')
    itdontwork = input('''Do you want to go back to the menu? Y/N''')

    if itdontwork == 'Y' or itdontwork == 'y':
        print()
        return 1 # back to menu...
    else:
        print('''SHUTTING DOWN''')
        return 0

This will get the data you need from the called functions to the loop as you want.

Upvotes: -1

Related Questions