This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 9 years ago.
I need help figuring out why I am getting the following error:
Traceback (most recent call last):
File "prawtest3.py", line 25, in <module>
commentMatcher()
File "prawtest3.py", line 13, in commentMatcher
commentCollection.append(comment)
UnboundLocalError: local variable 'commentCollection' referenced before assignment
This is my code. For background information, I am trying to create a reddit bot that compares a persons comments and then pms a user when the person they are monitoring submits a new comment. If you see a problem with the functionality as well, feel free to share your input. I just need to diagnose my code first to get rid of the syntactical errors before worrying about the semantic ones.
import praw
import time
r = praw.Reddit('PRAW related-question monitor by u/testpurposes v 1.0.')
r.login()
user = r.get_redditor('krumpqueen')
commentCollection = []
commentComparison = []
def commentMatcher():
comments = user.get_comments(limit = 4)
for comment in comments:
commentCollection.append(comment)
time.sleep(60)
comments = user.get_comments(limit = 4)
for comment in comments:
commentComparision.append(comment)
if commentCollection[1] != commentComparision[1]:
r.send_message('krumpqueen', 'just made a new comment', 'go check now')
commentCollection = list(commentComparision)
else:
r.send_message('krumpqueen', 'did not made a new comment', 'sorry')
while(True):
commentMatcher()
Your use of commentCollection makes python (incorrectly1) assume that commentCollection is a local (since you have an assignment to it later and no global statement). When you try to append to the local (which hasn't been created yet) python throws the UnboundLocalError.
1Of course, it's not python making an incorrect assumption, That's how the language is designed to work.
You do commentCollection = list(commentComparision) inside of commentMatcher. Because you've done this, Python concludes you have a local name commentCollection.
Your code fails for the same reason that the code
def foo():
bar.append(3)
bar = []
would fail.
To get commentCollection = list(commentComparision) to a) rebind the global name commentCollection, and b) not make it look like this is a local name at all, add global commentCollection as the first line in the definition of commentMatcher.
In serious code, you wouldn't want to manage your state as globals like this, but rather you'd make an object.
Related
Excuse the debugging question, new to coding in general. Cannot understand why my code suddenly wont run.
I have checked for typos which seems to not be my problem.
filepath = '/proper_noun.txt'
def pluralize(word):
proper_nouns = [line.strip() for line in open (filepath)]
for item in proper_nouns: ### print out the list once.
if (item==[-1]):
break;
currently working in google colab.
At this point, I'm just trying to return the items from 'proper_nouns' into a list to get the ball rolling. Any ideas?
print (proper_nouns)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-29-c6832e0493e8> in <module>()
----> 1 print (proper_nouns)
NameError: name 'proper_nouns' is not define
Thanks guys. I hope this question follows SOF etiquette
Since you are working on Google Colab, my guesss is that you accidentally don't run the code from the beginning (from example if you selected the code starting from for item in proper_nouns: and only run the selected part, or if you split your program in different cells), and therefore proper_nouns is not defined yet.
Please make sure you run everything and tell us if that was it.
EDIT: I just thought of another option: is the line print(proper_nouns) in the pluralize function? If not, the scope of proper_nouns being the function, it's normal that it is not defined outside of the function. To access it from the outside, you must either declare it outside the function, or return it.
Hey stackoverflow community,
i’m new to this forum and to python developing in general and have a problem with Alexa/ Python overriding the similar named variable from different files.
In my language learning skill I want Alexa to specifically link a “start specific practice” intent from the user to a specific practice file and from this file to import an intro, keyword and answer to give back to the user.
My problem with the importing, is that Python takes the last imported file and overrides the statements of the previous files.
I know I could probably change the variable names according to the practices but then wouldn't I have have to create a lot of individual handler functions which link the user intent to a specific file/function and basically look and act all the same?
Is there a better way more efficient of doing the specifying of those variables when importing or inside the functions?
import files and variables
from übung_1 import intro_1, keywords_1, real_1
from übung_2 import intro_1, keywords_1, real_1
working with the variables
def get_practice_response(practice_number):
print("get_practice_response")
session_attributes = {}
card_title = "Übung"
number = randint(0, len(keywords_1))
print(intro_1 + keywords_1[number])
speech_output = intro_1 + keywords_1[number]
session_attributes["answer"] = real_1[number]
session_attributes["practice_number"] = practice_number
session_attributes["keyword"] = keywords_1[number]
reprompt_text = "test"
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
I expected giving out the content of the specifically asked file and not variable content from the most recent files.
Sadly I haven't found a solution for this specific problem and hope someone could help me pointing me in the right direction.
Thank you very much in advance.
Might be easiest to import the modules like so:
import übung_1
import übung_2
The refer to the contents as übung_1.intro_1, übung_2.intro_1, übung_1.keywords_1 and so on.
As you point out, these two lines
from übung_1 import intro_1, keywords_1, real_1
from übung_2 import intro_1, keywords_1, real_1
don't work the way you want because the second import overrides the first. This has to happen because you can't have two different variables in the same namespace called intro_1.
You can get around this by doing
import übung_1
import übung_2
and then in your code you explicitly state the namespace you want:
print(übung_1.intro_1 + übung_1.keywords_1[number])
This question already has answers here:
Calling a function of a module by using its name (a string)
(18 answers)
Closed 5 years ago.
def runtest(testname):
usrdef_sship = sship_e.get()
usrdef_username = username_e.get()
usrdef_pass = pass_e.get()
testresult = cpdiag.testname(cpdiag.ssh(usrdef_sship, usrdef_username, usrdef_pass))
messagebox.showinfo( "Results", testresult)
#Button for disk Test
disktest = Button(top, text="Disk Test", command = lambda: runtest("diskTest")
disktest.grid(row=3,column=0, sticky=W)
#Button for cpwd Test
cpwdtest = Button(top, text="CPWD Test", command = lambda: runtest("cpwdTest")
cpwdtest.grid(row=4,column=0, sticky=W)
Tried to shrink the code for what is necessary. Full code at https://github.com/elta13/cpdiag. The above code, I've been banging my head on it for some time. I'm fairly new to python and have been learning as needed during this, my first project.
I'm using Tkinter to display 3 entry fields which are working to obtain usrdef variables. Then I'm using several buttons, each will call a function from another local file cpdiag.py. Right now, I have been rewriting function for each remote function I call with the only thing that changes being the line with cpdiag."testname".(cpdaig.ssh"etc".)
Current problems:
If I pass on the button runtest(diskTest), inside runtuest this prints as "function diskTest at x0xxxxx" And the code crashes with it trying to call "cpdiag.testname" which doesn't exist in the other local file cpdiag.py.
So then I figured out I could pass runtest("diskTest"), and it would print inside of runtest(). But runtest still tries to call "cpdiag.testname" from the other file. I'm realizing at this point, I don't understand how to call something remotely with a local variable.
So then I tried passing runtest("cpdiag.diskTest"), for which I incurred "'str' can't be called" or of the like.
How can I pass "testname" into runtest(), where "testname" is a function defined in other file cpdiag.py?!?!?
You can get the instance of the method you want to invoke on the object cpdiag using getattr builtin then invoke the method. Something like below:
your_function = getattr(cpdiag, testname) # Get the method first
# Now invoke
your_function(cpdiag.ssh(usrdef_sship, usrdef_username, usrdef_pass))
I get "UnboundLocalError: local variable 's' referenced before assign" in python script on one machine but not on another where the script runs OK. Both machines are on Windows 7 and use Python 2.7.3. Any suggestions what could be the reason for this behaviour? Thank you.
Here's the code that causes the error:
with open(self.temp_dir + test + ".log",'r') as log:
for line in log:
if "INPUT_SENTENCE" in line:
match = patternInput.match(line)
inputSentence = match.group(1).lower()
if inputSentence in self.testToDiagDict[test]:
continue
self.testToDiagDict[test][inputSentence] = []
if "STATS" in line:
if "Input Sentences" in line:
inputSentences = patternValue.findall(line)
self.testToDiagDict[test][inputSentence].append(inputSentences[0])
And the trace:
File "C:\X\Y\X\script.py", line 90, in extract_data
if "Input Sentences" in line:
UnboundLocalError: local variable 'inputSentence' referenced before assignment
The problem is on this line:
self.testToDiagDict[test][inputSentence].append(inputSentences[0])
There is no inputSentence in that scope
So the code might have worked on one machine because this if statement
if "INPUT_SENTENCE" in line:
evaluated to true, but in the case that it doesn't, that is when you get that error. I can't suggest a fix because I don't know what the rest of your code looks like or what you are trying to accomplish, but the much I have pointed out should allow you to reevaluate your design
Perhaps as #inspectorG4dget says - you have a different codepath somewhere. Here is a simple example that could cause your error
def f():
if machine1:
s = 1
else
S = 2
print s
If you would show the code, it would probably take just a few seconds to find
I hope this is an easy one for you guys.
This is my script, for Nuke.
selNodes = nuke.selectedNodes()
for list in selNodes:
if list.Class() == 'Read':
layerArray = []
# Get the list of layers and make unique using set
for chanList in list.channels():
channelLayer = chanList.split('.')
layerArray.append(channelLayer[0])
print list(set(layerArray))
It gives an error:
Traceback (most recent call last):
File "<string>", line 11, in <module>
TypeError: 'Node' object is not callable
So I tried a simpler code of the same nature:
a = [1, 1]
print list(set(a))
And it didn't work. Same error message. Now here's the strange thing: I opened up a new Nuke and ran the simpler codes again, it worked. I couldn't understand why, but I was happy. So I put in my original codes and ran it, error message. I deleted them, the editor is now clean. And ran the simpler code again, error message!!
Which means that a working code can be rendered failure after I pasted and deleted something else!
Can anyone shed some light on this issue? Nuke is a very established software I don't know if it's a software bug.
It is because, you are using list as the loop variable, which hides the builtin function list. You are using that function in
print list(set(layerArray))
The loop variables are leaked even when the loop is over, check this program to understand better
for i in range(10):
pass
print(i)
This will print 9. It means that, i is still available in the program even after the loop is over. The case in your program, after iterating over the selNodes, list variable has the last variable. And you are trying to call that like a function when you say
print list(set(layerArray))
That's why it fails. There are two ways to fix this.
Just change the loop variable to something else.
Use del list when the loop is over. Just pretend that I didn't suggest this. This is NOT recommended. Just change the loop variable to something else.