Ivic
Ivic

Reputation: 69

How to implement command line switches to my script?

I am a total newbie in python. I am writing a program that counts words, lines and characters. I started to have problems when I tried to use command line switches: -w, -l, -c, till then everything worked fine.

I read the posts on stackoverflow and python documentation about argparse but I don't now how to implement the argparse library and the code which is used with it.

When I run python wc.py file.txt --l

I get

too many values to unpac

Can someone please help me with this?

from sys import argv
import os.path
import argparse

script, filename = argv


def word_count(filename):
    my_file = open(filename)
    counter = 0
    for x in my_file.read().split():
        counter += 1
    return counter
    my_file.close()

def line_count(filename):
    my_file = open(filename, 'r').read()
    return len(my_file.splitlines())
    my_file.close()

def character_count(filename):
    my_file = open(filename, 'r').read()
    return len(my_file)
    my_file.close()

parser = argparse.ArgumentParser()
parser.add_argument('--w', nargs='+', help='word help')
parser.add_argument('--l', nargs='+', help='line help')
parser.add_argument('--c', nargs='+', help='character help')
args = parser.parse_args()


if os.path.exists(filename):
    print word_count(filename), line_count(filename), character_count(filename)
else:
   print "There is no such file"

Upvotes: 2

Views: 5668

Answers (1)

larsks
larsks

Reputation: 311426

If you're using argparse for argument parsing, you shouldn't be trying to parse argv yourself:

script, filename = argv

This is going to fail if argv has less than two elements:

Traceback (most recent call last):
  File "wc.py", line 5, in <module>
    script, filename = argv
ValueError: need more than 1 value to unpack

Or if it has more than two elements:

Traceback (most recent call last):
  File "wc.py", line 5, in <module>
    script, filename = argv
ValueError: too many values to unpack

You instead want to use argparse to extract the filename from the argument list:

parser.add_argument('filename')

Your existing command line arguments could also use some fixing. Instead of this:

parser.add_argument('--w', nargs='+', help='word help')

You want:

parser.add_argument('-w', action='store_true', help='word help')

This gives you a boolean option such that if the user passes -w then args.w will be True, otherwise None. This gives you:

parser = argparse.ArgumentParser()

parser.add_argument('-w', action='store_true')
parser.add_argument('-c', action='store_true')
parser.add_argument('-l', action='store_true')
parser.add_argument('filename')
args = parser.parse_args()


if os.path.exists(args.filename):
    print word_count(args.filename), line_count(args.filename), character_count(args.filename)
else:
   print "There is no such file"

You may also want to give your options long equivalents:

parser.add_argument('--words', '-w', action='store_true')
parser.add_argument('--characters', '-c', action='store_true')
parser.add_argument('--lines', '-l', action='store_true')

With this change, users can use either -w or --words, for example. You will then have args.words, args.characters, and args.lines (instead of args.w, args.c, args.l).

Upvotes: 6

Related Questions