Okay so I'm writing a code for a game and the way its currently programmed is the main menu is contained within a large function that references another function, and so on. Not too complicated. But (as you'll see with the code below) I have all the essential variables set before the functions even happen, at the very beginning of the code.

import pygame, sys, time, math

##This is where the variables are set
DISPLAY = pygame.display.set_mode((1023, 647))
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
clock = pygame.time.Clock()
active = True
started = False
mainScreen = True
coordsX = 0
coordsY = 0
coordsZ = 0
coordsW = 0

def backMain(fps):
    ##Loads main menu
    mainscreendisplayimg = pygame.image.load('mainScreen.png')
    def mainscreen(x, y):
        DISPLAY.blit(mainscreendisplayimg, (x, y))
    mainscreen(1, 1)

    while active:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_p:
                    if started == False:
                        if mainScreen == True:
                            started = True
                            mainScreen = False

        if started == True:
            started = False

def ultCoords():
    def c0_0_0_0():
        pygame.draw.rect(DISPLAY, GREEN, (507, 333, 8, 8), 0)

def forwardMain(fps):


This should display a rectangle on the screen and so on so forth, but instead it gives me an error saying that the variable 'started' is referenced before assignment

This means (I think) that the variable is being used before it's assigned, but it's clearly assigned up at the top, well before any of the functions use it.

Any help is appreciated, thank you!

The problem is that when a variable appears on the left hand side of the = operator in a function, such as in

def foo():
    started = "fubar"

then the rule is that this variable is a local variable in function foo. It means that if there is another variable in the global namespace, such as

started = False

then these are two different variables, and setting started in foo() has no effect on the global variable started.

There are two main workarounds for this. The first one is a quick and dirty fix: you can add a globaldeclaration at the very beginning of function foo()

def foo():
    global started
    started = "fubar"

This works, but it is not good python programming because with more than one variable, it creates obfuscated code. You'll notice that serious python code almost never uses the global statement.

The second workaround is to use object attributes instead of global variables. The code could be written

class Game(object):
    def __init__(self):
        self.started = False

    def foo(self):
        self.started = "fubar"

if __name__ == '__main__':
    game = Game()

This is by far the preferred way to handle this issue.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.