I am learning getopt
in Python to parse and validate command line inputs.
I have written my following code to parse command line arguments using getopt
:
#!/usr/bin/python
'''\nMailing Script
Usage: python script.py -y <year> -c <type_user>"
Arguments:
-y, --year any value from 2008 to 2013
-c, --campaign any value in:
'80c', '80d', 'allowances', 'late_filing',
'exempt_income', 'other_sources'
Flags:
-h help
'''
import sys, getopt
first_yr, last_yr = (2008, 2013)
campaign_type = (
'80c', '80d', 'allowances', 'late_filing',
'exempt_income', 'other_sources',
)
def usage():
print sys.exit(__doc__)
def parse_arguments(argv):
try:
opts, args = getopt.getopt(argv[1:], "y:c:", ["year=", "campaign="])
except getopt.GetoptError:
usage()
for opt, arg in opts:
if opt == '-h':
usage()
elif opt in ("-y", "--year"):
target_year = arg
# customized exception
try:
if not target_year in map(str, range(first_yr, last_yr+1)):
raise Exception()
except:
sys.exit("Argument Error: Invalid year passed. \n"
"One valid year is within (%s, %s)" % (first_yr, last_yr)
)
elif opt in ("-c", "--campaign"):
campaign = arg.lower()
try:
if not campaign in campaign_type:
raise Exception()
except Exception, e:
sys.exit("Argument Error: Invalid 'Campaign type' passed. \n"
"A valid value can be any of %s" % str(campaign_type)
)
# to avoid 'UnboundLocalError' Exception when one argument not passed
try:
target_year, campaign
except UnboundLocalError, u:
usage()
print 'Year : ', target_year
print 'campaign: ', campaign
# return argument values
return (target_year, campaign)
if __name__ == "__main__":
target_year, campaign = parse_arguments(sys.argv)
Presently I didn't learn 16.4. argparse. I will learn it in next step
I want to improve my script as follows:
All arguments are mandatory. Presently if user miss some argument then script raise
UnboundLocalError
exception I caught it and callusage()
. Is it correct way? Should I uselen(argv)
someways to handle this?I check for correct values of arguments, if any argument value is wrong then I explicitly rise an Exception and print error message in except clause. I am again not sure whether its preferable way to write this kind of code. I feel it adds one more level of nested block.
Some runs of this script:
$ python opt.py -y 2012 -c 80c
Year : 2012
campaign: 80c
correct as I want.
$ python opt.py -year=2012
Argument Error: Invalid year passed.
One valid year is within (2008, 2013)
I think I should print message something like "insufficient arguments passed" or "use --year=2012 or -y 2012".
Please suggest me improvements in my script.
If there are any other tips on how to improve this code please let me know.