mercredi 15 mai 2019

Python: How can I shorten this and make it more elegant?

I have several classes that are generating mathematical expressions using list comprehensions. All of these classes generate equations that have a similar structure, but there are some small differences. Overall, it is a lot of code and a bit hard to maintain. I am looking for ways to make this code shorter and more elegant.

Below is a simplified example that illustrates the problem. method_1 exists in several classes, but depending on the class, the index_sets and exp_conditions in the expression change.

def method_1(index_1):
    if some_condition:
        exp_1 = min_num-sum([
                                variable[(index_1, index_2, index_3)] +
                                variable[(index_2, index_1, index_3)]
                                for index_2 in index_set_2 
                                for index_3 in index_set_3
                                if index_1 != index_2 and 
                                if exp_condition_1 and exp_condition_2
                                ])
        exp_2 = sum([variable[(index_1, index_2, index_3a)] +
                                variable[(index_2, index_1, index_3a)]
                                for index_2 in index_set_2 
                                for index_3 in different_index_set_3
                                if index_1 != index_2 and 
                                if exp_condition_1 and exp_condition_4
                                ])-max_num
    elif some_other_condition:
        exp_1 = min_num-sum([
                                variable[(index_1, index_2, index_3)]
                                for index_2 in index_set_2 
                                for index_3 in index_set_3
                                if index_1 != index_2 and 
                                if exp_condition_1 and exp_condition_2
                                ])
        exp_2 = sum([variable[(index_1, index_2, index_3a)]
                                for index_2 in index_set_2 
                                for index_3 in different_index_set_3
                                if index_1 != index_2 and 
                                if exp_condition_1 and exp_condition_4
                                ])-max_num
    else:
        exp_1 = self.min_num-sum([
                                variable[(index_2, index_1, index_3)]
                                for index_2 in different_index_set_2 
                                for index_3 in index_set_3
                                if index_1 != index_2 and 
                                if exp_condition_1 and exp_condition_5 and exp_condition_6
                                ])
        exp_2 = sum([variable[(index_2, index_1, index_3a)]
                                for index_2 in index_set_2 
                                for index_3 in different_index_set_3
                                if index_1 != index_2 and 
                                if exp_condition_1 and exp_condition_5 and exp_condition_6
                                ])-self.max_num
    return [exp_1, exp_2]

The one thing that is always the same, is that depending on the condition in method_1, we always expect the method to return two terms: exp_1 and exp_2.

exp_1 = min_num-term_1
exp_2 = term_2-max_num

min_num and max_num are constants, so they are always the same.

term_1 and term_2 are sums over list comprehensions. These list comprehensions have a similar structure:

[some_expression for i in ..... for j in .... for x in ... if (list_of_conditions_depending_on_indexes)]

some_expression can just be a value from a dictionary, e.g. my_dict[(i,j, k)] or a linear combination of values from dictionaries, e.g. my_dict[(i,j,k)]+my_other_dict[(i,j,l,m)]

I think there must be some way to return term_1 and term_2 with a method, that takes as arguments:

  • some_expression
  • index_sets
  • list_of_conditions_depending_on_indexes

All of that wouldn't be a problem if some_expression and list_of_conditions_depending_on indexes would not depend on the index sets and I am struggling to see how to achieve this.

Aucun commentaire:

Enregistrer un commentaire