diff --git a/wizard-work/spark/README.md b/wizard-work/spark/README.md index a4c73ce..3424450 100644 --- a/wizard-work/spark/README.md +++ b/wizard-work/spark/README.md @@ -147,4 +147,33 @@ python3 json_schema_validator.py ## Verification -Check: python3 /root/.hermes/wizard-outputs/spark/json_schema_validator.py test_schema.json test_data_valid.json && echo "PASS" \ No newline at end of file +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 +``` + +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 \ No newline at end of file diff --git a/wizard-work/spark/line_counter.py b/wizard-work/spark/line_counter.py index 2b9c950..666288f 100644 --- a/wizard-work/spark/line_counter.py +++ b/wizard-work/spark/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_lines(filepath): + """Count lines in a file, return -1 if file doesn't exist or is unreadable.""" + try: + with open(filepath, 'r') as f: + return sum(1 for _ in f) + except (FileNotFoundError, PermissionError, IOError): + return -1 -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"): - try: - with open(py_file, 'r', encoding='utf-8') as f: - lines = f.readlines() - files_count += 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 - - 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 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 - -def main(): - if len(sys.argv) < 2: - print("Usage: line_counter.py ") - print("Counts lines in Python files recursively") +if __name__ == '__main__': + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} ", 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']}") - 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() \ No newline at end of file + 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) \ No newline at end of file diff --git a/wizard-work/spark/test_data.csv b/wizard-work/spark/test_data.csv new file mode 100644 index 0000000..0ad750b --- /dev/null +++ b/wizard-work/spark/test_data.csv @@ -0,0 +1 @@ +apple, banana, cherry, date, elderberry \ No newline at end of file diff --git a/wizard-work/spark/test_line_counter.py b/wizard-work/spark/test_line_counter.py new file mode 100644 index 0000000..73b2c3a --- /dev/null +++ b/wizard-work/spark/test_line_counter.py @@ -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) \ No newline at end of file diff --git a/wizard-work/spark/test_log.txt b/wizard-work/spark/test_log.txt new file mode 100644 index 0000000..b3f56ae --- /dev/null +++ b/wizard-work/spark/test_log.txt @@ -0,0 +1,10 @@ +line 1 +line 2 +line 3 +line 4 +line 5 +line 6 +line 7 +line 8 +line 9 +line 10 \ No newline at end of file