"Redeclared s defined above without usage" - python

for i in range(10):
s = 5
for j in range(10):
s = min(s)
The above code gives the title of this question as warning in IntelliJ for the second line.
I'm pretty sure that the warning happens because in the CFG there are possibly two consecutive writes (without read in between) to s because of the nested loops. Until now I have been ignoring the warning but to be on the safe side I'd like to ask for confirmation of my hypothesis.

Your hypothesis is nearly correct. The name s was bounded to an integer whose value was never used nor changed in the enclosing loop and yet it is rebounded to another value (although that will raise an error) in the nested loop. Note that the first assignment does not change with any iteration of the outer for loop.
The IDE's warning suggests the first assignment inside the loop is unnecessary as s was never changed. The assignment might as well have been better placed outside the for loop which will prevent a redundant binding and rebinding:
s = 5
for i in range(10):
...

It is what it says.
You remade something without using it or defining it.
Like for me, example:
def car(e):
color = "blue"
print(color)
def car(r):
Run
Error, I redefine the function, can't do that as far as I know, I didn't make it do anything.
Thought I was using the function, didn't realize I was re defining it.
correction
def car(e):
color = "blue"
print(color)
car(e)

Related

How to create a repeating loop in python with sympy, without changing one variable in the loop

so basically I have encountered a problem where I have made my loop, but since one of the variables is defined before the actual assignment, the code stops working. the code.
Another thing is that I'm working in Spyder, and I don't know why, but if I try to code so that the program collect variables initially (which is essential for this purpose), the program encounters an internal issue. Any ideas on how to ask for user input in Spyder?
Thanks to everyone in advance
Basically, what I want this to do is to differentiate functions, and the with these derivatives create a maclaurin series. When the actual error ((r-j)/r) is smaller than the stopping variable s, I want the program to stop and display the result, but I don't know what is wrong.
The second thing I want to achieve is to get to know how to gain input from the user in the program.
So, here is, in text form, your code (sorry, plagiarism argument is not valid around here)
q = sympy.Function('q')
q = sympy.diff(f)
def main():
a = sympy.Function('a')
a = sympy.diff(q)
j = sympy.function
j = 1+(1/sympy.factorial(count))*q
r = sympy.Function('r')
r = j+(1/sympy.factorial(count+1))*a
if ((r-j)/r)>s:
count = count + 1
q = sympy.diff(a)
j = r+(1/sympy.factorial(count))*q
r = j+(1/sympy.factorial(count+1))*a
main()
else:
print(f"Answer{r}")
In the middle of an obviously very confused code, and even more confused situation with that "plagiarism" stuff (don't worry, if you have a working code at the end of your effort, there is no way it will look similar enough to your original to be detected as plagiarism because I've posted it here:D) there is actually a good question, and I remember that I while ago I had to scratch my head to understand what was happening in a similar situation.
The problem you have here, is that you can't compute sympy.diff(q) in main function, before assigning something to q in that same function later.
Because of the line q = sympy.diff(a) that you have later, q has to be a local variable (unless you say otherwise, see later). That's default behavior in python: a variable that you assign in a function is a local variable.
But because you are reading this variable before, in the previous line (the one that triggers the error) a = sympy.diff(q), then python has a problem: the local variable a doesn't exist yet.
Without the future q = sympy.diff(a), q would have been "read-only" inside main, and python would have done what you probably expect: read the global variable q.
So, your real problem is not really that line. Your real problem is the line q = sympy.diff(a).
Because even without the current error, that line would not do what you expect it to do. You probably expect it to alter q so that in the subsequent recursive call of main, q has this new value for now on. Not to create a local value q, and have the next call of main start over with the global value of q.
You have several options here.
One would be to declare q has global. Just add line global q at the beginning of your main, and q is now the global variable.
A cleaner way would be to pass q as an argument to main.
Note that you'll have probably the same problem with count. You should also either declare it as global, or, neater way, pass it to main.
Note also that this would solve only syntax errors (well, not even all. j=sympy.function is meaningless for example). But there are many other errors here. The least serious being your strange habit to create a Function and immediately delete it by overwriting it by another function or expression.

Why there is an unbound variable error warning by IDE in this simple python function

Very simple question, but I can't find the answer to it. My IDE vs code (pylance) give me the warning/hint for a being possibly unbound. Why is this? How do I fix it?
def f():
for i in range(4):
a = 1
print(a)
return a
Because range(4) might be something empty (if you overwrite the built-in range), in which case the loop body will never run and a will not get assigned. Which is a problem when it's supposed to get returned.
Maybe you can tell your IDE to ignore this and not show the warning. Or assign some meaningful default to a before the loop.

loop is taking data from outside of loop

full code is here: https://repl.it/repls/UnevenLovingDecagons
line 29 with colony_size=(randrange(50,150)) is outside of loop
then at line 42 loop starts.
colony_size is in line 45 as well.
I would like the colony_size to be influenced by line 29 only once. With second run of loop I'd like the colony_size to be influenced only by what is going on inside of the loop. How can I do so?
part code below:
colony_size=(randrange(50,150))
the one above is still outside of loop
colony_size=(colony_size+immigrants)-died
this one is inside
enter code here
enter code here
enter code here
The concept you're looking at is scope. Loops do not have their own scope in python, the why of this was asked in this question: Scoping in Python 'for' loops
After the following code is executed:
x = 1
i = 1
for i in (2,3,4,5):
x = i
both x and i will contain 5. And the same would be true if they were set or changed in any other kind of loop.
There are several ways to control the scope.. and the most common is functions, which you aren't using in your code. Their variables are contained in their own scope, and you must explicitly pass variables to and from them (using the return keyword). You could also consider comprehensions, although their variables were not contained in the same way in earlier versions of python.
More specifically, in your code.. you may consider putting everything in the while True loop into a function.. (my_function as an example)
while True:
my_function(colony_size)
Or something like that. Then it will use the original colony_size the next time it runs (since you did not return it)
Of course, perhaps the easier option here is to just use a different variable name.
You should have another variable to define a default colony_size at line 29 like:
default_colony_size = (randrange(50,150))
Then define colony_size as a an empty int or just 0 before the loop.
At the start the loop you want to want to do something like this:
if colony_size == 0
colony_size = default_colony_size
Pardon syntax errors as I do not know Python very well

Why am I getting "Local variable unused in function" warning?

I'm new to programming and have just hit my first speed bump since starting this semester. We have been working in python and our latest assignment has us altering a previous program to use functions. I am understanding how to use them and what not, but some small things with local variables I think I lack in some conceptual understanding.
I use pycharm to write my assignments, and I can see it states one of my variables is unused and I don't understand why or how to fix it. I've been tinkering for a couple hours and am lost.
# Function "checkName" takes in 2 parameters
# The first is name, which will be given by user input
# The second is nameList, which comes from the function getNamesList
def checkName(name, nameList):
for i in range(0, len(nameList)):
if name == nameList[i]:
rank = i + 1
break
else:
rank = 0 ## This rank is undefined ##
return rank
Any pointers on what I'm doing wrong? An explanation of the differences between defining local and global variables would be appreciated as well!
You get the error "Local variable 'rank' value not used" on the line rank = i + 1 because the the break statement on the next line causes the the function to end without ever reading the value from rank. This is only the case because your return statement is indented too far. Move it back one level of indentation so it doesn't return until the loop is done and the warning will go away.
def checkName(name, nameList):
for i in range(0, len(nameList)):
if name == nameList[i]:
rank = i + 1
break
else:
rank = 0 ## This rank is undefined ##
return rank
I can tell you that if you hit your 'break' statement, you're not going to be returning anything, because you've got your indentation wrong. You need to take one indentation out of your return.
I can also tell you a little bit about global and local variables, in lay-terms: Any variable you define inside your function, such as 'rank', will not persist outside the function. If you run the above and then try to call 'rank' outside of your function, you'll be calling a blank variable (unless you specifically named another variable 'rank'). This enables you to use rank inside the function without fearing conflict with variables outside the function. In general, you want to avoid making any truly 'global' variables, but a variable named outside of a function is more 'global' than one named inside one.
As for what pyCharm is flagging, I'm not sure, because I don't use the program. Are you calling your function anywhere? It could be letting you know that you're defining your function, and then not calling it.
By reading your code, I understand that this functions returns the rank or the index of a name in a given list of names.
You have a wrong indentation on the return statement.
So to improve your code, check this:
def checkName(name, nameList):
for i in range(nameList):
if name == nameList[i]:
return i + 1
# you don't need an else here, just return -1 or 0 or None ( by default )
# whenever `name` doesn't exists on the nameList
# not very pythonic
return 0
Your code was not always using the local variable rank because of the wrong indentation.
From the point of view of the code as written, rank is defined but not used - you set it and break, so it looks like nothing is done with it. Once again, it's that indent others have mentioned.
Thank you all very much for the quick and helpful replies! My indentation was off, silly error. Honestly don't know how I overlooked it so many times.
I also appreciate the distinction on local variables. I think my previous understanding was alright, but the pycharm note i was getting threw me for a loop.
Probably the shortest it can be:
nameList = ["a", "b", "c"]
def checkName(name, nameList):
return(nameList.index(name) + 1 if name in nameList else 0)
for i in ["a", "b", "c", "d"]:
print(checkName(i, nameList))
Result:
1
2
3
0

Shadows name xyz from outer scope

I am using pycharm and it lists out all the errors/warnings associated with the code. While I understand most of them I am not sure of this one "Shadows name xyz from outer scope". There are a few SO posts regarding this: How bad is shadowing names defined in outer scopes? but then they seem to be accessing a global variable.
In my case, my __main__ function has a few variable names and then it is calling another function sample_func which uses those variable names again (primarily the loop variable names). I am assuming because I am in a different function, the scope for these variables will be local, however the warning seem to suggest otherwise.
Any thoughts? For your reference here is some code:
def sample_func():
for x in range(1, 5): --> shadows name x from outer scope
print x
if __name__ == "__main__":
for x in range(1, 5):
sample_func()
The warning is about the potential danger you are introducing by re-using these names at inner scopes. It can cause you to miss a bug. For example, consider this
def sample_func(*args):
smaple = sum(args) # note the misspelling of `sample here`
print(sample * sample)
if __name__ == "__main__":
for sample in range(1, 5):
sample_func()
Because you used the same name, your misspelling inside the function does not cause an error.
When your code is very simple, you will get away with this type of thing with no consequences. But it's good to use these "best practices" in order to avoid mistakes on more complex code.
The code inside of your if branch of your main function is actually in scope when you're inside of sample_func. You can read from the variable x (try it out). This is okay as you don't really care about it so you have a few options to move forward.
1) Disable shadowing warnings in pycharm. Honestly this is the most straightforward and depending on how experienced of a coder you are it probably makes the most sense (if you're relatively new I would not do this though.)
2) Put your main code into a main function. This is probably the best solution for any production level code. Python is very good at doing things the way you want to do them so you should be careful not to fall into traps. If you are building a module, having lots of logic at the module level can get you into sticky situations. Instead, something like the following could be helpful:
def main():
# Note, as of python 2.7 the interpreter became smart enough
# to realize that x is defined in a loop, so printing x on this
# line (prior to the for loop executing) will throw an exception!
# However, if you print x by itself without the for loop it will
# expose that it's still in scope. See https://gist.github.com/nedrocks/fe42a4c3b5d05f1cb61e18c4dabe1e7a
for x in range(1, 5):
sample_func()
if __name__ == '__main__':
main()
3) Don't use the same variable names that you're using in broader scopes. This is pretty hard to enforce and is kinda the opposite of #1.
It is just a warning, as explained in the linked question there are times when it can cause issues but in you case x is local to your function. You are getting the warning because of the x inside your if __name__ == "__main__": being in globals. It won't have any effect on the x in your function so I would not worry about the warning.
I know this is an old thread and this isn't appropriate for the problem the asker was trying to find out about, but I was searching for an answer to why PyCharm was showing me a 'Shadows name from outer scope' message on a complex if/elif statement block...
It turns out I had capitalised some global variable names at the start of the function but used lower case in my if/elif block much further down in the function.
School boy error I know, but once I corrected this, the 'Shadows name from outer scope' message in PyCharm disappeared and the variables stopped showing as greyed out...
So the lesson I learned is that this PyCharm message may be caused by something as simple as a upper/lower case error in a variable name...
I only realised the problem while I was breaking the function into three functions to see if this would remove the 'Shadows...' error, as I was thinking I had an issue with indentation and this was causing the problem!
This may help another newbie who is scratching their head wondering why they are getting this error :-)
I was running into this warning for an argument in a method named year, but no other variable was sharing that name. I then realized that it was because of the line from pyspark.sql.functions import * which was importing a year variable. Changing this to only import the functionality we needed go rid of the warning.

Categories