loop is taking data from outside of loop - python

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

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.

Running function code only when NOT assigning output to variable?

I am looking for a way in python to stop certain parts of the code inside a function but only when the output of the function is assigned to a variable. If the the function is run without any assignment then it should run all the inside of it.
Something like this:
def function():
print('a')
return ('a')
function()
A=function()
The first time that I call function() it should display a on the screen, while the second time nothing should print and only store value returned into A.
I have not tried anything since I am kind of new to Python, but I was imagining it would be something like the if __name__=='__main__': way of checking if a script is being used as a module or run directly.
I don't think such a behavior could be achieved in python, because within the scope of the function call, there is no indication what your will do with the returned value.
You will have to give an argument to the function that tells it to skip/stop with a default value to ease the call.
def call_and_skip(skip_instructions=False):
if not skip_instructions:
call_stuff_or_not()
call_everytime()
call_and_skip()
# will not skip inside instruction
a_variable = call_and_skip(skip_instructions=True)
# will skip inside instructions
As already mentionned in comments, what you're asking for is not technically possible - a function has (and cannot have) any knowledge of what the calling code will do with the return value.
For a simple case like your example snippet, the obvious solution is to just remove the print call from within the function and leave it out to the caller, ie:
def fun():
return 'a'
print(fun())
Now I assume your real code is a bit more complex than this so such a simple solution would not work. If that's the case, the solution is to split the original function into many distinct one and let the caller choose which part it wants to call. If you have a complex state (local variables) that need to be shared between the different parts, you can wrap the whole thing into a class, turning the sub functions into methods and storing those variables as instance attributes.

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

What are blocks of code in Python? The definitions are all confusing

I have looked up definitions, but all of them seem confusing.
Sorry I am a very new to this and I would improve it if there were a simpler way of putting it.
A code block is a group of statements that will be run as a unit.
For example:
if (condition):
# Statement 1
# Statement 2
# Statement 3
else:
# Statement 4
# Statement 5
# Statement 6
You will find that statements 1,2,3 will have the same indentation and therefore is of the same block.
And similarly, statements 4,5,6 is of a another block.
You may refer to:
Execution model
Flow of Control in Python
When we say "block" we mean an element of code nested inside another syntactical element, like a method or function, or a structure like if or for.
The exact definition depends on your language's syntax tree, something that's formally defined.
All of your programs, consist of too many blocks.
A block is just a concept and you can't see it like as function. A block is the structure of code to separate part of the code from another part of the code.
A function is a block, and classes are blocks and self consist of many blocks inside.

"Redeclared s defined above without usage"

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)

Categories