Global Variable Error in Python List - python

I am working on a function that would take an user's input for four people's names and to append them to a list. However with the code below I get this user error. However, when I declare significant_other as a global variable, I get an invalid syntax error. How would I fix my code?
Traceback (most recent call last):
File "mash.py", line 16, in <module>
print spouse()
File "mash.py", line 13, in spouse
significant_other = signficant_other.append(new_spouse)
NameError: global name 'signficant_other' is not defined
Here is the code.
import random
# import random module
def spouse():
# defined function
significant_other =[]
#empty list
for x in range(4):
# for loop for an iteration of four
new_spouse = str(raw_input("Type a person you would like to spend your life with."))
# new spouse input
significant_other = signficant_other.append(new_spouse)
#significant other gets added to the list
print spouse()
Thanks for your help with this.

You spelt significant_other like this signficant_other
plus you just need to do:
significant_other.append(new_spouse)

change your line:
significant_other = signficant_other.append(new_spouse)
To this:
significant_other.append(new_spouse)
Basically you cannot assign a append method because it by default returns None:
>>> a = []
>>> b = a.append(5)
>>> print b
None
And so if you change your code to signficant_other.append(new_spouse) It still fails because you made a small typo you've spelled significant as signficant

There are a few issues, firstly:
significant_other = signficant_other.append(new_spouse)
.append() will not return a list, it modifies the list and returns None.
Secondly, you're attempting to use print, but the function that you're calling doesn't return what you want, it returns None.
Additionally, there was a spelling issue, but the above two are more important.
Try this:
def spouse():
significant_other = []
for x in range(4):
new_spouse = str(raw_input("...."))
significant_other.append(new_spouse)
return significant_other
print spouse()

Related

Why one variable is accessed globally and other is not in Python?

I am trying to implement a simple BFS code.
Code:
def initalizeVertex():
n = int(input('Enter the no. of vertices.\n'))
for vertex in range(n):
Vertex.append(vertex)
node_adjacency[vertex] = []
def initalizeUndirectedEdges():
n = int(input("Enter the no. of edges.\n"))
print("Enter the space seperated edges.")
for i in range(n):
a,b = map(int,input().split())
node_adjacency[a].append(b)
node_adjacency[b].append(a)
def bfs():
current_level = 1
print(Vertex)
while(current_level_nodes):
for current_node in current_level_nodes:
for child_node in node_adjacency[current_node]:
if node_parent.get(child_node) == None:
node_parent[child_node] = current_node
next_level_nodes.append(child_node)
node_level[child_node] = current_level
current_level_nodes = [node for node in next_level_nodes]
next_level_nodes = []
current_level += 1
print(node_level)
print(node_parent)
def printData():
print(Vertex)
print(node_adjacency)
print(node_parent)
print(node_level)
print(current_level_nodes)
print(next_level_nodes)
if __name__ == "__main__":
root = 0
Vertex = []
node_adjacency = {}
node_parent = {root:None}
node_level = {root:0}
current_level_nodes = [root]
next_level_nodes = []
initalizeVertex()
initalizeUndirectedEdges()
printData()
bfs()
The codes output is :
This code gives me the error:
in bfs
while(current_level_nodes):
UnboundLocalError: local variable 'current_level_nodes' referenced before assignment
Clearly, the bfs() function cannot access the list current_level_nodes. I can solve this by passing the list current_level_nodes to the bfs function.
But, my question is why do I have to pass this list to bfs() function when I haven't passed the list Vertex to initalizeVertex() function and the function could still access and modify it?
Also I haven't passed any parameter to printData function but that function prints all the lists and dictionaries without giving any error.
Python will try to look for the variable at local scope 1st. If they're not found locally, Python will look for them globally.
for example -
In your printData() function -
Python will try to look for the variables locally, but no variables are defined in this method. So, Python will go at the global scope. It'll pick the values and will print them.
def printData():
print(Vertex)
print(node_adjacency)
print(node_parent)
print(node_level)
print(current_level_nodes)
print(next_level_nodes)
In another function bfs() -
Python will see current_level_nodes inside a while, and Python will try to find where the variable is defined. Here things will get tricky as you've assigned the same variable in the function later. This will confuse Python, and it'll throw the error.
line 1. - while(current_level_nodes):
line 2. - current_level_nodes = [node for node in next_level_nodes]
That's why you need to explicitly tell Python that you want to use global variable -
global current_level_nodes
The issue here involves the python compiler having compiled the rest of your function and it realizing that it must bind your variables within the function. This requires the global keyword as previously mentioned.
What is confusing here is that the error is shown on the first usage of the variable and not where the actual problem is. Here is an example:
access_only.py:
global_list = [1,2,3]
def f():
for x in global_list:
print(x)
f()
Here, we run it:
$python access_only.py
1
2
3
Now we change the function slightly to include an assignment to the list, as occurs in your code.
access_and_change.py:
global_list = [1,2,3]
def f():
for x in global_list:
global_list = [1, 2, 3]
print(x)
f()
Here we run it, but get an error on the for line even though the problem actually occurs on the global_list = line:
$python access_and_change.py
Traceback (most recent call last):
File "access_and_change.py", line 9, in <module>
f()
File "access_and_change.py", line 4, in f
for x in global_list:
UnboundLocalError: local variable 'global_list' referenced before assignment
The end result is the same, because you are assigning values to the lists, the global keyword must be used. If you eliminate the assignment within your function, the error goes away completely.
Thinking about this, I noticed that the error message says local variable referenced before assignment. I think the issue here is that because the function contains an assignment, the variable is considered to be local. Whereas if you just reference a global variable it is not considered a local variable. So, the assignment causes the variable to be considered local and the first time you reference it, python throws this error instead of searching the global/parent namespace because the compiler has already determined that it must be a local variable.
You have to define current_level_nodes is global in your bfs function this way :
def bfs():
current_level = 1
global current_level_nodes
...
Edit :
To access a global variable inside a function there is no need to use global keyword.
But if we need to assign a new value to a global variable or change it then we can do that by declaring the variable as global.
Because you used
next_level_nodes.append(child_node)
and
current_level_nodes = [node for node in next_level_nodes]
You need to use global;
If you didn't modify current_level_nodes in your function there was no need to use global

Function not returning random integer for variable

I have a very simple problem, when I run the following code:
from random import randint
def create_random():
x = random.randint(1,4)
return x
print(create_random)
The output comes to this:
< function create_random at 0x7f5994bd4f28 >
Note: every character between "0x7f" and "f28" are random each time the code is run.
My goal was to be able to call the function multiple times with x being assigned a new integer value between 1 and 3 with each invocation.
You aren't actually calling the function. To do this you need to do:
print(create_random())
Just now you're printing the reference to the function which isn't very helpful for you in this case.
You have to call the function, like:
print(create_random())
Also in the function, this line:
x = random.randint(1,4)
Should be just:
x = randint(1,4)
Since you did a from ... import ... statement.
your last line does not do anything, since you want it to print 'create_random' that is not a variable. if you want to call a function, it has to have (). So, you should call it and put it in the print function:
print(create_random())

return statement in python

I tried to code a program but ran into problem with the return statement.
The following lines of code raised an error message saying that the variable names is undefined.
However, I did use the return statement to return names and pass it to the main function:
def main(names):
names_in()
print(names)
# import the record, put it into a list, pass that list to main().
def names_in():
infile = open('names.txt','r')
names = infile.readlines()
infile.close()
index = 0
while index < len(names):
names[index] = names[index].rstrip('\n')
index += 1
return names
main(names)
I've written another program before that did the same thing and everything worked fine, so I'm not sure what's wrong here?
Your problem is here:
main(names)
You are calling your main function with a variable name that hasn't been defined yet. The error you're getting should display a line number that points to this line: that will validate this is where the problem is.
# 'names' is not defined in this scope
def main(names):
# Some code
# 'names' is a variable that is 'in scope' here because it's passed as an 'argument'
# 'names' is not defined in this scope either
# import the record, put it into a list, pass that list to main().
def names_in():
infile = open('names.txt','r')
names = infile.readlines() # defines 'names' for this scope
# more code
return names # because 'names' is defined it can return it
# 'names' is no longer defined in this scope
main(names) # This fails because when the compiler tries to resolve 'names' it can't find anything
Based on what you're apparently trying to do, you need to modify your main function like so:
def main():
print(names_in())
And call it like so:
main()
Note, too, you seem to have some confusion over how code is executed. If I write:
def a():
print("a")
def b():
print("b")
print("c")
b()
a()
It gets translated to something equivalent to:
print("c")
print("b")
print("a")
The def statements get copy-pasted, effectively, into where they are called.
Your main function should not take in any parameter. Instead, it should use the return value from names_in:
def main():
names = names_in()
print(names)
Later in your code:
main()

Iterate over a list of images and assign them as variables in python

I am trying to write a function that iterates over a list of images in python so that they are accessible for Pillow image processing.
ImTestA = Image.open("A.png")
ImTestB = Image.open("B.png")
ImTestC = Image.open("C.png")
ImTest1 = Image.open("1.png")
ImTest2 = Image.open("2.png")
ImTest3 = Image.open("3.png")
ImTest4 = Image.open("4.png")
ImTest5 = Image.open("5.png")
ImTest6 = Image.open("6.png")
I currently have the above but am trying to refactor it into something I can assign different length to (use a list with A-K or J-Z).
from PIL import Image
AtoC = ["A.png", "B.png", "C.png"]
def OpenAns(quest):
AtoCImages = []
for image in quest:
AtoCImages.append(Image.open(image))
return AtoCImages
OpenAns(AtoC)
ImTestA = AtoCImages[0]
ImTestB = AtoCImages[1]
ImTestC = AtoCImages[2]
Fixed earlier error, and went back to same problem as before. I am just trying to clean up my code and have it nice and DRY. Any help is appreciated.
Traceback (most recent call last):
File "C:\ImageTest.py", line 13, in <module>
ImTestA = AtoCImages[0]
NameError: name 'AtoCImages' is not defined
Maybe I will just have separate files with a list in each. If I cant shorten this up.
Change:
for image in AtoC:
AtoCIm = []
AtoCIm.append(Image.open(image))
to
AtoCIm = []
for image in AtoC:
AtoCIm.append(Image.open(image))
will do it.
You are creating a new list every iteration, rather than creating a list once and appending new items to it. Therefore, your list always has only 1 item. Attempting to get the 2nd item, AtoCIm[1], will raise exception.
AToCImages is a list you created within OpenAns() function, hence it is a local variable for that function. Local variables can't be accessed beyond their scope (in this case the OpenAns() function) and are only defined within it. Hence when you try to assign it outside the function,
ImTestA = AtoCImages[0]
ImTestB = AtoCImages[1]
ImTestC = AtoCImages[2]
it throws an error.

Getting Bound method error when calling function from another class

So i have a class called read that is full of Def, im trying to call one of them and i get a 'Bound method' error, what do you think.
from ExcelRead import Read
t = Read()
L = t.other
print L
def Other():
User = []
Excel = []
lst = OpenExcel()
User = OpenFile("whatever.txt")
for item in lst:
Excel.append(str(item.value))
Excel = [line.strip() for line in Excel]
Differ = comp(User, Excel)
print Differ
This is calling other functions
Where other is the name of the function i want to call, this function does return a value. thanks for your help
You aren't getting any error at all here. You're simply printing the function, which is indeed bound.
As with any other function in Python, if you want to call it, you need to use parentheses:
L = t.other()
print L

Categories

Resources