How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

Mark Bourne nntp.mbourne at spamgourmet.com
Sun Jan 22 09:01:37 EST 2023


Jach Feng wrote:
> Fail on command line,
> 
> e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2"
> usage: infix2postfix.py [-h] [infix]
> infix2postfix.py: error: unrecognized arguments: -4^2+5.3*abs(-2-1)/2
> 
> Also fail in REPL,
> 
> e:\Works\Python>py
> Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:08:11) [MSC v.1928 32 bit (Intel)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import argparse
>>>> parser = argparse.ArgumentParser(description='Convert infix notation to postfix')
>>>> parser.parse_args("-4^2+5.3*abs(-2-1)/2")
> usage: [-h]
> : error: unrecognized arguments: - 4 ^ 2 + 5 . 3 * a b s ( - 2 - 1 ) / 2
> 
> Just can't figure out where is wrong!?

First, you need to add an argument to the parser, so that it expects an 
argument:
 >>> parser.add_argument("expression")

Secondly, `parse_args` expects a list of arguments.  By passing a 
string, it interprets each character as a separate argument (since 
iterating over a string yields each character in turn).  Here, I 
intentionally leave off the initial hyphen because that's the next problem:
 >>> parser.parse_args(["4^2+5.3*abs(-2-1)/2"])
Namespace(expression='4^2+5.3*abs(-2-1)/2')

Thirdly, an initial hyphen indicates an optional argument so, for 
example if you pass "-l" it will expect a "-l" argument to be defined as 
one of the valid options, and also complain that you haven't specified 
the required expression:
 >>> parser.parse_args(["-4^2+5.3*abs(-2-1)/2"])
usage: [-h] expression
: error: the following arguments are required: expression

If you need to pass a value starting with a "-" there are a couple of 
options...

Perhaps it would be acceptable to represent it as "0-...":
 >>> parser.parse_args(["0-4^2+5.3*abs(-2-1)/2"])
Namespace(expression='0-4^2+5.3*abs(-2-1)/2')

While mathematically equivalent, that might have different meaning for 
whatever you're trying to do.  Alternatively, a double hyphen indicates 
that there are no more options and that anything else is positional 
arguments even if they begin with a hyphen:
 >>> parser.parse_args(["--", "-4^2+5.3*abs(-2-1)/2"])
Namespace(expression='-4^2+5.3*abs(-2-1)/2')

You wouldn't usually explicitly pass a list of arguments to `parse_args` 
like that, but it can be useful for testing and experimentation. 
Usually, you'd call `parse_args()` without any arguments, and it would 
parse the arguments passed on the command-line when calling your script. 
  e.g. you'd call (from a Windows command prompt / Linux shell / etc.):
 > ./convert_infix.py -- '-4^2+5.3*abs(-2-1)/2'
(it's probably a good idea to quote the expression, in case it includes 
any characters which would be interpreted specially by the shell - e.g. 
"*" without quotes usually expands to all matching files in the current 
directory)

-- 
Mark.


More information about the Python-list mailing list