snippetpythonMinor
Using getopt parse and validate command line arguments
Viewed 0 times
validateargumentslineparsegetoptusingandcommand
Problem
I am learning
```
#!/usr/bin/python
'''\nMailing Script
Usage: python script.py -y -c "
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__":
getopt in Python to parse and validate command line inputs:```
#!/usr/bin/python
'''\nMailing Script
Usage: python script.py -y -c "
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__":
Solution
I think you have too many try/excepts. More than one of them raise and catch their own exceptions. I've made some changes that improves readability.
For clarity the new code created a new exception class and raises it when appropriate.
Also using getopt's own handler for bogus input. The
Pay attention to the wording:
reads better than:
For clarity the new code created a new exception class and raises it when appropriate.
Also using getopt's own handler for bogus input. The
else in the main loop is redundant but it can also serve as a fallback in case you make a mistake by allowing an arg but forget to process it. Pay attention to the wording:
if target_year not in map( ...reads better than:
if not target_year in map( ...#!/usr/bin/python
'''\nMailing Script
Usage: python script.py -y -c "
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
import getopt
first_yr, last_yr = (2008, 2013)
campaign_type = (
'80c', '80d', 'allowances', 'late_filing',
'exempt_income', 'other_sources',
)
class ArgumentError(Exception):
pass
def usage():
print sys.exit(__doc__)
def parse_arguments(argv):
target_year = None
campaign = None
try:
opts, args = getopt.getopt(argv[1:], "y:c:", ["year=", "campaign="])
except getopt.GetoptError as err:
# print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
for opt, arg in opts:
if opt == '-h':
usage()
elif opt in ("-y", "--year"):
target_year = arg
if target_year not in map(str, range(first_yr, last_yr + 1)):
raise ArgumentError("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()
if campaign not in campaign_type:
raise ArgumentError("Argument Error: Invalid 'Campaign type' passed. "
"A valid value can be any of %s" % str(campaign_type))
else:
raise ArgumentError("Bad argument: I don't know what %s is" % arg)
if target_year is None or campaign is None:
raise ArgumentError("You need to supply both -y and -c")
print 'Year : ', target_year
print 'campaign: ', campaign
# return argument values
return target_year, campaign
if __name__ == "__main__":
target_year, campaign = parse_arguments(sys.argv)Code Snippets
#!/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
import getopt
first_yr, last_yr = (2008, 2013)
campaign_type = (
'80c', '80d', 'allowances', 'late_filing',
'exempt_income', 'other_sources',
)
class ArgumentError(Exception):
pass
def usage():
print sys.exit(__doc__)
def parse_arguments(argv):
target_year = None
campaign = None
try:
opts, args = getopt.getopt(argv[1:], "y:c:", ["year=", "campaign="])
except getopt.GetoptError as err:
# print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
for opt, arg in opts:
if opt == '-h':
usage()
elif opt in ("-y", "--year"):
target_year = arg
if target_year not in map(str, range(first_yr, last_yr + 1)):
raise ArgumentError("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()
if campaign not in campaign_type:
raise ArgumentError("Argument Error: Invalid 'Campaign type' passed. "
"A valid value can be any of %s" % str(campaign_type))
else:
raise ArgumentError("Bad argument: I don't know what %s is" % arg)
if target_year is None or campaign is None:
raise ArgumentError("You need to supply both -y and -c")
print 'Year : ', target_year
print 'campaign: ', campaign
# return argument values
return target_year, campaign
if __name__ == "__main__":
target_year, campaign = parse_arguments(sys.argv)Context
StackExchange Code Review Q#37499, answer score: 6
Revisions (0)
No revisions yet.