parser = argparse.ArgumentParser()
parser.add_argument('-model', type=str, default='linear_model')
parser.add_argument('-featuredim', type=int, default=20)
parser.add_argument('-inputfeatures', type=str, default='/Users/myname/Downloads/face-rating-master/data/features_ALL.txt')
parser.add_argument('-labels', type=str, default='/Users/myname/Downloads/face-rating-master/data/ratings.txt')
The above code can be run successfully. The following line
args = parser.parse_args()
gives this error:
usage: ipykernel_launcher.py [-h] [-model MODEL] [-featuredim FEATUREDIM]
[-inputfeatures INPUTFEATURES] [-labels LABELS]
ipykernel_launcher.py: error: argument -featuredim: invalid int value: '/Users/myname/Library/Jupyter/runtime/kernel-7d72fc3c-2c11-47e4-87f3-3587b2461a52.json'
An exception has occurred, use %tb to see the full traceback.
Code from https://github.com/avisingh599/face-rating
try:
args = parser.parse_args() #call from command line
except:
args = parser.parse_args(args=[]) #call from notebook
The featuredim argument expects an integer (i.e., type=int) but you've passed in a string that indicates the path to a json file.
You could get this script to work by re-engineering its logic a bit so that it would read in a JSON and then extract the integer from a key value (similar to how many scripts will read in .ini configuration files), but within the context of what you're doing that's overkill (and really wouldn't help much with your dilemma, since you want to use Jupyter). For reference, the file that you're passing into the script doesn't give you direct access to the variables defined in your notebook, and just stores information used by the application (such as the IP address that the notebook is running on and the TCP port number that it is using). To illustrate, this is what a similar JSON file on my laptop looks like:
09/28 18:26:53 [jsp2205#kaheta: ~/Library/Jupyter/runtime]
$ less kernel-40dad791-ffa1-4687-bcd1-3ec831884c83.json
{
"stdin_port": 60476,
"ip": "127.0.0.1",
"control_port": 60477,
"hb_port": 60478,
"signature_scheme": "hmac-sha256",
"key": "b52ef99c-0a1a70b17b600daea5263a29",
"kernel_name": "",
"shell_port": 60474,
"transport": "tcp",
"iopub_port": 60475
}
Your best bet is to take the code from trainModel.py, remove ArgumentParser, and replace any references to the arguments with hardcoded variables. Then add each of the lines in the modified code to your Jupyter notebook and modify the hardcoded variables manually within the notebook.
For other scripts using ArgumentParser, you might want to see if they pass the arguments extracted using parse_args() into a function, and then use an import statement similar to the following to import that function directly into your notebook. So something like the following:
cd [directory containing script]
from [script name minus the .py extension] import [function name]
Related
I have a script with several functions (before that I had one script per function)
Each function will require different arguments (some positional/mandatory, some optional).
I'd like to be able to call a specific function within the script and then hand over the argparse arguments.
Commandline:
python3 getSites.py getSites host token
I thought that using
if __name__ == '__main__':
globals()[sys.argv[1]]()
to use sys.argv[1] as the choice for the fuction and then within the function use:
def getSites():
parser = argparse.ArgumentParser(description="SentinelOne Site Statistics (#mianly for licnese usage")
parser.add_argument('host', type=str, help='REQUIRED: Please enter the Host (i.e. everything after "https://" and before ".domain.com"')
parser.add_argument('token', type=str, help='REQUIRED: Please enter your token (without the string "ApiToken")')
parser.add_argument('-s', '--savepath', type=str,
help='OPTIONAL: full path of the directory where to write the resulting XLS file. Defaults to directory of the script itself')
parser.add_argument('-a', '--accountid', type=str,
help='OPTIONAL: Enter the AccountID to query. Defaults to all accounts / sites the token user has access to')
f_args = parser.parse_args()
would work but when entering e.g.
python3 getSites.py getSites firsthost 98456984652984652984652985
I get
getSites.py: error: unrecognized arguments: 98456984652984652984652985
My Questions:
Is it possible to archive this without the "overcomplicated" -c switch when calling the script?
should I rather go with moving the required arguments from argparse into the function? i.e. getsites(host, token) and then use argparse only for the optional arguments?
Benefit of the second method would be that I could also call the function from within a python script, not only from command line. On the other hand: the user would need to know exactly what they have to provide, as that won't be shown when runnign the script with -h
I'm a bit confused here and would appreciate and help for a newbie.
So I'm trying to get my program to do take the command line arguments and use it in my script. I read argparse and the optparse documentation and I'm still lost.
What I'm trying to do is have my code execute this on the command line:
./program <-p port> <-s> [required1] [required2]
The -p is optional, and I want to make the port a variable in my script, like so:
server_address = ('some server name', **port**)
I thought that that's what store and dest would do... as in store would take the port argument and dest would be the variable name and I could call it like program.port. It doesn't work this way, however, and I can't find or decipher explanations for what exactly store and dest do.
I'm new to Python, so this might not be a well-formed question.
so, following the documentation:
You create a parser
import argparse
parser = argparse.ArgumentParser(description='Some helpful text about what your function does')
You add arguments, optional ones have '-'s before hand, see below
parser.add_argument('-p', '--port', type=int, default=0, help='port')
parser.add_argument('-s', help='I don\'t know what this is')
parser.add_argument('required_1') # Note the lack of dashes
parser.add_argument('required_2')
You need to parse the arguments with a function call
args = parser.parse_args()
This creates a namespace object which you can then access your variables from, see below
port = args.port
or
port = vars(args)['port']
req1 = args.required_1
req2 = args.required_2
etc...
For more information on namespace objects, checkout this question
Hopefully that helps.
Scenario: I have a python script that receives as inputs 2 directory paths (input and output folders) and a variable ID. With these, it performs a data gathering procedure from xlsx and xlsm macros, modifies the data and saves to a csv (from the input folder, the inner functions of the code will run loops, to get multiple files and process them, one at a time).
Issue: Since the code was working fine when I was running it from the Spyder console, I decided to step it up and learn about cmd caller, argparse and the main function. I trying to implement that, but I get the following error:
Unrecognized arguments (the output path I pass from cmd)
Question: Any ideas on what I am doing wrong?
Obs: If the full script is required, I can post it here, but since it works when run from Spyder, I believe the error is in my argparse function.
Code (argparse function and __main__):
# This is a function to parse arguments:
def parserfunc():
import argparse
parser = argparse.ArgumentParser(description='Process Files')
parser.add_argument('strings', nargs=3)
args = parser.parse_args()
arguments = args.strings
return arguments
# This is the main caller
def main():
arguments = parserfunc()
# this next function is where I do the processing for the files, based on the paths and id provided):
modifierfunc(arguments[0], arguments[1], arguments[2])
#
if __name__ == "__main__":
main()
If you decided to use argparse, then make use of named arguments, not indexed. Following is an example code:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('output')
parser.add_argument('id')
args = parser.parse_args()
print(args.input, args.output, args.id) # this is how you use them
In case you miss one of them on program launch, you will get human readable error message like
error: the following arguments are required: id
You could drop the entire parserfunc() function.
sys.argv does indeed contain all arguments (always processed as a string) as mentioned by grapes.
So instead of this:
modifierfunc(arguments[0], arguments[1], arguments[2])
This should suffice:
import sys
modifierfunc(sys.argv[0], sys.argv[1], sys.argv[2])
Perhaps, first do a print, to see if the sys.argv holds the values you expect.
print('Argument 0='+sys.argv[0])
print('Argument 1='+sys.argv[1])
print('Argument 2='+sys.argv[2])
Code:
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Build dataset')
parser.add_argument('jpeg_dir', type=str, help='path to jpeg images')
parser.add_argument('nb_channels', type=int, help='number of image channels')
parser.add_argument('--img_size', default=256, type=int,
help='Desired Width == Height')
parser.add_argument('--do_plot', action="store_true",
help='Plot the images to make sure the data processing went OK')
args = parser.parse_args()
Error:
$ python make_dataset.py /home/abhishek/Lectures/columbia/deep_learning/project/DeepLearningImplementations/pix2pix/data/pix2pix/datasets 3 --img_size 256 --do_plot True
usage: make_dataset.py [-h] [--img_size IMG_SIZE] [--do_plot]
jpeg_dir nb_channels
make_dataset.py: error: unrecognized arguments: True
I am using a bash shell here. I am passing as mentioned in the docs https://github.com/tdeboissiere/DeepLearningImplementations/tree/master/pix2pix/src/data
As you've configured it, the --do_plot option does not take any arguments. A store_true argument in argparse indicates that the very presence of the option will automatically store True in the corresponding variable.
So, to prevent your problem, just stop passing True to --do_plot.
You do not need to indicate True as far as I can tell, by just including --do_plot, it is telling it that you wanted to do plot. And plus, you did not configure it to take any arguments.
In the following line of the source code:
if args.do_plot:
If you actually included --do_plot in the command lines, it will be evaluated as True, if not, it will be evaluated as False.
The problem is in the specification here:
parser.add_argument('--do_plot', action="store_true",
help='Plot ...')
You've declared do_plot as an option without an argument; the True afterward has no purpose in your argument protocol. This is an option that's off by omission, on when present.
Just one of reason (which I faced) and hope my hypothesis helps your problem is that on Ubuntu (on Windows, IDK but it's fine),
When you imported a function from a .py file (let say A.py) which having args (people create __main__ to test a feature function, let call A function ). The .py importing/using A could be confusedly parsing arguments because A.py also parse arguments and so on.
So, you could solve by refactoring, or just (temporarily) comment out them to run first.
I have a program that stores a few important variables as strings that are necessary for the program to operate properly: DeviceNumber, IPAddress, and Port. These variables are stored in a file, which is loaded by the program.
For debugging purposes, I would like to be able to quickly overwrite the files with command line arguments. The args would all be optional, and if not used then it just uses the variables taken out of the file.
I can do simple positional args using something like DeviceNumber = sys.args[1], and only overwrite vars if the args are present, but this has the problem of not being able to handle if you enter the variables in the wrong order, or if you enter, say, the IPAddress and Port but not the DeviceNumber.
I have been reading through the pyDocs argparse Tutorial and documentation, but it does not seem terribly useful for what I need - it covers mandatory args, and optional flags, but does not seem to allow optional args that depend on a flag to denote their purpose. EDIT: Turns out it does, but the example is not very obvious, so I missed it. Similarly I have had trouble finding applicable questions here on SE.
In short, given a program like
#Default Names loaded from file
DeviceNumber = "2000"
IPAddress = "159.142.32.30"
Port = 80
#if command line args entered:
#overwrite default vars with arg corresponding to each one
#this probably involves argparse, but I don't know how
print "DNumber:"+DeviceNumber+" IP:"+IPAddress+" Port:"+Port
Some examples with different cmd line inputs/outputs would be:
All values are defaults
$ python myfile.py
DNumber:2000 IP:159.142.32.30 Port:80
All values are overridden
$ python myfile.py -n 1701 -ip 120.50.60.1 -p 3000
DNumber:1701 IP:120.50.60.1 Port:3000
Default DNumber, Override IPAddress + Port. Args were specified in different order.
$ python myfile.py -p 123 -ip 124.45.67.89
DNumber:2000 IP:124.45.67.89 Port:123
Default DNumber and IPAddress, Override Port
$ python myfile.py -p 500
DNumber:2000 IP:159.142.32.30 Port:500
You get the idea...
for the syntax of the flag/args relationship, I am also not sure if there is a specific syntax python needs you to use (i.e. -p 500 vs. -p500 v -p=500)
There's a few ways to define default values for arguments specified by argparse. When adding arguments to your parser, you can specify a default value. Simply:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--port", dest="port", default=500,
type=int, help="specify port")
args = parser.parse_args()
print "You've selected port: %d" % (args.port)
From the above example, it is trivial to extend to allow additional default functionality. Note that dest="port" is already by default due to the naming of the long argument --port. Like so:
parser.add_argument("-p", "--port", dest="port", default=None,
type=int, help="specify port")
args = parser.parse_args()
if args.port is None:
port = read_port_from_file()
print "No optional port specified. Reading value from file."
print "You've selected port: %d" % (args.port)