|
| 1 | +import argparse |
| 2 | +import os |
| 3 | +from pathlib import Path |
| 4 | + |
| 5 | + |
| 6 | +# Argument Handling |
| 7 | +parser = argparse.ArgumentParser( |
| 8 | + prog="wc", |
| 9 | + description="Give total word count of file", |
| 10 | +) |
| 11 | + |
| 12 | +parser.add_argument("-l", action="store_true", help="Show line count") |
| 13 | +parser.add_argument("-w", action="store_true", help="Show word count") |
| 14 | +parser.add_argument("-c", action="store_true", help="Show byte size") |
| 15 | +parser.add_argument("message", nargs="*", help="File names to process") |
| 16 | + |
| 17 | +args = parser.parse_args() |
| 18 | + |
| 19 | +# Global Variables |
| 20 | +metrics = ["line_count", "word_count", "byte_size"] |
| 21 | +displayed_metrics = [] |
| 22 | + |
| 23 | +# ===== wc Procedure ===== |
| 24 | +def wc(args): |
| 25 | + cwd = os.getcwd() |
| 26 | + file_names = args.message |
| 27 | + |
| 28 | + execute_flags() |
| 29 | + all_files_data = add_totals(extract_files_data(file_names, cwd)) |
| 30 | + print_output(all_files_data) |
| 31 | + |
| 32 | +# ===== Flag Handling ===== |
| 33 | +def execute_flags(): |
| 34 | + if args.w: |
| 35 | + displayed_metrics.append("word_count") |
| 36 | + if args.l: |
| 37 | + displayed_metrics.append("line_count") |
| 38 | + if args.c: |
| 39 | + displayed_metrics.append("byte_size") |
| 40 | + |
| 41 | +# ===== Extracting Files Data ===== |
| 42 | +def extract_files_data(file_names, cwd): |
| 43 | + all_files_data = [] |
| 44 | + |
| 45 | + for file_name in file_names: |
| 46 | + file_data = {} |
| 47 | + file_data["name"] = file_name |
| 48 | + file_data["text"] = read_file(file_name, cwd) |
| 49 | + file_data["line_count"] = calculate_line_count(file_data["text"]) |
| 50 | + file_data["word_count"] = calculate_word_count(file_data["text"]) |
| 51 | + file_data["byte_size"] = read_byte_size(file_name, cwd) |
| 52 | + |
| 53 | + all_files_data.append(file_data) |
| 54 | + |
| 55 | + return all_files_data |
| 56 | + |
| 57 | +def read_file(file_name, cwd): |
| 58 | + file_path = Path(cwd) / file_name |
| 59 | + return file_path.read_text(encoding="utf-8").rstrip() |
| 60 | + |
| 61 | +def calculate_line_count(text): |
| 62 | + if not text: |
| 63 | + return 0 |
| 64 | + return len(text.splitlines()) |
| 65 | + |
| 66 | + |
| 67 | +def calculate_word_count(text): |
| 68 | + return len(text.split()) |
| 69 | + |
| 70 | + |
| 71 | +def read_byte_size(file_name, cwd): |
| 72 | + file_path = os.path.join(cwd, file_name) |
| 73 | + return os.path.getsize(file_path) |
| 74 | + |
| 75 | +def add_totals(all_files_data): |
| 76 | + if len(all_files_data) <= 1: |
| 77 | + return all_files_data |
| 78 | + |
| 79 | + totals_data = {"name": "total"} |
| 80 | + |
| 81 | + for metric in metrics: |
| 82 | + metric_sum = 0 |
| 83 | + for file in all_files_data: |
| 84 | + metric_sum += file[metric] |
| 85 | + totals_data[metric] = metric_sum |
| 86 | + |
| 87 | + all_files_data.append(totals_data) |
| 88 | + return all_files_data |
| 89 | + |
| 90 | +# ===== Outputting Data ===== |
| 91 | +def print_output(output_data): |
| 92 | + for file in output_data: |
| 93 | + output_string = "" |
| 94 | + |
| 95 | + for metric in metrics: |
| 96 | + if not displayed_metrics or metric in displayed_metrics: |
| 97 | + output_string += str(file[metric]).rjust(8) |
| 98 | + |
| 99 | + output_string += f" {file['name']}" |
| 100 | + print(output_string) |
| 101 | + |
| 102 | +# ===== Run wc ===== |
| 103 | +wc(parser.parse_args()) |
| 104 | + |
| 105 | + |
0 commit comments