Skip to content Skip to sidebar Skip to footer

Cycle Through Previous Class Instances Results

This is a continuation from here. I have a class B which holds some data (a and b fields). I am loading these data to the Criteria class in order to pass through the criteria and c

Solution 1:

If I read P correctly it maintains 3 'state' variables. The 3 if clauses can called in any order (and I think could have been written with a if,ifthen,ifthen,else syntax since c.method only matches one (for each c.

But the order of the objects in the list will determine values. An AVG object will use what ever values were set by the last V object. Similarly the M will use the last AVG. If pass an AVG first it will use the initial None values in its calc.

So sequence of V1, AVG, M will use B values that were set by V1.

In this sequence V1, AVG, V2, M, M uses values from the last AVG which was dependent on V1;

avg should not be returning strings if its values are being used by func, or at least the tests must match. [] is an empty list with len() zero, but '[]' is a 2 character string, with len 2.

Similarly None is a unique value that you test with is None, while 'none' is a 4 character string. I used strings like that in earlier questions simply because we were printing the results of avg. At the time we weren't using them for further calculations.


If you want to make sure that AVG and M use values from the last V, you need to add some logic:

 lastV, lastA, lastM = None,None,Noneif c.method=='V':
     lastV = <newV>
     lastA, lastM = None,Noneelif c.method=='A':
     if lastV isNone:
        error
     else:
        lastA = <new A based on lastV>
 elif c.method=='M':
     if lastA isNone:
        error
        <or update lastA>
     else:
        lastM = <new M based on lastA>
 else:
     error unknown c.method

So I am using None to indicate that the values are not valid. In which case it should either raise an error, or it should calculate new values. Done right it should ensure that both AVG and M will produce values based on the latest V.


From your pastebin:

defavg(self, calcs=None):
    """Return the average of values"""if calcs isNone:          # fun called without argument
        calcs = self.measures  # get value stored in selfif calcs isNone:          # in case that too was Nonereturn'[]'# I would return None or []# '[]' is a useless stringelse:
        ifhasattr(calcs,'__len__'):
            return np.average([x.a for x in calcs])
        else:
            return np.average(calcs)

What works in np.average() that doesn't have a len? len(np.arange(10)) runs, but doesn't have the a attribute

In [603]: avg(None,calcs=np.arange(10))
....
<ipython-input-602-48c9f6b255e1> in <listcomp>(.0)
      8else:
      9if hasattr(calcs,'__len__'):
---> 10return np.average([x.a for x in calcs])
     11else:
     12return np.average(calcs)

AttributeError: 'numpy.int32'object has no attribute 'a'

That __len__ between an array or list with B objects and other lists or arrays. Maybe refine this to test dtype? Or a try/except?

def avg(self, calcs=None): """Return the average of values""" .... else: try: return np.average([x.a for x in calcs]) except AttributeError: return np.average(calcs)

In [606]: avg(None,calcs=np.arange(10))
Out[606]: 4.5

And list or array of B objects works:

In [609]: alist = [B(1,2),B(2,4),B(3,3)]
In [610]: avg(None, alist)
Out[610]: 2.0
In [611]: avg(None, np.array(alist))
Out[611]: 2.0

Solution 2:

I don't understand what you mean by not hardcoding P

  1. Is there a way to obtain only the last result?

Yes. Obtain all the results, but only print the last one:

for i in P(alist): pass
print(i)

Post a Comment for "Cycle Through Previous Class Instances Results"