NameError: name 'x' is not defined Python

Viewed 3092

I'm trying to get around this error but can't find a solution. Actually the code worked perfectly some time but suddendly started to drop the error:

"NameError: name 'number_exit' is not defined" 

And also:

"NameError: name 'price_buy' is not defined"

The code is generating a list of random numbers

import numpy as np

# This function generates a list of numbers under certain rules
def num_var_list():
    global number_list, number_exit, number_target
    number_list = []
    number_target = number_exit
    num_max_robot = (number_target * 20) / 100
    while num_max_robot > 0:
        num_robot = np.random.randint(1,int(num_max_robot))
        if num_robot > number_target:
                number_list.append(number_target)
        else: 
            number_list.append(num_robot)
        number_target = number_target - number_target
    return number_list
        
# This function generates a random number between a certain range
def fun_price_buy():
    global price_buy
    price_buy = np.random.randint(50000,300000)
    return price_buy

# This function generates a random number between a certain range
def fun_mx_buy():
    global number_exit
    number_exit = np.random.randint(50, 150)
    return number_exit

lista_number_list = []
lista_price_buy = []
lista_mx_buy = []

# This loop append each function 50 times to a new list
while len(lista_price_buy) <= 50: 
    lista_number_list.append(num_var_list())
    lista_price_buy.append(fun_price_buy())
    lista_mx_buy.append(fun_mx_buy())

Actually, when Python doesn't drop the error, the code makes exactly what I want it to do. So I'm not sure how to adjust it to let it work without NameError warnings.

Any help will be highly appreciated. Thank you!

5 Answers

When doing global price_buy that means you use the globally defined price_buy to be defined localy in your method but

  • neither price_buy nor number_exit are defined globally (outside a method)
  • you don't need global variable

They only to be local, and just better : inlined

def fun_price_buy():
    price_buy = np.random.randint(50000,300000)
    return price_buy

# inline, no temporaty variable is needed
def fun_price_buy():
    return np.random.randint(50000,300000)

Finally, and if you want to get the value from the method in a variable for doing something with it:

import numpy as np

# This function generates a list of numbers under certain rules
def num_var_list(number_exit):
    number_list = []
    number_target = number_exit
    num_max_robot = (number_target * 20) / 100
    while num_max_robot > 0:
        num_robot = np.random.randint(1,int(num_max_robot))
        if num_robot > number_target:
                number_list.append(number_target)
        else: 
            number_list.append(num_robot)
        number_target = number_target - number_target
    return number_list
        
def fun_price_buy():
    return np.random.randint(50000,300000)

def fun_mx_buy():
    return np.random.randint(50, 150)

lista_number_list = []
lista_price_buy = []
lista_mx_buy = []

# This loop append each function 50 times to a new list
while len(lista_price_buy) <= 50: 
    number_exit = fun_mx_buy()
    price_buy = fun_price_buy()
    vr_list = num_var_list(number_exit)
   
    lista_number_list.append(vr_list)
    lista_price_buy.append(price_buy )
    lista_mx_buy.append(number_exit )

why do you have so much global ?

def num_var_list():
    number_exit=fun_mx_buy()
    number_list = []
    number_target = number_exit
    num_max_robot = (number_target * 20) / 100
    while num_max_robot > 0:
        num_robot = np.random.randint(1, int(num_max_robot))
        if num_robot > number_target:
            number_list.append(number_target)
        else:
            number_list.append(num_robot)
        number_target = number_target - number_target
    return number_list

is it works for you?

It looks like you are defining variables via globals inside a function. You'll want to convert your price_buy and number_exit to local variables.

or:

# This function generates a random number between a certain range
def fun_price_buy():
    return np.random.randint(50000,300000)

# This function generates a random number between a certain range
def fun_mx_buy():
    return np.random.randint(50, 150)

If you still want to use global variables (as other answers pointed, not a recommended approach), you will have to give them a value before using them:

number_exit = 0
# This function generates a list of numbers under certain rules
def num_var_list():
    global number_list, number_exit, number_target
    number_list = []

You can instantiate number_exit in the scope of the function as well, but you need to do so before actually using it.

# This function generates a list of numbers under certain rules
def num_var_list():
    global number_list, number_exit, number_target
    number_list = []
    number_exit = 0

You haven't defined those global variables. Typing global whatever doesn't automatically define a variable called whatever. It just tells the interpreter that there's an existing variable called whatever in global scope.

For example, the following code produces no errors:

blah = 'yada'

def foo(bar):
    global blah
    print(blah, bar)
    
foo('test') # output: yada test

Whereas in this example, if the global variable isn't defined beforehand (I commented it out), it gets the same error as you:

#blah = 'yada'

def foo(bar):
    global blah
    print(blah, bar)
    
foo('test') # output: NameError: name 'blah' is not defined

So, to stop getting the error, you have to give your global variables some value beforehand, like None. Although you could be avoiding globals altogether if you used a class to hold those values you need, like this:

import numpy as np

class MyClass(object):
    def __init__(self):
        #you'll have to set the numerical values to something that causes num_var_list to not loop infinitely
        self.number_list = None
        self.number_exit = 0
        self.number_target = 0
        self.price_buy = 0

    # This function generates a list of numbers under certain rules
    def num_var_list(self):
        self.number_list = []
        self.number_target = self.number_exit
        num_max_robot = (self.number_target * 20) / 100
        while num_max_robot > 0:
            num_robot = np.random.randint(1,int(num_max_robot))
            if num_robot > self.number_target:
                    self.number_list.append(self.number_target)
            else: 
                self.number_list.append(num_robot)
            self.number_target = self.number_target - self.number_target
        return self.number_list
            
    # This function generates a random number between a certain range
    def fun_price_buy(self):
        self.price_buy = np.random.randint(50000,300000)
        return self.price_buy

    # This function generates a random number between a certain range
    def fun_mx_buy(self):
        self.number_exit = np.random.randint(50, 150)
        return self.number_exit

def main():
    lista_number_list = []
    lista_price_buy = []
    lista_mx_buy = []
    
    my_class_instance = MyClass()

    # This loop append each function 50 times to a new list
    while len(lista_price_buy) <= 50: 
        lista_number_list.append(my_class_instance.num_var_list())
        lista_price_buy.append(my_class_instance.fun_price_buy())
        lista_mx_buy.append(my_class_instance.fun_mx_buy())

if __name__ == '__main__':
    main()
Related