Python Forum

Full Version: local / global lists
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
So I coded a Program in python whith PyGameZero and the mu editor
def animate_nodes(): for current_node in node_list: x = current_node[0] + current_node[2] y = current_node[1] + current_node[3] if current_node[2] > 0 and current_node[2] < 10: vx = current_node[2] + random.randrange(-1, 1) if current_node[3] > 0 and current_node[3] < 10: vx = current_node[3] + random.randrange(-1, 1) new_node_list.append = [x, y, vx, vy] node_list = new_node_list.copy()
This is one part of my programm.
Now Im getting this error:
UnboundLocalError: local variable 'node_list' referenced before assignment

Now I now what global and local variables are but the variable node_list is a global one in my program so I don't understand why this happens.

for better context here the whole code (its supposed to animate a few nodes that get connected when they are in a particular range to each other and move the nodes by a few pixel every frame):
import random import math WIDTH = 1280 HEIGHT = 720 # defines the number of nodes visible on the screen (+ 1) node_count = 30 # defines the range in which the nodes will connect connection_range = 150 # stores the x and y coordinates of the nodes node_list = [] # stores the x and y values of the vectors connection_list = [] others_list = [] # creates the nodes for i in range(0, node_count): # generate random coordinates x = random.randrange(1, 1280) y = random.randrange(1, 720) vx = random.randrange(0, 10) vy = random.randrange(0, 10) # adds these x and y values to the nodelist node_list.append([x, y]) def calculate_connections(): others_list = node_list.copy() # after we have created the nodes we go over the nodes one by one for current_point in others_list: others_list.remove(current_point) # then we look at all the resting nodes (except for the current one) and we compare the distances # this is a so called nested loop (verschachtelte Schleife) for other_point in others_list: # coords_temp = [] x_temp = other_point[0] y_temp = other_point[1] x = current_point[0] y = current_point[1] # calculate the vector between the current and the other nodes vector_x = abs((x - x_temp)) vector_y = abs((y - y_temp)) vector_length = math.sqrt(vector_x ** 2 + vector_y ** 2) print(vector_length) # compare set connection range to vector range if vector_length <= connection_range: connection_temp = [] connection_temp.append([x, y]) connection_temp.append([x_temp, y_temp]) connection_list.append(connection_temp) def animate_nodes(): for current_node in node_list: x = current_node[0] + current_node[2] y = current_node[1] + current_node[3] if current_node[2] > 0 and current_node[2] < 10: vx = current_node[2] + random.randrange(-1, 1) if current_node[3] > 0 and current_node[3] < 10: vx = current_node[3] + random.randrange(-1, 1) new_node_list.append = [x, y, vx, vy] node_list = new_node_list.copy() # draws the Frame def draw(): calculate_connections() # draw the background screen.fill((255, 255, 255)) # draws the nodes for i in range(node_count): screen.draw.filled_circle(node_list[i-1], 3, (125, 125, 125)) # draw the connections for line in connection_list: print(line) screen.draw.line(line[0], line[1], (0, 0, 0)) animate_nodes()
I hope you can help me :)
thanks in advance <3
This is an odd case. You have a global "node_list", and if you left out the assignment at the end of animate_nodes, Python would use the global "node_list" and the code would run (well, eventually). The assignment changes things. The assignment creates a local variable named "node_list".
def animate_nodes(): for current_node in node_list: # node_list is a local variable. x = current_node[0] + current_node[2] y = current_node[1] + current_node[3] if current_node[2] > 0 and current_node[2] < 10: vx = current_node[2] + random.randrange(-1, 1) if current_node[3] > 0 and current_node[3] < 10: vx = current_node[3] + random.randrange(-1, 1) new_node_list.append = [x, y, vx, vy] node_list = new_node_list.copy() # Assignment makes a local node_list
Use "global" to inform python you want to use the global variable
def animate_nodes(): global node_list for current_node in node_list: # node_list is a local variable. x = current_node[0] + current_node[2] y = current_node[1] + current_node[3] if current_node[2] > 0 and current_node[2] < 10: vx = current_node[2] + random.randrange(-1, 1) if current_node[3] > 0 and current_node[3] < 10: vx = current_node[3] + random.randrange(-1, 1) new_node_list.append = [x, y, vx, vy] # This is the next bug node_list = new_node_list.copy() # Assignment makes a local node_list
Better yet, avoid using the global variable. Pass the variable as an argument and return the modified variable. This exposes the purpose of the function instead of hiding it as a side effect.
def animate_nodes(node_list): """Where is my docstring?""" new_list=[] for current_node in node_list: x = current_node[0] + current_node[2] y = current_node[1] + current_node[3] vx = 0 # Default values? vy = 0 # Used but never assigned if current_node[2] > 0 and current_node[2] < 10: vx = current_node[2] + random.randrange(-1, 1) if current_node[3] > 0 and current_node[3] < 10: vx = current_node[3] + random.randrange(-1, 1) new_list.append = [x, y, vx, vy] return new_list