-1

I am trying to write a programme to read and print the last n lines of a text file in python. My text file has 74 lines. I wrote a function like below to read the last n lines.

s=74 //Got this using another function, after enumerating the text file
n=5//

def readfile(x):
    print("The total number of lines in the file is",s)
    startline=(s-n)
    print("The last",n,"lines of the file are")
    with open(x,'r') as d:
        for i, l in enumerate(d):
            if (i>=startline):
                print(i)
                print(d.readline())`

My desired output is:

The total number of lines in the file is 74
The last 5 lines of the file are
69
Resources resembled forfeited no to zealously. 
70
Has procured daughter how friendly followed repeated who surprise. 
71
Great asked oh under on voice downs. 
72
Law together prospect kindness securing six. 
73
Learning why get hastened smallest cheerful.

But upon running, my output looks like

The total number of lines in the file is 74
69
Has procured daughter how friendly followed repeated who surprise. 

70
Law together prospect kindness securing six. 

71

The enumerated indexes are mismtached with lines and not all are printed. Also the loop is printing white spaces for indices 72 and 73.

if I comment out the following line on my function:

`#print(d.readline())`  

My output then becomes:

The total number of lines in the file is 74
The last 5 lines of the file are
69
70
71
72
73

The white spaces are gone and all indices are printed. I am not able to find out why certain indices and lines are not printed when print(d.readline()) is added to the function. And why the printed index and lines do not match.

zorbamj
  • 11
  • 9
  • `Reading n lines from end of text file using python`, those n lines will include lines with spaces or not? – Devesh Kumar Singh Jun 30 '19 at 15:43
  • Try reading the answers given [here](https://stackoverflow.com/questions/136168/get-last-n-lines-of-a-file-with-python-similar-to-tail) and [here](https://stackoverflow.com/questions/15647467/copy-the-last-three-lines-of-a-text-file-in-python) and [here](https://stackoverflow.com/questions/260273/most-efficient-way-to-search-the-last-x-lines-of-a-file-in-python) – Sheldore Jun 30 '19 at 15:47
  • Files are iterators in python. The for loop goes line by line, but `d.readline()` also reads in another line which causes you to skip lines. Just `print(l)`. – Mark Jun 30 '19 at 15:48
  • @DeveshKumarSingh did you mean if my file has emoty lines at the end? No. File terminates at the 74th line. – zorbamj Jun 30 '19 at 15:48
  • Why not show us how your file looks like, and what is the expected example for a given n – Devesh Kumar Singh Jun 30 '19 at 15:50
  • 1
    @MarkMeyer Thank You. It solved my issue. – zorbamj Jun 30 '19 at 15:51
  • @sheldore I have checked them now. But my issue was why my particular function was not working. As in why it was skipping lines. Mark Meyer has pointed out the issue with my code. – zorbamj Jun 30 '19 at 15:59

3 Answers3

0

You can do it right away, with readlines() and print(v):

n = 5

with open(x, 'r') as fp:

    lines = fp.readlines()
    total_length = len(lines)
    threshold = total_length - n

    for i, v in enumerate(lines): 
        if i >= threshold:
            print(i, v)
sashaboulouds
  • 1,566
  • 11
  • 16
0

You can use Python's readlines() function to read your file as a list of lines. You can then use len() to determine how many lines there are in the list that is returned:

n = 5

def readfile(x):
    with open(x) as f_input:
        lines = f_input.readlines()

    total_lines = len(lines)
    print(f"The total number of lines in the file is {total_lines}.")    
    print(f"The last {n} lines of the file are:")

    for line_number in range(total_lines-n, total_lines):
        print(f"{line_number+1}\n{lines[line_number]}",  end='')


readfile('input.txt')

You can also add an f as a prefix to your string, Python then interprets the string as containing variable names when enclosed with {} making is easier to format your text.

Martin Evans
  • 45,791
  • 17
  • 81
  • 97
0

It seems a little inefficient to be reading the file twice, but since you already did you can easily do what you want by using a collections.deque in the following manner:

from collections import deque


def print_last_lines(filename, linecount, n):

    # Get the last n lines of the file.
    with open(filename) as file:
        last_n_lines = deque(file, n)

    print("The total number of lines in the file is", linecount)
    print("The last", n, "lines of the file are:")

    for i, line in enumerate(last_n_lines, 1):
        print(linecount-n+i)
        print(line, end='')


filename = 'lastlines.txt'
n = 5

# Count lines in file.
with open(filename) as file:
    linecount = len(list(file))

print_last_lines(filename, linecount, n)
martineau
  • 119,623
  • 25
  • 170
  • 301