Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I had to replace all instances of scientific notation with fixed point, and wrote a Python script to help out. Here it is:

#!/usr/bin/python2

# Originally written by Anton Golov on 29 Jan 2012.
# Feedback can be sent to <email> .

"""Provide functions for converting scientific notation to fixed point.

When imported, reads lines from stdin and prints them back to stdout with
scientific notation removed.

WARNING:  The resulting fixed point values may be of a different precision
than the original values.  This will usually be higher, but may be lower for
large numbers.  Please don't rely on the precision of the values generated by
this script for error analysis.

"""

from re import compile


exp_regex = compile(r"(\d+(\.\d+)?)[Ee](\+|-)(\d+)")


def to_fixed_point(match):
    """Return the fixed point form of the matched number.

    Parameters:
        match is a MatchObject that matches exp_regex or similar.

    If you wish to make match using your own regex, keep the following in mind:
        group 1 should be the coefficient
        group 3 should be the sign
        group 4 should be the exponent

    """
    sign = -1 if match.group(3) == "-" else 1
    coefficient = float(match.group(1))
    exponent = sign * float(match.group(4))
    return "%.16f" % (coefficient * 10**exponent)


def main():
    """Read lines from stdin and print them with scientific notation removed.

    """
    try:
        while True:
            line = raw_input('')
            print exp_regex.sub(to_fixed_point, line)
    except EOFError:
        pass


if __name__ == "__main__":
    main()

I am primarily interested about the way the regex is used (can it match something it can't replace?), but comments on code clarity and features that may be simple to add are also welcome, as well as any further nitpicking .

share|improve this question

1 Answer 1

up vote 2 down vote accepted
from re import compile


exp_regex = compile(r"(\d+(\.\d+)?)[Ee](\+|-)(\d+)")

Python style guide recommends that global constants be in ALL_CAPS. And what about numbers like "1e99"? They won't match this regex.

def to_fixed_point(match):
    """Return the fixed point form of the matched number.

    Parameters:
        match is a MatchObject that matches exp_regex or similar.

    If you wish to make match using your own regex, keep the following in mind:
        group 1 should be the coefficient
        group 3 should be the sign
        group 4 should be the exponent

    """

I'd suggest breaking the groups out of the match into local variables

coefficient, decimals, sign, exponent = match.groups()

And then use those names instead of match.group(1). That way your code will be easier to follow.

    sign = -1 if match.group(3) == "-" else 1
    coefficient = float(match.group(1))
    exponent = sign * float(match.group(4))
    return "%.16f" % (coefficient * 10**exponent)

Here's the thing. Python already support scientific notation, so you should just ask python to do conversion for you:

 value = float(match.group(0))

Less bugs, more efficient, better all around.

def main():
    """Read lines from stdin and print them with scientific notation removed.

    """
    try:
        while True:
            line = raw_input('')
            print exp_regex.sub(to_fixed_point, line)
    except EOFError:
        pass

I'd suggest using for line in sys.stdin:. It'll automatically get you the lines, stop when the file ends. That'll make this piece of code simpler.

if __name__ == "__main__":
    main()
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.