Stalin
Stalin

Reputation: 17

Error related to input file, ValueError: need more than 1 value to unpack

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.

Upvotes: 0

Views: 493

Answers (3)

CristiFati
CristiFati

Reputation: 41206

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.

Upvotes: 1

ddor254
ddor254

Reputation: 1638

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.

Upvotes: 0

mika&#235;l
mika&#235;l

Reputation: 463

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'

Upvotes: 0

Related Questions