tags:

views:

89

answers:

6

Hi

I have a class as follows:

class X:
    def __init__(self):
          self.sum_x =0.0
          self.sum_x_squared=0.0
          self.var_x =0.0
          self.sum_y =0.0
          self.sum_y_squared=0.0
          self.var_y =0.0

    def update(self,data):
         [x,y,vx,vy]=data
         self.update_sums(self.sum_x,self.sum_x_squared,x)
         self.update_sums(self.sum_y,self.sum_y_squared,y)
         .


    def update_sums(self,sums,squares,val):
          sums += val
          squares += val*val
          .

I would like to pass the member variables sum_x, sum_x_squared etc to the update_sums function for update how do I do this, I am confused.

Thanks

A: 

self.sumx, self.sum_x_squared?

MadKeithV
+1  A: 

No need. You have direct access to self.sumx, etc.

Are you sure that the functions do belong to the class X? You seem to be missing semicolon and whitespace formatting.

Hamish Grubijan
+1  A: 

You don't have to pass them, update_sums can access them just like update can.

Nikola Smiljanić
+2  A: 

you don't need to pass nothing but the self, which you're mandated to do anyway:

def update_sums(self, val):
    self.sum += val
    self.sum_squared += val * val
    ...

the call will be the following: self.update_sums(x)

The way you designed the class so far is not very useful or flexible, I'd suggest something along these lines:

class X:
    def __init__(self):
          self.sums = [0] * 4
          self.sums_squared = [0] * 4

    def update(self, data):
         self.update_sums(data)

    def update_sums(self, vals):
          self.sums = [i + j for i, j in zip(self.sums, vals)]
          self.sums_squared = [i + j*j for i, j in zip(self.sums, vals)]

It's still no ideal, because I don't know what the purpose of this whole thing is, but it's better then to have all those values.

SilentGhost
ThanksBut if I want to call update_sums with say y to update sum_y , would I need another function just for sum_y?. In C I would pass a pointer, how is this acheived in Python?
mikip
Hi Thanks,I am trying to keep a running sum and sum of the squares of a set of values x,y,vx,vy. I receive these in a list I want to store the running sums in my class. I'm sorry but I dont understand your code, I'm new to Python
mikip
@OP: are these `x, y, vx, vy` values are related somehow?
SilentGhost
Thanks ,no they are independent variables, why do you ask, does it make a difference?
mikip
It just quite an unusual idea to track sums and the sum squared of 4 numbers. I've corrected the code to suit your interface.
SilentGhost
They are errors measurements of x,y positions and velocity, I intend to calculate the variance of each of these parameters, Thanks
mikip
+4  A: 

First, note that your question has nothing to do with classmethod (which makes class methods in Python) -- it's entirely about normal instance methods (you should edit your title... or your question, if you do mean it to be about class methods).

For the Q as it stands, the only way to do what you want is to pass the names of the attributes that the method needs to set (or enough data to let the method reconstruct the names), e.g.:

def update(self,data):
     x, y, vx, vy = data
     self.update_sums('x' , x)
     self.update_sums('y' , y)

def update_sums(self, attname, val):
     sums = 'sum_' + attname
     setattr(self, sums, getattr(self, sums, 0) + val)
     sums = 'sum_' + attname + '_squared'
     setattr(self, sums, getattr(self, sums, 0) + val * val)

I would not recommend this approach, in general, as it makes code bulkier, less readable, and marginally less efficient than the elementary approach of just hard-coding the attribute names. If the auxiliary method (here update_sums) encapsulates a lot of tricky logic that you're really very keen to avoid duplicating, maybe; but while eliminating repetition is a very worthwhile task, it takes taste and balance to avoid going overboard with it;-).

Alex Martelli
+1  A: 

It looks to me like there is another class in there wanting to be let out. I would remove duplication by refactoring the code like this:

class SumOfSquares(object):
    def __init__(self):
        self.sum = 0.0
        self.squares = 0.0

    def update(self, val):
        self.sum += val
        self.squares += val * val

class X(object):
    def __init__(self):
        self.x = SumOfSquares()
        self.y = SumOfSquares()

    def update(self,data):
         [x,y,vx,vy]=data
         self.x.update(x)
         self.y.update(y)
Dave Kirby