0

Given the following class:

class Example():

    def __init__(self, numerator1, denominator1, numerator2, denominator2):
        self.numerator1 = numerator1
        self.denominator1 = denominator1
        self.numerator2 = numerator2
        self.denominator2 = denominator2

I've created a couple of objects:

objects = [Example(1, 2, 2, 1), Example(1, 2, 2, 1)]

Now I want to perform the same operation to each of the two pairs of numerator/denominator combinations:

sum(m.numerator for m in objects) / sum(m.denominator for m in objects)

To try and stay in keeping with DRY I'd like to create a single function to perform this operation and simply change the numerator and denominator combinations each time. Something like:

def standard_func(numerator, denominator, objects):
    return (sum(m.numerator for m in objects) / sum(m.denominator for m in objects)

comb1 = standard_func(<numerator1>, <denominator1>, objects)
comb2 = standard_func(<numerator2>, <denominator2>, objects)

I can't figure out how to get the above example to work as the sum function needs to know that the numerator or denominator is associated with an Example instance.

I've experimented with incrementing class variables however I have a for loop that generates multiple iterations of the objects list and I want a unique sum of num/denom per list. I suppose I could reset the class variable total on each loop - maybe this is one solution?

Jossy
  • 589
  • 2
  • 12
  • 36
  • 2
    I don't really get what you're trying to do, but when you have variables that have similar roles to the point that you give them identical names with different indices, it's a good sign that you should have used a list or dict instead. So, something similar to `self.denominators = [denominator1, denominator2]` would probably be a good start. – Thierry Lathuille Oct 15 '20 at 16:36
  • What's the point of having class objects only to override their attributes when doing processing with them? – martineau Oct 15 '20 at 16:37
  • @ThierryLathuille - think your idea may work thanks! Will try it out and report back – Jossy Oct 15 '20 at 16:41
  • @martineau - I'm not sure what you mean when you say "override"? I'm not changing anything with the processing? In this case I'm simply looking to perform a sum? – Jossy Oct 15 '20 at 16:43
  • Guess I don't understand what you are trying to accomplish… – martineau Oct 15 '20 at 16:44
  • 1
    @martineau - appreciate you trying :) Marcus below has nailed it – Jossy Oct 15 '20 at 16:48

1 Answers1

1

An idea would be to use getattr() as described here. In your case, this would look like:

objects = [Example(1, 2, 2, 1), Example(1, 2, 2, 1)]
def standard_func(numerator, denominator, objects):
    return sum(getattr(m, numerator) for m in objects) / sum(getattr(m, denominator) for m in objects)

comb1 = standard_func("numerator1", "denominator1", objects)
comb2 = standard_func("numerator2", "denominator2", objects)
print(comb1, comb2)

Output:

0.5 2.0
Marcus
  • 943
  • 5
  • 21