Run a script that requires multiple arguments and uses ExitStack - python

I have a python3 script that requires three arguments: -orig, -corr, -out, where "orig" and "corr" are used to generate "out". "-orig" allows for only one file as argument, while "-corr" allows for multiple files as input. The script uses ExitStack for handling multiple files at the same time.
When I run the script in command line specifying the files for each argument:
python3 myscript.py -orig <orig_file> -cor <cor_file1> [<cor_file2> ...] -out <outputfile>
it works without problem, but I would like to run the script over several "orig" files and the corresponding "corr" files. Any ideas?
This is the start of the script:
with ExitStack() as stack:
in_files = [stack.enter_context(open(i)) for i in [args.orig]+args.cor]
# Process each line of all input files.
for line_id, line in enumerate(zip(*in_files)):
orig_sent = line[0].strip()
cor_sents = line[1:]
And the section corresponding to the arguments:
if __name__ == "__main__":
# Define and parse program input
parser = argparse.ArgumentParser(description="blabla",formatter_class=argparse.RawTextHelpFormatter, usage="%(prog)s [-h] [options] -orig ORIG -cor COR [COR ...] -out OUT")
parser.add_argument("-orig", help="The path to the original text file.", required=True)
parser.add_argument("-cor", help="The paths to >= 1 corrected text files.", nargs="+", default=[], required=True)
parser.add_argument("-out", help="The output filepath.", required=True)
args = parser.parse_args()
# Run the program.
main(args)

Related

argparse: Why do I get "the following arguments are required"?

I am a beginner in programming, I am using the example
import argparse
import pandas as pd
def read_data(fname):
return pd.read_csv(fname)
if __name__ == "__main__":
options = argparse.ArgumentParser()
options.add_argument("-f", "--file", type=str, required=True)
args = options.parse_args()
data = read_data(args.file)
print(data)
I got this error:
error: the following arguments are required: -f/--file
Would you please help me how can define my file name, where to write it?
Thank you
With required=True, the command-line must include the -f or --file arguments:
# python myprog.py --file=somefile.txt
Make required=False
options.add_argument("-f", "--file", type=str, required=False)
Your original code would require yourprogram -f filename.csv where yourprogram is the name of your script file, and filename.csv is the name of a CSV file with input data. The -f option can also be spelled out in longhand as --file.
But options should typically be optional. Make this a regular required argument if it is mandatory.
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("file", type=str)
args = parser.parse_args()
data = read_data(args.file)
print(data)
Usage: yourprogram filename.csv
Perhaps you are using python yourprogram.py to run this script; then the usage would be python yourprogram.py filename.csv

Python error: the following arguments are required

I have the Python script that works well when executing it via command line.
What I'm trying to do is to import this script to another python file and run it from there.
The problem is that the initial script requires arguments. They are defined as follows:
#file one.py
def main(*args):
import argparse
parser = argparse.ArgumentParser(description='MyApp')
parser.add_argument('-o','--output',dest='output', help='Output file image', default='output.png')
parser.add_argument('files', metavar='IMAGE', nargs='+', help='Input image file(s)')
a = parser.parse_args()
I imported this script to another file and passed arguments:
#file two.py
import one
one.main('-o file.png', 'image1.png', 'image2.png')
But although I defined input images as arguments, I still got the following error:
usage: two.py [-h] [-o OUTPUT]
IMAGE [IMAGE ...]
two.py: error: the following arguments are required: IMAGE
When calling argparse with arguments not from sys.argv you've got to call it with
parser.parse_args(args)
instead of just
parser.parse_args()
If your MAIN isn't a def / function you can simulate the args being passed in:
if __name__=='__main__':
# Set up command-line arguments
parser = ArgumentParser(description="Simple employee shift roster generator.")
parser.add_argument("constraints_file", type=FileType('r'),
help="Configuration file containing staff constraints.")
parser.add_argument("first_day", type=str,
help="Date of first day of roster (dd/mm/yy)")
parser.add_argument("last_day", type=str,
help="Date of last day of roster (dd/mm/yy)")
#Simulate the args to be expected... <--- SEE HERE!!!
argv = ["",".\constraints.txt", "1/5/13", "1/6/13"]
# Parse arguments
args = parser.parse_args(argv[1:])

How to use python argparse with conditionally optional arguments?

Here is the current code.
import time
import collections
from modules import outputs
from modules import scrub
from modules import lookups
parser = argparse.ArgumentParser(description='AppMap Converter to Generate Asset Files from AppMapp Data')
parser.add_argument("operation", nargs='?', default="empty", help='The operation to perform')
parser.add_argument("input", nargs='?', default="empty", help='The input AppMapp File Path')
parser.add_argument("output", nargs='?', default="empty", help='The output Asset File Path')
args = parser.parse_args()
start = time.time()
if(args.operation == "Convert"):
input_file_path = args.input
output_file_path = args.output
#DO LOTS OF STUFF
else:
exit()
The script is called sacsproc, so I run it from the command line as follows:
./sacsproc Convert input.csv output.csv
This all works nicely, the problem is that I need more sacsproc commands which may have a totally different set of secondary parameters. i.e. one command might be:
./sacsproc Clean -rts input.csv output.csv err.csv
Thus, I am trying to determine how one defines arguments that are conditional on the first argument? In my mind, I'm thinking about the zfs command line utilities that do what I am trying to do (e.g. zpool create mirror sdb sdc vs. zpool remove sda).
use subparsers
subparsers = parser.add_subparsers(help="sub-command help")
group1 = subparsers.add_parser("something",help="do something")
group1.set_defaults(which="g1") # some default value (so you know which group was activated)
group1.add_argument("ARG",help='do something on ARG')
group2 = subparsers.add_parser("other",help="do something else")
group2.set_defaults(which="g2") # give some default value
group2.add_argument("ARG",help='do something else on ARG')
ok ...
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help="sub-command help")
g1 = subparsers.add_parser("thing1",help="bind to a port and just echo back anything it gets ... with a prompt")
g1.set_defaults(which="g1")
g1.add_argument("input",help='the input file')
g1.add_argument("output",help='the output file')
g2 = subparsers.add_parser("thing2",help="create a bridge between two ports, this is useful for generating a logfile")
g2.set_defaults(which="g2")
g2.add_argument("input",help='thie input file')
g2.add_argument("output",help='the output file')
g2.add_argument("error",help="the err file")
def print_help(args):
print "ARGS:",args
try:
parser.parse_args(args)
except:
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
print_help(["-h"])
print_help(["thing1","-h"])
print_help(["thing2","-h"])

python - is it possible to enter user-chosen input and output files

I'm a newbie in python, so please bear with me.
I don't know how to describe,so I'll just show an example.
python CODE.py -i1 input1.txt -i2 input2.txt -o output.txt
Is such thing possible with python? I've looked up for a while but haven't find an answer.
Thank you!
Instead of just linking to the argparse module or the argparse tutorial,
the other respondents probably should have just shown you how to do it:
import argparse
# Build the parser
p = argparse.ArgumentParser(prog='CODE.PY')
p.add_argument('-i1', type=argparse.FileType('r'),
metavar='sourcefile1', help='First input file')
p.add_argument('-i2', type=argparse.FileType('r'),
metavar='sourcefile2', help='Second input file')
p.add_argument('-o', type=argparse.FileType('w'),
metavar='destfile', help='Destination filename')
# Parse sys.argv
ns = p.parse_args()
# Use the files
data1 = ns.i1.read()
data2 = ns.i2.read()
result = data1[:10] + data2[:10]
ns.o.write(result)
A nice feature of argparse is that not only does it build parsers, it creates a nice option for command-line help:
$ python CODE.PY -h
usage: CODE.PY [-h] [-i1 sourcefile1] [-i2 sourcefile2] [-o destfile]
optional arguments:
-h, --help show this help message and exit
-i1 sourcefile1 First input file
-i2 sourcefile2 Second input file
-o destfile Destination filename
Yes, you can use system argument with your code.
Following snippet of code might help you to resolve your problem
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('inFile', nargs=2, help="Choose in file to use")
parser.add_argument('outFile', nargs=1, help="Choose out file to use")
args=parser.parse_args()
your_fun_call( args.inFile , args.outFile[0] )
Might look wierd at first look but you can refer this document
argparse
Note: infile argument has nargs as 2 because you want two input
files ( nargs stands for number of argument)
As thefourtheye said you can used argparse module. But if you want simple solution, just pass 2 inputs and output file paths as arguments to your executable and use sys.argv to get them in your program in order. The sys.argv[0] is your application name, sys.argv[1] is first input file path, sys.argv[2] is second input file path and sys.argv[3] is output file path.
import sys
input1 = sys.argv[1]
input2 = sys.argv[2]
output = sys.argv[3]
now you can call like below:
python my_app.py /path/to/input1.txt /path/to/input2.txt /path/to/output.txt

Pass a directory with argparse (no type checking needed)

I've written a file crawler and I'm trying to expand it. I want to use argparse to handle settings for the script including passing the starting directory in at the command line.
Example: /var/some/directory/
I have gotten several other arguments to work but I'm unable to pass this directory in correctly. I don't care if it's preceded by a flag or not, (e.g -d /path/to/start/) but I need to make sure that at the very least, this is argument is used as it will be the only mandatory option for the script to run.
Code Sample:
parser = argparse.ArgumentParser(description='py pub crawler...')
parser.add_argument('-v', '--verbose', help='verbose output from crawler', action="store_true")
parser.add_argument('-d', '--dump', help='dumps and replaces existing dictionaries', action="store_true")
parser.add_argument('-f', '--fake', help='crawl only, nothing stored to DB', action="store_true")
args = parser.parse_args()
if args.verbose:
verbose = True
if args.dump:
dump = True
if args.fake:
fake = True
Simply add:
parser.add_argument('directory',help='directory to use',action='store')
before your args = parser.parse_args() line. A simple test from the commandline shows that it does the right thing (printing args at the end of the script):
$ python test.py /foo/bar/baz
Namespace(directory='/foo/bar/baz', dump=False, fake=False, verbose=False)
$ python test.py
usage: test.py [-h] [-v] [-d] [-f] directory
test.py: error: too few arguments

Categories

Resources