Reputation: 107
I've this issue with this condition using sys.argv inside a script.
The script includes several functions to classify, build and transform a dataset, no big deal.
In the beginning of the script I assign external arguments to 2 or 3 variables depending on the arguments.
if len(sys.argv) > 2:
nfcv=sys.argv[1]
pgrid = [int(x) for x in sys.argv[2].split(",")]
refit = sys.argv[3]
else:
nfcv=sys.argv[1]
pgrid = [int(x) for x in sys.argv[2].split(",")]
refit = ""
Below the command line to run the script with all 3 arg's.
OC_run_eval_ML.py 5 "2,4,6,8,10,12,14" y
During script execution I want to fit my classifier below only if the 3 argument = "y", if empty then pass
Below what I did
def fit(X,y):
clf.fit(X, y)
if refit == "y" :
fit(X_train_std,y_train)
else: pass
Without the 3rd argument (which mean I don't want to "fit" my model)
OC_run_eval_ML.py 5 "2,4,6,8,10,12,14"
I get the following error message :
Traceback (most recent call last):
File "OC_run_eval_ML.py", line 25, in <module>
refit = sys.argv[3]
IndexError: list index out of range
It seems is not accepting the condition : "len(sys.argv) > 2:"
Help is welcome.
Thank you in advance.
Rgds
Upvotes: 1
Views: 2796
Reputation: 1121484
The sys.argv
list always contains the script name as the first argument, so when you have 3 command-line arguments, the length of sys.argv
will be 4 elements. len(sys.argv) > 2
is true if there are only 3 elements too.
Test for 3 or more:
if len(sys.argv) > 3:
nfcv=sys.argv[1]
pgrid = [int(x) for x in sys.argv[2].split(",")]
refit = sys.argv[3]
else:
nfcv=sys.argv[1]
pgrid = [int(x) for x in sys.argv[2].split(",")]
refit = ""
You can simplify this to:
nfcv = sys.argv[1]
pgrid = [int(x) for x in sys.argv[2].split(",")]
if len(sys.argv) > 3:
refit = sys.argv[3]
else:
refit = ""
Personally, I'd use the argparse
library to do this work for you, or (for more complex projects) with click
.
Argparse example:
import argparse
parser = argparse.ArgumentParser(description='Classify, build and transform a dataset')
parser.add_argument("nfcv", help="The NFCV argument...")
parser.add_argument("pgrid",
help="Comma-separated pgrid values",
type=lambda v: [int(x) for x in v.split(",")]
)
parser.add_argument("refit", nargs="?", default="", help="The refit argument...")
args = parser.parse_args()
then use args.nfcv
, args.pgrid
and args.refit
in your code.
Demo:
$ cat demo.py
import argparse
parser = argparse.ArgumentParser(description='Classify, build and transform a dataset')
parser.add_argument("nfcv", help="The NFCV argument...")
parser.add_argument("pgrid",
help="Comma-separated pgrid values",
type=lambda v: [int(x) for x in v.split(",")]
)
parser.add_argument("refit", nargs="?", default="", help="The refit argument...")
args = parser.parse_args()
print(f"NFCV: {args.nfcv!r}")
print(f"prid: {args.pgrid!r}")
print(f"refit: {args.refit!r}")
$ python3 demo.py --help
usage: demo.py [-h] nfcv pgrid [refit]
Classify, build and transform a dataset
positional arguments:
nfcv The NFCV argument...
pgrid Comma-separated pgrid values
refit The refit argument...
optional arguments:
-h, --help show this help message and exit
$ python3 demo.py foo 42,81,117
NFCV: 'foo'
prid: [42, 81, 117]
refit: ''
$ python3 demo.py foo 42,81,117 y
NFCV: 'foo'
prid: [42, 81, 117]
refit: 'y'
Note that if refit
is meant to be a switch, then just use a store_true
action and make it a -r/--refit
command line argument:
parser.add_argument(
'-r', '--refit', action='store_true', default=False,
help="Enable refit"
)
instead of the parser.add_argument('refit', ...)
line. In that case args.refit
is a boolean that defaults to False
and is -r
or --refit
is used on the command line is set to True
. Then just use if args.refit:
to test for it.
The demo with that change then looks like this:
$ python3 demo.py --help
usage: demo.py [-h] [-r] nfcv pgrid
Classify, build and transform a dataset
positional arguments:
nfcv The NFCV argument...
pgrid Comma-separated pgrid values
optional arguments:
-h, --help show this help message and exit
-r, --refit Enable refit
$ python3 demo.py foo 42,81,117
NFCV: 'foo'
prid: [42, 81, 117]
refit: False
$ python3 demo.py foo 42,81,117 --refit
NFCV: 'foo'
prid: [42, 81, 117]
refit: True
Upvotes: 0
Reputation: 3672
argv[0]
is always the name of the program;argv[1]
is the first argument;argv[2]
is the second argument;
etc.So if you want to confirm how many arguments there are, you need to remember that the "first" argument is actually the name of the program!
You want len(sys.argv)>3
, not 2
Upvotes: 1