Python Forum
UnboundLocalError: local variable 'figure_perso' referenced before assignment
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
UnboundLocalError: local variable 'figure_perso' referenced before assignment
#1
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
Reply
#2
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.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
Gaming Collection
Homepage
my-python
Reply
#3
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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Referenced before assignment finndude 3 660 Mar-02-2021, 08:11 PM
Last Post: finndude
  exec + subprocess = UnboundLocalError paul18fr 6 745 Feb-04-2021, 06:27 AM
Last Post: Gribouillis
  Assignment of non-existing class variable is accepted - Why? DrZ 6 1,035 Jul-13-2020, 03:53 PM
Last Post: deanhystad
  UnBoundLocalError Seaninho 3 836 May-31-2020, 07:22 AM
Last Post: azajali43
  local variable 'marks' referenced before assignment Calli 3 758 May-25-2020, 03:15 PM
Last Post: Calli
  Variable assignment wierdness with Memory eoins 1 719 Mar-08-2020, 10:15 AM
Last Post: scidam
  UnboundLocalError: local variable referenced before assignment svr 1 1,323 Dec-27-2019, 09:08 AM
Last Post: perfringo
  local variable troubles yokaso 4 1,198 Oct-20-2019, 05:25 PM
Last Post: ichabod801
  accessing local variable outside class priyanka08 3 820 Sep-24-2019, 10:00 AM
Last Post: buran
  UnboundLocalError: local variable ' ' referenced before assignment d3fi 10 2,388 Sep-03-2019, 07:22 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020