I have a class which takes two arguments. I want to apply these two arguments to different methods. The output of each method should serve as the input for the next method. Additionally, I want this to work for all attributes without manually applying each method to every attribute. I want to use instance variables to store the results.
Example:
class Multiple_process:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
# To store intermediate results
self.param1_sq = None
self.param2_sq = None
self.param1_mul_10 = None
self.param2_mul_10 = None
def _square(self, value):
sq_val = value ** 2
return sq_val
def _mul_10(self,sq_val):
mul_10 = sq_val * 10
return mul_10
def applicaton(self):
self.param1_sq = self._square(self.param1)
self.param2_sq = self._square(self.param2)
self.param1_mul_10 = self._mul_10(self.param1_sq)
self.param2_mul_10 = self._mul_10(self.param2_sq)
return self.param1_sq, self.param2_sq, self.param1_mul_10, self.param2_mul_10
test = Multiple_process(5, 4)
print(test.applicaton())
The output is (25, 16, 250, 160)
, which is as expected. But suppose one is working on a complex project, then this way of creating multiple instance variables seems quite tiresome and illogical to store the results of each method applied to each argument. We may be interested in the final output of the last method in a complex project, but how do we handle the intermediate results?
My requirements:
- Class takes arguments.
- They are passed into different methods.
- Output of one method is input to the later one
- Ultimately produces final output for both arguments, which are to be used for a different purpose.
How can we simplify, or streamline, this whole process?
I have a class which takes two arguments. I want to apply these two arguments to different methods. The output of each method should serve as the input for the next method. Additionally, I want this to work for all attributes without manually applying each method to every attribute. I want to use instance variables to store the results.
Example:
class Multiple_process:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
# To store intermediate results
self.param1_sq = None
self.param2_sq = None
self.param1_mul_10 = None
self.param2_mul_10 = None
def _square(self, value):
sq_val = value ** 2
return sq_val
def _mul_10(self,sq_val):
mul_10 = sq_val * 10
return mul_10
def applicaton(self):
self.param1_sq = self._square(self.param1)
self.param2_sq = self._square(self.param2)
self.param1_mul_10 = self._mul_10(self.param1_sq)
self.param2_mul_10 = self._mul_10(self.param2_sq)
return self.param1_sq, self.param2_sq, self.param1_mul_10, self.param2_mul_10
test = Multiple_process(5, 4)
print(test.applicaton())
The output is (25, 16, 250, 160)
, which is as expected. But suppose one is working on a complex project, then this way of creating multiple instance variables seems quite tiresome and illogical to store the results of each method applied to each argument. We may be interested in the final output of the last method in a complex project, but how do we handle the intermediate results?
My requirements:
- Class takes arguments.
- They are passed into different methods.
- Output of one method is input to the later one
- Ultimately produces final output for both arguments, which are to be used for a different purpose.
How can we simplify, or streamline, this whole process?
Share Improve this question edited Apr 1 at 6:51 jonrsharpe 122k30 gold badges268 silver badges475 bronze badges asked Apr 1 at 6:21 Partha Pratim SarmaPartha Pratim Sarma 431 silver badge9 bronze badges 4 |1 Answer
Reset to default 0In some modules (for example for Machine Learning or Neural Network) you can find function or class with name like piping
(or pipeline
) which gets list of functions and list of values and it makes all calculation - result(s) of one function is used as parametere(s) for next function. But this doesn't keep inner results.
But you can use for
-loop to do the same with list of function's names and list of data.
Becasuse I created it as separate function (not part of class) so I can use it with methods from different classes (for example I could add math.sqrt
).
def piping(pipe, data):
all_results = []
for func in pipe:
inner_results = []
for item in data:
inner_results.append(func(item))
all_results += inner_results
data = inner_results
return all_results
pipe = (test._square, test._mul_10)
data = (5, 4)
results = piping(pipe, data)
print('results:', results)
Because it gets pipe
and data
as list so it can work with more functions and with more values.
import math
pipe = (test._square, test._mul_10, test._square, math.sqrt)
data = (5, 4, 3, 2, 1)
results = piping(pipe, data)
print('results:', results)
# results: [25, 16, 9, 4, 1, 250, 160, 90, 40, 10, 62500, 25600, 8100, 1600, 100, 250.0, 160.0, 90.0, 40.0, 10.0]
Maybe to make it more readable you could group inner results in lists or tuples.
all_results.append(inner_results) # append() instead of += or extend()
Results:
results: [[25, 16], [250, 160]]
results: [[25, 16, 9, 4, 1], [250, 160, 90, 40, 10], [62500, 25600, 8100, 1600, 100], [250.0, 160.0, 90.0, 40.0, 10.0]]
And if you replace for-loops then you can group inner results for every data.
def piping2(pipe, data):
all_results = []
for item in data:
inner_results = []
for func in pipe:
item = func(item)
inner_results.append(item)
all_results.append(inner_results)
return all_results
pipe = (test._square, test._mul_10)
data = (5, 4)
results = piping2(pipe, data)
print('results2:', results)
#pipe = (test._square, lambda x:int(math.sqrt(x)), 'price ${:_}'.format)
pipe = (test._square, test._mul_10, test._square, math.sqrt)
data = (5, 4, 3, 2, 1)
results = piping2(pipe, data)
print('results2:', results)
for item, result in zip(data, results):
print(item, "=>", result)
Result:
results2: [[25, 250], [16, 160]]
results2: [[25, 250, 62500, 250.0], [16, 160, 25600, 160.0], [9, 90, 8100, 90.0], [4, 40, 1600, 40.0], [1, 10, 100, 10.0]]
5 => [25, 250, 62500, 250.0]
4 => [16, 160, 25600, 160.0]
3 => [9, 90, 8100, 90.0]
2 => [4, 40, 1600, 40.0]
1 => [1, 10, 100, 10.0]
Full working code which I used for tests.
There is option flat
in piping
to create flat list or with sublists.
There is also example with lambda
and string format
in pipe.
class Multiple_process:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
# To store intermediate results
self.param1_sq = None
self.param2_sq = None
self.param1_mul_10 = None
self.param2_mul_10 = None
def _square(self, value):
sq_val = value ** 2
return sq_val
def _mul_10(self,sq_val):
mul_10 = sq_val * 10
return mul_10
def applicaton(self):
self.param1_sq = self._square(self.param1)
self.param2_sq = self._square(self.param2)
self.param1_mul_10 = self._mul_10(self.param1_sq)
self.param2_mul_10 = self._mul_10(self.param2_sq)
return self.param1_sq, self.param2_sq, self.param1_mul_10, self.param2_mul_10
test = Multiple_process(5, 4)
print(test.applicaton())
def piping(pipe, data, flat=False):
all_results = []
for func in pipe:
inner_results = []
for param in data:
result = func(param)
inner_results.append(result)
if flat:
all_results.extend(inner_results)
else:
all_results.append(inner_results)
data = inner_results # use previous results as new parameters
return all_results
def piping2(pipe, data):
all_results = []
for param in data:
inner_results = []
for func in pipe:
result = func(param)
inner_results.append(result)
param = result # use previous result as new parameter
all_results.append(inner_results)
return all_results
import math
pipe = (test._square, test._mul_10)
data = (5, 4)
results = piping(pipe, data)
print('results1:', results)
pipe = (test._square, test._mul_10, test._square, lambda x:int(math.sqrt(x)))
data = (5, 4, 1, 2, 3)
results = piping(pipe, data)
print('results1:', results)
pipe = (test._square, test._mul_10)
data = (5, 4)
results = piping2(pipe, data)
print('results2:', results)
pipe = (test._square, test._mul_10, test._square, lambda x:int(math.sqrt(x)), 'price ${:_}'.format)
data = (5, 4, 1, 2, 3)
results = piping2(pipe, data)
print('results2:', results)
for param, result in zip(data, results):
print(param, "=>", result)
as_dict = dict(zip(data, results))
print('dict:', as_dict)
Result:
(25, 16, 250, 160)
results1: [[25, 16], [250, 160]]
results1: [[25, 16, 1, 4, 9], [250, 160, 10, 40, 90], [62500, 25600, 100, 1600, 8100], [250, 160, 10, 40, 90]]
results2: [[25, 250], [16, 160]]
results2: [[25, 250, 62500, 250, 'price $250'], [16, 160, 25600, 160, 'price $160'], [1, 10, 100, 10, 'price $10'], [4, 40, 1600, 40, 'price $40'], [9, 90, 8100, 90, 'price $90']]
5 => [25, 250, 62500, 250, 'price $250']
4 => [16, 160, 25600, 160, 'price $160']
1 => [1, 10, 100, 10, 'price $10']
2 => [4, 40, 1600, 40, 'price $40']
3 => [9, 90, 8100, 90, 'price $90']
dict: {5: [25, 250, 62500, 250, 'price $250'], 4: [16, 160, 25600, 160, 'price $160'], 1: [1, 10, 100, 10, 'price $10'], 2: [4, 40, 1600, 40, 'price $40'], 3: [9, 90, 8100, 90, 'price $90']}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743905225a4527363.html
_square
and_mul_10
, so why you need any instance variable to store intermediate result? – Mullo Commented Apr 1 at 8:52[self._square, self._mul_10]
and usefor
-loop to run all of them one-by-one. Some modules (for example for Machine Learning) has class with name similar toPiping
which works this way - so you may also create own class for piping which will get list of function's names (even from different classes) and usefor
-loop to run them one-by-one. – furas Commented Apr 1 at 11:45return sq_val * 10
,return value ** 2
,return self._square(self.param1), self._square(self.param2), ...
etc, right? – chepner Commented Apr 1 at 13:10