0

How should I structure the argparse to form this? You should be able to call -l,-m,-s,-h,home or work but not both. You should have to call -l or -m before you can use any -i.

usage: prog 
           (-l | -m ) [-i1][-i2][-i3][-i4]
           -s
           -h
           home
           work

can be called using:

prog home 
prog work 
prog -l -i1 
prog -m -i1 -i2 
prog -s

The code that I wrote to make something like it.

    def get_args():
        parser = argparse.ArgumentParser(prog="prog")
        group = parser.add_mutually_exclusive_group(required=True)
        group.add_argument('-l', action='store_true', help='List Mode. List available options', default=False, dest='list')
        group.add_argument('-m', action='store_true', help='Departure Mode. Return a departure time from stopcode or agency and stopname', default=False, dest='mode')
        group.add_argument('-s', action='store_true', help='Setup Mode. Enter setup mode to make a home and a work list of station codes.', default=False, dest='setup')
        group.add_argument('home', help='Display HOME_LIST') # this causes it to break because positional arguments cant be required for some reason
        group.add_argument('work', help='Display WORK_LIST')
        parser.add_argument('-i1', nargs='?', dest='i1')
        parser.add_argument('-i2', nargs='?', dest='i1')
        parser.add_argument('-i3', nargs='?', dest='i1')
        return parser.parse_args()
hpaulj
  • 221,503
  • 14
  • 230
  • 353
polka
  • 1,383
  • 2
  • 25
  • 40
  • 2
    Unfortunately, Stack Overflow is not a code-writing service. If you come up with a solution that doesn't seem to work, we would be happy to help you find out what's wrong with it, but asking for the code without showing us what you have tried doesn't fit Stack Overflow's rules. – zondo Apr 28 '16 at 02:37
  • Okay, I can add my terrible code attempt – polka Apr 28 '16 at 02:38
  • i have to go, I can answer questions in an hour. – polka Apr 28 '16 at 02:59

1 Answers1

1

I'll clean this up a bit:

parser = argparse.ArgumentParser(prog="prog")

group = parser.add_mutually_exclusive_group(required=True)

one, and only one, of the following is allowed and required

group.add_argument('-l', '--list', action='store_true', 
    help='List Mode. List available options')

for 'store_true' default is False; no need to define it. Give the 'dest' in the long name

group.add_argument('-m', '--mode', action='store_true',
   help='Departure Mode. Return a departure time from stopcode or agency and stopname')

group.add_argument('-s', '--setup', action='store_true', 
   help='Setup Mode. Enter setup mode to make a home and a work list of station codes.')

group.add_argument('home',nargs='?', default='unknown',  help='Display HOME_LIST') 

Positional arguments are required by nature (unless nargs='?'). So they don't fit in a mutually_required_group. How can you supply one of the other arguments and still supply this required positional?

Only one optional positional is allowed in a m_ex_group.

parser.add_argument('work', help='Display WORK_LIST')

Why the nargs='?'? By nature they are optional. So they'll get the default value if not given. '?' is useful if you also define a const.

parser.add_argument('--i1')
parser.add_argument('--i2')
parser.add_argument('--i3')

return parser.parse_args()

You can specify the relative order of positionals. In this case work will come after home. But optionals can occur in any order. So these --i* arguments can occur anywhere. But that shouldn't matter.

To require -l or -m along with --i1 (etc), will require subparsers. That is, you'll define something like

sp = parser.add_subparsers(dest='mode')
p0 = sp.add_parser('list')
p1 = sp.add_parser('mode')
p2 = sp.add_parser('setup')

p0.add_argument('--i1')
p0.add_argument('--i2')
...
p1.add_argument('--i1')
...

But subparsers don't play nicely with other positionals, especially '?' ones.

e.g. argparse optional positional argument and subparsers arguments

Community
  • 1
  • 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • What do you mean by "play nicely"? – polka Apr 28 '16 at 16:05
  • 1
    Strings are allocated to `positionals` purely on the basis of order, not 'meaning'. `home work cmd` is clear, `[home][work] cmd` is ambiguous. `home cmd work` could also be problematic. – hpaulj Apr 28 '16 at 16:35