From b59a2bd9063c0cc5c57f7f50a6efeceaf4040c66 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 10 May 2008 22:03:16 +0000 Subject: Remove the fpformat module. --- Doc/library/fpformat.rst | 56 ------------------ Lib/fpformat.py | 142 ---------------------------------------------- Lib/test/test_fpformat.py | 75 ------------------------ Misc/NEWS | 2 + 4 files changed, 2 insertions(+), 273 deletions(-) delete mode 100644 Doc/library/fpformat.rst delete mode 100644 Lib/fpformat.py delete mode 100644 Lib/test/test_fpformat.py diff --git a/Doc/library/fpformat.rst b/Doc/library/fpformat.rst deleted file mode 100644 index 1a84b72..0000000 --- a/Doc/library/fpformat.rst +++ /dev/null @@ -1,56 +0,0 @@ - -:mod:`fpformat` --- Floating point conversions -============================================== - -.. module:: fpformat - :synopsis: General floating point formatting functions. -.. sectionauthor:: Moshe Zadka - - -The :mod:`fpformat` module defines functions for dealing with floating point -numbers representations in 100% pure Python. - -.. note:: - - This module is unnecessary: everything here can be done using the string - formatting functions described in the :ref:`string-formatting` section. - -The :mod:`fpformat` module defines the following functions and an exception: - - -.. function:: fix(x, digs) - - Format *x* as ``[-]ddd.ddd`` with *digs* digits after the point and at least one - digit before. If ``digs <= 0``, the decimal point is suppressed. - - *x* can be either a number or a string that looks like one. *digs* is an - integer. - - Return value is a string. - - -.. function:: sci(x, digs) - - Format *x* as ``[-]d.dddE[+-]ddd`` with *digs* digits after the point and - exactly one digit before. If ``digs <= 0``, one digit is kept and the point is - suppressed. - - *x* can be either a real number, or a string that looks like one. *digs* is an - integer. - - Return value is a string. - - -.. exception:: NotANumber - - Exception raised when a string passed to :func:`fix` or :func:`sci` as the *x* - parameter does not look like a number. This is a subclass of :exc:`ValueError` - when the standard exceptions are strings. The exception value is the improperly - formatted string that caused the exception to be raised. - -Example:: - - >>> import fpformat - >>> fpformat.fix(1.23, 1) - '1.2' - diff --git a/Lib/fpformat.py b/Lib/fpformat.py deleted file mode 100644 index c196436..0000000 --- a/Lib/fpformat.py +++ /dev/null @@ -1,142 +0,0 @@ -"""General floating point formatting functions. - -Functions: -fix(x, digits_behind) -sci(x, digits_behind) - -Each takes a number or a string and a number of digits as arguments. - -Parameters: -x: number to be formatted; or a string resembling a number -digits_behind: number of digits behind the decimal point -""" - -import re - -__all__ = ["fix","sci","NotANumber"] - -# Compiled regular expression to "decode" a number -decoder = re.compile(r'^([-+]?)0*(\d*)((?:\.\d*)?)(([eE][-+]?\d+)?)$') -# \0 the whole thing -# \1 leading sign or empty -# \2 digits left of decimal point -# \3 fraction (empty or begins with point) -# \4 exponent part (empty or begins with 'e' or 'E') - -try: - class NotANumber(ValueError): - pass -except TypeError: - NotANumber = 'fpformat.NotANumber' - -def extract(s): - """Return (sign, intpart, fraction, expo) or raise an exception: - sign is '+' or '-' - intpart is 0 or more digits beginning with a nonzero - fraction is 0 or more digits - expo is an integer""" - res = decoder.match(s) - if res is None: raise NotANumber(s) - sign, intpart, fraction, exppart = res.group(1,2,3,4) - if sign == '+': sign = '' - if fraction: fraction = fraction[1:] - if exppart: expo = int(exppart[1:]) - else: expo = 0 - return sign, intpart, fraction, expo - -def unexpo(intpart, fraction, expo): - """Remove the exponent by changing intpart and fraction.""" - if expo > 0: # Move the point left - f = len(fraction) - intpart, fraction = intpart + fraction[:expo], fraction[expo:] - if expo > f: - intpart = intpart + '0'*(expo-f) - elif expo < 0: # Move the point right - i = len(intpart) - intpart, fraction = intpart[:expo], intpart[expo:] + fraction - if expo < -i: - fraction = '0'*(-expo-i) + fraction - return intpart, fraction - -def roundfrac(intpart, fraction, digs): - """Round or extend the fraction to size digs.""" - f = len(fraction) - if f <= digs: - return intpart, fraction + '0'*(digs-f) - i = len(intpart) - if i+digs < 0: - return '0'*-digs, '' - total = intpart + fraction - nextdigit = total[i+digs] - if nextdigit >= '5': # Hard case: increment last digit, may have carry! - n = i + digs - 1 - while n >= 0: - if total[n] != '9': break - n = n-1 - else: - total = '0' + total - i = i+1 - n = 0 - total = total[:n] + chr(ord(total[n]) + 1) + '0'*(len(total)-n-1) - intpart, fraction = total[:i], total[i:] - if digs >= 0: - return intpart, fraction[:digs] - else: - return intpart[:digs] + '0'*-digs, '' - -def fix(x, digs): - """Format x as [-]ddd.ddd with 'digs' digits after the point - and at least one digit before. - If digs <= 0, the point is suppressed.""" - if type(x) != type(''): x = repr(x) - try: - sign, intpart, fraction, expo = extract(x) - except NotANumber: - return x - intpart, fraction = unexpo(intpart, fraction, expo) - intpart, fraction = roundfrac(intpart, fraction, digs) - while intpart and intpart[0] == '0': intpart = intpart[1:] - if intpart == '': intpart = '0' - if digs > 0: return sign + intpart + '.' + fraction - else: return sign + intpart - -def sci(x, digs): - """Format x as [-]d.dddE[+-]ddd with 'digs' digits after the point - and exactly one digit before. - If digs is <= 0, one digit is kept and the point is suppressed.""" - if type(x) != type(''): x = repr(x) - sign, intpart, fraction, expo = extract(x) - if not intpart: - while fraction and fraction[0] == '0': - fraction = fraction[1:] - expo = expo - 1 - if fraction: - intpart, fraction = fraction[0], fraction[1:] - expo = expo - 1 - else: - intpart = '0' - else: - expo = expo + len(intpart) - 1 - intpart, fraction = intpart[0], intpart[1:] + fraction - digs = max(0, digs) - intpart, fraction = roundfrac(intpart, fraction, digs) - if len(intpart) > 1: - intpart, fraction, expo = \ - intpart[0], intpart[1:] + fraction[:-1], \ - expo + len(intpart) - 1 - s = sign + intpart - if digs > 0: s = s + '.' + fraction - e = repr(abs(expo)) - e = '0'*(3-len(e)) + e - if expo < 0: e = '-' + e - else: e = '+' + e - return s + 'e' + e - -def test(): - """Interactive test run.""" - try: - while 1: - x, digs = input('Enter (x, digs): ') - print(x, fix(x, digs), sci(x, digs)) - except (EOFError, KeyboardInterrupt): - pass diff --git a/Lib/test/test_fpformat.py b/Lib/test/test_fpformat.py deleted file mode 100644 index a1b8722..0000000 --- a/Lib/test/test_fpformat.py +++ /dev/null @@ -1,75 +0,0 @@ -''' - Tests for fpformat module - Nick Mathewson -''' -from test.test_support import run_unittest -import unittest -from fpformat import fix, sci, NotANumber - -StringType = type('') - -# Test the old and obsolescent fpformat module. -# -# (It's obsolescent because fix(n,d) == "%.*f"%(d,n) and -# sci(n,d) == "%.*e"%(d,n) -# for all reasonable numeric n and d, except that sci gives 3 exponent -# digits instead of 2. -# -# Differences only occur for unreasonable n and d. <.2 wink>) - -class FpformatTest(unittest.TestCase): - - def checkFix(self, n, digits): - result = fix(n, digits) - if isinstance(n, StringType): - n = repr(n) - expected = "%.*f" % (digits, float(n)) - - self.assertEquals(result, expected) - - def checkSci(self, n, digits): - result = sci(n, digits) - if isinstance(n, StringType): - n = repr(n) - expected = "%.*e" % (digits, float(n)) - # add the extra 0 if needed - num, exp = expected.split("e") - if len(exp) < 4: - exp = exp[0] + "0" + exp[1:] - expected = "%se%s" % (num, exp) - - self.assertEquals(result, expected) - - def test_basic_cases(self): - self.assertEquals(fix(100.0/3, 3), '33.333') - self.assertEquals(sci(100.0/3, 3), '3.333e+001') - - def test_reasonable_values(self): - for d in range(7): - for val in (1000.0/3, 1000, 1000.0, .002, 1.0/3, 1e10): - for realVal in (val, 1.0/val, -val, -1.0/val): - self.checkFix(realVal, d) - self.checkSci(realVal, d) - - def test_failing_values(self): - # Now for 'unreasonable n and d' - self.assertEquals(fix(1.0, 1000), '1.'+('0'*1000)) - self.assertEquals(sci("1"+('0'*1000), 0), '1e+1000') - - # This behavior is inconsistent. sci raises an exception; fix doesn't. - yacht = "Throatwobbler Mangrove" - self.assertEquals(fix(yacht, 10), yacht) - try: - sci(yacht, 10) - except NotANumber: - pass - else: - self.fail("No exception on non-numeric sci") - - -def test_main(): - run_unittest(FpformatTest) - - -if __name__ == "__main__": - test_main() diff --git a/Misc/NEWS b/Misc/NEWS index 9c6feeb..e2c165c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -21,6 +21,8 @@ Extension Modules Library ------- +- The fpformat module has been removed. + - The dircache module has been removed. - The Canvas module has been removed. -- cgit v0.12