2
\$\begingroup\$

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 .

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
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() 
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.