Is it ‘allowed’ to get parameters like this

Cecil Westerhof Cecil at decebal.nl
Thu Aug 11 12:15:38 EDT 2016


On Thursday 11 Aug 2016 17:15 CEST, Cecil Westerhof wrote:

> On Thursday 11 Aug 2016 16:29 CEST, Peter Otten wrote:
>
>> Cecil Westerhof wrote:
>>
>>> It has been a while since I worked with Python. I wanted to get
>>> some stats about the idle time of my computer, so that was a good
>>> moment to pick up Python again. ;-)
>>>
>>>
>>> As I understood it getopt is the way to get the parameters for
>>> your script. But at the moment it looks a bit like overkill, my
>>> script does not have much parameters as parameter_error shows: def
>>> parameter_error(): print('Error: {0} [ --5 | --10 | --20 | --25 ]
>>> --all | --this-month | --this-year | --today'
>>> .format(basename(sys.argv[0]))) sys.exit(1)
>>>
>>> So at the moment this is my init function:
>>> def init():
>>> global conn
>>> global cursor
>>> global vmstat_params
>>>
>>> arg_length = len(sys.argv)
>>> if   (arg_length == 1):
>>> period       = '--today'
>>> slice_length = 20
>>> elif (arg_length == 2):
>>> period       = sys.argv[1]
>>> slice_length = 20
>>> elif (arg_length == 3):
>>> period = sys.argv[2]
>>> if (sys.argv[1] in ['--5', '--10', '--20', '--25']):
>>> slice_length = int(sys.argv[1][2:])
>>> else:
>>> parameter_error()
>>> else:
>>> parameter_error()
>>
>> <snip>
>>
>> Contrast that with the following cli based on argparse:
>>
>> $ cat demo.py
>> #!/usr/bin/env python3
>>
>> def init():
>> import argparse
>>
>> parser = argparse.ArgumentParser()
>> parser.add_argument(
>> "period", nargs="?",
>> choices="today this-month this-year all".split(),
>> default="today",
>> help="Period covered")
>> parser.add_argument(
>> "slice_length", type=int, nargs="?",
>> choices=[5, 10, 20, 25],
>> default=20,
>> help="Whatever...")
>>
>> print(parser.parse_args())
>>
>> init() $ ./demo.py -h usage: demo.py [-h]
>> [{today,this-month,this-year,all}] [{5,10,20,25}]
>>
>> positional arguments:
>> {today,this-month,this-year,all}
>> Period covered
>> {5,10,20,25}          Whatever...
>>
>> optional arguments: -h, --help show this help message and exit $
>> ./demo.py all Namespace(period='all', slice_length=20) $ ./demo.py
>> none usage: demo.py [-h] [{today,this-month,this-year,all}]
>> [{5,10,20,25}] demo.py: error: argument period: invalid choice:
>> 'none' (choose from 'today', 'this-month', 'this-year', 'all') $
>> ./demo.py all 5 Namespace(period='all', slice_length=5) $ ./demo.py
>> all 7 usage: demo.py [-h] [{today,this-month,this-year,all}]
>> [{5,10,20,25}] demo.py: error: argument slice_length: invalid
>> choice: 7 (choose from 5, 10, 20, 25)
>>
>> The interface is not exactly the same, but the code that defines it
>> is declarative rather than trying to cover all possible
>> combinations of input and should be easier to maintain in the long
>> run.
>
> That is very neat indeed. I am used of options starting with --, but
> I am not married to that. I am going to look into this.

I rewrote it to:
def init():
    global conn
    global cursor
    global vmstat_params

    parser = ArgumentParser()
    parser.add_argument(
        'period', nargs = '?',
        choices = 'all this-month this-year today'.split(),
        default = 'today',
        help='Period covered')
    parser.add_argument(
        'slice_length', type = int, nargs ='?',
        choices = [5, 10, 20, 25],
        default = 20,
        help = 'Length of a percentage slice')
    args            = parser.parse_args()
    period          = args.period
    slice_length    = args.slice_length
    conn            = connect(expanduser('~/Databases/general.sqlite'))
    cursor          = conn.cursor()
    all_data        = '%'
    today           = cursor.execute('SELECT CURRENT_DATE').fetchone()[0]
    this_month      = today[0:8] + '%'
    this_year       = today[0:5] + '%'
    if   (period == 'today'):
        vmstat_params = [today,      slice_length]
    elif (period == 'this-month'):
        vmstat_params = [this_month, slice_length]
    elif (period == 'this-year'):
        vmstat_params = [this_year,  slice_length]
    elif (period == 'all'):
        vmstat_params = [all_data,   slice_length]
    else:
        print('Unknown period: {0}'.format(period))
        sys.exit(1)

I kept the else part for the case that an argument is added that is
not put into the if/elif construction.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof



More information about the Python-list mailing list