72 lines
1.7 KiB
Python
72 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Count lines of Python code (LOC) in Python source files.
|
|
|
|
Usage: python linecount_pycount.py <file_or_directory>
|
|
|
|
Counts total lines and Python code lines (non-blank, non-comment).
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
def count_loc(filepath: str) -> tuple[int, int]:
|
|
"""Count total lines and Python code lines in a file.
|
|
|
|
Returns (total_lines, code_lines)
|
|
"""
|
|
total = 0
|
|
code = 0
|
|
|
|
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
|
|
for line in f:
|
|
total += 1
|
|
stripped = line.strip()
|
|
if stripped and not stripped.startswith('#'):
|
|
code += 1
|
|
|
|
return total, code
|
|
|
|
|
|
def process_path(path: str) -> tuple[int, int]:
|
|
"""Process a file or directory, return (total_lines, code_lines)."""
|
|
p = Path(path)
|
|
|
|
if p.is_file() and p.suffix == '.py':
|
|
return count_loc(str(p))
|
|
elif p.is_file():
|
|
return 0, 0
|
|
elif p.is_dir():
|
|
total = 0
|
|
code = 0
|
|
for py_file in p.rglob('*.py'):
|
|
t, c = count_loc(str(py_file))
|
|
total += t
|
|
code += c
|
|
return total, code
|
|
else:
|
|
return 0, 0
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 2:
|
|
print("Usage: python linecount_pycount.py <file_or_directory>")
|
|
sys.exit(1)
|
|
|
|
target = sys.argv[1]
|
|
if not os.path.exists(target):
|
|
print(f"Error: '{target}' does not exist")
|
|
sys.exit(1)
|
|
|
|
total, code = process_path(target)
|
|
print(f"Total lines: {total}")
|
|
print(f"Python code lines: {code}")
|
|
|
|
if total > 0:
|
|
pct = (code / total) * 100 if total > 0 else 0
|
|
print(f"Code ratio: {pct:.1f}%")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main() |