pass values from argparse to different methods - python

I have an issue with argparse. I pass different values from prompt with argparse and I want to use them with different functions. How should I arrange my code?
So far the issue is that when the method split_dataset is called the program stacks
def split_dataset(destpath):
start = t.clock()
load_atomrefs(os.path.join(destpath, 'atomref.npz'))
load_data(os.path.join(destpath, 'qm9.db'))
total_time = (t.clock()-start)
print(f"Download of DataSet Completed in {total_time}s")
def params_initialization(train_batch,test_batch,lr,**kwargs):
parameters = {'train_batch' : train_batch, 'test_batch' : test_batch, 'lr' : lr }
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.set_defaults(method = split_dataset)
parser.add_argument('--destpath', help='Path to QM9 directory')
parser.add_argument('--train_batch', type=int, help='Batch size for training', default=32)
parser.add_argument('--test_batch', type=int, help='Batch size for testing',default=32)
parser.add_argument('--lr', type=float, help='Learning rate',
default=1e-3)
parser.add_argument('--ntrain', help='Number of training examples',
type=int, default=-1)
parser.add_argument('--nval', help='Number of validation examples',
type=int, default=-1)
args = parser.parse_args()
if not os.path.exists(args.destpath):
os.makedirs(args.destpath)
args.method(**vars(args))

Use parser.add_argument_group and add call the group arguments in another function
def function_to_call_group(parser_group):
parser_group.add_argument(--argument)
if __name__ == '__main__':
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
group1 = parser.add_argument_group("Group1")
function_to_call_group(group1)
# add other arguments to parser
args = parser.parse_args()

Related

Argument parser object does not contain attribute defined in parser

I am working on a program that works on hyperspectral image super-resolution by using Neural Networks, Now in here the Mains directory of the program contains multiple parsers. The parsers and subparsers seem to have been defined correctly
def main():
# parsers
main_parser = argparse.ArgumentParser(description="parser for SR network")
subparsers = main_parser.add_subparsers(title="subcommands", dest="subcommand")
train_parser = subparsers.add_parser("train", help="parser for training arguments")
train_parser.add_argument("--cuda", type=int, required=False,default=1,
help="set it to 1 for running on GPU, 0 for CPU")
train_parser.add_argument("--batch_size", type=int, default=32, help="batch size, default set to 64")
train_parser.add_argument("--epochs", type=int, default=40, help="epochs, default set to 20")
train_parser.add_argument("--n_feats", type=int, default=256, help="n_feats, default set to 256")
train_parser.add_argument("--n_blocks", type=int, default=3, help="n_blocks, default set to 6")
train_parser.add_argument("--n_subs", type=int, default=8, help="n_subs, default set to 8")
train_parser.add_argument("--n_ovls", type=int, default=2, help="n_ovls, default set to 1")
train_parser.add_argument("--n_scale", type=int, default=4, help="n_scale, default set to 2")
train_parser.add_argument("--use_share", type=bool, default=True, help="f_share, default set to 1")
train_parser.add_argument("--dataset_name", type=str, default="Chikusei", help="dataset_name, default set to dataset_name")
train_parser.add_argument("--model_title", type=str, default="SSPSR", help="model_title, default set to model_title")
train_parser.add_argument("--seed", type=int, default=3000, help="start seed for model")
train_parser.add_argument("--learning_rate", type=float, default=1e-4,
help="learning rate, default set to 1e-4")
train_parser.add_argument("--weight_decay", type=float, default=0, help="weight decay, default set to 0")
train_parser.add_argument("--save_dir", type=str, default="./trained_model/",
help="directory for saving trained models, default is trained_model folder")
train_parser.add_argument("--gpus", type=str, default="1", help="gpu ids (default: 7)")
test_parser = subparsers.add_parser("test", help="parser for testing arguments")
test_parser.add_argument("--cuda", type=int, required=False,default=1,
help="set it to 1 for running on GPU, 0 for CPU")
test_parser.add_argument("--gpus", type=str, default="0,1", help="gpu ids (default: 7)")
args = main_parser.parse_args()
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
print(args.gpus)
if args.subcommand is None:
print("ERROR: specify either train or test")
sys.exit(1)
if args.cuda and not torch.cuda.is_available():
print("ERROR: cuda is not available, try running on CPU")
sys.exit(1)
if args.subcommand == "train":
train(args)
else:
test(args)
pass
however, upon using the args object, the compiler throws an error saying that the object has no attribute gpus. Though, the test parser does contain the attribute 'gpus'
"G:\Python projects\venv\Scripts\python.exe" "G:/Hyperspectral ISRO/SSPSR-master/mains.py"
Traceback (most recent call last):
File "G:\Hyperspectral ISRO\SSPSR-master\mains.py", line 309, in <module>
main()
File "G:\Hyperspectral ISRO\SSPSR-master\mains.py", line 70, in main
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
AttributeError: 'Namespace' object has no attribute 'gpus'
I cannot figure out as to why this is happening, as I believe I am parsing the arguments correctly before using args, I tried to find similar issues on forums, but failed to do so.
All you need to do is:
args = main_parser.parse_args()
print(args) # for debugging help
if args.subcommand is None:
print("ERROR: specify either train or test")
sys.exit(1)
# now it's safe to reference `gpus` and `cuda` which are defined by both subparsers
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus
if args.cuda and not torch.cuda.is_available():
print("ERROR: cuda is not available, try running on CPU")
sys.exit(1)
if args.subcommand == "train":
train(args)
else:
test(args)
Just beware that train and test will get different args. train won't get any of the test values.
Try different command line values and note the differences in the args.
if you use
subparsers = main_parser.add_subparsers(title="subcommands", dest="subcommand",
required=True)
you don't need to do your own test for args.subcommand is None. The parser will do that for you.

checkpoint_path and argparse error happend

def main(params):
# load the checkpoint
checkpoint_path = params['checkpoint_path']
max_images = params['max_images']
print ('loading checkpoint %s' % (checkpoint_path, ))
checkpoint = pickle.load(open(checkpoint_path, 'rb'))
checkpoint_params = checkpoint['params']
dataset = checkpoint_params['dataset']
model = checkpoint['model']
dump_folder = params['dump_folder']
...
...
...
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('checkpoint_path', type=str, help='the input checkpoint')
parser.add_argument('-b', '--beam_size', type=int, default=1, help='beam size in inference. 1
indicates greedy per-word max procedure. Good value is approx 20 or so, and more = better.')
parser.add_argument('--result_struct_filename', type=str, default='result_struct.json',
help='filename of the result struct to save')
parser.add_argument('-m', '--max_images', type=int, default=-1, help='max images to use')
parser.add_argument('-d', '--dump_folder', type=str, default="", help='dump the relevant images to
a separate folder with this name?')
args = parser.parse_args()
params = vars(args) # convert to ordinary dict
print ('parsed parameters:')
print (json.dumps(params, indent = 2))
main(params)
I fix parser.add_argument('-checkpoint_path', type=str, help='the input checkpoint')
and next problem showed up in checkpoint_path = params['checkpoint_path'].
I tried to putting a file like D:\neuraltalk\cv\model_checkpoint_flickr8k_DESKTOP-4PPS67A_baseline_26.76.p
but it doesn't work...
please help me
I solve this problem on my own.
just changed a line of code
checkpoint_path = 'D:\\neuraltalk\cv\\model_checkpoint_flickr8k_DESKTOP-4PPS67A_baseline_17.10.p'

passing a dict with arguments to argparse

I am using a codebase that expects a large set of argument via command line using argparse library and I neet to call that code inside a loop and inject the arguments via dictionary and not via command line without changing that codebase, I call the code as follow:
parser = argparse.ArgumentParser('Training', parents=[get_args_parser()])
args = parser.parse_args()
main(args)
Where get_args_parser() is a large list of arguments and defaults such as :
def get_args_parser():
parser = argparse.ArgumentParser('Set transformer detector', add_help=False)
parser.add_argument('--lr', default=1e-4, type=float)
parser.add_argument('--lr_backbone', default=1e-5, type=float)
parser.add_argument('--batch_size', default=2, type=int)
parser.add_argument('--weight_decay', default=1e-4, type=float)
parser.add_argument('--epochs', default=300, type=int)
parser.add_argument('--lr_drop', default=200, type=int)
...
If i need to pass a dictionary , as arguments , like:
argdict = {'lr_drop':20,'batch_size':5}
How can I do it?
you should use like this:
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dict", required=True, help="Your dict as string", default="{}")
args = vars(ap.parse_args())
argdict = eval(args["dict"])
print(argdict)
# or you cam print some dict specific var
print(argdict["name"]) #Jasar
the you can call your file like it:
python3 file.py -d '{"name":"Jasar"}'
using some clues by #Jaser and #chepner , what i did is as follow:
args_to_argdict = {'a':1 , 'b':49 ,'c': 'text' }
parser = argparse.ArgumentParser(parents=[get_args_parser()])
args = parser.parse_args()
arg_dict = vars(args)
for key,value in args_to_argdict.items():
arg_dict[key]= value
so that the args value change , then i run the main :
main(args)
with the modified args .

saving arguments with ArgumentParser in a dictionary

i obtain different arguments from command lines:
def get_args():
parser = ArgumentParser(description='neural network project')
parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--decay_epoch', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=1)
parser.add_argument('--lr', type=float, default=.0002)
parser.add_argument('--load_height', type=int, default=286)
parser.add_argument('--load_width', type=int, default=286)
args = parser.parse_args()
return args
I would like to save all the argument obtained from get_args in a dictionary (to save then in a file .json or in a .txt).
argparse.ArgumentParser.parse_args returns an argparse.Namespace object, which is trivial to turn into a dict. Straight from the documentation:
This class is deliberately simple, just an object subclass with a
readable string representation. If you prefer to have dict-like view
of the attributes, you can use the standard Python idiom, vars():
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}
Create a dictionary and add them by parser keyword.
neural_dict = {}
neural_dict['EPOCHS'] = args.epochs
neural_dict['DECAY_EPOCH'] = args.decay_epoch
.
.
.
To add to dictionary using a for loop:
neural_dict = {}
parser = argparse.ArgumentParser(description='neural network project')
parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--decay_epoch', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=1)
parser.add_argument('--lr', type=float, default=.0002)
parser.add_argument('--load_height', type=int, default=286)
parser.add_argument('--load_width', type=int, default=286)
args = parser.parse_args()
#chepner is right...use his method instead
neural_dict = vars(args)

How can i receive 1 argument with the python library parser and use just the argument?

I'm doing a command line application to verify if a website is active, and i want to receive one argument, but the parser needs receive an argument and a valor for this argument, So my question is: How can i use just 1 argument ?
This is my code:
if __name__=="__main__":
import requests
import datetime
from time import sleep
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('u', help="Unique verification")
parser.add_argument('c', help="Continuos verification")
parser.add_argument('s', help="Check and save to file")
parser.add_argument('d', help="Documentation")
args = parser.parse_args()
main(parser.parse_args)
My function main receives a char, how can i use a char via command line?
You are currently creating mandatory positional arguments, so that a call like
python3 verify.py foo bar baz bye
would result in
args.u == 'foo'
args.c == 'bar'
args.s == 'baz'
args.d == 'bye'
You want to define four options, using the store_true action so that providing the option will set a flag from its default False value to True.
parser = argparse.ArgumentParser()
parser.add_argument('-u', action='store_true', help="Unique verification")
parser.add_argument('-c', action='store_true', help="Continuos verification")
parser.add_argument('-s', action='store_true', help="Check and save to file")
parser.add_argument('-d', action='store_true', help="Documentation")
args = parser.parse_args()
Now a call like
python3 verify.py -u -s
would result in
args.u == True
args.c == False
args.s == True
args.d == False
If you want to further restrict the user to exactly one of the four options, use a mutual-exclusion group.
# Same as above, calling group.add_argument, not parser.add_argument
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-u', action='store_true', help="Unique verification")
group.add_argument('-c', action='store_true', help="Continuos verification")
group.add_argument('-s', action='store_true', help="Check and save to file")
group.add_argument('-d', action='store_true', help="Documentation")
args = parser.parse_args()

Categories

Resources