Skip to content

Instantly share code, notes, and snippets.

@stephenmcd
Last active September 5, 2015 10:54
Show Gist options
  • Save stephenmcd/480730 to your computer and use it in GitHub Desktop.
Save stephenmcd/480730 to your computer and use it in GitHub Desktop.
SLOC and comment stats
import os, sys
c_like = {"single": "//", "multi_start": ("/*",), "multi_end": ("*/",),}
langs = {
"py": {"single": "#", "multi_start": ("'''", '"""'),
"multi_end": ("'''", '"""'),},
"html": {"single": "//", "multi_start": ("<!--", "/*"),
"multi_end": ("-->", "*/"),},
"js": c_like,
"scala": c_like,
"css": {"single": None, "multi_start": ("/*",), "multi_end": ("*/",),},
}
for lang in langs:
langs[lang].update({"sloc": 0, "comments": 0, "files": 0, })
in_comment = False
root = "."
if len(sys.argv) > 1:
root = sys.argv[1]
if not os.path.isdir(root):
print
print "%s is not a directory" % root
print
sys.exit()
for (dirpath, dirnames, filenames) in os.walk(root):
for filename in filenames:
lang = langs.get(filename.split(".")[-1])
if lang:
filename = os.path.join(dirpath, filename)
print "Reading %s" % filename
with open(filename, "r") as f:
lang["files"] += 1
for line in f:
line = line.strip()
if line:
if in_comment:
for end in lang["multi_end"]:
if line.endswith(end):
# End of multi-line comment.
in_comment = False
if line.replace(end, "").strip():
lang["comments"] += 1
break
else:
# Inside multi-line comment.
lang["comments"] += 1
elif (lang["single"] and
line.startswith(lang["single"])):
# Single line comment.
lang["comments"] += 1
else:
for start in lang["multi_start"]:
if line.startswith(start):
# Start of multi-line comment.
in_comment = True
if line.replace(start, "").strip():
lang["comments"] += 1
break
else:
# Line of code.
lang["sloc"] += 1
def print_result(title, data):
print
print "=" * 20
print title.upper()
print "=" * 20
print "Files: %s" % data["files"]
print "SLOC: %s" % data["sloc"]
print "Lines of comments: %s" % data["comments"]
print "Total non-blank lines: %s" % (data["sloc"] + data["comments"])
if data["comments"] > 0:
ratio = "%s:1" % (data["sloc"] / data["comments"])
else:
ratio = 0
print "SLOC per lines of comments: %s" % ratio
def total(count):
return sum([lang[count] for lang in langs.values()])
for name, lang in langs.items():
print_result(name, lang)
counts = ("files", "sloc", "comments")
total = lambda count: sum([lang[count] for lang in langs.values()])
totals = dict([(count, total(count)) for count in counts])
print_result("Total", totals)
print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment