Skip to content

Instantly share code, notes, and snippets.

@rplzzz
Forked from quandyfactory/pyloc.py
Last active August 29, 2015 14:22
Show Gist options
  • Save rplzzz/75dab0bc8d8e62982d5e to your computer and use it in GitHub Desktop.
Save rplzzz/75dab0bc8d8e62982d5e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# coding: utf-8
"""
Calculates total, nonblank and net lines of code for Python scripts.
"""
import os
import re
def get_line_count(blob):
"""Returns the number of lines of code"""
return len(blob.split('\n'))
docstring_pattern = re.compile(r'\n\s*"""([^"]|"(?!""))*"""')
def strip_docstring(blob):
"""Removes docstrings from code"""
docstring = True
while docstring == True:
match_docstring = docstring_pattern.search(blob)
if not match_docstring:
docstring = False
else:
blob = blob.replace(blob[match_docstring.span()[0]:match_docstring.span()[1]], '')
return blob
def strip_blanklines(blob):
"""Strips blank lines from the code"""
lines = blob.split('\n')
return '\n'.join([line for line in lines if line.strip() != ''])
def strip_comments(blob, delim='#'):
"""Strips comments from the code"""
lines = blob.split('\n')
return '\n'.join([line for line in lines if line.strip()[0] != delim])
def loc(blob, delim='#'):
"""Returns the total line count, nonblank line count, and net line count excluding comments and docstrings"""
total = get_line_count(blob)
blob = strip_blanklines(blob)
nonblank = get_line_count(blob)
blob = strip_docstring(blob)
blob = strip_comments(blob, delim)
net = get_line_count(blob)
return { 'total': total, 'nonblank': nonblank, 'net': net }
def get_folder_total(path):
"""Returns the total, nonblank and net loc for all the python files in a directory"""
files = os.listdir(path)
pythonfiles = ['%s/%s' % (path, filename) for filename in files if filename[-3:] == '.py']
total = { 'net': 0, 'total': 0, 'nonblank': 0 }
for filename in pythonfiles:
with open(filename, 'r') as thisfile:
blob = thisfile.read()
# print filename
thisloc = loc(blob)
for k, v in thisloc.items():
total[k] += v
return total
if __name__ == '__main__':
import sys
args = sys.argv
rules = """
Command line arguments:
-f - File to be tested (required). Filename if in current directory, or else full path.
-c - Character(s) used to delimit a comment (optional - default is #).
"""
if len(args) == 1:
sys.exit(rules)
print
argdict = {}
for arg in args:
if arg[0] == '-':
try:
argdict[arg[1]] = args[args.index(arg)+1]
except:
pass
if 'f' not in argdict:
sys.exit('Error: no filename (-f) in command line arguments.\n\n%s' % (rules))
if 'c' not in argdict:
argdict['c'] = '#' # default comment delimiter
with open(argdict['f'], 'r') as thisfile:
blob = thisfile.read()
if not blob:
sys.exit("File %s does not exist or cannot be opened." % (argdict['f']))
results = loc(blob, argdict['c'])
print
print "---------------------------------------------"
print "Results for %s" % (argdict['f'])
print
for k, v in results.items():
print '%s: %s' % (k, v)
print
print "---------------------------------------------"
print
sys.exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment