How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?
Mark Bourne
nntp.mbourne at spamgourmet.com
Sat Jan 28 08:59:41 EST 2023
Jach Feng wrote:
> Jach Feng 在 2023年1月22日 星期日上午11:11:22 [UTC+8] 的信中寫道:
>> 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!?
>>
>> --Jach
> I have to admit that I don't know the background upon which the argparse was built. The good side is that I don't carry its historical knowledge ( or burden?), that's why I can use it in a new way which may make someone feel uneasy.
If you can use it in the way you want, that's great. I thought you were
asking here because you *couldn't* use it the way you want.
You're writing a command-line application. Your users are either
already familiar with the conventions of command-line applications, or
they'll soon need to be.
If your application supports options beginning with a "-" (which is what
argparse gives you, even if only the default "-h" and "--help" options
are actually valid), and you also need to be able to pass positional
arguments which begin with a "-", you need some way for the user to
indicate whether any particular argument is an option or positional.
Using "--" to indicate that all subsequent arguments are positional, not
options, is a common convention.
Some of your users might already be familiar with that convention from
other command-line tools. By using the same convention, you'd be making
it easier for them to use yours. Others might not already be familiar
with the convention, but by being consistent with other tools you'd
still be helping them when they eventually do come across it elsewhere.
You can always include an explanation of using "--" in your usage output
or other documentation.
Apart from dealing with how to pass an argument beginning with "-", your
users will also likely have to deal with the features of whichever shell
they're using, which you have no control over. For example, it's quite
common to need to enclose an argument in quotes if it contains spaces.
It may also be necessary to use quotes if certain special characters are
used, such as "*", "?" or "$" (perhaps "%" on Windows).
> The reason I am still keep on using argparse on this "one positional argument only" CLI app is that I can't see what advantage I can get when writing code to handling sys.argv directly for the following two situations,
> -----
> e:\Works\Python>py infix2postfix.py
> usage: infix2postfix.py [-h] infix
> infix2postfix.py: error: the following arguments are required: infix
>
> e:\Works\Python>py infix2postfix.py -h
> usage: infix2postfix.py [-h] infix
>
> Convert infix notation to postfix
>
> positional arguments:
> infix Put equations in quote if there is space in it and separate each one with a comma, ie.
> "-4^2+5.3*abs(-2-1)/2, abs(Abc)*(B+C)/D, (-3) * sqrt(1-(x1/7)*(y1/7)) * sqrt(abs((x0-4.5)/(y0-4)))"
>
> optional arguments:
> -h, --help show this help message and exit
> -----
>
> comparing with code using the argparse below,
>
> import argparse
> sample = "-4^2+5.3*abs(-2-1)/2, abs(Abc)*(B+C)/D, (-3) * sqrt(1-(x1/7)*(y1/7)) * sqrt(abs((x0-4.5)/(y0-4)))"
> parser = argparse.ArgumentParser(description='Convert infix notation to postfix')
> parser.add_argument('infix',
> help='Put equations in quote if there is space in it and separate each one with a comma, ie. "{}"'.format(sample))
>
> import sys
> if len(sys.argv) > 1 and not '-h' in sys.argv:
> ....sys.argv.insert(1, '--')
> args = parser.parse_args()
Personally, I do quite often use argparse even for simple cases, partly
because it produces nice usage details, and deals with wrapping the
output to whatever width the console is. But I work with it rather than
against it, and accept that a "--" is needed if a positional argument
starts with a "-".
I notice you explain the need to enclose the equation in quotes if it
contains spaces. That's not even a feature of your application, but of
the shell used to call it. So why so much objection to explaining the
need for "--"?
Depending on the shell, there are other cases where quoting might be
needed, e.g. if the equation includes a "*" or "?" and happens to look
like a pattern matching files in the current directory (most shells I've
used pass the pattern unchanged if it doesn't match any files). In
bash, if a "$" is used I'd need to enclose that in 'single quotes'
(can't even use "double quotes" for that one). You can't really expect
to document all that sort of thing, because it depends on which shell
the user happens to run your application from - you just have to trust
the user to know or learn how to use their shell.
--
Mark.
More information about the Python-list
mailing list