Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 334
Ger Avatar asked Jan 26 '12 20:01

Ger


People also ask

How do you make an argument optional in Argparse?

To add an optional argument, simply omit the required parameter in add_argument() . args = parser. parse_args()if args.

What does Nargs do in Argparse?

Number of Arguments If you want your parameters to accept a list of items you can specify nargs=n for how many arguments to accept. Note, if you set nargs=1 , it will return as a list not a single value.

What is Metavar in Argparse Python?

Metavar: It provides a different name for optional argument in help messages.


2 Answers

One workaround I've found is to quote the value, but adding a space. That is,

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

This way argparse won't think -2.e-3 is an option name because the first character is not a hyphen-dash, but it will still be converted properly to a float because float(string) ignores spaces on the left.

like image 181
itub Avatar answered Sep 20 '22 12:09

itub


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]) 
like image 34
jcollado Avatar answered Sep 22 '22 12:09

jcollado