David
David

Reputation: 27

Error with global variable

Whenever I start my game and it loads my menu I get the error "SyntaxWarning: name 'finishes' is assigned to before global declaration". How do I fix this? I doesn't disrupt my game but any error should be fixed. I have cut down the below code to just show the essential code.

def load_level(level):
    walls = []
    players = []
    finishes = []
    x = y = 0
    for row in levels[level]:
        for col in row:
            if col == "W":
                walls.append(Wall((x, y)))
            if col == "P":
                players.append(Player((x, y)))
            if col == "F":
                finishes.append(Finish1((x, y)))
            if col == "G":
                finishes.append(Finish2((x, y)))
            if col == "H":
                finishes.append(Finish3((x, y)))
            if col == "I":
                finishes.append(Finish4((x, y)))
            x += 40.96
        y += 30.72
        x = 0
    return walls, players, finishes

walls, players, finishes = load_level(currentLevel)

def Menu():
    runnin = True
    while runnin:
        clock.tick(60)
        screen.fill(BLACK)
        mouseclick = pygame.mouse.get_pressed()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()
                sys.exit(0)
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit(0)
        for option in options:
            if option.rect.collidepoint(pygame.mouse.get_pos()):
                option.hovered = True
                if mouseclick[0] == 1:
                    if option.text == "Easy":
                        global currentlevel, walls, players, finishes
                        walls, players, finishes = load_level(0)
                        currentlevel = 0
                        main()
                    elif option.text == "Medium":
                        global currentlevel, walls, players, finishes
                        walls, players, finishes = load_level(1)
                        currentlevel = 1
                        main()
                    elif option.text == "Hard":
                        global currentlevel, walls, players, finishes
                        walls, players, finishes = load_level(2)
                        currentlevel = 2
                        main()
                    elif option.text == "Help":
                        Help()
                    else:
                        runnin = False
            else:
                option.hovered = False
            option.draw()
            screen.blit(title_font.render("Amazeing Race", True, GREY), (130, 50))
        pygame.display.update()
    pygame.quit()
    sys.exit(0)

Upvotes: 0

Views: 89

Answers (1)

Moon Cheesez
Moon Cheesez

Reputation: 2701

The problem here is that you are declaring global on variables more than once. Globals should be declared at the start of the function. Read more here. To solve this, simply move global currentlevel, walls, players, finishes to the top of your function like so:

def Menu():
    global currentlevel, walls, players, finishes
    runnin = True
    # more code...

Concepts

Here are some tests that I hope will help you understand what will and what will not raise the SyntaxWarning.

1.Do not declare a variable before a global statement.

a = 3
global a

This will raise the SyntaxWarning.

2.You may declare a variable global in functions even after you declared it outside of the function.

a = 3
def asdf():
    global a
    a = 2

This will not raise the SyntaxWarning.

3.In a function, you may declare any other variable before the global declaration (However, not advised).

a = 3
def asdf():
    b = 2
    global a
    a = 2

This will not raise SyntaxWarning.

4.In a function, you may only declare globals before assignment even when enclosed in if else statements.

a = 0

def asdf():
    if a == 3:
        global a
        a = 2
        return a
    else:
        global a
        return a

This will raise the SyntaxWarning. As you can see, this is more similar to what you are doing.

In summary:

Declare all globals before declaration in the given scope even if the global code may not be reached.

Upvotes: 4

Related Questions