Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
local / global lists
#1
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
Reply
#2
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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  It's saying my global variable is a local variable Radical 5 1,097 Oct-02-2023, 12:57 AM
Last Post: deanhystad
  Delete all Excel named ranges (local and global scope) pfdjhfuys 2 1,689 Mar-24-2023, 01:32 PM
Last Post: pfdjhfuys
  Global variables or local accessible caslor 4 984 Jan-27-2023, 05:32 PM
Last Post: caslor
  How to use global value or local value sabuzaki 4 1,106 Jan-11-2023, 11:59 AM
Last Post: Gribouillis
  Global vs. Local Variables Davy_Jones_XIV 4 2,595 Jan-06-2021, 10:22 PM
Last Post: Davy_Jones_XIV
  Global - local variables Motorhomer14 11 4,127 Dec-17-2020, 06:40 PM
Last Post: Motorhomer14
  Split dict of lists into smaller dicts of lists. pcs3rd 3 2,312 Sep-19-2020, 09:12 AM
Last Post: ibreeden
  from global space to local space Skaperen 4 2,269 Sep-08-2020, 04:59 PM
Last Post: Skaperen
  Question regarding local and global variables donmerch 12 4,976 Apr-12-2020, 03:58 PM
Last Post: TomToad
  local/global variables in functions abccba 6 3,358 Apr-08-2020, 06:01 PM
Last Post: jefsummers

Forum Jump:

User Panel Messages

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