Running python 2.7.5 in Spyder, trying to set up an argument parser to import input from a file called data.csv in the same folder as my script. Currently, this part of my function looks like so:
from sys import argv
from argparse import ArgumentParser
def ParseArguments():
parser = ArgumentParser(description='Description of program')
parser.add_argument("-f", type=str, dest="data",
default="", help="Input file", required=True)
parser.add_argument("-o", type=str, dest="output_file",
default="", help="Output file")
parser.add_argument("-p", type=float, dest="first_parameter",
default=0.5, help="First Parameter (decimal)")
parser.add_argument("-n", type=int, dest="second_parameter",
default=0, help="Second Parameter (integer)")
args = parser.parse_args()
def my_function(args):
print "Input file is:", args.data
print "Output file is:", args.output_file
print "Parameter 1 is:", args.first_parameter
print "Parameter 2 is:", args.second_parameter
Then I call it in my main function:
def main(argv):
args = ParseArguments()
my_function(args)
args.data
def read(data):
fh = read(args.data, "data")
(...)
Now, when I try to run this I get the error message:
runfile('C:filepath', wdir='C:/filepath')
usage: code.py [-h] -f DATA [-o OUTPUT_FILE] [-p FIRST_PARAMETER]
[-n SECOND_PARAMETER]
code.py: error: argument -f is required
I can't comprehend how this is not defined - there is a file called data in the working directory, and from my understanding of the argument parser it doesn't care about file types when assigning input, so it should be assigning my data.csv as input. What gives?
Another option might be to just not use the argument parser, of course, and reading the file directly by commands, but I'd like to understand what I've done wrong here all the same.
Related
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('p', 'projectType', type=str, help = 'c or c++ project type', choices=['c', 'c++'])
parser.add_argument('i', 'inputfile', type=pathlib.Path, help = 'the input file path')
parser.add_argument('o',"outputfile",type=pathlib.Path, help= 'the output file path')
parser.add_argument
args = parser.parse_args()
when i run this code on command prompt, and enter the inputfile first for example.. it gives me an error. does Argparse have an option like getopt (where i call something with a letter before inputting it so no mix up ex, '-i ...input...'). Here this option is just for optional arguments.
Is there a way for positional arguments to do that?
As per the argparse documentation you would define it as an "optional" argument but with the required flag set to true, e.g.:
parser.add_argument('-i', '--inputfile', required=True, type=pathlib.Path, help='the input file path')
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
When I run the following code:
def read_args():
parser = default_parser()
parser.add_argument('--tensorboard-dir', type=str, default='/tmp/cifar10/tensorboard')
parser.add_argument('-N', type=int, default=50000, help="Use N training examples.")
return parser.parse_args()
def main():
flags = readargs()
I have the following error output:
The following arguments are required: --name
However when I add the --name argument:
def read_args():
parser = default_parser()
parser.add_argument('--name', type=str, default='cifar10test')
parser.add_argument('--tensorboard-dir', type=str, default='/tmp/cifar10/tensorboard')
parser.add_argument('-N', type=int, default=50000, help="Use N training examples.")
return parser.parse_args()
def main():
flags = readargs()
is also creating problem.
Any ideas?
It appears that default_parser contains a --name argument which is required. What you're doing in your second example is defining the argument twice - once in default_parser and once in your program. Instead, you should be passing a --name argument when calling your program from the command line.
Example:
python cifar.py -N=1200 --tensorboard-dir=file.txt --name=cool_name
Alternatively, you could remove default_parser and construct your own ArgumentParser:
`parser = argparse.ArgumentParser()`
Full working demo:
import argparse
def read_args():
parser = argparse.ArgumentParser()
parser.add_argument('--tensorboard-dir', type=str,
default='/tmp/cifar10/tensorboard')
parser.add_argument('-N', type=int, default=50000,
help="Use N training examples.")
return parser.parse_args()
def main():
flags = vars(read_args())
# You can access your args as a dictionary
for key in flags:
print("{} is {}".format(key, flags[key]))
main()
The parser returns a Namespace object, but we can access its (much simpler) internal dictionary using vars(Namespace). You can then get your arguments by accessing the dictionary, for example, flags['N']. Note that tensorboard-dir becomes tensorboard_dir inside your python program to avoid issues with the subtraction operator.
Call it from the command line (I'm using Bash):
python cifar.py -N=1200 --tensorboard-dir=file.txt
Output:
tensorboard_dir is file.txt
N is 1200
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:])
This is probably a silly question, but I have a python script that current takes in a bunch of arguments using argparser and I would like to load this script as a module in another python script, which is fine. But I am not sure how to call the module as no function is defined; can I still call it the same way I do if I was just invoking it from cmd?
Here is the child script:
import argparse as ap
from subprocess import Popen, PIPE
parser = ap.ArgumentParser(
description='Gathers parameters.')
parser.add_argument('-f', metavar='--file', type=ap.FileType('r'), action='store', dest='file',
required=True, help='Path to json parameter file')
parser.add_argument('-t', metavar='--type', type=str, action='store', dest='type',
required=True, help='Type of parameter file.')
parser.add_argument('-g', metavar='--group', type=str, action='store', dest='group',
required=False, help='Group to apply parameters to')
# Gather the provided arguments as an array.
args = parser.parse_args()
... Do stuff in the script
and here is the parent script that I want to invoke the child script from; it also uses arg parser and does some other logic
from configuration import parameterscript as paramscript
# Can I do something like this?
paramscript('parameters/test.params.json', test)
Inside the configuration directory, I also created an init.py file that is empty.
The first argument to parse_args is a list of arguments. By default it's None which means use sys.argv. So you can arrange your script like this:
import argparse as ap
def main(raw_args=None):
parser = ap.ArgumentParser(
description='Gathers parameters.')
parser.add_argument('-f', metavar='--file', type=ap.FileType('r'), action='store', dest='file',
required=True, help='Path to json parameter file')
parser.add_argument('-t', metavar='--type', type=str, action='store', dest='type',
required=True, help='Type of parameter file.')
parser.add_argument('-g', metavar='--group', type=str, action='store', dest='group',
required=False, help='Group to apply parameters to')
# Gather the provided arguments as an array.
args = parser.parse_args(raw_args)
print(vars(args))
# Run with command line arguments precisely when called directly
# (rather than when imported)
if __name__ == '__main__':
main()
And then elsewhere:
from first_module import main
main(['-f', '/etc/hosts', '-t', 'json'])
Output:
{'group': None, 'file': <_io.TextIOWrapper name='/etc/hosts' mode='r' encoding='UTF-8'>, 'type': 'json'}
There may be a simpler and more pythonic way to do this, but here is one possibility using the subprocess module:
Example:
child_script.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--name", help="your name")
args = parser.parse_args()
print("hello there {}").format(args.name)
Then another Python script can call that script like so:
calling_script.py:
import subprocess
# using Popen may suit better here depending on how you want to deal
# with the output of the child_script.
subprocess.call(["python", "child_script.py", "-n", "Donny"])
Executing the above script would give the following output:
"hello there Donny"
One of the option is to call it as subprocess call like below:
import subprocess
childproc = subprocess.Popen('python childscript.py -file yourjsonfile')
op, oe = childproc.communicate()
print op