blob: 7cf7899932b34d9f964c92f8cf5253aaa023866b [file] [log] [blame]
Christian Heimes3feef612008-02-11 06:19:17 +00001"""Tests for Lib/fractions.py."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +00002
3from decimal import Decimal
Zachary Ware38c707e2015-04-13 15:00:43 -05004from test.support import requires_IEEE_754
Guido van Rossum7736b5b2008-01-15 21:44:53 +00005import math
Mark Dickinson85424c92009-07-18 14:41:42 +00006import numbers
Guido van Rossum7736b5b2008-01-15 21:44:53 +00007import operator
Christian Heimes3feef612008-02-11 06:19:17 +00008import fractions
Ezio Melotti682d3742012-02-29 14:05:53 +02009import sys
Guido van Rossum7736b5b2008-01-15 21:44:53 +000010import unittest
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +030011import warnings
Christian Heimes969fe572008-01-25 11:23:10 +000012from copy import copy, deepcopy
Neal Norwitz6ff93fe2008-01-26 21:52:30 +000013from pickle import dumps, loads
Christian Heimes68f5fbe2008-02-14 08:27:37 +000014F = fractions.Fraction
Victor Stinner4691a2f2020-01-16 11:02:51 +010015
Christian Heimesaf98da12008-01-27 15:18:18 +000016
Mark Dickinson85424c92009-07-18 14:41:42 +000017class DummyFloat(object):
18 """Dummy float class for testing comparisons with Fractions"""
19
20 def __init__(self, value):
21 if not isinstance(value, float):
22 raise TypeError("DummyFloat can only be initialized from float")
23 self.value = value
24
25 def _richcmp(self, other, op):
26 if isinstance(other, numbers.Rational):
27 return op(F.from_float(self.value), other)
28 elif isinstance(other, DummyFloat):
29 return op(self.value, other.value)
30 else:
31 return NotImplemented
32
33 def __eq__(self, other): return self._richcmp(other, operator.eq)
34 def __le__(self, other): return self._richcmp(other, operator.le)
35 def __lt__(self, other): return self._richcmp(other, operator.lt)
36 def __ge__(self, other): return self._richcmp(other, operator.ge)
37 def __gt__(self, other): return self._richcmp(other, operator.gt)
38
39 # shouldn't be calling __float__ at all when doing comparisons
40 def __float__(self):
41 assert False, "__float__ should not be invoked for comparisons"
42
43 # same goes for subtraction
44 def __sub__(self, other):
45 assert False, "__sub__ should not be invoked for comparisons"
46 __rsub__ = __sub__
47
48
49class DummyRational(object):
50 """Test comparison of Fraction with a naive rational implementation."""
51
52 def __init__(self, num, den):
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +030053 g = math.gcd(num, den)
Mark Dickinson85424c92009-07-18 14:41:42 +000054 self.num = num // g
55 self.den = den // g
56
57 def __eq__(self, other):
58 if isinstance(other, fractions.Fraction):
59 return (self.num == other._numerator and
60 self.den == other._denominator)
61 else:
62 return NotImplemented
63
64 def __lt__(self, other):
65 return(self.num * other._denominator < self.den * other._numerator)
66
67 def __gt__(self, other):
68 return(self.num * other._denominator > self.den * other._numerator)
69
70 def __le__(self, other):
71 return(self.num * other._denominator <= self.den * other._numerator)
72
73 def __ge__(self, other):
74 return(self.num * other._denominator >= self.den * other._numerator)
75
76 # this class is for testing comparisons; conversion to float
77 # should never be used for a comparison, since it loses accuracy
78 def __float__(self):
79 assert False, "__float__ should not be invoked"
Christian Heimesaf98da12008-01-27 15:18:18 +000080
Ezio Melotti682d3742012-02-29 14:05:53 +020081class DummyFraction(fractions.Fraction):
82 """Dummy Fraction subclass for copy and deepcopy testing."""
83
Guido van Rossum7736b5b2008-01-15 21:44:53 +000084
85def _components(r):
86 return (r.numerator, r.denominator)
87
Christian Heimesaf98da12008-01-27 15:18:18 +000088
Christian Heimes3feef612008-02-11 06:19:17 +000089class FractionTest(unittest.TestCase):
Guido van Rossum7736b5b2008-01-15 21:44:53 +000090
91 def assertTypedEquals(self, expected, actual):
92 """Asserts that both the types and values are the same."""
Ezio Melottib3aedd42010-11-20 19:04:17 +000093 self.assertEqual(type(expected), type(actual))
94 self.assertEqual(expected, actual)
Guido van Rossum7736b5b2008-01-15 21:44:53 +000095
Stefan Behnel3a374e02019-01-02 13:22:06 +010096 def assertTypedTupleEquals(self, expected, actual):
97 """Asserts that both the types and values in the tuples are the same."""
98 self.assertTupleEqual(expected, actual)
99 self.assertListEqual(list(map(type, expected)), list(map(type, actual)))
100
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000101 def assertRaisesMessage(self, exc_type, message,
102 callable, *args, **kwargs):
103 """Asserts that callable(*args, **kwargs) raises exc_type(message)."""
104 try:
105 callable(*args, **kwargs)
106 except exc_type as e:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000107 self.assertEqual(message, str(e))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000108 else:
109 self.fail("%s not raised" % exc_type.__name__)
110
111 def testInit(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000112 self.assertEqual((0, 1), _components(F()))
113 self.assertEqual((7, 1), _components(F(7)))
114 self.assertEqual((7, 3), _components(F(F(7, 3))))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000115
Ezio Melottib3aedd42010-11-20 19:04:17 +0000116 self.assertEqual((-1, 1), _components(F(-1, 1)))
117 self.assertEqual((-1, 1), _components(F(1, -1)))
118 self.assertEqual((1, 1), _components(F(-2, -2)))
119 self.assertEqual((1, 2), _components(F(5, 10)))
120 self.assertEqual((7, 15), _components(F(7, 15)))
121 self.assertEqual((10**23, 1), _components(F(10**23)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000122
Ezio Melottib3aedd42010-11-20 19:04:17 +0000123 self.assertEqual((3, 77), _components(F(F(3, 7), 11)))
124 self.assertEqual((-9, 5), _components(F(2, F(-10, 9))))
125 self.assertEqual((2486, 2485), _components(F(F(22, 7), F(355, 113))))
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000126
Christian Heimes3feef612008-02-11 06:19:17 +0000127 self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000128 F, 12, 0)
Georg Brandl86b2fb92008-07-16 03:43:04 +0000129 self.assertRaises(TypeError, F, 1.5 + 3j)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000130
Georg Brandl86b2fb92008-07-16 03:43:04 +0000131 self.assertRaises(TypeError, F, "3/2", 3)
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000132 self.assertRaises(TypeError, F, 3, 0j)
133 self.assertRaises(TypeError, F, 3, 1j)
Mark Dickinson7caf9082016-08-23 16:16:52 +0100134 self.assertRaises(TypeError, F, 1, 2, 3)
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000135
Mark Dickinson98127c32010-04-03 11:18:52 +0000136 @requires_IEEE_754
137 def testInitFromFloat(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000138 self.assertEqual((5, 2), _components(F(2.5)))
139 self.assertEqual((0, 1), _components(F(-0.0)))
140 self.assertEqual((3602879701896397, 36028797018963968),
141 _components(F(0.1)))
Mark Dickinson73726aa2012-11-15 20:58:40 +0000142 # bug 16469: error types should be consistent with float -> int
143 self.assertRaises(ValueError, F, float('nan'))
144 self.assertRaises(OverflowError, F, float('inf'))
145 self.assertRaises(OverflowError, F, float('-inf'))
Mark Dickinson98127c32010-04-03 11:18:52 +0000146
147 def testInitFromDecimal(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000148 self.assertEqual((11, 10),
149 _components(F(Decimal('1.1'))))
150 self.assertEqual((7, 200),
151 _components(F(Decimal('3.5e-2'))))
152 self.assertEqual((0, 1),
153 _components(F(Decimal('.000e20'))))
Mark Dickinson73726aa2012-11-15 20:58:40 +0000154 # bug 16469: error types should be consistent with decimal -> int
155 self.assertRaises(ValueError, F, Decimal('nan'))
156 self.assertRaises(ValueError, F, Decimal('snan'))
157 self.assertRaises(OverflowError, F, Decimal('inf'))
158 self.assertRaises(OverflowError, F, Decimal('-inf'))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000159
160 def testFromString(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000161 self.assertEqual((5, 1), _components(F("5")))
162 self.assertEqual((3, 2), _components(F("3/2")))
163 self.assertEqual((3, 2), _components(F(" \n +3/2")))
164 self.assertEqual((-3, 2), _components(F("-3/2 ")))
165 self.assertEqual((13, 2), _components(F(" 013/02 \n ")))
166 self.assertEqual((16, 5), _components(F(" 3.2 ")))
167 self.assertEqual((-16, 5), _components(F(" -3.2 ")))
168 self.assertEqual((-3, 1), _components(F(" -3. ")))
169 self.assertEqual((3, 5), _components(F(" .6 ")))
170 self.assertEqual((1, 3125), _components(F("32.e-5")))
171 self.assertEqual((1000000, 1), _components(F("1E+06")))
172 self.assertEqual((-12300, 1), _components(F("-1.23e4")))
173 self.assertEqual((0, 1), _components(F(" .0e+0\t")))
174 self.assertEqual((0, 1), _components(F("-0.000e0")))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000175
176 self.assertRaisesMessage(
Christian Heimes3feef612008-02-11 06:19:17 +0000177 ZeroDivisionError, "Fraction(3, 0)",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000178 F, "3/0")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000179 self.assertRaisesMessage(
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000180 ValueError, "Invalid literal for Fraction: '3/'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000181 F, "3/")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000182 self.assertRaisesMessage(
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000183 ValueError, "Invalid literal for Fraction: '/2'",
184 F, "/2")
185 self.assertRaisesMessage(
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000186 ValueError, "Invalid literal for Fraction: '3 /2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000187 F, "3 /2")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000188 self.assertRaisesMessage(
189 # Denominators don't need a sign.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000190 ValueError, "Invalid literal for Fraction: '3/+2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000191 F, "3/+2")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000192 self.assertRaisesMessage(
193 # Imitate float's parsing.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000194 ValueError, "Invalid literal for Fraction: '+ 3/2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000195 F, "+ 3/2")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000196 self.assertRaisesMessage(
Christian Heimesaf98da12008-01-27 15:18:18 +0000197 # Avoid treating '.' as a regex special character.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000198 ValueError, "Invalid literal for Fraction: '3a2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000199 F, "3a2")
Christian Heimesaf98da12008-01-27 15:18:18 +0000200 self.assertRaisesMessage(
Christian Heimesaf98da12008-01-27 15:18:18 +0000201 # Don't accept combinations of decimals and rationals.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000202 ValueError, "Invalid literal for Fraction: '3/7.2'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000203 F, "3/7.2")
Christian Heimesaf98da12008-01-27 15:18:18 +0000204 self.assertRaisesMessage(
205 # Don't accept combinations of decimals and rationals.
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000206 ValueError, "Invalid literal for Fraction: '3.2/7'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000207 F, "3.2/7")
Christian Heimes292d3512008-02-03 16:51:08 +0000208 self.assertRaisesMessage(
209 # Allow 3. and .3, but not .
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000210 ValueError, "Invalid literal for Fraction: '.'",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000211 F, ".")
Christian Heimes587c2bf2008-01-19 16:21:02 +0000212
213 def testImmutable(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000214 r = F(7, 3)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000215 r.__init__(2, 15)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000216 self.assertEqual((7, 3), _components(r))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000217
Christian Heimes400adb02008-02-01 08:12:03 +0000218 self.assertRaises(AttributeError, setattr, r, 'numerator', 12)
219 self.assertRaises(AttributeError, setattr, r, 'denominator', 6)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000220 self.assertEqual((7, 3), _components(r))
Christian Heimes400adb02008-02-01 08:12:03 +0000221
222 # But if you _really_ need to:
223 r._numerator = 4
224 r._denominator = 2
Ezio Melottib3aedd42010-11-20 19:04:17 +0000225 self.assertEqual((4, 2), _components(r))
Christian Heimes400adb02008-02-01 08:12:03 +0000226 # Which breaks some important operations:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000227 self.assertNotEqual(F(4, 2), r)
Christian Heimes400adb02008-02-01 08:12:03 +0000228
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000229 def testFromFloat(self):
Georg Brandl2ee470f2008-07-16 12:55:28 +0000230 self.assertRaises(TypeError, F.from_float, 3+4j)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000231 self.assertEqual((10, 1), _components(F.from_float(10)))
Georg Brandl3a9b0622009-01-03 22:07:57 +0000232 bigint = 1234567890123456789
Ezio Melottib3aedd42010-11-20 19:04:17 +0000233 self.assertEqual((bigint, 1), _components(F.from_float(bigint)))
234 self.assertEqual((0, 1), _components(F.from_float(-0.0)))
235 self.assertEqual((10, 1), _components(F.from_float(10.0)))
236 self.assertEqual((-5, 2), _components(F.from_float(-2.5)))
237 self.assertEqual((99999999999999991611392, 1),
238 _components(F.from_float(1e23)))
239 self.assertEqual(float(10**23), float(F.from_float(1e23)))
240 self.assertEqual((3602879701896397, 1125899906842624),
241 _components(F.from_float(3.2)))
242 self.assertEqual(3.2, float(F.from_float(3.2)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000243
244 inf = 1e1000
245 nan = inf - inf
Mark Dickinson73726aa2012-11-15 20:58:40 +0000246 # bug 16469: error types should be consistent with float -> int
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000247 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200248 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000249 F.from_float, inf)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000250 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200251 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000252 F.from_float, -inf)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000253 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200254 ValueError, "cannot convert NaN to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000255 F.from_float, nan)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000256
Christian Heimes587c2bf2008-01-19 16:21:02 +0000257 def testFromDecimal(self):
Georg Brandl2ee470f2008-07-16 12:55:28 +0000258 self.assertRaises(TypeError, F.from_decimal, 3+4j)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000259 self.assertEqual(F(10, 1), F.from_decimal(10))
260 self.assertEqual(F(0), F.from_decimal(Decimal("-0")))
261 self.assertEqual(F(5, 10), F.from_decimal(Decimal("0.5")))
262 self.assertEqual(F(5, 1000), F.from_decimal(Decimal("5e-3")))
263 self.assertEqual(F(5000), F.from_decimal(Decimal("5e3")))
264 self.assertEqual(1 - F(1, 10**30),
265 F.from_decimal(Decimal("0." + "9" * 30)))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000266
Mark Dickinson73726aa2012-11-15 20:58:40 +0000267 # bug 16469: error types should be consistent with decimal -> int
Christian Heimes587c2bf2008-01-19 16:21:02 +0000268 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200269 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000270 F.from_decimal, Decimal("inf"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000271 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200272 OverflowError, "cannot convert Infinity to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000273 F.from_decimal, Decimal("-inf"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000274 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200275 ValueError, "cannot convert NaN to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000276 F.from_decimal, Decimal("nan"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000277 self.assertRaisesMessage(
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200278 ValueError, "cannot convert NaN to integer ratio",
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000279 F.from_decimal, Decimal("snan"))
Christian Heimes587c2bf2008-01-19 16:21:02 +0000280
Raymond Hettingerf03b4c82019-08-11 14:40:59 -0700281 def test_as_integer_ratio(self):
282 self.assertEqual(F(4, 6).as_integer_ratio(), (2, 3))
283 self.assertEqual(F(-4, 6).as_integer_ratio(), (-2, 3))
284 self.assertEqual(F(4, -6).as_integer_ratio(), (-2, 3))
285 self.assertEqual(F(0, 6).as_integer_ratio(), (0, 1))
286
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000287 def testLimitDenominator(self):
288 rpi = F('3.1415926535897932')
289 self.assertEqual(rpi.limit_denominator(10000), F(355, 113))
290 self.assertEqual(-rpi.limit_denominator(10000), F(-355, 113))
291 self.assertEqual(rpi.limit_denominator(113), F(355, 113))
292 self.assertEqual(rpi.limit_denominator(112), F(333, 106))
293 self.assertEqual(F(201, 200).limit_denominator(100), F(1))
294 self.assertEqual(F(201, 200).limit_denominator(101), F(102, 101))
295 self.assertEqual(F(0).limit_denominator(10000), F(0))
Ezio Melotti682d3742012-02-29 14:05:53 +0200296 for i in (0, -1):
297 self.assertRaisesMessage(
298 ValueError, "max_denominator should be at least 1",
299 F(1).limit_denominator, i)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000300
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000301 def testConversions(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000302 self.assertTypedEquals(-1, math.trunc(F(-11, 10)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200303 self.assertTypedEquals(1, math.trunc(F(11, 10)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000304 self.assertTypedEquals(-2, math.floor(F(-11, 10)))
305 self.assertTypedEquals(-1, math.ceil(F(-11, 10)))
306 self.assertTypedEquals(-1, math.ceil(F(-10, 10)))
307 self.assertTypedEquals(-1, int(F(-11, 10)))
308 self.assertTypedEquals(0, round(F(-1, 10)))
309 self.assertTypedEquals(0, round(F(-5, 10)))
310 self.assertTypedEquals(-2, round(F(-15, 10)))
311 self.assertTypedEquals(-1, round(F(-7, 10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000312
Ezio Melottib3aedd42010-11-20 19:04:17 +0000313 self.assertEqual(False, bool(F(0, 1)))
314 self.assertEqual(True, bool(F(3, 2)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000315 self.assertTypedEquals(0.1, float(F(1, 10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000316
317 # Check that __float__ isn't implemented by converting the
318 # numerator and denominator to float before dividing.
319 self.assertRaises(OverflowError, float, int('2'*400+'7'))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000320 self.assertAlmostEqual(2.0/3,
321 float(F(int('2'*400+'7'), int('3'*400+'1'))))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000322
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000323 self.assertTypedEquals(0.1+0j, complex(F(1,10)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000324
325 def testRound(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000326 self.assertTypedEquals(F(-200), round(F(-150), -2))
327 self.assertTypedEquals(F(-200), round(F(-250), -2))
328 self.assertTypedEquals(F(30), round(F(26), -1))
329 self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1))
330 self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000331
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000332 def testArithmetic(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000333 self.assertEqual(F(1, 2), F(1, 10) + F(2, 5))
334 self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5))
335 self.assertEqual(F(1, 25), F(1, 10) * F(2, 5))
336 self.assertEqual(F(1, 4), F(1, 10) / F(2, 5))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000337 self.assertTypedEquals(2, F(9, 10) // F(2, 5))
338 self.assertTypedEquals(10**23, F(10**23, 1) // F(1))
Stefan Behnel3a374e02019-01-02 13:22:06 +0100339 self.assertEqual(F(5, 6), F(7, 3) % F(3, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000340 self.assertEqual(F(2, 3), F(-7, 3) % F(3, 2))
Stefan Behnel3a374e02019-01-02 13:22:06 +0100341 self.assertEqual((F(1), F(5, 6)), divmod(F(7, 3), F(3, 2)))
342 self.assertEqual((F(-2), F(2, 3)), divmod(F(-7, 3), F(3, 2)))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000343 self.assertEqual(F(8, 27), F(2, 3) ** F(3))
344 self.assertEqual(F(27, 8), F(2, 3) ** F(-3))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000345 self.assertTypedEquals(2.0, F(4) ** F(1, 2))
Ezio Melotti682d3742012-02-29 14:05:53 +0200346 self.assertEqual(F(1, 1), +F(1, 1))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000347 z = pow(F(-1), F(1, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000348 self.assertAlmostEqual(z.real, 0)
349 self.assertEqual(z.imag, 1)
Mark Dickinson84479652016-08-22 10:50:53 +0100350 # Regression test for #27539.
351 p = F(-1, 2) ** 0
352 self.assertEqual(p, F(1, 1))
353 self.assertEqual(p.numerator, 1)
354 self.assertEqual(p.denominator, 1)
355 p = F(-1, 2) ** -1
356 self.assertEqual(p, F(-2, 1))
357 self.assertEqual(p.numerator, -2)
358 self.assertEqual(p.denominator, 1)
359 p = F(-1, 2) ** -2
360 self.assertEqual(p, F(4, 1))
361 self.assertEqual(p.numerator, 4)
362 self.assertEqual(p.denominator, 1)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000363
Stefan Behnel3a374e02019-01-02 13:22:06 +0100364 def testLargeArithmetic(self):
365 self.assertTypedEquals(
366 F(10101010100808080808080808101010101010000000000000000,
367 1010101010101010101010101011111111101010101010101010101010101),
368 F(10**35+1, 10**27+1) % F(10**27+1, 10**35-1)
369 )
370 self.assertTypedEquals(
371 F(7, 1901475900342344102245054808064),
372 F(-2**100, 3) % F(5, 2**100)
373 )
374 self.assertTypedTupleEquals(
375 (9999999999999999,
376 F(10101010100808080808080808101010101010000000000000000,
377 1010101010101010101010101011111111101010101010101010101010101)),
378 divmod(F(10**35+1, 10**27+1), F(10**27+1, 10**35-1))
379 )
380 self.assertTypedEquals(
381 -2 ** 200 // 15,
382 F(-2**100, 3) // F(5, 2**100)
383 )
384 self.assertTypedEquals(
385 1,
386 F(5, 2**100) // F(3, 2**100)
387 )
388 self.assertTypedEquals(
389 (1, F(2, 2**100)),
390 divmod(F(5, 2**100), F(3, 2**100))
391 )
392 self.assertTypedTupleEquals(
393 (-2 ** 200 // 15,
394 F(7, 1901475900342344102245054808064)),
395 divmod(F(-2**100, 3), F(5, 2**100))
396 )
397
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000398 def testMixedArithmetic(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000399 self.assertTypedEquals(F(11, 10), F(1, 10) + 1)
400 self.assertTypedEquals(1.1, F(1, 10) + 1.0)
401 self.assertTypedEquals(1.1 + 0j, F(1, 10) + (1.0 + 0j))
402 self.assertTypedEquals(F(11, 10), 1 + F(1, 10))
403 self.assertTypedEquals(1.1, 1.0 + F(1, 10))
404 self.assertTypedEquals(1.1 + 0j, (1.0 + 0j) + F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000405
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000406 self.assertTypedEquals(F(-9, 10), F(1, 10) - 1)
407 self.assertTypedEquals(-0.9, F(1, 10) - 1.0)
408 self.assertTypedEquals(-0.9 + 0j, F(1, 10) - (1.0 + 0j))
409 self.assertTypedEquals(F(9, 10), 1 - F(1, 10))
410 self.assertTypedEquals(0.9, 1.0 - F(1, 10))
411 self.assertTypedEquals(0.9 + 0j, (1.0 + 0j) - F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000412
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000413 self.assertTypedEquals(F(1, 10), F(1, 10) * 1)
414 self.assertTypedEquals(0.1, F(1, 10) * 1.0)
415 self.assertTypedEquals(0.1 + 0j, F(1, 10) * (1.0 + 0j))
416 self.assertTypedEquals(F(1, 10), 1 * F(1, 10))
417 self.assertTypedEquals(0.1, 1.0 * F(1, 10))
418 self.assertTypedEquals(0.1 + 0j, (1.0 + 0j) * F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000419
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000420 self.assertTypedEquals(F(1, 10), F(1, 10) / 1)
421 self.assertTypedEquals(0.1, F(1, 10) / 1.0)
422 self.assertTypedEquals(0.1 + 0j, F(1, 10) / (1.0 + 0j))
423 self.assertTypedEquals(F(10, 1), 1 / F(1, 10))
424 self.assertTypedEquals(10.0, 1.0 / F(1, 10))
425 self.assertTypedEquals(10.0 + 0j, (1.0 + 0j) / F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000426
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000427 self.assertTypedEquals(0, F(1, 10) // 1)
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700428 self.assertTypedEquals(0.0, F(1, 10) // 1.0)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000429 self.assertTypedEquals(10, 1 // F(1, 10))
430 self.assertTypedEquals(10**23, 10**22 // F(1, 10))
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700431 self.assertTypedEquals(1.0 // 0.1, 1.0 // F(1, 10))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000432
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000433 self.assertTypedEquals(F(1, 10), F(1, 10) % 1)
434 self.assertTypedEquals(0.1, F(1, 10) % 1.0)
435 self.assertTypedEquals(F(0, 1), 1 % F(1, 10))
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700436 self.assertTypedEquals(1.0 % 0.1, 1.0 % F(1, 10))
437 self.assertTypedEquals(0.1, F(1, 10) % float('inf'))
438 self.assertTypedEquals(float('-inf'), F(1, 10) % float('-inf'))
439 self.assertTypedEquals(float('inf'), F(-1, 10) % float('inf'))
440 self.assertTypedEquals(-0.1, F(-1, 10) % float('-inf'))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000441
Stefan Behnel3a374e02019-01-02 13:22:06 +0100442 self.assertTypedTupleEquals((0, F(1, 10)), divmod(F(1, 10), 1))
443 self.assertTypedTupleEquals(divmod(0.1, 1.0), divmod(F(1, 10), 1.0))
444 self.assertTypedTupleEquals((10, F(0)), divmod(1, F(1, 10)))
445 self.assertTypedTupleEquals(divmod(1.0, 0.1), divmod(1.0, F(1, 10)))
446 self.assertTypedTupleEquals(divmod(0.1, float('inf')), divmod(F(1, 10), float('inf')))
447 self.assertTypedTupleEquals(divmod(0.1, float('-inf')), divmod(F(1, 10), float('-inf')))
448 self.assertTypedTupleEquals(divmod(-0.1, float('inf')), divmod(F(-1, 10), float('inf')))
449 self.assertTypedTupleEquals(divmod(-0.1, float('-inf')), divmod(F(-1, 10), float('-inf')))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000450
451 # ** has more interesting conversion rules.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000452 self.assertTypedEquals(F(100, 1), F(1, 10) ** -2)
453 self.assertTypedEquals(F(100, 1), F(10, 1) ** 2)
454 self.assertTypedEquals(0.1, F(1, 10) ** 1.0)
455 self.assertTypedEquals(0.1 + 0j, F(1, 10) ** (1.0 + 0j))
456 self.assertTypedEquals(4 , 2 ** F(2, 1))
457 z = pow(-1, F(1, 2))
Ezio Melottib3aedd42010-11-20 19:04:17 +0000458 self.assertAlmostEqual(0, z.real)
459 self.assertEqual(1, z.imag)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000460 self.assertTypedEquals(F(1, 4) , 2 ** F(-2, 1))
461 self.assertTypedEquals(2.0 , 4 ** F(1, 2))
462 self.assertTypedEquals(0.25, 2.0 ** F(-2, 1))
463 self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10))
Mark Dickinson3c286e22014-04-05 09:29:00 +0100464 self.assertRaises(ZeroDivisionError, operator.pow,
465 F(0, 1), -2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000466
467 def testMixingWithDecimal(self):
Mark Dickinson08ade6f2010-06-11 10:44:52 +0000468 # Decimal refuses mixed arithmetic (but not mixed comparisons)
Stefan Krah1919b7e2012-03-21 18:25:23 +0100469 self.assertRaises(TypeError, operator.add,
470 F(3,11), Decimal('3.1415926'))
471 self.assertRaises(TypeError, operator.add,
472 Decimal('3.1415926'), F(3,11))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000473
474 def testComparisons(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000475 self.assertTrue(F(1, 2) < F(2, 3))
476 self.assertFalse(F(1, 2) < F(1, 2))
477 self.assertTrue(F(1, 2) <= F(2, 3))
478 self.assertTrue(F(1, 2) <= F(1, 2))
479 self.assertFalse(F(2, 3) <= F(1, 2))
480 self.assertTrue(F(1, 2) == F(1, 2))
481 self.assertFalse(F(1, 2) == F(1, 3))
482 self.assertFalse(F(1, 2) != F(1, 2))
483 self.assertTrue(F(1, 2) != F(1, 3))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000484
Mark Dickinson85424c92009-07-18 14:41:42 +0000485 def testComparisonsDummyRational(self):
486 self.assertTrue(F(1, 2) == DummyRational(1, 2))
487 self.assertTrue(DummyRational(1, 2) == F(1, 2))
488 self.assertFalse(F(1, 2) == DummyRational(3, 4))
489 self.assertFalse(DummyRational(3, 4) == F(1, 2))
490
491 self.assertTrue(F(1, 2) < DummyRational(3, 4))
492 self.assertFalse(F(1, 2) < DummyRational(1, 2))
493 self.assertFalse(F(1, 2) < DummyRational(1, 7))
494 self.assertFalse(F(1, 2) > DummyRational(3, 4))
495 self.assertFalse(F(1, 2) > DummyRational(1, 2))
496 self.assertTrue(F(1, 2) > DummyRational(1, 7))
497 self.assertTrue(F(1, 2) <= DummyRational(3, 4))
498 self.assertTrue(F(1, 2) <= DummyRational(1, 2))
499 self.assertFalse(F(1, 2) <= DummyRational(1, 7))
500 self.assertFalse(F(1, 2) >= DummyRational(3, 4))
501 self.assertTrue(F(1, 2) >= DummyRational(1, 2))
502 self.assertTrue(F(1, 2) >= DummyRational(1, 7))
503
504 self.assertTrue(DummyRational(1, 2) < F(3, 4))
505 self.assertFalse(DummyRational(1, 2) < F(1, 2))
506 self.assertFalse(DummyRational(1, 2) < F(1, 7))
507 self.assertFalse(DummyRational(1, 2) > F(3, 4))
508 self.assertFalse(DummyRational(1, 2) > F(1, 2))
509 self.assertTrue(DummyRational(1, 2) > F(1, 7))
510 self.assertTrue(DummyRational(1, 2) <= F(3, 4))
511 self.assertTrue(DummyRational(1, 2) <= F(1, 2))
512 self.assertFalse(DummyRational(1, 2) <= F(1, 7))
513 self.assertFalse(DummyRational(1, 2) >= F(3, 4))
514 self.assertTrue(DummyRational(1, 2) >= F(1, 2))
515 self.assertTrue(DummyRational(1, 2) >= F(1, 7))
516
517 def testComparisonsDummyFloat(self):
518 x = DummyFloat(1./3.)
519 y = F(1, 3)
520 self.assertTrue(x != y)
521 self.assertTrue(x < y or x > y)
522 self.assertFalse(x == y)
523 self.assertFalse(x <= y and x >= y)
524 self.assertTrue(y != x)
525 self.assertTrue(y < x or y > x)
526 self.assertFalse(y == x)
527 self.assertFalse(y <= x and y >= x)
528
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000529 def testMixedLess(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000530 self.assertTrue(2 < F(5, 2))
531 self.assertFalse(2 < F(4, 2))
532 self.assertTrue(F(5, 2) < 3)
533 self.assertFalse(F(4, 2) < 2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000534
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000535 self.assertTrue(F(1, 2) < 0.6)
536 self.assertFalse(F(1, 2) < 0.4)
537 self.assertTrue(0.4 < F(1, 2))
538 self.assertFalse(0.5 < F(1, 2))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000539
Mark Dickinson85424c92009-07-18 14:41:42 +0000540 self.assertFalse(float('inf') < F(1, 2))
541 self.assertTrue(float('-inf') < F(0, 10))
542 self.assertFalse(float('nan') < F(-3, 7))
543 self.assertTrue(F(1, 2) < float('inf'))
544 self.assertFalse(F(17, 12) < float('-inf'))
545 self.assertFalse(F(144, -89) < float('nan'))
546
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000547 def testMixedLessEqual(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000548 self.assertTrue(0.5 <= F(1, 2))
549 self.assertFalse(0.6 <= F(1, 2))
550 self.assertTrue(F(1, 2) <= 0.5)
551 self.assertFalse(F(1, 2) <= 0.4)
552 self.assertTrue(2 <= F(4, 2))
553 self.assertFalse(2 <= F(3, 2))
554 self.assertTrue(F(4, 2) <= 2)
555 self.assertFalse(F(5, 2) <= 2)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000556
Mark Dickinson85424c92009-07-18 14:41:42 +0000557 self.assertFalse(float('inf') <= F(1, 2))
558 self.assertTrue(float('-inf') <= F(0, 10))
559 self.assertFalse(float('nan') <= F(-3, 7))
560 self.assertTrue(F(1, 2) <= float('inf'))
561 self.assertFalse(F(17, 12) <= float('-inf'))
562 self.assertFalse(F(144, -89) <= float('nan'))
563
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000564 def testBigFloatComparisons(self):
565 # Because 10**23 can't be represented exactly as a float:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000566 self.assertFalse(F(10**23) == float(10**23))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000567 # The first test demonstrates why these are important.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000568 self.assertFalse(1e23 < float(F(math.trunc(1e23) + 1)))
569 self.assertTrue(1e23 < F(math.trunc(1e23) + 1))
570 self.assertFalse(1e23 <= F(math.trunc(1e23) - 1))
571 self.assertTrue(1e23 > F(math.trunc(1e23) - 1))
572 self.assertFalse(1e23 >= F(math.trunc(1e23) + 1))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000573
574 def testBigComplexComparisons(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000575 self.assertFalse(F(10**23) == complex(10**23))
Mark Dickinson327f02c2010-03-27 11:11:13 +0000576 self.assertRaises(TypeError, operator.gt, F(10**23), complex(10**23))
577 self.assertRaises(TypeError, operator.le, F(10**23), complex(10**23))
578
579 x = F(3, 8)
580 z = complex(0.375, 0.0)
581 w = complex(0.375, 0.2)
582 self.assertTrue(x == z)
583 self.assertFalse(x != z)
584 self.assertFalse(x == w)
585 self.assertTrue(x != w)
586 for op in operator.lt, operator.le, operator.gt, operator.ge:
587 self.assertRaises(TypeError, op, x, z)
588 self.assertRaises(TypeError, op, z, x)
589 self.assertRaises(TypeError, op, x, w)
590 self.assertRaises(TypeError, op, w, x)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000591
592 def testMixedEqual(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000593 self.assertTrue(0.5 == F(1, 2))
594 self.assertFalse(0.6 == F(1, 2))
595 self.assertTrue(F(1, 2) == 0.5)
596 self.assertFalse(F(1, 2) == 0.4)
597 self.assertTrue(2 == F(4, 2))
598 self.assertFalse(2 == F(3, 2))
599 self.assertTrue(F(4, 2) == 2)
600 self.assertFalse(F(5, 2) == 2)
Mark Dickinson85424c92009-07-18 14:41:42 +0000601 self.assertFalse(F(5, 2) == float('nan'))
602 self.assertFalse(float('nan') == F(3, 7))
603 self.assertFalse(F(5, 2) == float('inf'))
604 self.assertFalse(float('-inf') == F(2, 5))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000605
606 def testStringification(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000607 self.assertEqual("Fraction(7, 3)", repr(F(7, 3)))
608 self.assertEqual("Fraction(6283185307, 2000000000)",
609 repr(F('3.1415926535')))
610 self.assertEqual("Fraction(-1, 100000000000000000000)",
611 repr(F(1, -10**20)))
612 self.assertEqual("7/3", str(F(7, 3)))
613 self.assertEqual("7", str(F(7, 1)))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000614
615 def testHash(self):
Ezio Melotti682d3742012-02-29 14:05:53 +0200616 hmod = sys.hash_info.modulus
617 hinf = sys.hash_info.inf
Ezio Melottib3aedd42010-11-20 19:04:17 +0000618 self.assertEqual(hash(2.5), hash(F(5, 2)))
619 self.assertEqual(hash(10**50), hash(F(10**50)))
620 self.assertNotEqual(hash(float(10**23)), hash(F(10**23)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200621 self.assertEqual(hinf, hash(F(1, hmod)))
Mark Dickinsonfec66202010-11-13 10:27:38 +0000622 # Check that __hash__ produces the same value as hash(), for
623 # consistency with int and Decimal. (See issue #10356.)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000624 self.assertEqual(hash(F(-1)), F(-1).__hash__())
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000625
626 def testApproximatePi(self):
627 # Algorithm borrowed from
628 # http://docs.python.org/lib/decimal-recipes.html
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000629 three = F(3)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000630 lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000631 while abs(s - lasts) > F(1, 10**9):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000632 lasts = s
633 n, na = n+na, na+8
634 d, da = d+da, da+32
635 t = (t * n) / d
636 s += t
Ezio Melottib3aedd42010-11-20 19:04:17 +0000637 self.assertAlmostEqual(math.pi, s)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000638
639 def testApproximateCos1(self):
640 # Algorithm borrowed from
641 # http://docs.python.org/lib/decimal-recipes.html
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000642 x = F(1)
643 i, lasts, s, fact, num, sign = 0, 0, F(1), 1, 1, 1
644 while abs(s - lasts) > F(1, 10**9):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000645 lasts = s
646 i += 2
647 fact *= i * (i-1)
648 num *= x * x
649 sign *= -1
650 s += num / fact * sign
Ezio Melottib3aedd42010-11-20 19:04:17 +0000651 self.assertAlmostEqual(math.cos(1), s)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000652
Christian Heimes969fe572008-01-25 11:23:10 +0000653 def test_copy_deepcopy_pickle(self):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000654 r = F(13, 7)
Ezio Melotti682d3742012-02-29 14:05:53 +0200655 dr = DummyFraction(13, 7)
Christian Heimes969fe572008-01-25 11:23:10 +0000656 self.assertEqual(r, loads(dumps(r)))
657 self.assertEqual(id(r), id(copy(r)))
658 self.assertEqual(id(r), id(deepcopy(r)))
Ezio Melotti682d3742012-02-29 14:05:53 +0200659 self.assertNotEqual(id(dr), id(copy(dr)))
660 self.assertNotEqual(id(dr), id(deepcopy(dr)))
661 self.assertTypedEquals(dr, copy(dr))
662 self.assertTypedEquals(dr, deepcopy(dr))
Christian Heimes969fe572008-01-25 11:23:10 +0000663
Mark Dickinsonc28ad272009-02-12 17:58:36 +0000664 def test_slots(self):
665 # Issue 4998
666 r = F(13, 7)
667 self.assertRaises(AttributeError, setattr, r, 'a', 10)
668
Victor Stinner4691a2f2020-01-16 11:02:51 +0100669
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000670if __name__ == '__main__':
Zachary Ware38c707e2015-04-13 15:00:43 -0500671 unittest.main()