1


I want to make my python script work like below:

  • example.py -a number
  • example.py -a -f input-file

So the first command should take only one number and do some action.
But the second command should take numbers from the file (.txt) and do the same action

For example:
-a number option reads the number and prints to the screen
-a -f inputfile should also read the numbers and print to the screen, but from the .txt file (which can have multiple numbers)

Is it possible?
If not please suggest a best way. Thanks

John W
  • 45
  • 7

1 Answers1

1

Your idea doesn't make sense from the user side of things.

Meaning: when you say -f the user already has to understand that the tool will open the corresponding file and process it. Therefore you shouldn't ask him to provide -a on top of that.

But of course you can do it. What I would do here: provide a default value for the -a switch, as outlined here for example.

Then your script can check if that default value is used. And then you can make decisions based on that, like in:

  • if -a has its default value and -f is given: read from file and do what -a should do with it
  • if -a has not its default value and -f is given: ??? (you have to think up what that means)
  • ...

Those ... are a symptom of why I consider your approach to not be elegant: it really complicates the whole argument handling massively. I would just go for -a NUMBER or -f file and not allow for those to be mixed. You see, any interface should make it easy to do the right thing, and hard to do the wrong thing. Allowing for combinations of flags/switches simply leads to an explosion of possible paths. And that means that you have to deal with all of them, and the user has to remember those that are actually valid.

And given your comment: of course you could unify this to have -a take either a number or a string denoting a filename.

Then you simply instruct argparse that -a stores string values. Then your script can decide whether that string is a number or a valid filename. To then do what is necessary. Something like this:

from __future__ import print_function
import os.path
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-a", "--add",
                    help="whatever",
                    type=str)
args = parser.parse_args()

if args.add:
    if args.add.isdigit():
        print("input contains only digits: {}".format(args.add))
    else:
        print("input contains other stuff: {}".format(args.add))
        if os.path.isfile(args.add):
            print("input is a valid file name!")
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • oh! Thank you for explaining in detail – John W Sep 06 '17 at 08:12
  • sure! quick question though, Can one single option take value from both command line and a file. I mean, in my case - can I just use -a, and user can either input number from command line or provide the file with all the numbers ? – John W Sep 06 '17 at 08:20
  • If you can give a small example - that'll be really awesome. because I am a little not sure how my function should know if the input is from command line or from the file – John W Sep 06 '17 at 08:46