-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcountlines.py
73 lines (65 loc) · 2.81 KB
/
countlines.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Estimate project size in lines of code."""
# TODO: add sorting options: name, code count, SLOC count, code ratio.
import os
import re
from operator import itemgetter
def listpy(path):
return list(sorted(filename for filename in os.listdir(path) if filename.endswith(".py")))
def count_sloc(code, *, blanks, docstrings, comments):
"""blanks et al.: include this item?"""
if not docstrings:
# TODO: make sure it's a docstring (and not some other """...""" string)
code = re.sub(r'""".*?"""', r'', code, flags=(re.MULTILINE + re.DOTALL))
code = re.sub(r"'''.*?'''", r'', code, flags=(re.MULTILINE + re.DOTALL))
lines = code.split("\n")
if not blanks:
lines = [line for line in lines if line.strip()]
if not comments:
lines = [line for line in lines if not line.strip().startswith("#")] # ignore whole-line comments
return len(lines)
def report(paths):
print(f"Code size for {os.getcwd()}")
def format_name(s, width=25):
return s.ljust(width)
def format_number(n, width=5):
return str(n).rjust(width)
def format_path(s): # ./subdir/something
def label(s):
if s == ".":
return "top level"
return s[2:]
return format_name(label(s))
codes_grandtotal = 0
slocs_grandtotal = 0
for path in paths:
filenames = listpy(path)
results = []
for filename in filenames:
with open(os.path.join(path, filename), "rt", encoding="utf-8") as f:
content = f.read()
code = count_sloc(content, blanks=False, docstrings=False, comments=False)
sloc = count_sloc(content, blanks=True, docstrings=True, comments=True)
results.append((code, sloc))
if results:
codes, slocs = zip(*results)
codes = sum(codes)
slocs = sum(slocs)
print(f"\n {format_path(path)} {format_number(codes)} / {format_number(slocs)} {int(codes / slocs * 100):d}% code")
for filename, (code, sloc) in sorted(zip(filenames, results), key=itemgetter(1)):
print(f" {format_name(filename)} {format_number(code)} / {format_number(sloc)} {int(code / sloc * 100):d}% code")
codes_grandtotal += codes
slocs_grandtotal += slocs
print(f"\n{format_name('Total')} {format_number(codes_grandtotal)} / {format_number(slocs_grandtotal)} {int(codes_grandtotal / slocs_grandtotal * 100):d}% code")
def main():
blacklist = [".git", "build", "dist", "__pycache__", "00_stuff"]
paths = []
for root, dirs, files in os.walk("."):
paths.append(root)
for x in blacklist:
if x in dirs:
dirs.remove(x)
report(sorted(paths))
if __name__ == '__main__':
main()