views:

186

answers:

5

I can't see why this won't work. I am performing lstrip() on the string being passed to the function, and trying to see if it starts with """. For some reason, it gets caught in an infinite loop

def find_comment(infile, line):

    line_t = line.lstrip()
    if not line_t.startswith('"""') and not line_t.startswith('#'):
        print (line, end = '')
        return line

    elif line.lstrip().startswith('"""'):
            while True:
                if line.rstrip().endswith('"""'):
                    line = infile.readline()
                    find_comment(infile, line)
                else:
                    line = infile.readline()
    else:
        line = infile.readline()
        find_comment(infile, line)

And my output:

Enter the file name: test.txt
import re
def count_loc(infile):

Here is the top of the file i am reading in for reference:

    import re

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

        loc = 0
        func_records = {}
        for line in infile:
        (...)
+1  A: 
not line_t.startswith('"""') or not line_t.startswith('#')

This expression evaluates to True no matter what string line_t denotes. Do you want 'and' instead of 'or'? Your question isn't clear to me.

Darius Bacon
woops, yeah I changed that, but it gets stuck in an infinite loop at the while statement posted above. I updated my original post to reflect this
Justen
+1  A: 
if not line_t.startswith('"""') or not line_t.startswith('#'):

This if will always be satisfied -- either the line doesn't start with """, or it doesn't start with # (or both). You probably meant to use and where you used or.

Alex Martelli
yeah, that's right, however I now get stuck in the infinite while loop. But I don't know why, any insight from the source given? I updated my original post to reflect this
Justen
Maybe because your while loop says "while True" and you don't break. Just a wild guess...
Matthew Flaschen
+2  A: 

while True is an infinite loop. You need to break once you're done.

Roberto Bonvallet
+3  A: 

You haven't provided and exit path from the recursive loop. A return statement should do the trick.

    (...)
    while True:
        if line.rstrip().endswith('"""'):
            line = infile.readline()
            return find_comment(infile, line)
        else:
            line = infile.readline()
Chirayu Patel
O man, I can't believe I forgot that. For some reason i thought that calling the function again would break the loop. Thanks a lot!
Justen
+1  A: 

As long as lines start or end with a comment, the code below should work.

However, keep in mind that the docstrings can start or end in the middle of a line of code.

Also, you'll need to code for triple single-quotes as well as docstrings assigned to variables which aren't really comments.

Does this get you closer to an answer?

def count_loc(infile):
  skipping_comments = False
  loc = 0 
  for line in infile:
    # Skip one-liners
    if line.strip().startswith("#"): continue
    # Toggle multi-line comment finder: on and off
    if line.strip().startswith('"""'):
      skipping_comments = not skipping_comments
    if line.strip().endswith('"""'):
      skipping_comments = not skipping_comments
      continue
    if skipping_comments: continue
    print line,
tom
Ah I forgot about the triple single quotes. This project is actually for my C++ class, but I've been trying to teach myself python at the same time and decided to the project twice. Thanks for the code, all I needed was that return statement out of the while loop.
Justen