-2

I'm finishing up an assignment but the thing is that it says 'restart' is undefined even though it's defined throughout the assignment.

I've had errors on where it was local so I made it global but now it says that 'restart' is undefined

def main():   

        global restart

        def changeMyList(myList):
            for i in range(len(myList)):
                myList[i] = myList[i].title()
            myList.sort()

        soccer_teams = ["Arsenal", "Chelsea", "Liverpool", "Barcelona", "Juventus", "Manchester City", "Atletico Madrid", "Borussia Dortmund"]

        team_length = len(soccer_teams)

        changeMyList(soccer_teams)

        print("|||||" + str(team_length) + " TEAMS" + "|||||")

        import random

        for team in soccer_teams:
            print(team)

        shuffle_user = input("Reshuffle? Y/N: ")
        if shuffle_user == 'y':
            random.shuffle(soccer_teams)
            print("List after first shuffle: ", soccer_teams)

            random.shuffle(soccer_teams)
            print("List after second shuffle: ", soccer_teams)
            restart = input("Run Again? Y/N: ").lower()

        if restart == 'y':
                        main()

        elif restart == 'n':
                        exit



main()

When I press 'n' when it asks to reshuffle it says "name 'restart' is not defined" line 32; line 40

pppery
  • 3,731
  • 22
  • 33
  • 46
  • Defined means it is set. There is a possibility of it not being set under some conditions. Please check your logic again – Antti Haapala -- Слава Україні Sep 12 '19 at 23:22
  • `global restart` doesn't create variable. It only inform function to use external/global variable when you will assign value `restart = new_value`. So at start this variable doesn't exist. When `shuffle_user` is not `y` then it doesn't run `restart = input(..)` and it doesn't create variable. So finally variable doesn't exist when you check `restart == 'y'` – furas Sep 12 '19 at 23:22

3 Answers3

1

The only place in this code where restart is defined is:

restart = input("Run Again? Y/N: ").lower()

in the if shuffle_user == 'y': block. Therefore, if you answer no to the reshuffle prompt, no value is ever assigned to the restart variable, and the attempts to read it produce a NameError.

pppery
  • 3,731
  • 22
  • 33
  • 46
0

restart is defined inside the if that's why you cannot reach it, the scope is inside the if:

restart = input("Run Again? Y/N: ").lower()

so you have to move it up and outside the if:

    restart = "n"
    if shuffle_user == 'y':
        random.shuffle(soccer_teams)
        print("List after first shuffle: ", soccer_teams)

        random.shuffle(soccer_teams)
        print("List after second shuffle: ", soccer_teams)
        input("Run Again? Y/N: ").lower()
developer_hatch
  • 15,898
  • 3
  • 42
  • 75
0

You rarely need to use the global keyword. In your case, the easiest solution would be to pass restart to main() as an argument.

Update

I took your full code and modified it so there isn't any confusion. Also, I named restart some_globally_accessible_var to add clarity to what exactly is happening. In your exact case it isn't really necessary to have restart defined globally.

If you are still confused about variable scope, this seems like a decent explanation of it. Also, here is a good StackOverflow question about variable scope within if statements.

some_globally_accessible_var = ''

def main(restart):   
        def changeMyList(myList):
            for i in range(len(myList)):
                myList[i] = myList[i].title()
            myList.sort()

        soccer_teams = ["Arsenal", "Chelsea", "Liverpool", "Barcelona", "Juventus", "Manchester City", "Atletico Madrid", "Borussia Dortmund"]

        team_length = len(soccer_teams)

        changeMyList(soccer_teams)

        print("|||||" + str(team_length) + " TEAMS" + "|||||")

        import random

        for team in soccer_teams:
            print(team)

        shuffle_user = input("Reshuffle? Y/N: ")
        if shuffle_user == 'y':
            random.shuffle(soccer_teams)
            print("List after first shuffle: ", soccer_teams)

            random.shuffle(soccer_teams)
            print("List after second shuffle: ", soccer_teams)
            restart = input("Run Again? Y/N: ").lower()

        if restart == 'y':
                        main(restart) #remember to pass restart to your function here!

        elif restart == 'n':
                        exit



main(some_globally_accessible_var)

See pppery’s answer for an explanation of your error.

Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
  • Assuming you are suggesting removing the `global` keyword, this solution wouldn't work, because any attempt to modify a variable in a python function declares that variable as local, even if there is a global variable of the same name. – pppery Sep 12 '19 at 23:25
  • @pppery that’s true, but I was assuming he didn’t actually need it as a global. I added a work around to make it globally accessible – Lord Elrond Sep 12 '19 at 23:29
  • Additionally, you need to declare `restart` using straight quotes (`restart = ''`), not curly quotes like your answer is using. – pppery Sep 12 '19 at 23:30
  • I don’t know how to do that on my phone xD – Lord Elrond Sep 12 '19 at 23:31
  • @pppery Thanks! How would I put that into the code? –  Sep 13 '19 at 01:32
  • The comment you responded to was me talking to the poster of this answer, pointing out a syntax error with the answer (which I then corrected). This question, to the extent it makes sense (How would you put **what** into the code), should be directed at Caleb Goodman, who wrote the answer. – pppery Sep 13 '19 at 01:35