How to run a Python file with boolean arguments
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Beneath the City Looping
--
Chapters
00:00 How To Run A Python File With Boolean Arguments
00:58 Answer 1 Score 4
02:04 Accepted Answer Score 4
02:34 Answer 3 Score 1
02:59 Answer 4 Score 1
03:50 Thank you
--
Full question
https://stackoverflow.com/questions/6924...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #sys
#avk47
ANSWER 1
Score 4
I would use argparse for this type of thing. Use a boolean flag argument. I also like to provide a positive and a negative version for ease of use.
import argparse
...
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog='log-to-pickle')
parser.add_argument('--imperial-units', dest='imperial_units', action='store_true')
parser.add_argument('--no-imperial-units', dest='imperial_units', action='store_false')
parser.set_defaults(imperial_units=True)
args = parser.parse_args()
log_to_pickle(args.imperial_units)
Using argparse you'll get some nice help messages too:
$ python3 file.py -h
usage: log-to-pickle [-h] [--imperial-units] [--no-imperial-units]
optional arguments:
-h, --help show this help message and exit
--imperial-units
--no-imperial-units
Now you can call the application like this:
# These are the same given the default.
$ python3 file.py
$ python3 file.py --imperial-units
Or to do the negative version:
$ python3 file.py --no-imperial-units
If you really want to provide a string argument to the bool flag, then I would make a custom method to transform string to boolean:
import argparse
def bool_arg(val):
return val.lower() in ('y', 'yes', 't', 'true', 'on', '1')
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog='log-to-pickle')
parser.add_argument('--imperial-units', type=bool_arg, default=True)
args = parser.parse_args()
print(args.imperial_units)
Examples:
$ python3 file.py --imperial-units y
True
$ python3 file.py --imperial-units True
True
$ python3 file.py --imperial-units 0
False
ACCEPTED ANSWER
Score 4
There are a few wrong things here but the root cause is that the code doesn't use sys.argv correctly. Try printing sys.argv:
if __name__ == "__main__":
import sys
print(sys.argv)
$ python3 argv.py imperial_units=True ['argv.py', 'imperial_units=True']
You need to parse the command line arguments.
if __name__ == "__main__":
if len(sys.argv) <= 1 or sys.argv[1] == "imperial_units=True":
log_to_pickle(True)
else:
log_to_pickle(False)
Take a look at the argparse package for more robust command line argument handling.
ANSWER 3
Score 1
sys.argv provides a list of arguments. You can iterate through it to find an argument that contains "imperial_units". You can then process this to get the boolean.
if __name__ == "__main__":
#Find arguments which contain imperial_units
arg = [x.split("=")[1] for x in sys.argv if "imperial_units" in x]
#If the length is 0, no args were found, default to true
#Otherwise use value after = and convert it to bool
arg = True if len(arg) == 0 else bool(arg[0])
log_to_pickle(arg)
ANSWER 4
Score 1
argparse results in a more user-friendly program with help text and uses an arguably more standard method of dash-delimited parameters. Since you only want one thing, the unit of measure, I think it is best implemented with a choice flag that includes a default, but you could make a single argument such as --use-metric that defaults to False.
#!/usr/bin/env python3
import argparse
parser = argparse.ArgumentParser(description='CSV to Pickle with unit conversion to metric')
parser.add_argument('-u', '--unit', default='imperial', choices=['imperial', 'metric'],
help='Source unit type (imperial or metric)')
parser.add_argument('from_file', help="CSV file to convert")
parser.add_argument('to_file', help="Converted Pickle file")
args = parser.parse_args()
print(args.unit)
Options for using the program are
$ ./test.py --help
usage: test.py [-h] [-u {imperial,metric}] from_file to_file
CSV to Pickle with unit conversion to metric
positional arguments:
from_file CSV file to convert
to_file Converted Pickle file
optional arguments:
-h, --help show this help message and exit
-u {imperial,metric}, --unit {imperial,metric}
Source unit type (imperial or metric)
$ ./test.py --unit metric aaa.csv aaa.pkl
metric
$ ./test.py -u imperial aaa.csv aaa.plk
imperial
$ ./test.py aaa.csv aaa.pkl
imperial
$ ./test.py --unit=other aaa.csv aaa.pkl
usage: test.py [-h] [-u {imperial,metric}] from_file to_file
test.py: error: argument -u/--unit: invalid choice: 'other' (choose from 'imperial', 'metric')