「「1から9までの数字を一回ずつ使って2010にする」の検算」の検算2

 お世話になっております。

 一昨日の「1から9までの数字を一回ずつ使って2010にする」の検算は、小数の計算に問題があるという指摘を受けました。(http://takanory.net/takalog/1192
 解き方も教えていただきましたが、自分でもやってみないとダメだろうと思い、分数クラスを作って解いてみました。
 結果、すべて2010という答えが出ました。

 以下、コードです。
fraction.py

# -*- coding: sjis -*-

class Fraction(object):
  @staticmethod
  def parse(s):
    assert isinstance(s, str)
    if '.' in s:
      numerator = s.replace('.', '')
      splitted = s.split('.')
      denominator = 10 ** len(splitted[1])
      return Fraction(int(numerator), int(denominator))
    else:
      return Fraction(int(s))

  def __init__(self, numerator, denominator=1):
    assert denominator != 0
    assert isinstance(numerator, int)
    assert isinstance(denominator, int)
    self._num = numerator
    self._den = denominator
    euc = self._euc()
    assert isinstance(euc, int)
    self._num = int(self._num / euc)
    self._den = int(self._den / euc)

  def __add__(self, another):
    assert isinstance(another, Fraction)
    new_den = self._den * another._den
    new_self_num = self._num * another._den
    new_another_num = another._num * self._den
    new_num = new_self_num + new_another_num
    return Fraction(new_num, new_den)

  def __sub__(self, another):
    assert isinstance(another, Fraction)
    new_den = self._den * another._den
    new_self_num = self._num * another._den
    new_another_num = another._num * self._den
    new_num = new_self_num - new_another_num
    return Fraction(new_num, new_den)

  def __mul__(self, another):
    assert isinstance(another, Fraction)
    new_num = self._num * another._num
    new_den = self._den * another._den
    return Fraction(new_num, new_den)

  def __div__(self, another):
    assert isinstance(another, Fraction)
    reversed_num = another._den
    reversed_den = another._num
    return self * Fraction(reversed_num, reversed_den)

  def __truediv__(self, another):
    return self.__div__(another)

  def __eq__(self, another):
    if not isinstance(another, Fraction):
      return False
    numIsEqual = self._num == another._num
    denIsEqual = self._den == another._den
    if numIsEqual and denIsEqual:
      return True
    else:
      return False

  def __str__(self):
    num = self._num
    den = self._den
    return ('%d/%d' % (num, den)).strip('/1')

  def __repr__(self):
    return str(self)

  def _euc(self):
    m = 0
    n = 0
    if self._num >= self._den:
      m = self._num
      n = self._den
    else:
      m = self._den
      n = self._num
    if n == 0:
      return m
    while True:
      temp = m % n
      if temp == 0:
        return n
      else:
        m = n
        n = temp


import unittest as UT

class FractionTestCase(UT.TestCase):

  def setUp(self):
    self.one_3rd = Fraction(1, 3)
    self.one_2nd = Fraction(1, 2)

  def testCalculate(self):
    expected = Fraction(1)
    calculated = (Fraction(1) / Fraction(3)) * Fraction(3)
    self.assertEqual(expected, calculated)

  def testAdd(self):
    answer = self.one_3rd + self.one_2nd
    self.assertEqual(answer, Fraction(5, 6))

    answer = self.one_3rd + self.one_3rd
    self.assertEqual(answer, Fraction(6, 9))

  def testSub(self):
    answer = self.one_3rd - self.one_2nd
    self.assertEqual(answer, Fraction(-1, 6))

  def testMul(self):
    answer = self.one_3rd * self.one_2nd
    self.assertEqual(answer, Fraction(1, 6))

  def testDiv(self):
    answer = self.one_3rd / self.one_2nd
    self.assertEqual(answer, Fraction(2, 3))

  def testEqual(self):
    self.assertEqual(Fraction(1), Fraction(1))
    self.assertNotEqual(Fraction(1), 1)
    self.assertNotEqual(Fraction(1), None)

  def testParse(self):
    self.assertEqual(Fraction.parse('100'), Fraction(100))
    self.assertEqual(Fraction.parse('100.1'), Fraction(1001, 10))
    self.assertEqual(Fraction.parse('.1'), Fraction(1, 10))


if __name__ == '__main__':
  # run unittest
  UT.main()

src.py

# -*- coding: sjis -*-

import httplib, re
from fraction import *

REGEX = re.compile("^2010 = (.+?)$", re.M)
REGEX_NUM = re.compile(r"([\.0-9]+)")
conn = None


try:
    conn = httplib.HTTPConnection('www.thesamet.com')
    conn.request('GET', '2010.txt')
    res = conn.getresponse()
    body = res.read()
    
    equal_count = 0
    total_count = 0
    for matched in REGEX.findall(body):
        cmd = matched
        cmd = REGEX_NUM.sub(r"Fraction.parse('\1')", cmd)

        result = eval(cmd)
        if Fraction(2010) == result:
            equal_count += 1
        total_count += 1
        print cmd + ':' + str(result)
    print 'eq/total %d/%d' % (equal_count, total_count)
finally:
    if conn:
        conn.close()

以上