Captain-Robot
Captain-Robot

Reputation: 123

How can I use argparse with the existance of sys.args

I want to call the functions using arguments, But I am confused because I am using two arguments by Sys.arg[1] and Sys.arg[2] for file input-output functions.

My script works as a $ python script.py inputfile.txt outputfile.txt

import argparse
import sys

input_file = sys.argv[1]
out_file = sys.argv[2]

def fuction1():
    #Stuff

def fucntion2():
    #Stuff

I am using input_file and out_file in both of these functions for different tasks! Now, I want to call these function from the command line argument for example $ python script.py runfuction1 inputfile.txt outputfile.txt $ python script.py runfuction2 inputfile.txt outputfile.txt

I have tried some solutions from other posts like the question in post number: 27529610 but it's not working, I am confused in using system arguments and argparse together.

Thanks!

Upvotes: 0

Views: 443

Answers (2)

hpaulj
hpaulj

Reputation: 231355

Here's a version using argparse and 3 positional arguments:

import argparse
import sys

def function1(input, output):
    print(f'1: {input} to {output}')

def function2(input, output):
    print(f'2: {input} to {output}')

adict = {'runfunction1': function1, 'runfunction2': function2}

parser = argparse.ArgumentParser()
parser.add_argument('cmd', choices=adict)
parser.add_argument('input')
parser.add_argument('output')

args = parser.parse_args()
print(sys.argv[1:])
print(args)
adict[args.cmd](args.input, args.output)

Some sample runs:

1445:~/mypy$ python3 stack54614049.py -h
usage: stack54614049.py [-h] {runfunction1,runfunction2} input output

positional arguments:
  {runfunction1,runfunction2}
  input
  output

optional arguments:
  -h, --help            show this help message and exit

1445:~/mypy$ python3 stack54614049.py 
usage: stack54614049.py [-h] {runfunction1,runfunction2} input output
stack54614049.py: error: the following arguments are required: cmd, input, output

1446:~/mypy$ python3 stack54614049.py foo
usage: stack54614049.py [-h] {runfunction1,runfunction2} input output
stack54614049.py: error: argument cmd: invalid choice: 'foo' (choose from 'runfunction1', 'runfunction2')

1446:~/mypy$ python3 stack54614049.py runfunction1 in out
['runfunction1', 'in', 'out']
Namespace(cmd='runfunction1', input='in', output='out')
1: in to out

1446:~/mypy$ python3 stack54614049.py runfunction2 in out
['runfunction2', 'in', 'out']
Namespace(cmd='runfunction2', input='in', output='out')
2: in to out

With 3 required positional arguments like this argparse doesn't do much fancier parsing than looking at

cmd, input, output = sys.argv[1:]

With choices it objects if the cmd string isn't in the approved list. It adds a help display. Delegation from cmd string to function uses some sort of mapping.

Upvotes: 0

iz_
iz_

Reputation: 16583

You shouldn't need argparse for this. Try:

import sys

to_run = int(sys.argv[1][-1])
input_file = sys.argv[2]
out_file = sys.argv[3]

def function1():
    # Stuff
    pass

def function2():
    # Stuff
    pass

(function1, function2)[to_run - 1]()

Even better, you could just create two separate scripts!

You can also use a dictionary, which is a bit more flexible:

import sys

input_file = sys.argv[2]
out_file = sys.argv[3]

def function1():
    # Stuff
    pass

def function2():
    # Stuff
    pass

funcs = {'runfunction1': function1, 'runfunction2': function2}    
funcs[sys.argv[1]]()

Upvotes: 2

Related Questions