-1

How would I go about getting the first N lines of a text file in python? With N have to give as argument

usage:

python file.py datafile -N 10

My code

import sys
from itertools import islice

args = sys.argv
print (args)
if args[1] == '-h':
    print ("-N for printing the number of lines: python file.py datafile -N 10")

if args[-2] == '-N':
    datafile = args[1]
    number = int(args[-1])
    with open(datafile) as myfile:
        head = list(islice(myfile, number))
        head = [item.strip() for item in head]

        print (head)
        print ('\n'.join(head))

I wrote the program, can let me know better than this code

3 Answers3

2

Assuming that the print_head logic you've implemented need not be altered, here's the script I think you're looking for:

import sys
from itertools import islice

def print_head(file, n):
    if not file or not n:
        return

    with open(file) as myfile:
        head = [item.strip() for item in islice(myfile, n)]

    print(head)

def parse_args():
    result = {'script': sys.argv[0]}
    args = iter(sys.argv)
    for arg in args:
        if arg == '-F':
            result['filename'] = next(args)

        if arg == '-N':
            result['num_lines'] = int(next(args))

    return result

if __name__ == '__main__':
    script_args = parse_args()
    print_head(script_args.get('filename', ''), script_args.get('num_lines', 0))

Running the script

python file.py -F datafile -N 10

Note: The best way to implement it would be to use argparse library

  • Error throwing result['filename'] = args.next() AttributeError: 'list_iterator' object has no attribute 'next' –  Jul 24 '19 at 11:24
  • result['filename'] = args.next() AttributeError: 'list_iterator' object has no attribute 'next' –  Jul 24 '19 at 11:43
  • @Mous My bad, the code was not python3 compatible. I've fixed it now. – Vignesh Bayari R. Jul 24 '19 at 11:59
  • head = [next(myfile) for x in range(n)] StopIteration I have changed xrange also and from the below comment I came to know that head does not check for EOF. –  Jul 24 '19 at 13:46
  • @Mous You're right, as I had mentioned, I had not looked into the head logic. I've made the necessary changes in my code now. – Vignesh Bayari R. Jul 25 '19 at 06:42
0

You can access argument passed to the script through sys

sys.argv
The list of command line arguments passed to a Python script. argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string.

So in code it would look like this:

import sys

print("All of argv")
print(sys.argv)
print("Last element every time")
print(sys.argv[-1])

Reading the documentation you'll see that the first values stored in the sys.argv vary according to how the user calls the script. If you print the code I pasted with different types of calls you can see for yourself the kind of values stored.

For a basic first approach: access n through sys.argv[-1] which returns the last element every time, assuming. You still have to do a try and beg for forgiveness to make sure the argument passed is a number. For that you would have:

import sys

try:
    n = int(sys.argv[-1])
except ValueError as v_e:
    print(f"Please pass a valid number as argument, not ${sys.argv[-1]}")

That's pretty much it. Obviously, it's quite basic, you can improve this even more by having the users pass values with flags, like --skip-lines 10 and that would be your n, and it could be in any place when executing the script. I'd create a function in charge of translating sys.argv into a key,value dictionary for easy access within the script.

Chayemor
  • 3,577
  • 4
  • 31
  • 54
-1

Arguments are available via the sys package.


Example 1: ./file.py datafile 10

#!/usr/bin/env python3

import sys

myfile = sys.argv[1]
N = int(sys.argv[2])

with open("datafile") as myfile:
    head = myfile.readlines()[0:args.N]
print(head)

Example 2: ./file.py datafile --N 10

If you want to pass multiple optional arguments you should have a look at the argparse package.

#!/usr/bin/env python3

import argparse

parser = argparse.ArgumentParser(description='Read head of file.')
parser.add_argument('file', help='Textfile to read')
parser.add_argument('--N', type=int, default=10, help='Number of lines to read')

args = parser.parse_args()
with open(args.file) as myfile:
    head = myfile.readlines()[0:args.N]
print(head)
Simpl
  • 1,938
  • 1
  • 10
  • 21
  • head = [next(myfile) for x in range(N)] error throwing > StopIteration –  Jul 24 '19 at 09:04
  • i have changed range to xrange also –  Jul 24 '19 at 09:07
  • even I execute with python3.7 file1.py datafile --N 10. still same error –  Jul 24 '19 at 10:06
  • That's because `[next(myfile) for x in range(N)]` does not check for EOF. I changed it to `myfile.readlines()[0:args.N]` – Simpl Jul 24 '19 at 11:11