Python Arguments and Passing Floats in Arguments
<p>I've run into a couple of issues using arguments within a python script. Can i please get some help or direction to get this code functional? Thank you in advance.</p>

<p>First issue: I am unable to specify multiple arguments at once. 
For example I am able to pass a single argument fine:</p>

<pre><code>$ ./my_arg_scenario.py -a
Argument_A
$ ./my_arg_scenario.py -c
Argument_C
$ ./my_arg_scenario.py -d
Argument_D
</code></pre>

<p>However, I am looking for a way to pass multiple arguments in any position. Is there a way I can accomplish this?
For example, I would like the below to occur:</p>

<pre><code>./my_arg_scenario.py -a -c -d
Argument_A
Argument_C
Argument_D

# OR    

./my_arg_scenario.py -c -a
Argument_C
Argument_A
</code></pre>

<p>Second Issue: I am trying to pass both whole numbers and floats in the -b argument. But when I pass a float/decimal I get the below error. Is there a way I can pass both a float and whole number?</p>

<p>This works:</p>

<pre><code>$ ./my_arg_scenario.py -b 5
The number provided is: 5
</code></pre>

<p>But this does NOT:</p>

<pre><code>$ ./my_arg_scenario.py -b 5.50
Traceback (most recent call last):
  File "./my_arg_scenario.py", line 18, in &lt;module&gt;
    if int(sys.argv[2]) not in range(0,11):
ValueError: invalid literal for int() with base 10: '5.50'
</code></pre>

<p>Below is my testable code:</p>

<pre><code>#!/usr/local/bin/python3.5
import sys

script_options = ['-a', '-b', '-c', '-d']
manual_flag = ''
build_flag = ''

if len(sys.argv) &gt; 1:
    if sys.argv[1] in script_options:
        pass
    else:
        print('\n\t\tParameter "' + sys.argv[1] + '" is an invalid argument.\n')
        sys.exit()
    if sys.argv[1] == '-a':
        print('Argument_A')
        sys.exit()
    elif sys.argv[1] == '-b':
        if int(sys.argv[2]) not in range(0,11):
            print('Invalid interval. Please select a value bewteen 1-5s.')
            sys.exit()
        else:
            print('The number provided is: ' + (sys.argv[2]))
    elif sys.argv[1] == '-c':
        manual_flag = 'Argument_C'
        print(manual_flag)
    elif sys.argv[1] == '-d':
        build_flag ='Argument_D'
        print(build_flag)
else:
    pass
</code></pre>

<p><s>You didn't actually provide the code you're using (aside from incidentally in the traceback),</s>(<strong>Update:</strong> Code added later) but the answer is: Stop messing around with parsing <code>sys.argv</code> manually and use <a href="https://docs.python.org/3/library/argparse.html" rel="nofollow">the <code>argparse</code> module</a> (or <code>docopt</code> or something that doesn't involve rolling your own switch parsing).</p>

<pre><code>import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a', action='store_true')
parser.add_argument('-b', metavar='INTERVAL', type=int, choices=range(11))
parser.add_argument('-c', action='store_true')
parser.add_argument('-d', action='store_true')
args = parser.parse_args()

if args.a: print('Argument_A')
if args.b is not None: print('The number provided is:', args.b)
if args.c: print('Argument_C')
if args.d: print('Argument_D')
</code></pre>

<p>If you want to accept <code>int</code> or <code>float</code>, the easiest solution is to just make <code>type=float</code> and use a consistent type (but the <code>range</code> check must be done outside the parsing step). If you must allow both, <code>ast.literal_eval</code> or a homegrown <code>argparse</code> type conversion function are options. Since you want a range check too (which <code>range</code> won't handle properly for <code>float</code> values that aren't equal to <code>int</code> values), roll a type checker:</p>

<pre><code>def int_or_float(minval=None, maxval=None):
    def checker(val):
        try:
            val = int(val)
        except ValueError:
            val = float(val)
        if minval is not None and val &lt; minval:
            raise argparse.ArgumentTypeError('%r must be &gt;= %r' % (val, minval))
        if maxval is not None and val &gt; maxval:
            raise argparse.ArgumentTypeError('%r must be &lt;= %r' % (val, maxval))
        return val
    return checker
</code></pre>

<p>Then use it by replacing the definition for <code>-b</code> with:</p>

<pre><code># Might want int_or_float(0, 10) depending on range exclusivity rules
parser.add_argument('-b', metavar='INTERVAL', type=int_or_float(0, 11))
</code></pre>

python python-3.x int argv