4

I have a working code to print random lines from a csv column.

#!/usr/bin/python

import csv
from random import shuffle

filename = 'example.csv'
col = 2
sample = 100

with open(filename, 'r') as f:
    reader = csv.reader(f)
    data = [row[col] for row in reader]
    shuffle(data)
    print '\n'.join(data[:sample])

How can I parameterize this script by passing filename, col & sample (e.g. 100 values)?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
sumoka
  • 117
  • 1
  • 2
  • 12
  • 1
    possible duplicate of [Command Line Arguments In Python](http://stackoverflow.com/questions/1009860/command-line-arguments-in-python) – l4mpi Apr 03 '14 at 19:55

3 Answers3

12

You can use the sys module like this to pass command line arguments to your Python script.

import sys

name_of_script = sys.argv[0]
position = sys.argv[1]
sample = sys.argv[2]

and then your command line would be...

./myscript.py 10 100
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Genome
  • 1,106
  • 8
  • 10
12

Use argparse module:

The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.

It's pretty powerful: you can specify help messages, make validations, provide defaults..whatever you can imagine about working with command-line arguments.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-p", "--position", type=int)
parser.add_argument("-s", "--sample", type=int)

args = parser.parse_args()
col = args.position
sample = args.sample

print col
print sample

Here's what on the command-line:

$ python test.py --help
usage: test.py [-h] [-p POSITION] [-s SAMPLE]

optional arguments:
  -h, --help            show this help message and exit
  -p POSITION, --position POSITION
  -s SAMPLE, --sample SAMPLE

$ python test.py -p 10 -s 100
10
100
$ python test.py --position 10 --sample 100
10
100

Speaking about the code you've provided:

  • unused import random statement
  • move from random import shuffle to the top of the script
  • no need to call f.close() (especially with ;) - with handles closing the file automagically

Here's how the code would look like after the fixes:

#!/usr/bin/python
import argparse
import csv
from random import shuffle


parser = argparse.ArgumentParser()
parser.add_argument("-p", "--position", type=int)
parser.add_argument("-s", "--sample", type=int)

args = parser.parse_args()

with open('<filename>', 'r') as f:
    reader = csv.reader(f)
    data = [row[args.position] for row in reader]
    shuffle(data)
    print '\n'.join(data[:args.sample])
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks alecxe. Unfortunately 2.6.6 doesn't have argparse module. is there any other way I like this style of storing & parsing variables. – sumoka Apr 03 '14 at 19:34
  • @sumoka sure, install it from PyPi: http://stackoverflow.com/questions/15330175/how-can-i-get-argparse-in-python-2-6 – alecxe Apr 03 '14 at 19:37
0

I could not install argparse due to lack of permission - meanwhile.

Here's the solution:

#!/usr/bin/python

import csv   # This will help us reading csv formated files.
import sys
import optparse #import optparse

from random import shuffle

parser=optparse.OptionParser()

# import options

parser.add_option('-f','--filename',help='Pass the csv filename')
parser.add_option('-p','--position',help='column position in the file',type=int)
parser.add_option('-s','--sample',help='sample size',type=int)

(opts,args) = parser.parse_args() # instantiate parser


# Program to select random values

with open('<filepath>'+opts.filename,'r') as f:
        reader=csv.reader(f)
        data=[row[opts.position] for row in reader]

        shuffle(data)

        #print '\n'.join(data[:opts.sample])

# create o/p file
file=open("<opfilename>.txt","w")
file.write('\n'.join(data[:opts.sample]))
file.close()
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
sumoka
  • 117
  • 1
  • 2
  • 12