I am trying to build a simple chatbot, but it says "Local variable 'cb_answer' value is not used" for multiple states and "cb_answers"'s. Hence the chatbot doesn't give me an answer, when I run the program. I attached a screenshot from the code.
enter image description here
Local variable 'cb_answer' value is not used is a warning not an error.
The problem is that you are creating a variable inside of your ifs. You won't be able to access it outside of the if you created it in. To fix this put:
cb_answer = None
state = None
At the top of your function.
And like #luk2302 mentioned the return should be one less indented.
Related
PyPDF2 update page form field values function working fine with hardcoded strings but nothing shows if using variable text.
I have tried using string variables like this
writer.update_page_form_field_values(
#writer.pages[0], {"Piece Weight": variableString} doesn't work
writer.pages[0], {"Piece Weight": "hardcoded string"}#works
)
as well as like this
writer.update_page_form_field_values(
#writer.pages[0], {"Piece Weight": f"{variableString}"} doesn't work
writer.pages[0], {"Piece Weight": "hardcoded string"}#works
)
I am expecting the final output file to show the text I store into a string variable within the field named "piece weight" but what actually happens is absolutely no data is displayed on in the field when a variable is applied to it.
UPDATE-
found that my issue was not that it refuses to show variable data, rather it was a matter of, my variable data not being updated after it is initialized. I am creating it at one point
variablestring = ""
and then later in the code i am attempting to change it within a function
def onStart():
variablestring = variableEntry.get()
This is an issue of scope as the variablestring within the function and outside the function are seen as separate memory spaces.
there in lies an issue however, I can not pass this function parameters as it needs to be automatically called by a
tkinter.Button(form, text="start", command=onStart)
Final answer to my issue was to use the global tag to call the variable outside of the function into it.
variable = "te"
def onStart():
global variable
variable = variableEntry.get()
when reading about globals for python i misunderstood it as a declarative global and not a call global
As far as I understand variables initialised inside if statments are scoped to the function but the following code is throwing up UnboundLocalError: local variable 'seq_name' referenced before assignment errors
def scraper(filename):
if 'Identified secondary metabolite regions using strictness' in line:
seq_name = readfile[i + 1].split('_')[0]
if seq_name in line
I have shortend the code to contain only the relavent bits. I am unsure how to fix this error given that my understanding is correct. Please correct me if it is not.
Your understanding of scope is correct. Variables initialized inside if blocks are scoped to the enclosing function.
However, it's still possible (as is happening here) to skip the condition in which you assign the variable, and thus never have assigned it at all. UnboundLocalError: local variable 'seq_name' referenced before assignment is the error message for whenever a variable hasn't been assigned in the current scope yet, even when it could have been. You have to account for that possibility in your code - an else clause is the easiest way to do that.
I am trying to figure out how to pass variables between (both directions) a python file and RobotFramework. I am aiming to have a function in python gather values (folder names) and store them in a variable to then be used by another function which will then test each folder name in succession. I am aiming to leverage RF's test reporting feature to generate a pass/fail report of which folders pass/fail.
(The folder names/locations will change which is why I do not want to hard code them and instead have opted to use some code to gather the folder names via a file picker menu - but the implementation of this will come once I get these more basic issues resolved :) )
I have found this example about getting a variable from a python file and having RF recognize it and do something with it - in this case Log To Console. how to pass values from python code to variable of robot framework
I have tried the example in the link and it does work. The first bit of trouble I run into is when a put the variable inside a function.
So my Python File (test.py) looks like this:
def create_the_thing():
a = 'Testing'
def do_the_thing():
print(a)
My RF file (test.robot) looks like this:
*** Settings ***
Variables C:/.../Desktop/test/test.py
Library C:/.../Desktop/test/test.py
*** Test Cases ***
Make Something
Create The Thing
Log To Console ${a}
Do Something
Do The Thing
I would expect that 'Create The Thing' would run, which would make the variable 'a'. I would then think that variable 'a' would be passed back to RF (as it is in the linked example), which then would log it to the console.
I am at a loss as to how to get the variable 'a' passed between the 2 test cases. Perhaps the Set Global Variable keyword?
Instead, I see "Variable ${a} not found" as the error for the first test and "NameError: global name 'a' is not defined" as the error for the second test.
I get that test 2 is failing because the variable is never passed back to RF in the first test, but is there not a way to have tests run as keywords and then return a variable that can be used later on in other tests?
Adding a new section to show how I am using the answer form Todor to solve my issue since comments are not accepting code.
Fixed Python file:
def create_the_thing():
a = 'Testing'
return a
def do_the_thing(thing):
print(thing)
Fixed RF file:
*** Settings ***
Variables [path_to_py_file]
Library [path_to_py_file]
*** Test Cases ***
Make Something
${thingy} Create The Thing
Set Global Variable ${thingy}
Do Something
Do The Thing ${thingy}
Now to see if I can get this all to work with Sikuli's implementation of RF :)
Perhaps you should read some more about variables scope in python - here's a bit too technical explanation, a relevant entry in the language's FAQ and something lighter.
In essence, if you define a variable inside a function, it is bound to it, and its scope is limited to the function (e.g. its lifetime is only during the function execution). When the execution point leaves the function, that variable is no longer present.
When you think of it, this makes perfect sense - you don't want your global namespace polluted with all intermediate variables you used, plus that would lead to a lot conflicts and unexpected side effects.
And this is what happened with your code - the function create_the_thing() defined a variable - which was local to it, and not visible/existent for any other function in the same module.
I'm sure your code as given will throw the same NameError exception when you run it through python interpreter, no Robotframework involved.
There are different solutions to your problem, here are a couple.
Use returned values and argument passing.
This is the cleanest one - the function generating something (the files list in your case) returns it at the end of its execution; the function that uses a generated something (the same files list) accepts it as a calling argument. Thus you have isolation - each of them has a single (and different) purpose, and they don't have a hard dependency on one another. In python speak:
def create_the_thing():
a = 'Testing'
return a
def do_the_thing(thing):
print(thing)
the_thing = create_the_thing()
do_the_thing(the_thing)
Usage in RF:
${thingy}= Create The Thing
Do The Thing ${thingy}
Use global variables.
A global variable is one defined at module scope level, and available to all its functions. Being available throughout you have to be careful in their usage (they are a shared state, with all the consequences of that), but are quite handy. So in python:
a = 'I am global!'
def create_the_thing():
global a
a = 'Testing'
def do_the_thing():
print(a)
do_the_thing()
# you get "I am global!"
create_the_thing()
do_the_thing()
# and now - "Testing"
As you can see, the change was defining the variable as such by using the global keyword, thus instructing the interpreter all changes are for the global variable "a", not for one limited to the scope of the function.
Usage in Robotframework - the same as in your sample.
There are also other approaches - like using the RF's Set Global/Suite/Test Variable, inside the python code or in RF keywords; it boils down to design choices.
If you want to get Varialbe a from your python function you should create one variable in RF for receive value from python function and you can do following below code
${a}= Create The Thing
Set Global Variable ${a}
Log To Console ${a}
and your python code should be use return for return value
def create_the_thing():
a = 'Testing'
return a
and here the link for Pass variables from python file to robot framework variables link here .
I'm new to django (and programming in general) and I am trying to create a Reviewboard extension.
This extension will display the fullname of the user in a column. The code works for the most part, however I don't understand what the state variable in this method does.
# renders column to display
def render_data(self, state, review_request):
# returns user's fullname (or username if fullname does not exist)
user = review_request.submitter
return user.get_full_name() or user.username
This code works, however when I remove the 'state' argument, the field shows 'None' instead of the fullname of the user. I tried looking online but I could not find an explanation for what that variable does.
I dont even call it in my method, yet it still affects the result.
I don't like having code that I don't fully understand (harder to debug), so could someone shed some light on this?
What I think it means
I think state refers to the instance of the object. In this case it would be the review_request that the fullname is being rendered for. Without this instance, one review request can't be differentiated from all of them. I still don't know how it affects the code without me even calling it.
Edit: C14L was right, I renamed state to foobar and my code still functioned properly. I dug a bit more into the source of the djblets/django code where it calls the function.
rendered_data = self.render_data(state, obj)
In the code you posted, state isn't used at all. But, if you remove it, then review_request will be the second argument. But this function is called, expecting review_request to be the third argument. You can't just change the number or order of arguments, because the callers don't know about that. Try renaming state to foobar and the function will still work as before.
You can just leave state there, that's perfectly fine. The interface of the function/method shouldn't change only because one of the arguments isn't used (anymore) inside the function or method.
We discussed in my job about the following piece of Python code (maybe an anti-pattern):
if conditional_variable_:
a = "Some value"
print a
Supose conditional_variable was defined but a variable didn't.
The question is about using a variable without declaring it. The variable a is created inside a piece of code that maybe never will be executed but it is used.
Maybe that fix may repair the anti-pattern:
a = "default value"
if conditional_variable:
a = "changed_value"
print a
In that case, a variable was defined before use it. Consider print a like a ussage of the a variable.
It is not an anti-pattern. It is a bug.
Python has no 'declarations', only binding operations; a name is either bound, or it is not. Trying to access a name that hasn't been bound to yet results in an exception.
Unless your code specifically handles the exception and expected it, running into a NameError or UnboundLocalError exception should be considered a bug.
In other words, code that tries to reference a name should always be subject to the same conditions that bind the name, or be prepared to handle the exception that'll be raised if those conditions don't always hold. Giving your variable a default value outside the if statement means it is bound under all circumstances, so you can also reference it always.