1

Here is the problem. I have names.txt file. The contents of this file as follows. The question asks to display to numbers of names in this file. I could do with while loop. It works, no problem. But for some reason, if I wanted to do this with for loop it gives me wrong number of names.

    Julia Roberts 
    Michael Scott
    Kevin Malone
    Jim Halpert
    Pam Halpert
    Dwight Schrute

This is the while loop. It runs perfect.

def main():
    try:
        # open the names.txt file in read mode.
        infile=open("names.txt", "r")

        # set an accumulator for number of names
        numbers_of_name=0.0

        # read the first line
        line=infile.readline()

        # read the rest of the file
        while line!="":
            numbers_of_name+=1
            line=infile.readline()

        # print the numbers of names in the names.txt file.    
        print("There are", int(numbers_of_name), "names in the names.txt file.")

        # close the file
        infile.close()
    except IOError as err:
        print (err) 

# call the main function
main()

The console gives me correct answer.

There are 6 names in the names.txt file.

And this is my problematic for loop

def main():
    try:
        # open the names.txt file in read mode.
        infile=open("names.txt", "r")

        # set an accumulator for number of names
        numbers_of_name=0.0

        # read the rest of the file
        for line in infile:
            line=infile.readline()
            numbers_of_name+=1

        # print the numbers of names in the names.txt file.    
        print("There are ", numbers_of_name, "names in the names.txt file.")

        # close the file
        infile.close()
    except IOError as err:
        print (err) 

# call the main function
main()

And this is the output.

There are  3.0 names in the names.txt file. 

There should be 6 names not 3 names.:

What might be missing part in this file reading code? Thanks in advance.

1
  • The Infile file objects already has the content and each line of the content is taken as a list element as they are newline seperated. Commented Jan 7, 2019 at 7:26

4 Answers 4

6

The problem is you are reading two lines in each iteration, when you do:

for line in infile:

line is the first line in the file, when you do:

line.readline()

Then line is now the second line, and then you add one two you name count

You should do:

for line in infile:
    numbers_of_name+=1
Sign up to request clarification or add additional context in comments.

1 Comment

It worked. Thanks a lot. I was not aware of that it was double reading. Thanks a lot.
2

The problem lies with this section

# read the rest of the file
for line in infile:
    line=infile.readline()
    numbers_of_name+=1

If you do a sectional print, you will see why:

# read the rest of the file
for i, line in enumerate(infile):
    print (i, line)
    line=infile.readline()
    print (i, line)
    numbers_of_name+=1

By doing line=infile.readline(), you are changing the value of line in the for loop and altering it for subsequent loop passthrough

1 Comment

Ok now I see. So, basically for line in file already reads the file. Thanks for print functions to make it visible to me. I got it now.
2
# Initialise count
count = 0
with open('bar.py', 'r') as fd:
  # Strip newline char and and any leading/trailing spaces
  lines = map(lambda x: x.strip(), fd.readlines())

  # Strip empty lines
  lines = filter(lambda x: x, lines)

  # Get the count
  count = len(lines)
print "Count: ", count

Note: With map and filter being used, we're iterating over the list twice. An efficient implementation (for a large list) would be to iterate over the elements just once and apply conditions to eliminate unwanted entries - empty lines, lines starting with #, etc.

2 Comments

Thanks. Probably this is an advanced solution. I am beginner to Python. I am not aware of yet this lambda. But thanks though. I appreciate it much.
Python lambda are unnamed functions - typically one-liners. More at w3schools.com/python/python_lambda.asp
1

This one line will achieve what you're trying to do with all that code:

len(open("names.txt", "r").readlines())

A loop is not required for the purpose of counting the number of lines.

3 Comments

This is not the reason why the questioner asked the question. He is well aware of what works, he's asking why his for loop does not work
Hmm. That worked also. I am going chapter by chapter in my book "Tony Gaddis - Starting out with Python 3rd Edition". Didn't arrive in len function yet. Maybe it is in "Lists" chapter. Thanks this worked also.
@ycx The questioner has not indicated that they're aware of what works. Their end goal is : "The question asks to display to numbers of names in this file". If the question stated that only for loops are to be used, then it would make sense to restrict answers to that only.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.