python - How to apply multiple methods sequentially to class arguments - Stack Overflow

I have a class which takes two arguments. I want to apply these two arguments to different methods. The

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:

  1. Class takes arguments.
  2. They are passed into different methods.
  3. Output of one method is input to the later one
  4. 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:

  1. Class takes arguments.
  2. They are passed into different methods.
  3. Output of one method is input to the later one
  4. 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
  • Give an example of what you mean by "...handle the intermediate results..." – Adon Bilivit Commented Apr 1 at 7:44
  • You are not using any instance varibles inside _square and _mul_10, so why you need any instance variable to store intermediate result? – Mullo Commented Apr 1 at 8:52
  • you can keep function's names on list [self._square, self._mul_10] and use for-loop to run all of them one-by-one. Some modules (for example for Machine Learning) has class with name similar to Piping 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 use for-loop to run them one-by-one. – furas Commented Apr 1 at 11:45
  • You are aware that you can simply write return sq_val * 10, return value ** 2, return self._square(self.param1), self._square(self.param2), ... etc, right? – chepner Commented Apr 1 at 13:10
Add a comment  | 

1 Answer 1

Reset to default 0

In 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

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信