In Fortran you can do something like this:
#:for DTYPE, NAME in [('real','ssygvd'), ('dble', 'dsygvd'), ('cmplx', 'chegvd')] subroutine ${DTYPE}$_something_${NAME}$(args) [some commands] end subroutine ${DTYPE}$_something_${NAME}$
Can something like this be done in Python?
I want to write a function like this for float, int and str.
def get_int_tuple(value): try: values = [int(i) for i in value.split(',')] assert len(values) in range(1,4) except (ValueError, AssertionError): raise argparse.ArgumentTypeError( 'Provide a CSV list of 1 up to 3 integers' ) # return our value as is if there is only one if len(values) == 1: return tuple(np.array(values)) # if there are three - return a range return tuple(np.arange(*values))
Which I will then pass to the parser:
parser.add_argument( "--kernel", type=get_str_tuple, help="SVM kernel. Options: 'linear', 'poly', 'rbf' (default=rbf)" ) parser.add_argument( '--c', type=get_float_tuple, help="C (hyper)parameter of 'rbf' kernel (default=0.05)." ) parser.add_argument( '--degree', type=get_int_tuple, help="Degree of the 'poly' kernel. (default=3)." )
Advertisement
Answer
The types themselves are first-class objects, so you can pass them as arguments to a single function.
First, define a function that defines the common function, closing over the desired type.
def make_type(type_, type_name): def get_tuple(value): try: values = [type_(i) for i in value.split(',')] assert len(values) in range(1,4) except (ValueError, AssertionError): raise argparse.ArgumentTypeError( f'Provide a CSV list of 1 or 3 {type_name}' ) # return our value as is if there is only one if len(values) == 1: return tuple(np.array(values)) # if there are three - return a range return tuple(np.arange(*values)) return get_tuple
Then use make_type
to create the necessary argument for the type
argument to `add_argument.
parser.add_argument( "--kernel", type=make_type(str, "strings"), help="SVM kernel. Options: 'linear', 'poly', 'rbf' (default=rbf)" ) parser.add_argument( '--c', type=make_type(float, "floating-point values"), help="C (hyper)parameter of 'rbf' kernel (default=0.05)." ) parser.add_argument( '--degree', type=make_tuple(int, "integers"), help="Degree of the 'poly' kernel. (default=3)." )