pythoncalculuspython-fractions

TypeError: both arguments should be Rational instances when trying to use fractions


So im trying to write a code that will solve general solutions in calculus and one of my values is a fraction with f1 = fractions.Fraction(2.0, period) but if I use 12.5 as the period it comes back with an error. Code:

from cmath import sin
import math
import re
import operator
import fractions
from decimal import Decimal

amplitude = input("What is the A value?: ")
period = input("What is the P value?: ")
ogperiod = float(period)
period = float(period)


f1 = fractions.Fraction(2.0, period)
print(f1)

But all I get is TypeError: both arguments should be Rational instances full error code:

TypeError                                 Traceback (most recent call last)
Input In [84], in <cell line: 27>()
     23 ogperiod = float(period)
     24 period = float(period)
---> 27 f1 = fractions.Fraction(2.0, period)
     28 print(f1)
     31 bpi = 2 * math.pi

File /opt/homebrew/Cellar/python@3.9/3.9.8/Frameworks/Python.framework/Versions/3.9/lib/python3.9/fractions.py:152, in Fraction.__new__(cls, numerator, denominator, _normalize)
    147     numerator, denominator = (
    148         numerator.numerator * denominator.denominator,
    149         denominator.numerator * numerator.denominator
    150         )
    151 else:
--> 152     raise TypeError("both arguments should be "
    153                     "Rational instances")
    155 if denominator == 0:
    156     raise ZeroDivisionError('Fraction(%s, 0)' % numerator)

TypeError: both arguments should be Rational instances

Solution

  • I found that one problem is to assign a float to period. Fraction class has a constructor that accepts two values (the numerator and the denominator) of a Rational class (see the documentation). Since Python version 3.2, there is the possibility of initialize a Fraction from a float but only using one parameter.

    So, if you want to keep the 2 values (2.0 and period), you have to change 2.0 to 2 and use period as int (loosing precision). So, your code will be:

    f1 = fractions.Fraction(2, int(period))
    

    EDIT:

    If you want to keep the precision of period, it's better to convert it to a fraction and do the fractional division to initialize f1. That is:

    period = fractions.Fraction(period)
    f1 = fractions.Fraction(2 * period.denominator, period.nominator)