Search code examples
pythonpython-2.7argv

Why does argv not work with my function?


So here is my code

from sys import argv

a,b = argv

def gcd(a,b):
    while a:
        a,b = b%a, a
    print b

Now if I run it from the command line with this

python euclidian_algorithm.py 40, 48

I get this error

Traceback (most recent call last):
File "euclidian_algorithm.py", line 3, in <module>
a,b = argv
ValueError: too many values to unpack

However if I then remove the space between the two inputs, like so

python euclidian_algorithm.py 40,48

I then get no output at all.

Now firstly I do not understand how there are too many values to unpack, when I have only put two arguments. Secondly, why do I get no output in the second case?


Solution

  • Quoting sys.argv documentation,

    The list of command line arguments passed to a Python script. argv[0] is the script name (it is operating system dependent whether this is a full pathname or not).

    So, argv's first value will be the current script name. In the first case, you are trying to unpack three values on to two variables. That is why it fails.

    In the second case, you are assigning the current script name to a and 48,40 to b.

    You can confirm this by printing argv, a and b, like this

    ➜  Desktop  cat Test.py
    from sys import argv
    
    print argv
    a, b = argv
    print a, b
    
    
    def gcd(a, b):
        while a:
            a, b = b % a, a
        print b
    ➜  Desktop  python Test.py 40, 48
    ['Test.py', '40,', '48']           # Note that argv has three items and first is the file name
    Traceback (most recent call last):
      File "Test.py", line 4, in <module>
        a, b = argv
    ValueError: too many values to unpack
    ➜  Desktop  python Test.py 40,48 
    ['Test.py', '40,48']
    Test.py 40,48
    

    Secondly, why do I get no output in the second case?

    That is because, the function gcd is not invoked at all.


    To fix this, as you are expecting only two items, I would simply assign them like this

    a = int(argv[1])
    b = int(argv[2])
    

    and then invoke the function, like this

    gcd(a, b)
    

    we need to convert the values to integers as the arguments will be strings.

    Note: Also, the arguments being passed need to be separated with white space characters, not comma. So, you would execute the program like this

    from sys import argv
    
    def gcd(a, b):
        while a:
            a, b = b % a, a
        print b
    
    a = int(argv[1])
    b = int(argv[2])
    
    gcd(a, b)
    
    ➜  Desktop  python Test.py 40 48
    8