why do i keep getting this error and how do i solve it

Question:

So i have this massive python code but i cant get it to work. It keeps saying:

UnboundLocalError: local variable ‘secondnum’ referenced before assignment

This problem is actually solved now thanks for the help but the program still doesnt seem to work correctly. I dont get any errors but its supposed to be a stopwatch but i cant change the appearance of the sprites.

I tried to google it but no one seemed to have had the same problem as i did.

Please help. And Please have a bit patient with me im only 14

import pygame, sys
import time
import threading


secondnum = "0"
tensecondnum = "0"
minutenum = "0"
tenminutenum = "0"

secondimage = {"0": "0.png", 1: "1.png", 2: "2.png", 3: "3.png", 4: "4.png", 5: "5.png", 6:"6.png", 7: "7.png"
}
tensecondimage = {"0": "0.png"
}
minuteimage = {"0": "0.png"
}
tenminuteimage = {"0": "0.png"
}




def background():
    while True:
        global secondnum
        global tensecondnum
        global minutenum
        global tenminutenum
        time.sleep(1)
        secondnum = "1"
    
def foreground():
    global numbers1_group
    global numbers2_group
    global numbers3_group
    global numbers4_group
    global screen
    class Colon(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y):
            super().__init__()
            self.image = pygame.image.load("kolon.png")
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]
            
    class Numbers1(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    class Numbers2(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    class Numbers3(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    class Numbers4(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    # General setup
    pygame.init()
    clock = pygame.time.Clock()

    # Game Screen
    screen_width = 700
    screen_height = 350
    screen = pygame.display.set_mode((screen_width,screen_height))
    background = pygame.image.load("BG.png")
    pygame.mouse.set_visible(True)

    # Colon
    colon = Colon(350, 175)
    colon_group = pygame.sprite.Group()
    colon_group.add(colon)

    # Numbers1
    numbers1 = Numbers1(140, 175, tenminuteimage["0"])
    numbers1_group = pygame.sprite.Group()
    numbers1_group.add(numbers1)
    

    # Numbers2
    numbers2 = Numbers2(280, 175, minuteimage["0"])
    numbers2_group = pygame.sprite.Group()
    numbers2_group.add(numbers2)

    # Numbers3
    numbers3 = Numbers3(420, 175, tensecondimage["0"])
    numbers3_group = pygame.sprite.Group()
    numbers3_group.add(numbers3)

    # Numbers4
    numbers4 = Numbers4(560, 175, secondimage[secondnum])
    numbers4_group = pygame.sprite.Group()
    numbers4_group.add(numbers4)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        pygame.display.flip()
        screen.blit(background,(0,0))
        colon_group.draw(screen)
        numbers1_group.draw(screen)
        numbers2_group.draw(screen)
        numbers3_group.draw(screen)
        numbers4_group.draw(screen)
        clock.tick(60)

b = threading.Thread(name='background', target=background)
f = threading.Thread(name='foreground', target=foreground)

b.start()
f.start()
Asked By: Sydney Myrén

||

Answers:

Please read https://stackoverflow.com/help/minimal-reproducible-example about asking better questions. Also, include the python version and the complete traceback when asking about an error.

In any case, the following shows what you did and the solution.

s = 0
def bad():
    s = s+1

def good():
    global s
    s = s+1

good()
bad()

prints

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    bad()
  File "<pyshell#7>", line 2, in bad
    s = s+1
UnboundLocalError: local variable 's' referenced before assignment

In 3.11, out in a month, the message is changed to "cannot access local variable ‘s’ where it is not associated with a value", which we hope is clearer.

Answered By: Terry Jan Reedy

Python works that way, that if Python find a variable being assign in some function it defines this variable as local and stops looking for it to be assign somewhere out of the function. To fix it you better make secondnum global inside of function background.

import pygame, sys
import time
import threading

global tensecondnum
global minutenum
global tenminutenum
secondnum = "0"
tensecondnum = "0"
minutenum = "0"
tenminutenum = "0"

secondimage = {"0": "0.png", 1: "1.png", 2: "2.png", 3: "3.png", 4: "4.png", 5: "5.png", 6:"6.png", 7: "7.png"
}
tensecondimage = {"0": "0.png"
}
minuteimage = {"0": "0.png"
}
tenminuteimage = {"0": "0.png"
}




def background():
    while True:
        global secondnum
        time.sleep(1)
        secondnum = str(int(secondnum) + 1)
    
def foreground():
    class Colon(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y):
            super().__init__()
            self.image = pygame.image.load("kolon.png")
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]
            
    class Numbers1(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    class Numbers2(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    class Numbers3(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    class Numbers4(pygame.sprite.Sprite):
        def __init__(self, pos_x, pos_y, number):
            super().__init__()
            self.image = pygame.image.load(number)
            self.rect = self.image.get_rect()
            self.rect.center = [pos_x, pos_y]

    # General setup
    pygame.init()
    clock = pygame.time.Clock()

    # Game Screen
    screen_width = 700
    screen_height = 350
    screen = pygame.display.set_mode((screen_width,screen_height))
    background = pygame.image.load("BG.png")
    pygame.mouse.set_visible(True)

    # Colon
    colon = Colon(350, 175)
    colon_group = pygame.sprite.Group()
    colon_group.add(colon)

    # Numbers1
    numbers1 = Numbers1(140, 175, tenminuteimage["0"])
    numbers1_group = pygame.sprite.Group()
    numbers1_group.add(numbers1)

    # Numbers2
    numbers2 = Numbers2(280, 175, minuteimage["0"])
    numbers2_group = pygame.sprite.Group()
    numbers2_group.add(numbers2)

    # Numbers3
    numbers3 = Numbers3(420, 175, tensecondimage["0"])
    numbers3_group = pygame.sprite.Group()
    numbers3_group.add(numbers3)

    # Numbers4
    numbers4 = Numbers4(560, 175, secondimage[secondnum])
    numbers4_group = pygame.sprite.Group()
    numbers4_group.add(numbers4)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        pygame.display.flip()
        screen.blit(background,(0,0))
        colon_group.draw(screen)
        numbers1_group.draw(screen)
        numbers2_group.draw(screen)
        numbers3_group.draw(screen)
        numbers4_group.draw(screen)
        clock.tick(60)

b = threading.Thread(name='background', target=background)
f = threading.Thread(name='foreground', target=foreground)

b.start()
f.start()
Answered By: Dima