Kaydet (Commit) d058cd2c authored tarafından Mark Dickinson's avatar Mark Dickinson

Rename rational.Rational to fractions.Fraction, to avoid name clash

with numbers.Rational.  See issue #1682 for related discussion.
üst da614dcc
:mod:`rational` --- Rational numbers
:mod:`fractions` --- Rational numbers
====================================
.. module:: rational
.. module:: fractions
:synopsis: Rational numbers.
.. moduleauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
.. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
.. versionadded:: 2.6
The :mod:`rational` module defines an immutable, infinite-precision
Rational number class.
The :mod:`fractions` module defines an immutable, infinite-precision
Fraction number class.
.. class:: Rational(numerator=0, denominator=1)
Rational(other_rational)
Rational(string)
.. class:: Fraction(numerator=0, denominator=1)
Fraction(other_fraction)
Fraction(string)
The first version requires that *numerator* and *denominator* are
instances of :class:`numbers.Integral` and returns a new
``Rational`` representing ``numerator/denominator``. If
``Fraction`` representing ``numerator/denominator``. If
*denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The
second version requires that *other_rational* is an instance of
second version requires that *other_fraction* is an instance of
:class:`numbers.Rational` and returns an instance of
:class:`Rational` with the same value. The third version expects a
:class:`Fraction` with the same value. The third version expects a
string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded
by spaces.
......@@ -31,39 +31,39 @@ Rational number class.
:class:`numbers.Rational` and is immutable and hashable.
.. method:: Rational.from_float(flt)
.. method:: Fraction.from_float(flt)
This classmethod constructs a :class:`Rational` representing the
This classmethod constructs a :class:`Fraction` representing the
exact value of *flt*, which must be a :class:`float`. Beware that
``Rational.from_float(0.3)`` is not the same value as ``Rational(3,
``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3,
10)``
.. method:: Rational.from_decimal(dec)
.. method:: Fraction.from_decimal(dec)
This classmethod constructs a :class:`Rational` representing the
This classmethod constructs a :class:`Fraction` representing the
exact value of *dec*, which must be a
:class:`decimal.Decimal`.
.. method:: Rational.__floor__()
.. method:: Fraction.__floor__()
Returns the greatest :class:`int` ``<= self``. Will be accessible
through :func:`math.floor` in Py3k.
.. method:: Rational.__ceil__()
.. method:: Fraction.__ceil__()
Returns the least :class:`int` ``>= self``. Will be accessible
through :func:`math.ceil` in Py3k.
.. method:: Rational.__round__()
Rational.__round__(ndigits)
.. method:: Fraction.__round__()
Fraction.__round__(ndigits)
The first version returns the nearest :class:`int` to ``self``,
rounding half to even. The second version rounds ``self`` to the
nearest multiple of ``Rational(1, 10**ndigits)`` (logically, if
nearest multiple of ``Fraction(1, 10**ndigits)`` (logically, if
``ndigits`` is negative), again rounding half toward even. Will be
accessible through :func:`round` in Py3k.
......
......@@ -106,7 +106,7 @@ Notes for type implementors
Implementors should be careful to make equal numbers equal and hash
them to the same values. This may be subtle if there are two different
extensions of the real numbers. For example, :class:`rational.Rational`
extensions of the real numbers. For example, :class:`fractions.Fraction`
implements :func:`hash` as follows::
def __hash__(self):
......@@ -201,11 +201,11 @@ in :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b
Because most of the operations on any given type will be very similar,
it can be useful to define a helper function which generates the
forward and reverse instances of any given operator. For example,
:class:`rational.Rational` uses::
:class:`fractions.Fraction` uses::
def _operator_fallbacks(monomorphic_operator, fallback_operator):
def forward(a, b):
if isinstance(b, (int, long, Rational)):
if isinstance(b, (int, long, Fraction)):
return monomorphic_operator(a, b)
elif isinstance(b, float):
return fallback_operator(float(a), b)
......@@ -217,7 +217,7 @@ forward and reverse instances of any given operator. For example,
forward.__doc__ = monomorphic_operator.__doc__
def reverse(b, a):
if isinstance(a, RationalAbc):
if isinstance(a, Rational):
# Includes ints.
return monomorphic_operator(a, b)
elif isinstance(a, numbers.Real):
......@@ -233,7 +233,7 @@ forward and reverse instances of any given operator. For example,
def _add(a, b):
"""a + b"""
return Rational(a.numerator * b.denominator +
return Fraction(a.numerator * b.denominator +
b.numerator * a.denominator,
a.denominator * b.denominator)
......
......@@ -578,8 +578,8 @@ and comparisons.
:class:`Rational` numbers derive from :class:`Real`, have
:attr:`numerator` and :attr:`denominator` properties, and can be
converted to floats. Python 2.6 adds a simple rational-number class
in the :mod:`rational` module.
converted to floats. Python 2.6 adds a simple rational-number class,
:class:`Fraction`, in the :mod:`fractions` module.
:class:`Integral` numbers derive from :class:`Rational`, and
can be shifted left and right with ``<<`` and ``>>``,
......@@ -598,29 +598,29 @@ one, :func:`trunc`, that's been backported to Python 2.6.
The Rational Module
The Fraction Module
--------------------------------------------------
To fill out the hierarchy of numeric types, a rational-number class
has been added as the :mod:`rational` module. Rational numbers are
has been added as the :mod:`fractions` module. Rational numbers are
represented as a fraction; rational numbers can exactly represent
numbers such as two-thirds that floating-point numbers can only
approximate.
The :class:`Rational` constructor takes two :class:`Integral` values
The :class:`Fraction` constructor takes two :class:`Integral` values
that will be the numerator and denominator of the resulting fraction. ::
>>> from rational import Rational
>>> a = Rational(2, 3)
>>> b = Rational(2, 5)
>>> from fractions import Fraction
>>> a = Fraction(2, 3)
>>> b = Fraction(2, 5)
>>> float(a), float(b)
(0.66666666666666663, 0.40000000000000002)
>>> a+b
rational.Rational(16,15)
Fraction(16,15)
>>> a/b
rational.Rational(5,3)
Fraction(5,3)
The :mod:`rational` module is based upon an implementation by Sjoerd
The :mod:`fractions` module is based upon an implementation by Sjoerd
Mullender that was in Python's :file:`Demo/classes/` directory for a
long time. This implementation was significantly updated by Jeffrey
Yaskin.
......
......@@ -5,7 +5,7 @@ from test.test_support import fcmp, have_unicode, TESTFN, unlink, \
run_unittest, run_with_locale
from operator import neg
import sys, warnings, cStringIO, random, rational, UserDict
import sys, warnings, cStringIO, random, fractions, UserDict
warnings.filterwarnings("ignore", "hex../oct.. of negative int",
FutureWarning, __name__)
warnings.filterwarnings("ignore", "integer argument expected",
......@@ -703,7 +703,7 @@ class BuiltinTest(unittest.TestCase):
n, d = f.as_integer_ratio()
self.assertEqual(float(n).__truediv__(d), f)
R = rational.Rational
R = fractions.Fraction
self.assertEqual(R(0, 1),
R(*float(0.0).as_integer_ratio()))
self.assertEqual(R(5, 2),
......
"""Tests for Lib/rational.py."""
"""Tests for Lib/fractions.py."""
from decimal import Decimal
from test.test_support import run_unittest, verbose
import math
import operator
import rational
import fractions
import unittest
from copy import copy, deepcopy
from cPickle import dumps, loads
R = rational.Rational
gcd = rational.gcd
R = fractions.Fraction
gcd = fractions.gcd
class GcdTest(unittest.TestCase):
......@@ -31,7 +31,7 @@ def _components(r):
return (r.numerator, r.denominator)
class RationalTest(unittest.TestCase):
class FractionTest(unittest.TestCase):
def assertTypedEquals(self, expected, actual):
"""Asserts that both the types and values are the same."""
......@@ -60,7 +60,7 @@ class RationalTest(unittest.TestCase):
self.assertEquals((7, 15), _components(R(7, 15)))
self.assertEquals((10**23, 1), _components(R(10**23)))
self.assertRaisesMessage(ZeroDivisionError, "Rational(12, 0)",
self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)",
R, 12, 0)
self.assertRaises(TypeError, R, 1.5)
self.assertRaises(TypeError, R, 1.5 + 3j)
......@@ -83,41 +83,41 @@ class RationalTest(unittest.TestCase):
self.assertRaisesMessage(
ZeroDivisionError, "Rational(3, 0)",
ZeroDivisionError, "Fraction(3, 0)",
R, "3/0")
self.assertRaisesMessage(
ValueError, "Invalid literal for Rational: 3/",
ValueError, "Invalid literal for Fraction: 3/",
R, "3/")
self.assertRaisesMessage(
ValueError, "Invalid literal for Rational: 3 /2",
ValueError, "Invalid literal for Fraction: 3 /2",
R, "3 /2")
self.assertRaisesMessage(
# Denominators don't need a sign.
ValueError, "Invalid literal for Rational: 3/+2",
ValueError, "Invalid literal for Fraction: 3/+2",
R, "3/+2")
self.assertRaisesMessage(
# Imitate float's parsing.
ValueError, "Invalid literal for Rational: + 3/2",
ValueError, "Invalid literal for Fraction: + 3/2",
R, "+ 3/2")
self.assertRaisesMessage(
# Avoid treating '.' as a regex special character.
ValueError, "Invalid literal for Rational: 3a2",
ValueError, "Invalid literal for Fraction: 3a2",
R, "3a2")
self.assertRaisesMessage(
# Only parse ordinary decimals, not scientific form.
ValueError, "Invalid literal for Rational: 3.2e4",
ValueError, "Invalid literal for Fraction: 3.2e4",
R, "3.2e4")
self.assertRaisesMessage(
# Don't accept combinations of decimals and rationals.
ValueError, "Invalid literal for Rational: 3/7.2",
# Don't accept combinations of decimals and fractions.
ValueError, "Invalid literal for Fraction: 3/7.2",
R, "3/7.2")
self.assertRaisesMessage(
# Don't accept combinations of decimals and rationals.
ValueError, "Invalid literal for Rational: 3.2/7",
# Don't accept combinations of decimals and fractions.
ValueError, "Invalid literal for Fraction: 3.2/7",
R, "3.2/7")
self.assertRaisesMessage(
# Allow 3. and .3, but not .
ValueError, "Invalid literal for Rational: .",
ValueError, "Invalid literal for Fraction: .",
R, ".")
def testImmutable(self):
......@@ -138,7 +138,7 @@ class RationalTest(unittest.TestCase):
def testFromFloat(self):
self.assertRaisesMessage(
TypeError, "Rational.from_float() only takes floats, not 3 (int)",
TypeError, "Fraction.from_float() only takes floats, not 3 (int)",
R.from_float, 3)
self.assertEquals((0, 1), _components(R.from_float(-0.0)))
......@@ -154,19 +154,19 @@ class RationalTest(unittest.TestCase):
inf = 1e1000
nan = inf - inf
self.assertRaisesMessage(
TypeError, "Cannot convert inf to Rational.",
TypeError, "Cannot convert inf to Fraction.",
R.from_float, inf)
self.assertRaisesMessage(
TypeError, "Cannot convert -inf to Rational.",
TypeError, "Cannot convert -inf to Fraction.",
R.from_float, -inf)
self.assertRaisesMessage(
TypeError, "Cannot convert nan to Rational.",
TypeError, "Cannot convert nan to Fraction.",
R.from_float, nan)
def testFromDecimal(self):
self.assertRaisesMessage(
TypeError,
"Rational.from_decimal() only takes Decimals, not 3 (int)",
"Fraction.from_decimal() only takes Decimals, not 3 (int)",
R.from_decimal, 3)
self.assertEquals(R(0), R.from_decimal(Decimal("-0")))
self.assertEquals(R(5, 10), R.from_decimal(Decimal("0.5")))
......@@ -176,16 +176,16 @@ class RationalTest(unittest.TestCase):
R.from_decimal(Decimal("0." + "9" * 30)))
self.assertRaisesMessage(
TypeError, "Cannot convert Infinity to Rational.",
TypeError, "Cannot convert Infinity to Fraction.",
R.from_decimal, Decimal("inf"))
self.assertRaisesMessage(
TypeError, "Cannot convert -Infinity to Rational.",
TypeError, "Cannot convert -Infinity to Fraction.",
R.from_decimal, Decimal("-inf"))
self.assertRaisesMessage(
TypeError, "Cannot convert NaN to Rational.",
TypeError, "Cannot convert NaN to Fraction.",
R.from_decimal, Decimal("nan"))
self.assertRaisesMessage(
TypeError, "Cannot convert sNaN to Rational.",
TypeError, "Cannot convert sNaN to Fraction.",
R.from_decimal, Decimal("snan"))
def testFromContinuedFraction(self):
......@@ -301,7 +301,7 @@ class RationalTest(unittest.TestCase):
# Decimal refuses mixed comparisons.
self.assertRaisesMessage(
TypeError,
"unsupported operand type(s) for +: 'Rational' and 'Decimal'",
"unsupported operand type(s) for +: 'Fraction' and 'Decimal'",
operator.add, R(3,11), Decimal('3.1415926'))
self.assertNotEquals(R(5, 2), Decimal('2.5'))
......@@ -363,7 +363,7 @@ class RationalTest(unittest.TestCase):
self.assertFalse(R(5, 2) == 2)
def testStringification(self):
self.assertEquals("Rational(7,3)", repr(R(7, 3)))
self.assertEquals("Fraction(7,3)", repr(R(7, 3)))
self.assertEquals("7/3", str(R(7, 3)))
self.assertEquals("7", str(R(7, 1)))
......@@ -406,7 +406,7 @@ class RationalTest(unittest.TestCase):
self.assertEqual(id(r), id(deepcopy(r)))
def test_main():
run_unittest(RationalTest, GcdTest)
run_unittest(FractionTest, GcdTest)
if __name__ == '__main__':
test_main()
......@@ -400,6 +400,10 @@ Core and builtins
Library
-------
- Rename rational.py to fractions.py and the rational.Rational class
to fractions.Fraction, to avoid the name clash with the abstract
base class numbers.Rational. See discussion in issue #1682.
- The pickletools module now provides an optimize() function
that eliminates unused PUT opcodes from a pickle string.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment