Reputation: 317
I wrote a function in python which takes 2 lists
(with the same length) and returns another list with 2 elements. the function works perfectly but I am trying to run the python script in command line
. to do so, I want to use argparse
module in python. I wrote the following script in python3 using the following command:
python3 text.py a b results
the script should take 3 arguments 2 lists as input and one list as output. here is the script:
def fun(a, b):
a_is_greater = 0
b_is_greater = 0
for element_a, element_b in zip(a, b):
if element_a > element_b:
a_is_greater += 1
elif element_a < element_b:
b_is_greater += 1
return [a_is_greater, b_is_greater]
def main():
import argparse
ap = argparse.ArgumentParser(description="")
ap.add_argument('--list-type', type=list)
ap.add_argument('--list-type', type=list)
ap.add_argument('-o', '--outlist', required=True)
args = ap.parse_args()
results = fun(a, b)
return results
if __name__ == "__main__":
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)
try:
main()
except IOError as e:
if e.errno != 32:
raise
except KeyboardInterrupt as e:
pass
do you know how to fix it? I have tried these 2 lists: a = [4, 5, 2]
and b = [3, 5, 4]
. fun function in the script works perfectly for these 2 inputs.
Upvotes: 0
Views: 181
Reputation: 231385
With the corrected code using type=list
, sys.argv
and args
display as:
1353:~/mypy$ python3 stack56531390.py --list1 [4,5,2] --list2 [3,5,4] -o result
['stack56531390.py', '--list1', '[4,5,2]', '--list2', '[3,5,4]', '-o', 'result']
Namespace(list1=['[', '4', ',', '5', ',', '2', ']'], list2=['[', '3', ',', '5', ',', '4', ']'], outlist='result')
[1, 1]
Note that the 'lists' come in as strings. The list
function splits that string into a list of characters.
In [607]: list('astring')
Out[607]: ['a', 's', 't', 'r', 'i', 'n', 'g']
The fact that fun
works for these inputs is more a coincidence, not by design. The inputs don't match the tested: a = [4, 5, 2]' and 'b = [3, 5, 4]
.
Look at what happens if the user puts spaces in the lists:
1355:~/mypy$ python3 stack56531390.py --list1 [4, 5, 2] --list2 [3,5,4] -o result
usage: stack56531390.py [-h] [--list1 LIST1] [--list2 LIST2] -o OUTLIST
stack56531390.py: error: unrecognized arguments: 5, 2]
or quotes to keep the spaced lists together:
1357:~/mypy$ python3 stack56531390.py --list1 "[4, 5, 2]" --list2 [3,5,4] -o result
['stack56531390.py', '--list1', '[4, 5, 2]', '--list2', '[3,5,4]', '-o', 'result']
Namespace(list1=['[', '4', ',', ' ', '5', ',', ' ', '2', ']'], list2=['[', '3', ',', '5', ',', '4', ']'], outlist='result')
[2, 3]
So while type=list
can be made to work, it usually isn't a good choice. Remember, the argparse type
is a function that is given a string; it's not a type or class specifier.
If I change the two arguments to take *
inputs of type int:
ap.add_argument('--list1', nargs='*', type=int)
ap.add_argument('--list2', nargs='*', type=int)
1358:~/mypy$ python3 stack56531390.py --list1 4 5 2 --list2 3 5 4 -o result
['stack56531390.py', '--list1', '4', '5', '2', '--list2', '3', '5', '4', '-o', 'result']
Namespace(list1=[4, 5, 2], list2=[3, 5, 4], outlist='result')
[1, 1]
Now the two inputs are normal lists of integers, not those lists of characters that include brackets and commas. The comparison will be numeric, not lexical.
Upvotes: 0
Reputation: 369
Is this better?
python3 text.py --list1 [4,5,2] --list2 [3,5,4] -o result # [1, 1]
def main():
import argparse
ap = argparse.ArgumentParser(description="")
ap.add_argument('--list1', type=list)
ap.add_argument('--list2', type=list)
ap.add_argument('-o', '--outlist', required=True)
args = ap.parse_args()
results = fun(args.list1, args.list2)
print(results)
return results
Code :
def fun(a, b):
a_is_greater = 0
b_is_greater = 0
for element_a, element_b in zip(a, b):
if element_a > element_b:
a_is_greater += 1
elif element_a < element_b:
b_is_greater += 1
return [a_is_greater, b_is_greater]
def main():
import argparse
ap = argparse.ArgumentParser(description="")
ap.add_argument('--list1', type=list)
ap.add_argument('--list2', type=list)
ap.add_argument('-o', '--outlist', required=True)
args = ap.parse_args()
results = fun(args.list1, args.list2)
print(results)
return results
if __name__ == "__main__":
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)
try:
main()
except IOError as e:
if e.errno != 32:
raise
except KeyboardInterrupt as e:
pass
Upvotes: 1