invalid syntax when using self.size = size - python

super, super new to Python and programming in general. I have a question that should be simple enough. I'm using a python beginners programming book using Python version 3.1.
I am currently writing out one of the programs in the book and I am learning about how important indentation is when using python so I was fixing those errors I found and then I get to where I put self.size = size and it highlights that self in the code block is invalid syntax but I'm typing this word for word from the manual so I am not sure what I'm doing wrong. Here is the code block:
def _init_(self, x, y, size):
""" Initialize asteroid sprite. """
super(Asteroid, self)._init_(
image = Asteroid.images[size],
x = x, y = y,
dx = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size,
dy = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size
self.size = size
The problem is that last line, it highlights self as invalid syntax but nothing else... Also one last note, when I put this particular block into the shell and try running it there it also gives me a syntax error but not the same one, it gives me one right after the colon on the first line of this block and highlights that entire blank area with red.....and I can't figure why. I was putting it in shell so it could highlight the self thing and help me, but instead shows me something completely different.
Any help will be greatly appreciated! thanks!

You forgot to close the parentheses.
Usually, when you forget to close some parentheses, the interpreted points the error as being in the following line:
def _init_(self, x, y, size):
""" Initialize asteroid sprite. """
super(Asteroid, self)._init_( <-- here you have a parentheses opening
image = Asteroid.images[size],
x = x, y = y,
dx = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size,
dy = random.choice([1, -1]) * Asteroid.SPEED * random.random()/size <-- no more commas here
self.size = size <-- first line without a trailing comma OR parentheses: SYNTAX ERROR HERE! (even though the assignment itself is ok)
Perhaps what the book actually meant was this - as Martijn Pieters pointed out, some of the self.__init__ parameters (x and y) are being passed to the parent's __init__ method, for which other parameters are being read elsewhere (image) or created on-the-fly (dx and dy). Finally, one of the parameters (size) is passed only to the instance, in the body of self.__init__, assigning to self.size:
def __init__(self, x, y, size):
""" Initialize asteroid sprite. """
super(Asteroid, self)._init_(
image = Asteroid.images[size],
x = x,
y = y,
dx = (random.choice([1, -1]) * Asteroid.SPEED * random.random()/size),
dy = (random.choice([1, -1]) * Asteroid.SPEED * random.random()/size))
self.size = size
It is important to know that any method (routine defined inside a class) in Python receives a first argument automatically, which is the object instance itself. Although you might call it what you want, self is the universal Python convention for that. So, when you define __init__ and pass selfas first parameter, you can use it throughout this function to refer to the object you are creating. Thus, saying self.x = x means you want the object to have a x attribute, its value being the x argument you passed upon object creation.

Related

Two consecutive animations synchronised with one longer animation

In particular, I would like to smoothly zoom out and then zoom in all the while an object rotates. I cannot seem to control runtimes separately and I couldn't figure out how to use LaggedStart or Succession to achieve this. I also couldn't make an updater work – the width does not change at all. I'm including the last try on the updater.
class Rectangles(MovingCameraScene):
def construct(self):
rect1 = Rectangle(height=4.2, width=9.3)
staticobj = Rectangle(height=8,width=2,fill_color=BLUE).shift(RIGHT*7)
self.add(rect1,staticobj)
self.camera.frame.set(width=20)
x = ValueTracker(-.99)
def zoom_level(inp):
inp.set(width=math.exp(10 / (x.get_value() ** 2 - 1) + 20))
self.camera.frame.add_updater(zoom_level)
self.play(Rotate(rect1, angle=PI / 2, about_point=ORIGIN),x.animate.set_value(0.99),run_time=5)
self.wait(1)
To whoever stumbles upon this: the solution I came up with in the end was to use UpdateFromAlphaFunc.
class Rectangles(MovingCameraScene):
def construct(self):
rect1 = Rectangle(height=4.2, width=9.3)
staticobj = Rectangle(height=8,width=2,fill_color=BLUE).shift(RIGHT*7)
self.add(rect1,staticobj)
self.camera.frame.set(width=20)
def zoom_level(inp,alpha):
inp.set(width=20+5-20*(alpha-0.5)**2)
self.play(Rotate(rect1, angle=PI / 2, about_point=ORIGIN),
UpdateFromAlphaFunc(self.camera.frame,zoom_level),run_time=5)
self.wait(1)

Read a CSV and interpolate its data

I have a code in which I need the solar radiance. To calculate it I use the Planck function, which I have defined as:
def planck_W(self, x, t):
return (2*self.h*self.c**2/x**5) / (np.exp(self.h*self.c / (self.k*x*t)) -1)
Where x is the wavelength and t is the temperature, and the output is the radiance value.
However I want to be able to use also values coming from a CSV with different solar spectra, which already provides radiance values for different wavelengths. The sturcture of the CSV is Name of the spectrum used, _xx (wavelength), _yy (radiance)
self.spectra_list= pd.read_csv('solar.csv',converters={'_xx': literal_eval, '_yy':literal_eval)
def planck_W(self):
self.spectra_list= pd.read_csv('solar.csv',converters={'_xx':literal_eval, '_yy':literal_eval)
return interp1d( np.array(self._xx)*1e-9,
np.array(self._yy),
kind='linear')
Later I need to use this curve for a calculation at a wavelength range given by another variable, it starts with:
n0 = simpson((planck_W(s.wavelength)...
and I get the error:
planck_W() takes 1 positional argument but 2 were given
I'm kinda new to programming and don't have much idea what I'm doing, how do I manage to make it take the CSV values?
def planck_W(self):
This is the function signature which expects only self. But, while calling the function s.wavelength is supplied.
This causes the the error takes 1 positional argument but 2 were given.
self is not an argument in your case. Since you not pasted whole code I'm just guessing that planck_W() function is a part of a bigger picture which need to a class indeed.
If this is the case your function call should look like this:
n0 = simpson(planck_W())
wavelength value you put in your call is not used anywhere.
Otherwise, if you need that value, you have to add wavelength parameter like this:
def planck_W(self, wavelength):
and then use it inside the function
I hope this explains the situation
You should understand the difference between a function and a method.
Function
A function is a piece of code that may or may not take arguments/keywords and perform some actions.
The main reason for a function to be a thing might be to prevent repeating same code.
Example:
Calculate the sin of a given angle (In radians) See: https://en.wikipedia.org/wiki/Sine#Series_definition
angle = 3.1416
factorial3 = 1
for i in range(1, 4):
factorial3 *= i
factorial5 = 1
for i in range(1, 6):
factorial5 *= i
factorial7 = 1
for i in range(1, 8):
factorial7 *= i
sine = angle - ((angle * angle * angle) / factorial3) + ((angle * angle * angle * angle * angle) / factorial5) - \
((angle * angle * angle * angle * angle * angle * angle) / factorial7)
We can see the repeating pattern here.
The factorial and power are used multiple times. Those can be functions:
def factorial(n):
result = 1
for i in range(1, n+1):
result *= i
return result
def power(base, pow):
result = 1
for _ in range(pow):
result *= base
return result
sine2 = angle - (power(angle, 3) / factorial(3)) + (power(angle, 5) / factorial(5)) - (power(angle, 7) / factorial(7))
Method
A method is a function of a class.
We can create an object from a class and ask questions to the object (using method and attributes) and get results.
When you are calling a method of a class you use name spacing as such:
object_from_class = TheClass()
object_from_class.the_method(*possible_args)
Now you refereeing to the_method of the object_from_class.
The question is what if you want to refer to a method of the object inside the object.
Let's say we have a class which does trigonometric operations. We can have a sin, cos, tan etc.
You see here when we trying to calculate tan we do not need a whole new method. We can use sin/cos. Now I need to refer to the methods inside the object.
class Trigonometry:
def sin(self, angle):
return some_thing
def cos(self, angle):
return some_thing_else
def tan(self, angle):
return self.sin(angle) / self.cos(angle)
self.sin is equivalent of object_from_class.the_method when you are inside the object.
Note: Some languages, such as javascript, usesthis instead of self
Now, in your case, you are calling a method of an object def planck_W(self): which takes no arguments (technically it takes 1 argument but you should provide none) and passing some. That's why python is complaining about what number of arguments.

How to use "lambda" as input inside of a class

I want to use lambda as an input for a class function named Integrator. Inside of the Integrator class, the object should be called based on the current state. I do not know how to introduce these objects to the Integrator class.
Could you please tell me how can I call a created object inside of another class?
Here is the main simulation program:
# create LJ force object
lj_object = LennardJones(self.sigma, self.epsilon, self.compmethod, self.r_cut, self.box_len)
# create spring force object
sp_object = InterMolecularForce (self.oh_len, self.k_b, self.tet_eq, self.k_tet)
# create Integrator object
integrator_object = Integrator (O_mass, H_mass)
for i in range (grid.shape[0]-1) :
timespan = (grid [i], grid [i+1])
lj_force =lj_object (new_postate)
sp_force = sp_object(new_postate)
new_postate[i+1], new_velocity[i+1] = integrator_object (new_postate, new_velocity, lambda new_postate: lj_object (new_postate) + sp_object(new_postate), timespan)
return new_postate, new_velocity
The integrator is :
# calculate half step momenta
momenta_half_step = diag_mass * velocity + (force * (timespan[1] - timespan[0]) / 2)
position_full_step = posate + (timespan[1] - timespan[0]) * np.dot (inv(mass_matrix), momenta_half_step)
# calculate forces
lj_force = lj_object (position_full_step)
spring_force = sp_object(position_full_step)
force = lj_force + spring_force
momenta_full_step = momenta_half_step + ( timespan[1] - timespan[0] ) * force / 2
I have a strong feeling that I have missed the point here. But without attempting any of the complex applied mathematics your code is doing, here is a simple, bare-bones approach to passing a function defined in a lambda statement and passing it to a class to use.
class Operation:
def __init__(self, operator):
self.operator = operator
def compute(self, *operands):
return self.operator(operands[0], operands[1])
>>> addition=Operation(operator=lambda a,b: a+b)
>>> multiplication=Operation(operator=lambda a,b: a*b)
>>> addition.compute(3,5)
8
>>> multiplication.compute(3,5)
15
This is deliberately simplified and contrived: it does no type checking, it neither handles nor rejects operators that are not dyadic, and all in all it is not very useful. Its only purpose is to show how to call the function that was passed into the class, which seems to be the fundamental point of your question.

Make Hatch object in AutoCAD by the use of COM

I`m working with AutoCAD drawing using Python language and comtypes library. This is fragment of my code:
from comtypes.client import *
from comtypes.automation import *
def connect_acad(self):
self.acad = GetActiveObject("AutoCAD.Application")
self.dwg = self.acad.ActiveDocument
self.mspace = self.dwg.ModelSpace
def mark_point(self, xy, num, lay):
def point(*args):
lst = [0.]*3
if len(args) < 3:
lst[0:2] = [float(x) for x in args[0:2]]
else:
lst = [float(x) for x in args[0:3]]
return VARIANT(array("d",lst))
def variant(data):
return VARIANT(VT_VARIANT, data)
def vararr(*data):
if ( len(data) == 1 and
isinstance(data, collections.Iterable) ):
data = data[0]
return map(variant, data)
p1 = point(xy[0], xy[1])
ent = self.mspace.AddCircle(p1, 0.3)
htch = self.mspace.AddHatch(0, 'SOLID', False)
htch.AppendOuterLoop(vararr([ent,]))
htch.Evaluate()
If anyone interested, full code here: https://github.com/nsedenkov/py_acadcoord/blob/master/acadcoord.py
And anything works correctly, but command htch.AppendOuterLoop raises exception "ComTypeError". Probably, anyone knows the right way to make variant array from AutoCAD graphical entitys for method AppendOuterLoop? Thank you!
The expected types are:
Type: Variant (array of Arc, Circle, Ellipse, Line, Polyline, Region, Spline objects)
And I would also recommend double check the condition:
An array of objects forming a closed boundary. The array can consist of one or more objects. If more than one object is used, their endpoints must coincide for the loop to be created properly.
See complete documentation at http://knowledge.autodesk.com/support/autocad-mechanical/getting-started/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-4CA06494-CDFF-46FA-9E1D-A0E8220F69F4-htm.html

Class or Metaclass Design for Astrodynamics Engine

Gurus out there:
The differential equations for modeling spacecraft motion can be described in terms of a collection of acceleration terms:
d2r/dt2 = a0 + a1 + a2 + ... + an
Normally a0 is the point mass acceleration due to a body (a0 = -mu * r/r^3); the "higher order" terms can be due to other planets, solar radiation pressure, thrust, etc.
I'm implementing a collection of algorithms meant to work on this sort of system. I will start with Python for design and prototyping, then I will move on to C++ or Fortran 95.
I want to design a class (or metaclass) which will allow me to specify the different acceleration terms for a given instance, something along the lines of:
# please notice this is meant as "pseudo-code"
def some_acceleration(t):
return (1*t, 2*t, 3*t)
def some_other_acceleration(t):
return (4*t, 5*t, 6*t)
S = Spacecraft()
S.Acceleration += someacceleration + some_other_acceleration
In this case, the instance S would default to, say, two acceleration terms and I would add a the other two terms I want: some acceleration and some_other_acceleration; they return a vector (here represented as a triplet). Notice that in my "implementation" I've overloaded the + operator.
This way the algorithms will be designed for an abstract "spacecraft" and all the actual force fields will be provided on a case-by-case basis, allowing me to work with simplified models, compare modeling methodologies, etc.
How would you implement a class or metaclass for handling this?
I apologize for the rather verbose and not clearly explained question, but it is a bit fuzzy in my brain.
Thanks.
PyDSTool lets you build up "components" that have spatial or physical meaning, and have mathematical expressions associated with them, into bigger components that know how to sum things up etc. The result is a way to specify differential equations in a modular fashion using symbolic tools, and then PyDSTool will create C code automatically to simulate the system using fast integrators. There's no need to see python only as a slow prototyping step before doing the "heavy lifting" in C and Fortran. PyDSTool already moves everything, including the resulting vector field you defined, down to the C level once you've fully specified the problem.
Your example for second order DEs is very similar to the "current balance" first-order equation for the potential difference across a biological cell membrane that contains multiple types of ion channel. By Kirchoff's current law, the rate of change of the p.d. is
dV/dt = 1/memb_capacitance * (sum of currents)
The example in PyDSTool/tests/ModelSpec_tutorial_HH.py is one of several bundled in the package that builds a model for a membrane from modular specification components (the ModelSpec class from which you inherit to create your own - such as "point_mass" in a physics environment), and uses a macro-like specification to define the final DE as the sum of whatever currents are present in the "ion channel" components added to the "membrane" component. The summing is defined in the makeSoma function, simply using a statement such as 'for(channel,current,+)/C', which you can just use directly in your code.
Hope this helps. If it does, feel free to ask me (the author of PyDSTool) through the help forum on sourceforge if you need more help getting it started.
For those who would like to avoid numpy and do this in pure python, this may give you a few good ideas. I'm sure there are disadvantages and flaws to this little skit also. The "operator" module speeds up your math calculations as they are done with c functions:
from operator import sub, add, iadd, mul
import copy
class Acceleration(object):
def __init__(self, x, y, z):
super(Acceleration, self).__init__()
self.accel = [x, y , z]
self.dimensions = len(self.accel)
#property
def x(self):
return self.accel[0]
#x.setter
def x(self, val):
self.accel[0] = val
#property
def y(self):
return self.accel[1]
#y.setter
def y(self, val):
self.accel[1] = val
#property
def z(self):
return self.accel[2]
#z.setter
def z(self, val):
self.accel[2] = val
def __iadd__(self, other):
for x in xrange(self.dimensions):
self.accel[x] = iadd(self.accel[x], other.accel[x])
return self
def __add__(self, other):
newAccel = copy.deepcopy(self)
newAccel += other
return newAccel
def __str__(self):
return "Acceleration(%s, %s, %s)" % (self.accel[0], self.accel[1], self.accel[2])
def getVelocity(self, deltaTime):
return Velocity(mul(self.accel[0], deltaTime), mul(self.accel[1], deltaTime), mul(self.accel[2], deltaTime))
class Velocity(object):
def __init__(self, x, y, z):
super(Velocity, self).__init__()
self.x = x
self.y = y
self.z = z
def __str__(self):
return "Velocity(%s, %s, %s)" % (self.x, self.y, self.z)
if __name__ == "__main__":
accel = Acceleration(1.1234, 2.1234, 3.1234)
accel += Acceleration(1, 1, 1)
print accel
accels = []
for x in xrange(10):
accel += Acceleration(1.1234, 2.1234, 3.1234)
vel = accel.getVelocity(2)
print "Velocity of object with acceleration %s after one second:" % (accel)
print vel
prints the following:
Acceleration(2.1234, 3.1234, 4.1234)
Velocity of object with acceleration
Acceleration(13.3574, 24.3574, 35.3574) after one second:
Velocity(26.7148, 48.7148, 70.7148)
You can get fancy for faster calculations:
def getFancyVelocity(self, deltaTime):
from itertools import repeat
x, y, z = map(mul, self.accel, repeat(deltaTime, self.dimensions))
return Velocity(x, y, z)
Are you asking how to store an arbitrary number of acceleration sources for a spacecraft class?
Can't you just use an array of functions? (Function pointers when you get to c++)
i.e:
#pseudo Python
class Spacecraft
terms = []
def accelerate(t):
a = (0,0,0)
for func in terms:
a+= func(t)
s = Spacecraft
s.terms.append(some_acceleration)
s.terms.append(some_other_acceleration)
ac = s.accelerate(t)
I would use instead some library which can work with vectors (in python, try numpy) and represent the acceleration as vector. Then, you are not reinventing the wheel, the + operator works like you wanted. Please correct me if I misunderstood your problem.

Categories