spark: Add line_counter.py utility for counting lines and CSV fields
This commit is contained in:
1 parent
4e509f1343
commit
6b5197bf37
5 files changed
+126
-55
No files matched your search
@@ -148,3 +148,32 @@ python3 json_schema_validator.py <schema_file.json> <data_file.json>
|
||||
## Verification
|
||||
|
||||
Check: python3 /root/.hermes/wizard-outputs/spark/json_schema_validator.py test_schema.json test_data_valid.json && echo "PASS"
|
||||
|
||||
---
|
||||
|
||||
# Line Counter Utility (spark/artifact)
|
||||
|
||||
A simple Python utility for counting lines in files and fields in CSV files.
|
||||
|
||||
## Files
|
||||
|
||||
- **line_counter.py** - Main script (1,542 bytes)
|
||||
- **test_data.csv** - Test CSV file with 5 comma-separated items
|
||||
- **test_log.txt** - Test log file with 10 lines
|
||||
- **test_line_counter.py** - Test script verifying functionality
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
python3 line_counter.py <filepath> <mode>
|
||||
```
|
||||
|
||||
Modes:
|
||||
- `count` - Count total lines in a file
|
||||
- `csv` - Count items in comma-separated line (first row)
|
||||
|
||||
## Verification
|
||||
|
||||
VERDICT: Utility correctly counts lines and CSV fields with proper error handling
|
||||
|
||||
CHECK: python3 /root/troupe-standup/wizard-work/spark/test_line_counter.py
|
||||
@@ -1,66 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Count lines in Python files - a simple verification utility."""
|
||||
"""Line counter utility - counts lines in a file."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def count_python_lines(directory: str) -> dict:
|
||||
"""Count total lines, code lines, and comment lines in Python files."""
|
||||
total_lines = 0
|
||||
code_lines = 0
|
||||
comment_lines = 0
|
||||
files_count = 0
|
||||
|
||||
dir_path = Path(directory)
|
||||
if not dir_path.exists():
|
||||
return {"error": f"Directory not found: {directory}"}
|
||||
|
||||
for py_file in dir_path.rglob("*.py"):
|
||||
def count_lines(filepath):
|
||||
"""Count lines in a file, return -1 if file doesn't exist or is unreadable."""
|
||||
try:
|
||||
with open(py_file, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
files_count += 1
|
||||
with open(filepath, 'r') as f:
|
||||
return sum(1 for _ in f)
|
||||
except (FileNotFoundError, PermissionError, IOError):
|
||||
return -1
|
||||
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
total_lines += 1
|
||||
if stripped.startswith('#'):
|
||||
comment_lines += 1
|
||||
elif stripped:
|
||||
code_lines += 1
|
||||
except Exception as e:
|
||||
pass
|
||||
def count_comma_separated(filepath):
|
||||
"""Count items in a comma-separated file (first row, count commas + 1)."""
|
||||
try:
|
||||
with open(filepath, 'r') as f:
|
||||
first_line = f.readline().strip()
|
||||
if not first_line:
|
||||
return 0
|
||||
return len(first_line.split(','))
|
||||
except (FileNotFoundError, PermissionError, IOError):
|
||||
return -1
|
||||
|
||||
return {
|
||||
"directory": str(dir_path.resolve()),
|
||||
"python_files": files_count,
|
||||
"total_lines": total_lines,
|
||||
"code_lines": code_lines,
|
||||
"comment_lines": comment_lines,
|
||||
"empty_lines": total_lines - code_lines - comment_lines
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: line_counter.py <directory>")
|
||||
print("Counts lines in Python files recursively")
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print(f"Usage: {sys.argv[0]} <filepath> <mode>", file=sys.stderr)
|
||||
print("Modes: count (lines), csv (fields)", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
result = count_python_lines(sys.argv[1])
|
||||
filepath = sys.argv[1]
|
||||
mode = sys.argv[2]
|
||||
|
||||
if "error" in result:
|
||||
print(f"Error: {result['error']}")
|
||||
if mode == 'count':
|
||||
result = count_lines(filepath)
|
||||
if result == -1:
|
||||
print(f"ERROR: Cannot read file '{filepath}'", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
print(result)
|
||||
elif mode == 'csv':
|
||||
result = count_comma_separated(filepath)
|
||||
if result == -1:
|
||||
print(f"ERROR: Cannot read file '{filepath}'", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
print(result)
|
||||
else:
|
||||
print(f"Unknown mode: {mode}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Python files: {result['python_files']}")
|
||||
print(f"Total lines: {result['total_lines']}")
|
||||
print(f"Code lines: {result['code_lines']}")
|
||||
print(f"Comment lines: {result['comment_lines']}")
|
||||
print(f"Empty lines: {result['empty_lines']}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1 @@
|
||||
apple, banana, cherry, date, elderberry
|
||||
|
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test script for line_counter.py utility."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def run_test(cmd, expected, description):
|
||||
"""Run a test command and verify output."""
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
actual = result.stdout.strip()
|
||||
|
||||
if actual == str(expected) and result.returncode == 0:
|
||||
print(f"PASS: {description}")
|
||||
return True
|
||||
else:
|
||||
print(f"FAIL: {description}")
|
||||
print(f" Expected: {expected}, Got: {actual}")
|
||||
return False
|
||||
|
||||
# Test CSV mode with known data
|
||||
test_csv_pass = run_test(
|
||||
['python3', 'line_counter.py', 'test_data.csv', 'csv'],
|
||||
5,
|
||||
"CSV count mode (5 items)"
|
||||
)
|
||||
|
||||
# Test count mode with known lines
|
||||
test_count_pass = run_test(
|
||||
['python3', 'line_counter.py', 'test_log.txt', 'count'],
|
||||
10,
|
||||
"Line count mode (10 lines)"
|
||||
)
|
||||
|
||||
# Test error handling for non-existent file
|
||||
result = subprocess.run(
|
||||
['python3', 'line_counter.py', 'nonexistent.txt', 'count'],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
if result.returncode == 2:
|
||||
print("PASS: Error handling (exit code 2 for missing file)")
|
||||
error_pass = True
|
||||
else:
|
||||
print(f"FAIL: Error handling (expected exit code 2, got {result.returncode})")
|
||||
error_pass = False
|
||||
|
||||
all_pass = test_csv_pass and test_count_pass and error_pass
|
||||
print(f"\nAll tests: {'PASSED' if all_pass else 'FAILED'}")
|
||||
sys.exit(0 if all_pass else 1)
|
||||
@@ -0,0 +1,10 @@
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line 5
|
||||
line 6
|
||||
line 7
|
||||
line 8
|
||||
line 9
|
||||
line 10
|
||||
Reference in new issue
Block a user