Odd variable bug with scene
This one had me going for a day or so. I wrote an animation with scene and it drew the wrong thing. I finally traced it down to a variable of mine getting changed outside of my code. I'm guessing I overrode an internal variable accidentally and scene was changing the value.
Simple example to demonstrate. Run it for a second, stop it, see in the console that the variable gets constantly changed.
from scene import * class MyScene (Scene): t = 0.01 def draw(self): print(self.t) run(MyScene())
Is there a better place for variables that persist between draw() calls?
First, instance variables should be defined in
setup-- you defined a class variable which would be a problem if you had more than one instance of your class.
Next, you need to look at the docs for variable names that are not already used. If you override an existing attribute or method name, there probably won't be a warning, yet things won't work. Or dir(Scene), etc
From my early stumblings, I had come to the conclusion that ‘t’ was a Scene variable that correlates to elapsed time. The other related variable is dt.
The scene documentation confirms this:
The time (in seconds) that has passed since the last invocation of update(). You can use this to calculate the progress of custom animations.
The time (in seconds) that has passed since the scene was started. You can use this to calculate the progress of custom animations.
Ok, thanks for the refresher on how Python manages member variables or data attributes. I haven't done a lot of python OOP yet.
So it sounds like scene's internal variables are in the same namespace as the variables we create to perform our animation, and that makes sense now that I've thought about it. I don't know why it surprised me so much. I did read a fair amount of documentation before writing my code, I guess it would have been nice if there had been a mention of avoiding scene's internal variables when introducing scene.
For the benefit of anyone running across this after making the same mistakes here is the fixed version:
from scene import * class MyScene (Scene): # note any variables declared here are class variables (shared by all copies of the class # Also avoid Scene's internal variables like t, dt, etc. setup(self): self.my_t = 0.1 #this is an instance variable, each copy of the class would get it's own def draw(self): print(self.my_t) run(MyScene())