Search code examples
python-3.xfractions

Python3: The Fraction


from fractions import Fraction
from functools import reduce

def product(fracs): ## fracs is a list of Fraction objects from the subsequent function call
    t = Fractions(reduce(lambda x,y: x.numerator * y.numerator,fracs), reduce(lambda x,y: x.denominator * y.denominator, fracs))
    return t.numerator, t.denominator

if __name__ == '__main__':
    fracs = []
    for _ in range(int(input())):
        fracs.append(Fraction(*map(int, input().split())))
    result = product(fracs)
    print(*result)

I'm trying to multiply a series of fractions together using Python3 functool's Fraction function. The problem i have is with the denominator perimeter for the t variable in the product(fracs) function. Upon testing with the following test case:

3
1 2
3 4
10 6
5 1

The output was 5 1. The numerator seem to work fine but broke down for the denominator. I am aware and have found alternative solutions to my problem however i am hoping to get this mystery solved. I've ran it through python tutor but i couldn't decipher the code's behavior.


Solution

  • I think it's how you are using reduce. The first time it's called you are passing two Fraction objects:

    Fraction(1,2).denominator * Fraction(3,4).denominator
    

    which returns 8 and is what you expect. However, the reduce function is not making this 8 a fraction so the next call to reduce looks like this:

    8.denominator * Fraction(10,6).denominator
    

    Which is 6 not the expected 48. This problem doesn't exist for the numerator because for an Int X:

    X = X.numerator
    

    Therefore you get 30 in the numerator and 6 in the denominator which reduces to 5.

    I'm not familiar with the Fraction class but it seems like you might be reinventing the wheel a bit.

    I suspect you can just multiply the fraction objects and it's multiplication operator is overloaded:

    def product(fracs):
      return reduce(lambda x,y: x * y, fracs)