I actually don't have any question about my code but i use a ide named pycharm while running my code i don't get any error but my ide gives me a warning why is that so?
Here's my code :
def hi():
global d
d = 5
hi()
print(d)
My code works fine but my ide gives me a warning at line 2 of my code which is Global variable 'd' is undefined at the module level.
Did i do anything wrong in my code i just created a global variable through a function and accesed it outside the function.
does anyone know why this is happening?
As you said there is no error, just a warning. You can look up the different inspection severity levels here
I quote from this website:
Warning: marks code fragments that might produce bugs or require enhancement.
So Pycharm is trying to tell you that using global in this way could lead to bugs down the line, especially if your code gets more complicated. This warning appears so that you get a change to rethink how your code works and that there are maybe better ways to achieve the same goal.
In this case the warning comes from the fact that d is undefined at the module level, which can be fixed by defining it, e.g. at the top.
d = 11
In general there are many reason why one should avoid the global keyword (see discussion here), but if you know why you are using it then its fine.
Global variables are never recommended as they could produce errors in the future as see Why are global variables evil?
your code should be
def hi():
return 5
print(hi())
If you just want to get rid of the warning "Global variable 'd' is undefined at the module level."
You could declare the desired global variable and don't not assign a value (None) with type hints.
d :str
d :str
def hi():
global d
d = 5
hi()
print(d)
Related
I have a working interview (yay!), and I'm working on refactoring it. I'm trying to figure out what might be a good way to move my code blocks into .py files. In particular, I'm worried about maintaining some of the fancy things docassemble does (the particular code block I'm thinking about is marked initial: True, for example).
Would the idea be to convert whatever your code blocks are doing into functions, and then assign the variables docassemble is looking for in a way that uses those functions? Presumably the results of those functions still need to be dealt with in code blocks?
Is the below roughly the right approach (code below)? I'm assuming that:
Trying to run Bcode.func(A ...) as below, if A was undefined, would trigger the exception necessary to cause docassemble to search for the question needed to set A?
Variables can be passed as set out below.
returning from functions works as set out below.
Are any / all of these assumptions correct / incorrect?
So...
If this was my questions.yml file:
---
question: A?
yesno: A
---
# code setting value of B
---
code: |
if A:
answer = "A"
elif B:
answer = "B"
else:
answer = "C"
---
To abstract away the code, I assume I might do something like this?
questions.yml:
---
imports:
- Bcode
---
question: A?
yesno: A
---
initial: True
code: |
answer = Bcode.func(A, *args_to_set_value_of_B)
---
Bcode.py:
---
def func(a, *args_to_set_value_of_b):
# code computing value of b
if a:
return "A"
elif b:
return "B"
else:
return "C"
---
If you do
modules:
- .Bcode
Then docassemble will run (in effect):
exec("from docassemble.yourpackage.Bcode import *", user_dict)
where user_dict is the interview answers (the namespace of Python code in your YAML file). This will make the name func available in the namespace of your interview so that it can be used in code blocks, Mako templating, etc.
Your initial block will raise an exception because Bcode is not a name in the interview answers.
Your function func() will always raise an exception whenever a is true, because b is not defined in the namespace of func().
Docassemble works by trapping NameError, IndexError, and AttributeError exceptions and then looking for a question or code block that will define whatever variable was undefined. NameError exceptions work with any type of variable, but IndexError and AttributeError exceptions only work on instances of DAObject or subclasses thereof.
When you move code into module files, it is important to make sure that the code in the module file does not raise NameError exceptions, because those will cause confusion; docassemble will try to define the variable in the interview answer namespace, but this will never fix the problem inside the module because that name will be undefined inside the module no matter what. However, it is safe for code in a module file to raise IndexError and AttributeError errors on DAObject variables that have been passed from the interview namespace to the module namespace, because when docassemble defines those variables in the interview answer namespace, the definitions will be available inside the module as well.
I would avoid moving code into a module that doesn't have a clear interface. It's totally appropriate to have code blocks in the YAML that contain interview logic. I keep modules for reusable, abstracted code.
I am working on developing a large-scale Python (backend) project. I was working with a firm that does extensive testing, and they built the frontend and test tools. Before every deploy, all the tools (like linters) are run regularly.
I had put down the code for a while, and now it fails many tests. Some of these are deprecation warnings for features or syntax soon to be deprecated, and they note they started classifying those as warnings (to later become errors) starting January 1, 2020, so I know they make dynamic changes in the tools themselves.
My problem is a bunch of code that used to pass no longer does. And the error is always the same: if I have a line that looks like so, I get an error that says something along the lines of "error: may not use operator '-' with incompatible types; a and b are of types numpy.array and NoneType":
x = a - b
This gets fixed by making the code super-messy with this sort of fix:
x = a.astype(float) - b.astype(float)
It's even worse because in the actual code there are 3 variables, all doing addition and subtraction with a 'c' that is an integer array kicking around along with the two numpy arrays. But then the code goes from:
x = a - b - c
to:
x = a.astype(float) - b.astype(float) - c.astype(float)
And this won't work since int's don't have an astype method. The error looks like this now:
File "/home/engine.py", line 165, in Foo
lower_array[t].astype(float)) / num_values.astype(float)
AttributeError: 'NoneType' object has no attribute 'astype'
Thus, I end up with:
x = a.astype(float) - b.astype(float) - float(c)
This is all extraordinarily cumbersome and nasty casting that is required, and makes the code impossible to read.
The odd thing to me is that all three arrays were instantiated as numpy arrays, i.e.,:
a=numpy.array(_a)
b=numpy.array(_b)
c=numpy.array(_c)
When I ask the code to put output to stdout the type of all three vars, they all say . Yet, the next line of code blows up and dumps, saying "Attribute error: 'NoneType' object has no attribute 'astype'"
I can't fathom how a static code analyzer determines the types - other than as numpy.ndarray type - since Python uses duck-typing. Thus, the type could change dynamically. But that's not the case here; all three vars are identified as numpy.ndarray type, but "z = a - b - c" fails.
Anyone understand what's going on here?
After much work, the answer is to ignore the linter. Readable code is the object, not code that satisfies a linter.
I am getting a weird problem. I call the same method against instances of a class and they work fine. But somewhere along the line of running the programs I lose the object reference and now it shows me trying to make a call against my class instead. Here is what I see in the debugger for a good call:
<Move.Move object at 0x0000000003F362E8> (object reference)
but later I will just get a
<Move.Move class> (class reference)
How am I at times losing my object reference and instead getting a class reference.
Famous last words, I have checked my code against my change files and don't see any changes in this area.
Any thoughts or suggestions are appreciated.
Code as requested. Hope it helps.
for move in moves:
if move.targetStack is not None:
t = t+1
bestMove = move #Just need to have one to compare to
if t==0:
break
try:
for move in moves:
if move.targetStack is None:
continue
elif move.highCard.rank > bestMove.highCard.rank:
P.S. This raises AttributeError instead. But has same cause of referencing the Move class and not an instance. It works for about 6 full cycles before breaking.
Found my problem. It was a capitalization issue. In of my cases it was assignin Move (the name of the class) to the variable bestMove. Sometimes I miss type safe languages!
I would like PyCharm to warn me on the following python3 code:
def foo() -> str:
return 'abc'
x: int = foo() # I want to be warned here
Is there an option I can enable to get this warning?
The motivation here is that I have functions whose return-types are not as easily deducible at first glance like in this example. I want to declare what I think the types of my variables should be, for readability, and I want PyCharm to deduce whether what I think is correct.
Turns out this is an open issue in PyCharm (PY-24832).
I'm having trouble with the input() function in Python3.4 using the Anaconda integrated editor. If I just type
x = input()
into the editor, it returns a blank line that I can type text into. If I type:
foo
into this line, I would expect 'foo' be stored as a string with variable name x. But, instead I get:
NameError: name 'foo' is not defined
To make the function work as expected, I must instead type in:
'foo'
which is unfortunate because what I really want is just to pause my code and wait for an arbitrary user input, and I read somewhere that "wait = input()" is the most pythonic way to do this. Using that line in my actual script returns an "unexpected EOF" error - I assume as another symptom of the same problem. Can anyone suggest a workaround?
Note: I suspect this is an Anaconda-specific problem, given the following reference:
https://docs.python.org/3.4/library/functions.html#input
Thanks for your time.
Your code is being run by Python 2, not 3. I don't know enough about Anaconda to know if the problem is with their editor, or if you have your path messed up, but the problem is that the wrong version of Python is being used.