1

I have a user defined function within a python script I am calling via the command line. In this function, there are 3 required parameters and 3 optional ones.

So the function definition looks like this:

def main(csv, inDir, batchID, mapprj=True, doP2D=True, rp=100):

When I call the function on the CL I may or may not set the latter three input variables. To call this function using these inputs, right now I have:

if __name__ == '__main__':
    import sys
    main(sys.argv[1], sys.argv[2], sys.argv[3])

But say I want to set rp = 50, then this call misses that argument. However if I go up to sys.argv[6], this will fail if I don't specify the other 3 optional arguments.

Is there a better way besides the following block to supply these arguments to the main function?

if __name__ == '__main__':
    import sys

    if len(sys.argv) == 4: # i.e. 3 arguments are supplied
        main(sys.argv[1], sys.argv[2], sys.argv[3])

    if len(sys.argv) == 5: # i.e. 4 arguments are supplied
        main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

    if len(sys.argv) == 6: # i.e. 5 arguments are supplied
        main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])

    if len(sys.argv) == 7: # i.e. 6 arguments are supplied
        main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])

ALSO, if I call the script (with the if statements like above) from the command line like this:

python script.py 'csvFile.csv' 'path/to/directory' 'batchName' False False rp=50

when I "print rp" in the main function, it's returning 'rp=50'. I thought setting rp=100 at the function definition indicated that rp is an optional argument whose default value is 100 and that explicitly calling "rp=50" is supposed to override the default value and set rp to 50, not "rp=50"

Lastly, when I call the script like this:

python script.py 'csvFile.csv' 'path/to/directory' 'batchName' rp=50

The variable mapprj is getting set to 'rp=50', doP2D is True as per the default value, and rp is remaining the default value of 100. I thought that the above call was supposed to keep mapprj and doP2D as their default True values, and set rp to 50 since I explicitly set it to 50.

What am I doing wrong?

Thanks

user20408
  • 679
  • 2
  • 7
  • 23

1 Answers1

1

Parse the arguments from command line via argparse, making all the positional arguments required, and simply unpack a dict of the parsed args and pass it to your function:

import argparse


if __name__ == '__main__': 
    ap = argparse.ArgumentParser()
    ap.add_argument("-c", "--csv", required=True, help = "filename")
    ...
    kwargs = vars(ap.parse_args())
    main(**kwargs)
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • thanks, Moses. I tried doing this (replace -c with -incsv) but keep getting TypeError: main() got an unexpected keyword argument 'incsv' .... What's that all about do you know? – user20408 Feb 13 '17 at 20:22
  • nevermind. I got around that, but now even when I supply one of the optional arguments something other than it's default, it still won't override the default value. So if one of my arguments is added like this: ap.add_argument("-mapprj", default=True, type=bool And if I call the function with the 3 required values plus -mapprj=False or -mapprj False, it's still being passed along as True. Any idea why? – user20408 Feb 13 '17 at 20:42
  • This is only true of mapprj and doP2D, which are booleans. Setting rp actually works. However if I set the default to False and then in the CL set it to True, that does work. Why not the other way around and how can I fix this? Sorry for all the comments – user20408 Feb 13 '17 at 22:02
  • Thanks for the response. I should have mentioned this but I did do type=bool – user20408 Feb 13 '17 at 22:08
  • best way to do this seems to be using action='store_true' which means the bool variable defaults to False unless it is called at the command line i.e. -mapprj. Thx! – user20408 Feb 13 '17 at 22:18
  • You could ask about this problem in a new question. I can't think of why the first approach did not work. – Moses Koledoye Feb 13 '17 at 22:21