Kristie
Kristie

Reputation: 241

Run python program from command line and specify arguments

I have a document that defines several functions (assignment_2a.py). I'm trying to achieve the following:

Modify the [assignment_2a.py](../code/assignment_2a.py) to be able to run
the program `make_random_story` from the command line:

```
$ python assignment_2a.py '../data/alice.txt' 2 200
```

I know how to run this specified function by going into ipython, and it works fine. But how do I alter the document so I can run it from the command line using the above command, i.e., specifying the input variables in that format?

UPDATE: I updated the function as suggested in the comments and am getting the following error message:

COMMAND LINE INPUT:
python assignment_2a.py '../data/alice.txt' 2 200

COMMAND LINE OUTPUT:
Traceback (most recent call last):
File "assignment_2a.py", line 202, in <module>
make_random_story(*sys.argv[1:])
File "assignment_2a.py", line 189, in make_random_story
for i in xrange(0,num_words):
TypeError: an integer is required

And here's the relevant updated function text:

def make_random_story(f, n_gram=2, num_words=200):
    f = open(f)
    random.seed('Is the looking-glass is half full or half-empty?')
    story = ''
    if n_gram==1:
        d = associated_unigrams(f)
    elif n_gram==2:
        d = associated_bigrams(f)
    elif n_gram==3:
        d = associated_trigrams(f)
    for i in xrange(0,num_words):
        chosenkey = random.choice(d.keys())
        story += random.choice(d[chosenkey]) + " "
    print story
    f.close()

if __name__ == '__main__':
    make_random_story(*sys.argv[1:])

Upvotes: 2

Views: 364

Answers (3)

ffledgling
ffledgling

Reputation: 12170

As pointed out by others (and yourself) you need to use sys.argv.

Here's how your main() function needs to look like:

if __name__ == '__main__':
    f = sys.argv[1]
    n_gram = sys.argv[2]
    num_words = sys.argv[3]

    make_random_story(f, n_gram=n_gram, num_words=num_words)

This forces you to type out all 3 arguments every time you make the call to make_random_story. This is a bit more explicit and allows you to tack on sanity checking for the arguments if required. I'd also argue it's a tad easier to read, but is also more cumbersome to call.

See @Alex Hall's answer for more flexibility.

Upvotes: 0

Arpit Solanki
Arpit Solanki

Reputation: 9931

Use sys.argv it's very simple. Don't specify sys.argv[0] it's script's name.

make_random_story(sys.argv[1])

A better suggestion include use of native module argparse

import argparse 
parser =  argparse.ArgumentParser()
parser.add_argument('--foo', help='foo help') 
args = vars(parser.parse_args())
foo_param = args['foo'] #args is a dict and any Param can be accessed using the key

Upvotes: 1

Alex Hall
Alex Hall

Reputation: 36043

In your case it's very simple. Here's how you could use the fact that n_gram and num_words are optional, but they still have to be specified in order as positional arguments:

if __name__ == '__main__':
    make_random_story(*sys.argv[1:])

So all the following would be the same:

python assignment_2a.py '../data/alice.txt'
python assignment_2a.py '../data/alice.txt' 2
python assignment_2a.py '../data/alice.txt' 2 200

And having more or fewer arguments will raise an error.

Upvotes: 2

Related Questions