0

All,

I have a personal script that I'm trying to write, and I've run into a small problem. The problem is that I want to be able to support a '-s' argument no matter where the argument is. I also want that argument to be allowed more than once. For example:

script.py firstargument secondargument -s thirdargument -s fourth fifth -s sixth

What I've tried isn't working. I've tried the following:

currentArg = 1
foldername = sys.argv[1:]
for folders in foldername:
   if "-s" in folders:
   newArg = currentArg + 1
   setType = str(sys.argv[newArg])
   function(setType)

What it's doing is that it's taking the -s as an argument and still passing that to the function. What I'd like it to above is see that the first '-s' is at the fourth position, add 1 to 4, and then setType is set to sys.argv[5]. I'd also like it to continue to loop through the arguments and find any '-s' and then use the next argument as the value. Any ideas?

The error that I get is:

WindowsError: [Error 3] The system cannot find the path specified: 'c:\\-s/*.*'

Notice that it sees -s as an argument and tries to pass that as a folder, but I want it to pass the NEXT argument as the folder...

Is there a better way of doing this? I'll need to take all "-s" into account...

3
  • 4
    you should take a look at argparse docs.python.org/2/howto/argparse.html Commented Jul 16, 2013 at 10:29
  • 4
    Any reason you are not using the argparse module that comes with Python? Why have a dog, and bark yourself? Commented Jul 16, 2013 at 10:29
  • Argparse doesn't seem to allow me to pass an option without a -- notation. In other words, I get an error when I pass the following command: <script> folderA folderB -s folderC . I want folderA and folderB to go to one function, but I want folderC to go to another. Commented Jul 17, 2013 at 2:28

5 Answers 5

1

argparse is beautiful. Redesign your command line interface for it or write your own CLI-parser. CLI example:

args = ['firstargument', 'secondargument', '-s', 'thirdargument', '-s', 'fourth', 'fifth', '-s', 'sixth']
last_arg = None
container = []
marker = '-s'
for arg in args:
    if (arg != marker): last_arg = arg
    else: container.append(last_arg) 
print container        

Result of execute:

$python test.py
['secondargument', 'thirdargument', 'fifth']
Sign up to request clarification or add additional context in comments.

1 Comment

I've been looking at your code. It doesn't seem like the output that you get is what I'm looking for. Your output is missing firstargument. It should see firstargument since "-s" isn't listed before it, correct? I've also tried to play with argparse today and simply can't get it to work without using a "-s". If I specify the -s, it works, but without it it says that it's an unknown option.
0

See other solution:

args = ['firstargument', 'secondargument', '-s', 'thirdargument', '-s', 'fourth', 'fifth', '-s', 'sixth', 'seventh']
args1 = ['firstargument', 'secondargument', '-s', 'thirdargument', '-s', 'fourth', 'fifth', '-s', 'sixth', 'seventh', '-s']

marker = "-s"
def parser(arglist):
    scraplist, result = [], []
    arglist_range = range(len(arglist))
    #Remember candidates for exclude. It's your marker and previous element.
    for arg in arglist_range:
        if arglist[arg] == marker:
            scraplist.append(arg - 1)
            scraplist.append(arg)
    #Excluding marked elements
    for arg in arglist_range:
        if (not arg in scraplist):
            result.append(arglist[arg])
    return result

print parser(args)
print parser(args1)

Run it:

$ python test.py 
['firstargument', 'fourth', 'sixth', 'seventh']
['firstargument', 'fourth', 'sixth']

Goog practice afford result what you want. For example: input = ['some', 'input', 'data'] output = ['some', 'correct', 'output']

2 Comments

After playing with this a little more, I found a workaround for what I was needing. Using argparse, I can 'stack' options, so I can do a '-s' and all options that need to be behind that, and then for the folders that don't need -s, I decided to go with -g. All options are stacked correctly and sending to the appropriate functions. Thank you!!
Yes, use tools from distributive is right practice and reason to redesign some part of application.
0

Something to start with:

import sys
import getopt

def some_function(*args):
    print "Got", args
    return None

funct_dict = \
{
    "-s" : some_function,
    "--skip" : some_function
}
safety_dance = lambda *x: None

try:
    optlist, args = getopt.getopt(sys.argv[1:], "s:", ["--skip="])
except getopt.GetoptError:
    print "Das ist verboten"
    sys.exit()

for (key, option) in optlist:
    funct_dict.get(key, safety_dance)(option)

Comments

0

I second the advice of using a dedicated library for parsing arguments when they get a bit more complex than, say, nothing more than a list of strings. Docopt is great, or if you don't want to install a third party library, go for argparse.

However, if you want to do it yourself, try something along those lines:

args = sys.argv[1:]
if '-s' in args:
    i = args.index('-s')
    opt_val = args.pop(i+1)
    args.remove('-s')
folders = []
for folder in args:
    folders.append(folder)

Comments

0

I've been using http://docopt.org/ with great satisfaction.

https://github.com/docopt/docopt

It does all the monkey work for you and you get your command line arguments structure just from writing the documentation for it...

Added benefit: your users get help for free :-)

For your specific case it will however (strongly :-)) encourage you to use certain standard conventions that you may or may not like. You for instance have the choice of positional and named parameters and docopt will put them together for you, but the named parameters typically have the following form:

--speed=20
-fmyfile.txt

1 Comment

I tried docopt a few days ago. It is indeed a great library ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.