symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_fractions.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Tests for Lib/fractions.py."""
       
     2 
       
     3 from decimal import Decimal
       
     4 from test.test_support import run_unittest
       
     5 import math
       
     6 import operator
       
     7 import fractions
       
     8 import unittest
       
     9 from copy import copy, deepcopy
       
    10 from cPickle import dumps, loads
       
    11 F = fractions.Fraction
       
    12 gcd = fractions.gcd
       
    13 
       
    14 
       
    15 class GcdTest(unittest.TestCase):
       
    16 
       
    17     def testMisc(self):
       
    18         self.assertEquals(0, gcd(0, 0))
       
    19         self.assertEquals(1, gcd(1, 0))
       
    20         self.assertEquals(-1, gcd(-1, 0))
       
    21         self.assertEquals(1, gcd(0, 1))
       
    22         self.assertEquals(-1, gcd(0, -1))
       
    23         self.assertEquals(1, gcd(7, 1))
       
    24         self.assertEquals(-1, gcd(7, -1))
       
    25         self.assertEquals(1, gcd(-23, 15))
       
    26         self.assertEquals(12, gcd(120, 84))
       
    27         self.assertEquals(-12, gcd(84, -120))
       
    28 
       
    29 
       
    30 def _components(r):
       
    31     return (r.numerator, r.denominator)
       
    32 
       
    33 
       
    34 class FractionTest(unittest.TestCase):
       
    35 
       
    36     def assertTypedEquals(self, expected, actual):
       
    37         """Asserts that both the types and values are the same."""
       
    38         self.assertEquals(type(expected), type(actual))
       
    39         self.assertEquals(expected, actual)
       
    40 
       
    41     def assertRaisesMessage(self, exc_type, message,
       
    42                             callable, *args, **kwargs):
       
    43         """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
       
    44         try:
       
    45             callable(*args, **kwargs)
       
    46         except exc_type, e:
       
    47             self.assertEquals(message, str(e))
       
    48         else:
       
    49             self.fail("%s not raised" % exc_type.__name__)
       
    50 
       
    51     def testInit(self):
       
    52         self.assertEquals((0, 1), _components(F()))
       
    53         self.assertEquals((7, 1), _components(F(7)))
       
    54         self.assertEquals((7, 3), _components(F(F(7, 3))))
       
    55 
       
    56         self.assertEquals((-1, 1), _components(F(-1, 1)))
       
    57         self.assertEquals((-1, 1), _components(F(1, -1)))
       
    58         self.assertEquals((1, 1), _components(F(-2, -2)))
       
    59         self.assertEquals((1, 2), _components(F(5, 10)))
       
    60         self.assertEquals((7, 15), _components(F(7, 15)))
       
    61         self.assertEquals((10**23, 1), _components(F(10**23)))
       
    62 
       
    63         self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
       
    64                                  F, 12, 0)
       
    65         self.assertRaises(TypeError, F, 1.5)
       
    66         self.assertRaises(TypeError, F, 1.5 + 3j)
       
    67 
       
    68         self.assertRaises(TypeError, F, F(1, 2), 3)
       
    69         self.assertRaises(TypeError, F, "3/2", 3)
       
    70 
       
    71     def testFromString(self):
       
    72         self.assertEquals((5, 1), _components(F("5")))
       
    73         self.assertEquals((3, 2), _components(F("3/2")))
       
    74         self.assertEquals((3, 2), _components(F(" \n  +3/2")))
       
    75         self.assertEquals((-3, 2), _components(F("-3/2  ")))
       
    76         self.assertEquals((13, 2), _components(F("    013/02 \n  ")))
       
    77         self.assertEquals((13, 2), _components(F(u"    013/02 \n  ")))
       
    78 
       
    79         self.assertEquals((16, 5), _components(F(" 3.2 ")))
       
    80         self.assertEquals((-16, 5), _components(F(u" -3.2 ")))
       
    81         self.assertEquals((-3, 1), _components(F(u" -3. ")))
       
    82         self.assertEquals((3, 5), _components(F(u" .6 ")))
       
    83 
       
    84 
       
    85         self.assertRaisesMessage(
       
    86             ZeroDivisionError, "Fraction(3, 0)",
       
    87             F, "3/0")
       
    88         self.assertRaisesMessage(
       
    89             ValueError, "Invalid literal for Fraction: '3/'",
       
    90             F, "3/")
       
    91         self.assertRaisesMessage(
       
    92             ValueError, "Invalid literal for Fraction: '3 /2'",
       
    93             F, "3 /2")
       
    94         self.assertRaisesMessage(
       
    95             # Denominators don't need a sign.
       
    96             ValueError, "Invalid literal for Fraction: '3/+2'",
       
    97             F, "3/+2")
       
    98         self.assertRaisesMessage(
       
    99             # Imitate float's parsing.
       
   100             ValueError, "Invalid literal for Fraction: '+ 3/2'",
       
   101             F, "+ 3/2")
       
   102         self.assertRaisesMessage(
       
   103             # Avoid treating '.' as a regex special character.
       
   104             ValueError, "Invalid literal for Fraction: '3a2'",
       
   105             F, "3a2")
       
   106         self.assertRaisesMessage(
       
   107             # Only parse ordinary decimals, not scientific form.
       
   108             ValueError, "Invalid literal for Fraction: '3.2e4'",
       
   109             F, "3.2e4")
       
   110         self.assertRaisesMessage(
       
   111             # Don't accept combinations of decimals and fractions.
       
   112             ValueError, "Invalid literal for Fraction: '3/7.2'",
       
   113             F, "3/7.2")
       
   114         self.assertRaisesMessage(
       
   115             # Don't accept combinations of decimals and fractions.
       
   116             ValueError, "Invalid literal for Fraction: '3.2/7'",
       
   117             F, "3.2/7")
       
   118         self.assertRaisesMessage(
       
   119             # Allow 3. and .3, but not .
       
   120             ValueError, "Invalid literal for Fraction: '.'",
       
   121             F, ".")
       
   122 
       
   123     def testImmutable(self):
       
   124         r = F(7, 3)
       
   125         r.__init__(2, 15)
       
   126         self.assertEquals((7, 3), _components(r))
       
   127 
       
   128         self.assertRaises(AttributeError, setattr, r, 'numerator', 12)
       
   129         self.assertRaises(AttributeError, setattr, r, 'denominator', 6)
       
   130         self.assertEquals((7, 3), _components(r))
       
   131 
       
   132         # But if you _really_ need to:
       
   133         r._numerator = 4
       
   134         r._denominator = 2
       
   135         self.assertEquals((4, 2), _components(r))
       
   136         # Which breaks some important operations:
       
   137         self.assertNotEquals(F(4, 2), r)
       
   138 
       
   139     def testFromFloat(self):
       
   140         self.assertRaises(TypeError, F.from_float, 3+4j)
       
   141         self.assertEquals((10, 1), _components(F.from_float(10)))
       
   142         self.assertEquals((0, 1), _components(F.from_float(-0.0)))
       
   143         self.assertEquals((10, 1), _components(F.from_float(10.0)))
       
   144         self.assertEquals((-5, 2), _components(F.from_float(-2.5)))
       
   145         self.assertEquals((99999999999999991611392, 1),
       
   146                           _components(F.from_float(1e23)))
       
   147         self.assertEquals(float(10**23), float(F.from_float(1e23)))
       
   148         self.assertEquals((3602879701896397, 1125899906842624),
       
   149                           _components(F.from_float(3.2)))
       
   150         self.assertEquals(3.2, float(F.from_float(3.2)))
       
   151 
       
   152         inf = 1e1000
       
   153         nan = inf - inf
       
   154         self.assertRaisesMessage(
       
   155             TypeError, "Cannot convert inf to Fraction.",
       
   156             F.from_float, inf)
       
   157         self.assertRaisesMessage(
       
   158             TypeError, "Cannot convert -inf to Fraction.",
       
   159             F.from_float, -inf)
       
   160         self.assertRaisesMessage(
       
   161             TypeError, "Cannot convert nan to Fraction.",
       
   162             F.from_float, nan)
       
   163 
       
   164     def testFromDecimal(self):
       
   165         self.assertRaises(TypeError, F.from_decimal, 3+4j)
       
   166         self.assertEquals(F(10, 1), F.from_decimal(10))
       
   167         self.assertEquals(F(0), F.from_decimal(Decimal("-0")))
       
   168         self.assertEquals(F(5, 10), F.from_decimal(Decimal("0.5")))
       
   169         self.assertEquals(F(5, 1000), F.from_decimal(Decimal("5e-3")))
       
   170         self.assertEquals(F(5000), F.from_decimal(Decimal("5e3")))
       
   171         self.assertEquals(1 - F(1, 10**30),
       
   172                           F.from_decimal(Decimal("0." + "9" * 30)))
       
   173 
       
   174         self.assertRaisesMessage(
       
   175             TypeError, "Cannot convert Infinity to Fraction.",
       
   176             F.from_decimal, Decimal("inf"))
       
   177         self.assertRaisesMessage(
       
   178             TypeError, "Cannot convert -Infinity to Fraction.",
       
   179             F.from_decimal, Decimal("-inf"))
       
   180         self.assertRaisesMessage(
       
   181             TypeError, "Cannot convert NaN to Fraction.",
       
   182             F.from_decimal, Decimal("nan"))
       
   183         self.assertRaisesMessage(
       
   184             TypeError, "Cannot convert sNaN to Fraction.",
       
   185             F.from_decimal, Decimal("snan"))
       
   186 
       
   187     def testLimitDenominator(self):
       
   188         rpi = F('3.1415926535897932')
       
   189         self.assertEqual(rpi.limit_denominator(10000), F(355, 113))
       
   190         self.assertEqual(-rpi.limit_denominator(10000), F(-355, 113))
       
   191         self.assertEqual(rpi.limit_denominator(113), F(355, 113))
       
   192         self.assertEqual(rpi.limit_denominator(112), F(333, 106))
       
   193         self.assertEqual(F(201, 200).limit_denominator(100), F(1))
       
   194         self.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
       
   195         self.assertEqual(F(0).limit_denominator(10000), F(0))
       
   196 
       
   197     def testConversions(self):
       
   198         self.assertTypedEquals(-1, math.trunc(F(-11, 10)))
       
   199         self.assertTypedEquals(-1, int(F(-11, 10)))
       
   200 
       
   201         self.assertEquals(False, bool(F(0, 1)))
       
   202         self.assertEquals(True, bool(F(3, 2)))
       
   203         self.assertTypedEquals(0.1, float(F(1, 10)))
       
   204 
       
   205         # Check that __float__ isn't implemented by converting the
       
   206         # numerator and denominator to float before dividing.
       
   207         self.assertRaises(OverflowError, float, long('2'*400+'7'))
       
   208         self.assertAlmostEquals(2.0/3,
       
   209                                 float(F(long('2'*400+'7'), long('3'*400+'1'))))
       
   210 
       
   211         self.assertTypedEquals(0.1+0j, complex(F(1,10)))
       
   212 
       
   213 
       
   214     def testArithmetic(self):
       
   215         self.assertEquals(F(1, 2), F(1, 10) + F(2, 5))
       
   216         self.assertEquals(F(-3, 10), F(1, 10) - F(2, 5))
       
   217         self.assertEquals(F(1, 25), F(1, 10) * F(2, 5))
       
   218         self.assertEquals(F(1, 4), F(1, 10) / F(2, 5))
       
   219         self.assertTypedEquals(2, F(9, 10) // F(2, 5))
       
   220         self.assertTypedEquals(10**23, F(10**23, 1) // F(1))
       
   221         self.assertEquals(F(2, 3), F(-7, 3) % F(3, 2))
       
   222         self.assertEquals(F(8, 27), F(2, 3) ** F(3))
       
   223         self.assertEquals(F(27, 8), F(2, 3) ** F(-3))
       
   224         self.assertTypedEquals(2.0, F(4) ** F(1, 2))
       
   225         # Will return 1j in 3.0:
       
   226         self.assertRaises(ValueError, pow, F(-1), F(1, 2))
       
   227 
       
   228     def testMixedArithmetic(self):
       
   229         self.assertTypedEquals(F(11, 10), F(1, 10) + 1)
       
   230         self.assertTypedEquals(1.1, F(1, 10) + 1.0)
       
   231         self.assertTypedEquals(1.1 + 0j, F(1, 10) + (1.0 + 0j))
       
   232         self.assertTypedEquals(F(11, 10), 1 + F(1, 10))
       
   233         self.assertTypedEquals(1.1, 1.0 + F(1, 10))
       
   234         self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + F(1, 10))
       
   235 
       
   236         self.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
       
   237         self.assertTypedEquals(-0.9, F(1, 10) - 1.0)
       
   238         self.assertTypedEquals(-0.9 + 0j, F(1, 10) - (1.0 + 0j))
       
   239         self.assertTypedEquals(F(9, 10), 1 - F(1, 10))
       
   240         self.assertTypedEquals(0.9, 1.0 - F(1, 10))
       
   241         self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - F(1, 10))
       
   242 
       
   243         self.assertTypedEquals(F(1, 10), F(1, 10) * 1)
       
   244         self.assertTypedEquals(0.1, F(1, 10) * 1.0)
       
   245         self.assertTypedEquals(0.1 + 0j, F(1, 10) * (1.0 + 0j))
       
   246         self.assertTypedEquals(F(1, 10), 1 * F(1, 10))
       
   247         self.assertTypedEquals(0.1, 1.0 * F(1, 10))
       
   248         self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * F(1, 10))
       
   249 
       
   250         self.assertTypedEquals(F(1, 10), F(1, 10) / 1)
       
   251         self.assertTypedEquals(0.1, F(1, 10) / 1.0)
       
   252         self.assertTypedEquals(0.1 + 0j, F(1, 10) / (1.0 + 0j))
       
   253         self.assertTypedEquals(F(10, 1), 1 / F(1, 10))
       
   254         self.assertTypedEquals(10.0, 1.0 / F(1, 10))
       
   255         self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))
       
   256 
       
   257         self.assertTypedEquals(0, F(1, 10) // 1)
       
   258         self.assertTypedEquals(0.0, F(1, 10) // 1.0)
       
   259         self.assertTypedEquals(10, 1 // F(1, 10))
       
   260         self.assertTypedEquals(10**23, 10**22 // F(1, 10))
       
   261         self.assertTypedEquals(10.0, 1.0 // F(1, 10))
       
   262 
       
   263         self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
       
   264         self.assertTypedEquals(0.1, F(1, 10) % 1.0)
       
   265         self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
       
   266         self.assertTypedEquals(0.0, 1.0 % F(1, 10))
       
   267 
       
   268         # No need for divmod since we don't override it.
       
   269 
       
   270         # ** has more interesting conversion rules.
       
   271         self.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
       
   272         self.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
       
   273         self.assertTypedEquals(0.1, F(1, 10) ** 1.0)
       
   274         self.assertTypedEquals(0.1 + 0j, F(1, 10) ** (1.0 + 0j))
       
   275         self.assertTypedEquals(4 , 2 ** F(2, 1))
       
   276         # Will return 1j in 3.0:
       
   277         self.assertRaises(ValueError, pow, (-1), F(1, 2))
       
   278         self.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
       
   279         self.assertTypedEquals(2.0 , 4 ** F(1, 2))
       
   280         self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
       
   281         self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
       
   282 
       
   283     def testMixingWithDecimal(self):
       
   284         # Decimal refuses mixed comparisons.
       
   285         self.assertRaisesMessage(
       
   286             TypeError,
       
   287             "unsupported operand type(s) for +: 'Fraction' and 'Decimal'",
       
   288             operator.add, F(3,11), Decimal('3.1415926'))
       
   289         self.assertNotEquals(F(5, 2), Decimal('2.5'))
       
   290 
       
   291     def testComparisons(self):
       
   292         self.assertTrue(F(1, 2) < F(2, 3))
       
   293         self.assertFalse(F(1, 2) < F(1, 2))
       
   294         self.assertTrue(F(1, 2) <= F(2, 3))
       
   295         self.assertTrue(F(1, 2) <= F(1, 2))
       
   296         self.assertFalse(F(2, 3) <= F(1, 2))
       
   297         self.assertTrue(F(1, 2) == F(1, 2))
       
   298         self.assertFalse(F(1, 2) == F(1, 3))
       
   299         self.assertFalse(F(1, 2) != F(1, 2))
       
   300         self.assertTrue(F(1, 2) != F(1, 3))
       
   301 
       
   302     def testMixedLess(self):
       
   303         self.assertTrue(2 < F(5, 2))
       
   304         self.assertFalse(2 < F(4, 2))
       
   305         self.assertTrue(F(5, 2) < 3)
       
   306         self.assertFalse(F(4, 2) < 2)
       
   307 
       
   308         self.assertTrue(F(1, 2) < 0.6)
       
   309         self.assertFalse(F(1, 2) < 0.4)
       
   310         self.assertTrue(0.4 < F(1, 2))
       
   311         self.assertFalse(0.5 < F(1, 2))
       
   312 
       
   313     def testMixedLessEqual(self):
       
   314         self.assertTrue(0.5 <= F(1, 2))
       
   315         self.assertFalse(0.6 <= F(1, 2))
       
   316         self.assertTrue(F(1, 2) <= 0.5)
       
   317         self.assertFalse(F(1, 2) <= 0.4)
       
   318         self.assertTrue(2 <= F(4, 2))
       
   319         self.assertFalse(2 <= F(3, 2))
       
   320         self.assertTrue(F(4, 2) <= 2)
       
   321         self.assertFalse(F(5, 2) <= 2)
       
   322 
       
   323     def testBigFloatComparisons(self):
       
   324         # Because 10**23 can't be represented exactly as a float:
       
   325         self.assertFalse(F(10**23) == float(10**23))
       
   326         # The first test demonstrates why these are important.
       
   327         self.assertFalse(1e23 < float(F(math.trunc(1e23) + 1)))
       
   328         self.assertTrue(1e23 < F(math.trunc(1e23) + 1))
       
   329         self.assertFalse(1e23 <= F(math.trunc(1e23) - 1))
       
   330         self.assertTrue(1e23 > F(math.trunc(1e23) - 1))
       
   331         self.assertFalse(1e23 >= F(math.trunc(1e23) + 1))
       
   332 
       
   333     def testBigComplexComparisons(self):
       
   334         self.assertFalse(F(10**23) == complex(10**23))
       
   335         self.assertTrue(F(10**23) > complex(10**23))
       
   336         self.assertFalse(F(10**23) <= complex(10**23))
       
   337 
       
   338     def testMixedEqual(self):
       
   339         self.assertTrue(0.5 == F(1, 2))
       
   340         self.assertFalse(0.6 == F(1, 2))
       
   341         self.assertTrue(F(1, 2) == 0.5)
       
   342         self.assertFalse(F(1, 2) == 0.4)
       
   343         self.assertTrue(2 == F(4, 2))
       
   344         self.assertFalse(2 == F(3, 2))
       
   345         self.assertTrue(F(4, 2) == 2)
       
   346         self.assertFalse(F(5, 2) == 2)
       
   347 
       
   348     def testStringification(self):
       
   349         self.assertEquals("Fraction(7, 3)", repr(F(7, 3)))
       
   350         self.assertEquals("Fraction(6283185307, 2000000000)",
       
   351                           repr(F('3.1415926535')))
       
   352         self.assertEquals("Fraction(-1, 100000000000000000000)",
       
   353                           repr(F(1, -10**20)))
       
   354         self.assertEquals("7/3", str(F(7, 3)))
       
   355         self.assertEquals("7", str(F(7, 1)))
       
   356 
       
   357     def testHash(self):
       
   358         self.assertEquals(hash(2.5), hash(F(5, 2)))
       
   359         self.assertEquals(hash(10**50), hash(F(10**50)))
       
   360         self.assertNotEquals(hash(float(10**23)), hash(F(10**23)))
       
   361 
       
   362     def testApproximatePi(self):
       
   363         # Algorithm borrowed from
       
   364         # http://docs.python.org/lib/decimal-recipes.html
       
   365         three = F(3)
       
   366         lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
       
   367         while abs(s - lasts) > F(1, 10**9):
       
   368             lasts = s
       
   369             n, na = n+na, na+8
       
   370             d, da = d+da, da+32
       
   371             t = (t * n) / d
       
   372             s += t
       
   373         self.assertAlmostEquals(math.pi, s)
       
   374 
       
   375     def testApproximateCos1(self):
       
   376         # Algorithm borrowed from
       
   377         # http://docs.python.org/lib/decimal-recipes.html
       
   378         x = F(1)
       
   379         i, lasts, s, fact, num, sign = 0, 0, F(1), 1, 1, 1
       
   380         while abs(s - lasts) > F(1, 10**9):
       
   381             lasts = s
       
   382             i += 2
       
   383             fact *= i * (i-1)
       
   384             num *= x * x
       
   385             sign *= -1
       
   386             s += num / fact * sign
       
   387         self.assertAlmostEquals(math.cos(1), s)
       
   388 
       
   389     def test_copy_deepcopy_pickle(self):
       
   390         r = F(13, 7)
       
   391         self.assertEqual(r, loads(dumps(r)))
       
   392         self.assertEqual(id(r), id(copy(r)))
       
   393         self.assertEqual(id(r), id(deepcopy(r)))
       
   394 
       
   395 def test_main():
       
   396     run_unittest(FractionTest, GcdTest)
       
   397 
       
   398 if __name__ == '__main__':
       
   399     test_main()