Cycle Through Previous Class Instances Results
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
- 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"