]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_binop.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / test_binop.py
CommitLineData
4710c53d 1"""Tests for binary operators on subtypes of built-in types."""\r
2\r
3import unittest\r
4from test import test_support\r
5\r
6def gcd(a, b):\r
7 """Greatest common divisor using Euclid's algorithm."""\r
8 while a:\r
9 a, b = b%a, a\r
10 return b\r
11\r
12def isint(x):\r
13 """Test whether an object is an instance of int or long."""\r
14 return isinstance(x, int) or isinstance(x, long)\r
15\r
16def isnum(x):\r
17 """Test whether an object is an instance of a built-in numeric type."""\r
18 for T in int, long, float, complex:\r
19 if isinstance(x, T):\r
20 return 1\r
21 return 0\r
22\r
23def isRat(x):\r
24 """Test wheter an object is an instance of the Rat class."""\r
25 return isinstance(x, Rat)\r
26\r
27class Rat(object):\r
28\r
29 """Rational number implemented as a normalized pair of longs."""\r
30\r
31 __slots__ = ['_Rat__num', '_Rat__den']\r
32\r
33 def __init__(self, num=0L, den=1L):\r
34 """Constructor: Rat([num[, den]]).\r
35\r
36 The arguments must be ints or longs, and default to (0, 1)."""\r
37 if not isint(num):\r
38 raise TypeError, "Rat numerator must be int or long (%r)" % num\r
39 if not isint(den):\r
40 raise TypeError, "Rat denominator must be int or long (%r)" % den\r
41 # But the zero is always on\r
42 if den == 0:\r
43 raise ZeroDivisionError, "zero denominator"\r
44 g = gcd(den, num)\r
45 self.__num = long(num//g)\r
46 self.__den = long(den//g)\r
47\r
48 def _get_num(self):\r
49 """Accessor function for read-only 'num' attribute of Rat."""\r
50 return self.__num\r
51 num = property(_get_num, None)\r
52\r
53 def _get_den(self):\r
54 """Accessor function for read-only 'den' attribute of Rat."""\r
55 return self.__den\r
56 den = property(_get_den, None)\r
57\r
58 def __repr__(self):\r
59 """Convert a Rat to an string resembling a Rat constructor call."""\r
60 return "Rat(%d, %d)" % (self.__num, self.__den)\r
61\r
62 def __str__(self):\r
63 """Convert a Rat to a string resembling a decimal numeric value."""\r
64 return str(float(self))\r
65\r
66 def __float__(self):\r
67 """Convert a Rat to a float."""\r
68 return self.__num*1.0/self.__den\r
69\r
70 def __int__(self):\r
71 """Convert a Rat to an int; self.den must be 1."""\r
72 if self.__den == 1:\r
73 try:\r
74 return int(self.__num)\r
75 except OverflowError:\r
76 raise OverflowError, ("%s too large to convert to int" %\r
77 repr(self))\r
78 raise ValueError, "can't convert %s to int" % repr(self)\r
79\r
80 def __long__(self):\r
81 """Convert a Rat to an long; self.den must be 1."""\r
82 if self.__den == 1:\r
83 return long(self.__num)\r
84 raise ValueError, "can't convert %s to long" % repr(self)\r
85\r
86 def __add__(self, other):\r
87 """Add two Rats, or a Rat and a number."""\r
88 if isint(other):\r
89 other = Rat(other)\r
90 if isRat(other):\r
91 return Rat(self.__num*other.__den + other.__num*self.__den,\r
92 self.__den*other.__den)\r
93 if isnum(other):\r
94 return float(self) + other\r
95 return NotImplemented\r
96\r
97 __radd__ = __add__\r
98\r
99 def __sub__(self, other):\r
100 """Subtract two Rats, or a Rat and a number."""\r
101 if isint(other):\r
102 other = Rat(other)\r
103 if isRat(other):\r
104 return Rat(self.__num*other.__den - other.__num*self.__den,\r
105 self.__den*other.__den)\r
106 if isnum(other):\r
107 return float(self) - other\r
108 return NotImplemented\r
109\r
110 def __rsub__(self, other):\r
111 """Subtract two Rats, or a Rat and a number (reversed args)."""\r
112 if isint(other):\r
113 other = Rat(other)\r
114 if isRat(other):\r
115 return Rat(other.__num*self.__den - self.__num*other.__den,\r
116 self.__den*other.__den)\r
117 if isnum(other):\r
118 return other - float(self)\r
119 return NotImplemented\r
120\r
121 def __mul__(self, other):\r
122 """Multiply two Rats, or a Rat and a number."""\r
123 if isRat(other):\r
124 return Rat(self.__num*other.__num, self.__den*other.__den)\r
125 if isint(other):\r
126 return Rat(self.__num*other, self.__den)\r
127 if isnum(other):\r
128 return float(self)*other\r
129 return NotImplemented\r
130\r
131 __rmul__ = __mul__\r
132\r
133 def __truediv__(self, other):\r
134 """Divide two Rats, or a Rat and a number."""\r
135 if isRat(other):\r
136 return Rat(self.__num*other.__den, self.__den*other.__num)\r
137 if isint(other):\r
138 return Rat(self.__num, self.__den*other)\r
139 if isnum(other):\r
140 return float(self) / other\r
141 return NotImplemented\r
142\r
143 __div__ = __truediv__\r
144\r
145 def __rtruediv__(self, other):\r
146 """Divide two Rats, or a Rat and a number (reversed args)."""\r
147 if isRat(other):\r
148 return Rat(other.__num*self.__den, other.__den*self.__num)\r
149 if isint(other):\r
150 return Rat(other*self.__den, self.__num)\r
151 if isnum(other):\r
152 return other / float(self)\r
153 return NotImplemented\r
154\r
155 __rdiv__ = __rtruediv__\r
156\r
157 def __floordiv__(self, other):\r
158 """Divide two Rats, returning the floored result."""\r
159 if isint(other):\r
160 other = Rat(other)\r
161 elif not isRat(other):\r
162 return NotImplemented\r
163 x = self/other\r
164 return x.__num // x.__den\r
165\r
166 def __rfloordiv__(self, other):\r
167 """Divide two Rats, returning the floored result (reversed args)."""\r
168 x = other/self\r
169 return x.__num // x.__den\r
170\r
171 def __divmod__(self, other):\r
172 """Divide two Rats, returning quotient and remainder."""\r
173 if isint(other):\r
174 other = Rat(other)\r
175 elif not isRat(other):\r
176 return NotImplemented\r
177 x = self//other\r
178 return (x, self - other * x)\r
179\r
180 def __rdivmod__(self, other):\r
181 """Divide two Rats, returning quotient and remainder (reversed args)."""\r
182 if isint(other):\r
183 other = Rat(other)\r
184 elif not isRat(other):\r
185 return NotImplemented\r
186 return divmod(other, self)\r
187\r
188 def __mod__(self, other):\r
189 """Take one Rat modulo another."""\r
190 return divmod(self, other)[1]\r
191\r
192 def __rmod__(self, other):\r
193 """Take one Rat modulo another (reversed args)."""\r
194 return divmod(other, self)[1]\r
195\r
196 def __eq__(self, other):\r
197 """Compare two Rats for equality."""\r
198 if isint(other):\r
199 return self.__den == 1 and self.__num == other\r
200 if isRat(other):\r
201 return self.__num == other.__num and self.__den == other.__den\r
202 if isnum(other):\r
203 return float(self) == other\r
204 return NotImplemented\r
205\r
206 def __ne__(self, other):\r
207 """Compare two Rats for inequality."""\r
208 return not self == other\r
209\r
210 # Silence Py3k warning\r
211 __hash__ = None\r
212\r
213class RatTestCase(unittest.TestCase):\r
214 """Unit tests for Rat class and its support utilities."""\r
215\r
216 def test_gcd(self):\r
217 self.assertEqual(gcd(10, 12), 2)\r
218 self.assertEqual(gcd(10, 15), 5)\r
219 self.assertEqual(gcd(10, 11), 1)\r
220 self.assertEqual(gcd(100, 15), 5)\r
221 self.assertEqual(gcd(-10, 2), -2)\r
222 self.assertEqual(gcd(10, -2), 2)\r
223 self.assertEqual(gcd(-10, -2), -2)\r
224 for i in range(1, 20):\r
225 for j in range(1, 20):\r
226 self.assertTrue(gcd(i, j) > 0)\r
227 self.assertTrue(gcd(-i, j) < 0)\r
228 self.assertTrue(gcd(i, -j) > 0)\r
229 self.assertTrue(gcd(-i, -j) < 0)\r
230\r
231 def test_constructor(self):\r
232 a = Rat(10, 15)\r
233 self.assertEqual(a.num, 2)\r
234 self.assertEqual(a.den, 3)\r
235 a = Rat(10L, 15L)\r
236 self.assertEqual(a.num, 2)\r
237 self.assertEqual(a.den, 3)\r
238 a = Rat(10, -15)\r
239 self.assertEqual(a.num, -2)\r
240 self.assertEqual(a.den, 3)\r
241 a = Rat(-10, 15)\r
242 self.assertEqual(a.num, -2)\r
243 self.assertEqual(a.den, 3)\r
244 a = Rat(-10, -15)\r
245 self.assertEqual(a.num, 2)\r
246 self.assertEqual(a.den, 3)\r
247 a = Rat(7)\r
248 self.assertEqual(a.num, 7)\r
249 self.assertEqual(a.den, 1)\r
250 try:\r
251 a = Rat(1, 0)\r
252 except ZeroDivisionError:\r
253 pass\r
254 else:\r
255 self.fail("Rat(1, 0) didn't raise ZeroDivisionError")\r
256 for bad in "0", 0.0, 0j, (), [], {}, None, Rat, unittest:\r
257 try:\r
258 a = Rat(bad)\r
259 except TypeError:\r
260 pass\r
261 else:\r
262 self.fail("Rat(%r) didn't raise TypeError" % bad)\r
263 try:\r
264 a = Rat(1, bad)\r
265 except TypeError:\r
266 pass\r
267 else:\r
268 self.fail("Rat(1, %r) didn't raise TypeError" % bad)\r
269\r
270 def test_add(self):\r
271 self.assertEqual(Rat(2, 3) + Rat(1, 3), 1)\r
272 self.assertEqual(Rat(2, 3) + 1, Rat(5, 3))\r
273 self.assertEqual(1 + Rat(2, 3), Rat(5, 3))\r
274 self.assertEqual(1.0 + Rat(1, 2), 1.5)\r
275 self.assertEqual(Rat(1, 2) + 1.0, 1.5)\r
276\r
277 def test_sub(self):\r
278 self.assertEqual(Rat(7, 2) - Rat(7, 5), Rat(21, 10))\r
279 self.assertEqual(Rat(7, 5) - 1, Rat(2, 5))\r
280 self.assertEqual(1 - Rat(3, 5), Rat(2, 5))\r
281 self.assertEqual(Rat(3, 2) - 1.0, 0.5)\r
282 self.assertEqual(1.0 - Rat(1, 2), 0.5)\r
283\r
284 def test_mul(self):\r
285 self.assertEqual(Rat(2, 3) * Rat(5, 7), Rat(10, 21))\r
286 self.assertEqual(Rat(10, 3) * 3, 10)\r
287 self.assertEqual(3 * Rat(10, 3), 10)\r
288 self.assertEqual(Rat(10, 5) * 0.5, 1.0)\r
289 self.assertEqual(0.5 * Rat(10, 5), 1.0)\r
290\r
291 def test_div(self):\r
292 self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))\r
293 self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))\r
294 self.assertEqual(2 / Rat(5), Rat(2, 5))\r
295 self.assertEqual(3.0 * Rat(1, 2), 1.5)\r
296 self.assertEqual(Rat(1, 2) * 3.0, 1.5)\r
297\r
298 def test_floordiv(self):\r
299 self.assertEqual(Rat(10) // Rat(4), 2)\r
300 self.assertEqual(Rat(10, 3) // Rat(4, 3), 2)\r
301 self.assertEqual(Rat(10) // 4, 2)\r
302 self.assertEqual(10 // Rat(4), 2)\r
303\r
304 def test_eq(self):\r
305 self.assertEqual(Rat(10), Rat(20, 2))\r
306 self.assertEqual(Rat(10), 10)\r
307 self.assertEqual(10, Rat(10))\r
308 self.assertEqual(Rat(10), 10.0)\r
309 self.assertEqual(10.0, Rat(10))\r
310\r
311 def test_future_div(self):\r
312 exec future_test\r
313\r
314 # XXX Ran out of steam; TO DO: divmod, div, future division\r
315\r
316future_test = """\r
317from __future__ import division\r
318self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))\r
319self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))\r
320self.assertEqual(2 / Rat(5), Rat(2, 5))\r
321self.assertEqual(3.0 * Rat(1, 2), 1.5)\r
322self.assertEqual(Rat(1, 2) * 3.0, 1.5)\r
323self.assertEqual(eval('1/2'), 0.5)\r
324"""\r
325\r
326def test_main():\r
327 test_support.run_unittest(RatTestCase)\r
328\r
329\r
330if __name__ == "__main__":\r
331 test_main()\r