user1027686 user1027686 - 1 month ago 12
Python Question

Python Argparse: Issue with optional arguments which are negative numbers

I'm having a small issue with argparse. I have an option xlim which is the xrange of a plot. I want to be able to pass numbers like -2e-5. However this does not work - argparse interprets this is a positional argument. If I do -0.00002 it works - argparse reads it as a negative number. Is it possible to have able to read in -2e-3?

The code is below, and an example of how I would run it is:

./blaa.py --xlim -2.e-3 1e4


If I do the following it works:

./blaa.py --xlim -0.002 1e4


The code:

parser.add_argument('--xlim', nargs = 2,
help = 'X axis limits',
action = 'store', type = float,
default = [-1.e-3, 1.e-3])


Whilst I can get it to work this way I would really rather be able to use scientific notation. Anyone have any ideas?

Cheers

Answer

As already pointed out by the comments, the problem is that a - prefix is parsed as an option instead of as an argument. One way to workaround this is change the prefix used for options with prefix_chars argument:

#!/usr/bin/python
import argparse

parser = argparse.ArgumentParser(prefix_chars='@')
parser.add_argument('@@xlim', nargs = 2,
                  help = 'X axis limits',
                  action = 'store', type = float,
                  default = [-1.e-3, 1.e-3])
print parser.parse_args()

Example output:

$ ./blaa.py @@xlim -2.e-3 1e4
Namespace(xlim=[-0.002, 10000.0])

Edit: Alternatively, you can keep using - as separator, pass xlim as a single value and use a function in type to implement your own parsing:

#!/usr/bin/python
import argparse

def two_floats(value):
    values = value.split()
    if len(values) != 2:
        raise argparse.ArgumentError
    values = map(float, values)
    return values

parser = argparse.ArgumentParser()
parser.add_argument('--xlim', 
                  help = 'X axis limits',
                  action = 'store', type=two_floats,
                  default = [-1.e-3, 1.e-3])
print parser.parse_args()

Example output:

$ ./blaa.py --xlim "-2e-3 1e4"
Namespace(xlim=[-0.002, 10000.0])