Python Forum

Full Version: UnboundLocalError: local variable 'figure_perso' referenced before assignment
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,
I'm a French user (so my English is bad), and I make a "John Conway Life's Game".
I want to make a function that place where you want custom elements by clicking on the canvas (glider, blinker, and others...), but I'm going to be crazy! Wall

Please, help me, here is the code :

from tkinter import *
from time import *
largeur = 60
hauteur = 60
cellules = [[0 for j in range(largeur)] for i in range (hauteur)]
voisins = [[0 for j in range(largeur)] for i in range (hauteur)]

def	compte_voisins(i,j):
	if i == 0:
		if j == 0:
			return cellules[0][1] + cellules[1][1] + cellules[1][0]
		if j == largeur - 1:
			return cellules[0][largeur - 2] + cellules[1][largeur - 2] + \
			cellules[1][largeur - 1]
		return cellules[0][j - 1] + cellules[0][j + 1] + \
		cellules[1][j-1] + cellules[1][j] + cellules[1][j+1]
	if i == hauteur - 1:
		if j == 0:
			return cellules[hauteur - 1][1] + cellules[hauteur - 2][1] + cellules[hauteur - 2][0]
		if j == largeur - 1:
			return cellules[hauteur - 1][largeur - 2] + cellules[hauteur - 2][largeur - 2] + \
			cellules[hauteur - 2][largeur - 1]
		return cellules[hauteur - 1][j - 1] + cellules[hauteur - 1][j + 1] + \
		cellules[hauteur - 2][j-1] + cellules[hauteur - 2][j] + cellules[hauteur - 2][j+1]
	else:
		if j == 0:
			return cellules[i - 1][0] + cellules[i + 1][0] + \
		cellules[i - 1][1] + cellules[i][1] + cellules[i + 1][1]
		if j == largeur - 1:
			return cellules[i - 1][largeur - 1] + cellules[i + 1][largeur - 1] + \
		cellules[i - 1][largeur - 2] + cellules[i][largeur - 2] + cellules[i + 1][largeur - 2]
		else:
			return cellules[i - 1][j -1] + cellules[i - 1][j] + cellules[i - 1][j + 1] + \
			       cellules[i ][j - 1]          +               cellules[i ][j+1] + \
                   cellules[i + 1][j - 1] + cellules[i + 1][j] + cellules[i + 1][j + 1]

def grille_voisins():
	for i in range (hauteur):
		for j in range (largeur):
			voisins[i][j] = compte_voisins(i,j)

def grille_lendemain():
	for i in range (hauteur):
		for j in range (largeur):
			if cellules[i][j] == 0 and voisins[i][j] == 3:
				cellules[i][j] = 1
			if cellules[i][j] == 1 and voisins[i][j] != 2 and voisins[i][j] !=3:
				cellules[i][j] = 0

def affichage_grille(tab):
	for i in range(len(tab)):
		print(tab[i])

def jeu():
    dessine_etat()
    for i in range (regle_jours.get()):
        print(" ")
        grille_voisins()
        grille_lendemain()
        sleep(0.1)
        dessine_etat()

def dessine_cellule(i,j):
    can.create_rectangle(j * e, i * e,(j + 1) * e - 1,(i + 1) * e - 1, fill="red", width=0)

def dessine_etat():
    can.delete("all")
    for i in range (hauteur):
        for j in range (largeur):
            if cellules[i][j] == 1:
                dessine_cellule(i,j)
    fen.update()

def trace_quadrillage():
	for i in range(hauteur):
		can.create_line(0, i * e - 1, largeur * e + 1, i * e - 1, fill='black')
	for j in range(largeur):
		can.create_line(j * e - 1, 0, j * e - 1, hauteur * e + 1, fill='black')

def action_clic_souris(event):
    b = regle_taille.get()
    f = regle_taillebis.get()
    can.focus_set()
    x = event.x // e
    y = event.y // e
    for c in range(b):
        for d in range(f):
            cellules[y+c][x+d] = 1
            can.create_rectangle((x+d) * e, (y+c) * e,(x+d + 1) * e - 1,(y+c + 1) * e - 1, fill="red", width=0)

def action_declic_souris(event):
    b = regle_taille.get()
    f = regle_taillebis.get()
    can.focus_set()
    x = event.x // e
    y = event.y // e
    for c in range(b):
        for d in range(f):
            cellules[y+c][x+d] = 0
            can.create_rectangle((x+d) * e, (y+c) * e,(x+d + 1) * e - 1,(y+c + 1) * e - 1, fill="white", width=0)

def create_perso():
    figure_perso = perso_planeur()
    for i in range(int(len(figure_perso)/2)):
        cellules[figure_perso[i*2+1]][figure_perso[i*2]] = 1
        can.create_rectangle(figure_perso[i*2] * e, figure_perso[i*2+1] * e,(figure_perso[i*2] + 1) * e - 1,(figure_perso[i*2+1] + 1) * e - 1, fill="red", width=0)

def perso_planeur(type):
    print(type)
    if type == 1:
        figure_perso = [0,1, 1,2, 2,0, 2,1, 2,2]
    elif type == 2:
        figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,2]
    elif type == 3:
        figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,3, 1,2]
    elif type == 4:
        figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,3, 1,3, 0,2]
    return figure_perso

def perso_vaisseau_leger():
    figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,2]
    return figure_perso

def perso_vaisseau_moyen():
    figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,3, 1,2]
    return figure_perso

def perso_vaisseau_lourd():
    figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,3, 1,3, 0,2]
    return figure_perso

def action_planeur(event):
    can.focus_set()
    x = event.x // e
    y = event.y // e
    figure_perso = perso_planeur(type)
    print(figure_perso)
    for i in range(int(len(figure_perso)/2)):
        cellules[figure_perso[i*2+1]+y][figure_perso[i*2]+x] = 1
        can.create_rectangle((figure_perso[i*2]+x) * e, (figure_perso[i*2+1]+y) * e,(figure_perso[i*2]+x + 1) * e - 1,(figure_perso[i*2+1]+y + 1) * e - 1, fill="red", width=0)
    return figure_perso

e = 10
figure_perso=[]
fen = Tk()

can = Canvas(fen, width=600, height=800, bg="white")
can.grid(row=0, column=0, rowspan=6)

can.bind("<Button-1>", action_clic_souris)
can.bind("<Button-2>", action_planeur)
can.bind("<Button-3>", action_declic_souris)

bouton_lancer = Button(fen, text="Lancer",command=jeu)
bouton_lancer.grid(row=4, column=2)

regle_jours = Scale(fen,orient='vertical', from_=5000, to=0, resolution=1,
	tickinterval=500, length=300)
regle_jours.grid(row=3, column=2)
regle_jours.set(5000)

regle_taille = Scale(fen,orient='vertical', from_=hauteur, to=0, resolution=1,
	tickinterval=int(hauteur/10), length=300)
regle_taille.grid(row=3, column=3)
regle_taille.set(1)

regle_taillebis = Scale(fen,orient='vertical', from_=largeur, to=0, resolution=1,
	tickinterval=int(largeur/10), length=300)
regle_taillebis.grid(row=3, column=4)
regle_taillebis.set(1)

bouton_planeur = Button(fen, text="Planeur",command=lambda: perso_planeur(1))
bouton_planeur.grid(row=0, column=3)
bouton_planeur.place(rely=0.1, relx= 0.82)

bouton_vaisseau_leger = Button(fen, text="Vaisseau Léger",command=lambda: perso_planeur(2))
bouton_vaisseau_leger.grid(row=0, column=3)
bouton_vaisseau_leger.place(rely=0.14, relx= 0.82)

bouton_vaisseau_moyen = Button(fen, text="Vaisseau Moyen",command=lambda: perso_planeur(3))
bouton_vaisseau_moyen.grid(row=0, column=3)
bouton_vaisseau_moyen.place(rely=0.18, relx= 0.82)

bouton_vaisseau_lourd = Button(fen, text="Vaisseau Lourd",command=lambda: perso_planeur(4))
bouton_vaisseau_lourd.grid(row=0, column=3)
bouton_vaisseau_lourd.place(rely=0.22, relx= 0.82)

dessine_etat()
trace_quadrillage()
fen.mainloop()
The problems come from lines 102 to line 186, ignore the rest. I have this error :

Error:
*** Console de processus distant Réinitialisée *** <class 'type'> Exception in Tkinter callback Traceback (most recent call last): File "C:\EduPython\App\lib\tkinter\__init__.py", line 1538, in __call__ return self.func(*args) File "C:\Users\meder\Downloads\jeu-de-la-vie-2020-06-10-test4.py", line 150, in action_planeur figure_perso2 = perso_planeur(type) File "C:\Users\meder\Downloads\jeu-de-la-vie-2020-06-10-test4.py", line 132, in perso_planeur return figure_perso UnboundLocalError: local variable 'figure_perso' referenced before assignment >>>
What is does mean?

If you want to help me, I think I have a problem with the variables appelation into the functions, the "return", and the buttons...

Thank you. Smile
It means you are trying to print or use a variable before assigning it.
This is not the best example but, follows along the lines of your error
Example
print(myvar)
myvar = 'hello'
This would give an error because myvar has not been assigned.
in the method def action_planeur(event):
there is
figure_perso = perso_planeur(type)
type is a bulitin you should have some other variable name here.

when perso_planeur(type) is called with type
def perso_planeur(type):
    print(type)
    if type == 1:
        figure_perso = [0,1, 1,2, 2,0, 2,1, 2,2]
    elif type == 2:
        figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,2]
    elif type == 3:
        figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,3, 1,2]
    elif type == 4:
        figure_perso = [5,0, 6,1, 6,2, 6,3, 5,3, 4,3, 3,3, 2,3, 1,3, 0,2]
        print()
    return figure_perso
type will never be true in any of the if conditions so when it tries to return figure_perso it has not been defined as it would only be defined is one of the condition where true.