Skip to content

Instantly share code, notes, and snippets.

@knzm
Created April 10, 2012 02:41
Show Gist options
  • Save knzm/2348034 to your computer and use it in GitHub Desktop.
Save knzm/2348034 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from fractions import Fraction
import unittest
def fraction_from_repeating(period, base=10):
"""
Return a fraction equivalent to the given repeating decimal.
`period` is a list of integers which represents the repeating period.
When period = [1, 2, 3], it is regarded as 0.123123123...
`base` is a base of number, aka radix. It is usually 10 (decimal),
and may be 2 (binary) or any natural number.
"""
# eg. n = 0.xyzxyzxyz...
# 1000n - n = xyz
# n = xyz/999
num = sum([d * (base ** i) for i, d in enumerate(reversed(period))])
denom = (base ** len(period)) - 1
return Fraction("%d/%d" % (num, denom))
class RepeatingTestCase(unittest.TestCase):
def test_simple1(self):
"""0.33333... = 1/3"""
self.assertEquals(fraction_from_repeating([3]),
Fraction("1/3"))
def test_simple2(self):
"""0.123123123... = 41/333"""
self.assertEquals(fraction_from_repeating([1, 2, 3]),
Fraction("41/333"))
def test_complex(self):
"""2.2234234... = 1234/555"""
self.assertEquals((22 + fraction_from_repeating([2, 3, 4])) / 10,
Fraction("1234/555"))
def test_limit(self):
"""0.999... = 1"""
self.assertEquals(fraction_from_repeating([9]),
Fraction("1"))
def test_base(self):
"""0.101010...[2] = 2/3"""
self.assertEquals(fraction_from_repeating([1, 0], 2),
Fraction("2/3"))
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment