0

I am trying to run the following code from a coding book I have but I get this error:

Traceback (most recent call last): File "ex20.py", line 3, in script, input_file = argv ValueError: need more than 1 value to unpack

I have created a txt file called input_file and tried other troubleshooting methods but I continue to get errors.

from sys import argv

script, input_file = argv

def print_all(f):
        print f.read()

def rewind(f):
    f.seek(0)

def print_a_line(line_count, f):
    print line_count, f.readline()

current_line = open(input_file)

print "First let's print the whole file:\n"

print_all(current_file)

print("Now lets rewind, kind of like a tape")

current_line = 1
print_a_line(current_line, current_line)

current_line = current_line + 1
print_a_line(current_line, current_file)

I expect it to print and work as coded.

Praveenkumar
  • 2,056
  • 1
  • 9
  • 18
Stalin
  • 17
  • 5
  • Was the `input_file` provided as command line param? Please check. – Praveenkumar Jun 03 '19 at 09:59
  • How did you run the script? What arguments did you pass to it? – Gino Mempin Jun 03 '19 at 09:59
  • Why are you setting the script, and the input_file to the package you just imported? - I mean argv comes back with a list you need to define what you set to what... script, input_file = argv[0], argv[1] – Anna Semjén Jun 03 '19 at 10:03
  • I am assuming the script is the code its self and the input_file is a text file int he same file that has the code/.py script. I Am running it via terminal aka "python ex20.py", I am setting it because that is what the book told me to do. – Stalin Jun 03 '19 at 10:07
  • bash-4.3$ python ex20.py input_file.txt First let's print the whole file: Traceback (most recent call last): File "ex20.py", line 18, in print_all(current_file) NameError: name 'current_file' is not defined I am using python 2 and this is the error I get when attempting to provide the two parameters. – Stalin Jun 04 '19 at 02:02

3 Answers3

1
script, input_file = argv

According to [Python 3.Docs]: sys.argv:

The list of command line arguments passed to a Python script.

So, regardless an argument was passed or not to the script (or if a script was passed to the interpreter), it's always a list (sequence).

Since on the left side you have 2 variables (script and input_file), the list should also contain 2 elements (according to error text yours only contains one - meaning that no argument was given to the script).

Behind the scenes, [Python 3.Docs]: More Control Flow Tools - Unpacking Argument Lists happens.

A common way of dealing with this kind of situation, is checking how many elements are in the list:

if len(argv) != 2:
    raise SystemExit("Script should receive exactly one argument!")

Make sure to also pass a value for your input file, when you invoke the interpreter (your script) from cmdline.

@EDIT0:

Technically, this is beyond the (original) question scope.

The code contains a bunch of nonsense parts (mainly because confusing current_file and current_line - which denotes bad naming). I'm not going to insist on them, but paste the code as it should look like:

import sys


def print_all(f):
    print(f.read())


def rewind(f):
    f.seek(0)


def print_a_line(line_number, f):
    print(line_number, f.readline())


_, input_file_name = sys.argv

input_file = open(input_file_name)

print("First, let's print the whole file:\n")
print_all(input_file)
print("Now lets rewind, kind of like a tape:\n")
rewind(input_file)
current_line = 1
print_a_line(current_line, input_file)
current_line += 1
print_a_line(current_line, input_file)

Note that although you mentioned using Python 2, prints will also work in Python 3.

CristiFati
  • 38,250
  • 9
  • 50
  • 87
  • I am using python2, I get this error when I provide the 2 parameters requested: bash-4.3$ python ex20.py input_file.txt First let's print the whole file: Traceback (most recent call last): File "ex20.py", line 18, in print_all(current_file) NameError: name 'current_file' is not defined – Stalin Jun 04 '19 at 02:02
  • Not really but I was reading a python2.7 book and decided to ditch it because 3.xx is the modern version. No use in learning 2.7 when I could learn 3.xx and just "reverse learn" any code I may have to patch up or what ever the case may be in the future. – Stalin Jun 12 '19 at 23:47
  • Note that you don't have to accept an answer unless it solves your problem. Hmm, what didn't work? Let me know so I can modify (improve) the answer. Anyway (the code I posted) it should work on both *Python 3* and 2 (as it solved the problem in the question and several others). – CristiFati Jun 13 '19 at 04:51
0

This error means that argv did not have "enough values to unpack", i.e. you tried to assign script and input_file from the argv variable by doing what is called destructuring, but argv had only one value (the name of the script)

It seems you ran your script without supplying an argument (the input_file). You should run your script in the following way:

python ex20.py 'path/to/input_file'
mikaël
  • 453
  • 3
  • 8
0

The problem occur when you have, not surprisingly "more than 1 value to unpack", meaning that argv is smaller then the number of variables you want to assign to.

you should make sure your argv length is exactly 2 if you want your line of code to work, or just access the argv values through argv without the assignment, but, if you do want to keep it as is i suggest a quick test before :

if len(argv) != 2:
    exit()

and the rest of your code afterward. but you need to remember to run your code with the appropriate amount of args' like so:

python <your_script_file>.py arg1

in that way replace arg1 with the value you want to be assign to input_file, since argv[0] is always the name of the script/file you are running.

IMHO you should use a lib like argumentParser or something like that.

ddor254
  • 1,570
  • 1
  • 12
  • 28