I have a very frustrating python problem. In this code
fixedKeyStringInAVar = "SomeKey"
def myFunc(a, b):
global sleepTime
global fixedKeyStringInAVar
varMe=int("15")
sleepTime[fixedKeyStringInAVar] = varMe*60*1000
#more code
Now this works. BUT sometimes when I run this function I get
TypeError: 'int' object does not support item assignment
It is extremely annoying since I tried several test cases and could not reproduce the error, yet it happens very often when I run the full code. The code reads data from a db, access sites, etc. so its hard for me to go through the data since it reads from several sources and depends on 3rd party input that changes (websites).
What could this error be?
Don't use global keyword in a function unless you'd like to change binding of a global name.
Search for 'sleepTime =' in your code. You are binding an int object to the sleepTime name at some point in your program.
Your sleepTime is a global variable. It could be changed to be an int at some point in your program.
The item assignment is the "foo[bar] = baz" construction in your function.
Related
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.
I'm trying to understand how "in memory" works within python. From my understanding it's a variable that is not stored anywhere but just kind of floats in the memory. I'm not exactly sure how to word this correctly.
To clarify I'm using PyKEP module and I'm loading in a SPICE kernel pykep.util.load_spice_kernel('kernel_name.bsp'). Link to the documentation
When I do this I have no new variable in the the global scope. However, it allows me to then access more data (velocity, position, ect) of the asteroid that I would call after as such.
asteroid = pk.planet.spice(spiceID, 'SUN', 'ECLIPJ2000', 'NONE', pk.MU_SUN, mu_self, self_radius, self_radius * 1.05)
I can now use asteroid.eph(epoch) without any errors in the global scope. However, this is not the case if I define it in other places or try to move it.
For example:
example 1: functions
Note pk is the PyKEP module below.
def loadKernel(name = 'de440s_Ryugu.bsp', spiceID = '162173', mu_self = 30.03336, self_radius = 432.5):
pk.util.load_spice_kernel(name)
asteroid = pk.planet.spice(spiceID, 'SUN', 'ECLIPJ2000', 'NONE', pk.MU_SUN, mu_self, self_radius, self_radius * 1.05)
return asteroid
Inside the function's local scope I could use asteroid.eph(epoch) but outside I need to re-execute that first line. Which makes sense. But, why can't I return it to the global scope.
example 2: inside objects/classes
class Trajectory:
def __init__(
self,
seq=[pk.planet.gtoc7(3413), pk.planet.gtoc7(
234), pk.planet.gtoc7(11432)])
# We define data members:
self.__seq = seq
def velAndPos(self):
r, v = self.__seq[i + 1].eph(end)
return r, v
Here I would encounter an error saying that the kernel file is not loaded even if I add pykep.util.load_spice_kernel('kernel_name.bsp') as the first line in the velAndPos method. Why would this be the case? Is it because the __seq is privet?
Further, what is the advantage of using "in memory" variables?
Thank you in advance.
I had a quick look at pykep and I suspect some of the confusion is because it's implemented in C++ and bound to Python.
The kernels, it seems, are binary data files that the load function brings into memory, and then the other pykep functions can access them (again, under the hood it's all C++).
So it's not such a surprise that you aren't seeing the data appear as Python variables.
Now, as for your code - managing data with classes is a good practice. You can actually run arbitrary code in the class definition scope, so I think the following has a decent chance of working:
class Trajectory:
pk.util.load_spice_kernel(name)
def __init__(self, seq=None, name=None):
if seq is None:
# don't use something mutable as your default value,
# else modifying it also modify the default behaviour
seq = [
pk.planet.gtoc7(3413),
pk.planet.gtoc7(234),
pk.planet.gtoc7(11432)
]
# We define data members:
self.__seq = seq
def velAndPos(self):
r, v = self.__seq[i + 1].eph(end)
return r, v
If that doesn't work, you might try having the load call in both methods, but that seems inefficient.
You can create a variable as a "global variable" in the global scope, prior to utilizing it inside of a function definition, and then declare it as "global" inside of the function. Here is an example that may help you:
globvar = 0
def set_globvar_to_one():
global globvar # Needed to modify global copy of globvar
globvar = 1
def print_globvar():
print(globvar) # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar() # Prints 1
And here is a link to a thread that covers this topic: Using global variables in a function
Doing my best to answer your question, but if someone else knows better please correct me in the comments.
How do in memory variable's work?
Linked here you'll see that python and other high-level languages use a symbol table to map a variable name to the address it represents. And from the PyKep docs you'll find that your call to that utility loads the kernel into memory. At this point, the page table of the process that is executing your python process is aware of where the kernel has been loaded.
How it applies to your code (best guess)
It's hard to say exactly without seeing your project structure, but I'll give it a shot. My guess is that you are not properly sequencing your calls to methods/attributes requiring a loaded kernel. For example, if you load the kernel only at the time of a function call, that kernel won't exist in the process until that function is called.
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.
I have a function in a program that I`m working at and I named a variable inside this function and I wanted to make it global. For example:
def test():
a = 1
return a
test()
print (a)
And I just can`t access "a" because it keeps saying that a is not defined.
Any help would be great, thanks.
I have made some changes in your function.
def test():
# Here I'm making a variable as Global
global a
a = 1
return a
Now if you do
print (a)
it outputs
1
As Vaibhav Mule answered, you can create a global variable inside a function but the question is why would you?
First of all, you should be careful with using any kind of global variable, as it might be considered as a bad practice for this. Creating a global from a function is even worse. It will make the code extremely unreadable and hard to understand. Imagine, you are reading the code where some random a is used. You first have to find where that thing was created, and then try to find out what happens to it during the program execution. If the code is not small, you will be doomed.
So the answer is to your question is simply use global a before assignment but you shouldn't.
BTW, If you want c++'s static variable like feature, check this question out.
First, it is important to ask 'why' would one want that? Essentially what a function returns is a 'local computation' (normally). Having said so - if I have to use return 'value' of a function in a 'global scope', it's simply easier to 'assign it to a global variable. For example in your case
def test():
a = 1 # valid this 'a' is local
return a
a = test() # valid this 'a' is global
print(a)
Still, it's important to ask 'why' would I want to do that, normally?
I have read the following posts but I am still unsure of something.
Python Compilation/Interpretation Process
Why python compile the source to bytecode before interpreting?
If I have a single Python file myfunctions.py containing the following code.
x = 3
def f():
print x
x = 2
Then, saying $ python myfunctions.py runs perfectly fine.
But now make one small change to the above file. The new file looks as shown below.
x = 3
def f():
print x
x = 2
f() # there is a function call now
This time, the code gives out an error. Now, I am trying to understand this behavior. And so far, these are my conclusions.
Python creates bytecode for x=3
It creates a function object f, quickly scans and has bytecode which talks about the local variables within f's scope but note that the bytecode for all statements in Python are unlikely to have been constructed.
Now, Python encounters a function call, it knows this function call is legitimate because the bare minimum bytecode talking about the function object f and its local variables is present.
Now the interpreter takes the charge of executing the bytecode but from the initial footprint it knows x is a local variable here and says - "Why are you printing before you assign?"
Can someone please comment on this? Thanks in advance. And sorry if this has been addressed before.
When the interpreter reads a function, for each "name" (variable) it encounters, the interpreter decides if that name is local or non-local. The criteria that is uses is pretty simple ... Is there an assignment statement anywhere in the body to that name (barring global statements)? e.g.:
def foo():
x = 3 # interpreter will tag `x` as a local variable since we assign to it here.
If there is an assignment statement to that name, then the name is tagged as "local", otherwise, it gets tagged as non-local.
Now, in your case, you try to print a variable which was tagged as local, but you do so before you've actually reached the critical assignment statement. Python looks for a local name, but doesn't find it so it raises the UnboundLocalError.
Python is very dynamic and allows you to do lots of crazy things which is part of what makes it so powerful. The downside of this is that it becomes very difficult to check for these errors unless you actually run the function -- In fact, python has made the decision to not check anything other than syntax until the function is run. This explains why you never see the exception until you actually call your function.
If you want python to tag the variable as global, you can do so with an explicit global1 statement:
x = 3
def foo():
global x
print x
x = 2
foo() # prints 3
print x # prints 2
1python3.x takes this concept even further an introduces the nonlocal keyword
mgilson got half of the answer.
The other half is that Python doesn't go looking for errors beyond syntax errors in functions (or function objects) it is not about to execute. So in the first case, since f() doesn't get called, the order-of-operations error isn't checked for.
In this respect, it is not like C and C++, which require everything to be fully declared up front. It's kind of like C++ templates, where errors in template code might not be found until the code is actually instantiated.