-1

Is there any way I can convert 84.66666666666667 to 84 and 2/3? I've tried using as.integer_ratio (), but I can't seem to make it work. For example, I want the outputs to be like the ones below:
The temperature is 84.66666666666667.
The temperature is 84 and 2/3.

dawg
  • 98,345
  • 23
  • 131
  • 206
  • What did you try? [See minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) – Kirk Feb 03 '21 at 18:50
  • Please be aware this is not a code-writing or tutoring service. We can help solve specific, technical problems, not open-ended requests for code or advice. Please edit your question to show what you have tried so far, and what specific problem you need help with. – itprorh66 Feb 03 '21 at 18:52
  • 1
    If you need fractions, rather than trying to convert floats to fractions, you should do things in rational arithmetic from the start. Otherwise, you risk getting screwed by rounding error. – user2357112 Feb 03 '21 at 18:56
  • 1
    You could try Fraction(84.66666666666667).limit_denominator(). produces a Fraction(254, 3) object that you could get to your 84 2/3 – Kirk Feb 03 '21 at 18:58
  • What is the expected output for `84.1234132762`? – Mr. T Feb 03 '21 at 20:15
  • @Mr.T: Either approach in my answer that would be `84 1/8` which is accurate to 16/1000's... – dawg Feb 03 '21 at 20:21

1 Answers1

2

You can use the Fractions module:

from fractions import Fraction 

l=16 # meaning any reduced fraction can be /16 like 15/16 or better
frac=Fraction(84.66666666666667).limit_denominator(l)
f2=divmod(frac.numerator, frac.denominator)

print(f'{f2[0]} {f2[1]}/{frac.denominator}')

Prints:

84 2/3

Alternatively, you can maintain a list of 'acceptable' fractions and then find the closest to the actual fractional part:

# these are just kinda random...
f_I_like=[Fraction(*e) for e in [(1,3),(1,4),(1,8),
                  (1,10),(2,3),(15,16),(3,8),(1,16),(5,8),(3,16),(7,8),(5,16)]]

def closest(li, x):
    return li[min(range(len(li)), key = lambda i: abs(li[i]-x))] 

frac=84.3333.as_integer_ratio()
f2=divmod(frac[0], frac[1])
f3=f2[1]/frac[1]

print(f'{f2[0]} {closest(f_I_like, f3)}')

Prints

84 1/3
dawg
  • 98,345
  • 23
  • 131
  • 206