Question

I'm trying to use the str.find() and it keeps raising an error, what am I doing wrong?

import codecs

    def countLOC(inFile):
        """ Receives a file and then returns the amount
            of actual lines of code by not counting commented
            or blank lines """

        LOC = 0  
        for line in inFile:
            if line.isspace():
                continue
            comment = line.find('#')
            if comment > 0:
                for letter in range(comment):
                    if not letter.whitespace:
                        LOC += 1
                        break            
        return LOC

    if __name__ == "__main__":
        while True:
            file_loc = input("Enter the file name: ").strip()
            try:
                source = codecs.open(file_loc)
            except:
                print ("**Invalid filename**")
            else:
                break 
        LOC_count = countLOC(source)

        print ("\nThere were {0} lines of code in {1}".format(LOC_count,source.name))

Error

  File "C:\Users\Justen-san\Documents\Eclipse Workspace\countLOC\src\root\nested\linesOfCode.py", line 12, in countLOC
        comment = line.find('#')
    TypeError: expected an object with the buffer interface
Was it helpful?

Solution

Use the built-in function open() instead of codecs.open().

You're running afoul of the difference between non-Unicode (Python 3 bytes, Python 2 str) and Unicode (Python 3 str, Python 2 unicode) string types. Python 3 won't convert automatically between non-Unicode and Unicode like Python 2 will. Using codecs.open() without an encoding parameter returns an object which yields bytes when you read from it.

Also, your countLOC function won't work:

for letter in range(comment):
    if not letter.whitespace:
        LOC += 1
        break            

That for loop will iterate over the numbers from zero to one less than the position of '#' in the string (letter = 0, 1, 2...); whitespace isn't a method of integers, and even if it were, you're not calling it.

Also, you're never incrementing LOC if the line doesn't contain #.

A "fixed" but otherwise faithful (and inefficient) version of your countLOC:

def countLOC(inFile):
    LOC = 0  
    for line in inFile:
        if line.isspace():
            continue
        comment = line.find('#')
        if comment > 0:
            for letter in line[:comment]:
                if not letter.isspace():
                    LOC += 1
                    break
        else:
            LOC += 1
    return LOC

How I might write the function:

def count_LOC(in_file):
    loc = 0  
    for line in in_file:
        line = line.lstrip()
        if len(line) > 0 and not line.startswith('#'):
            loc += 1
    return loc

OTHER TIPS

Are you actually passing an open file to the function? Maybe try printing type(file) and type(line), as there's something fishy here -- with an open file as the argument, I just can't reproduce your problem! (There are other bugs in your code but none that would cause that exception). Oh btw, as best practice, DON'T use names of builtins, such as file, for your own purposes -- that causes incredible amounts of confusion!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top