Skip to content

Commit e7ffcfe

Browse files
committed
refactor(wc): simplify flag handling and improve code clarity
- Replace should_show_all_stats boolean with active_flags list - Simplify print_formatted_report to accept flag list instead of args object - Increase column width from 4 to 8 for better alignment with standard wc - Remove unused os import - Simplify comments for clarity - Refactor flag resolution into straightforward list building - Improve readability of argument parser definitions
1 parent c19c165 commit e7ffcfe

2 files changed

Lines changed: 33 additions & 42 deletions

File tree

implement-shell-tools/wc/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ Your task is to implement your own version of `wc`.
66

77
It must act the same as `wc` would, if run from the directory containing this README.md file, for the following command lines:
88

9-
* `wc sample-files/*`
10-
* `wc -l sample-files/3.txt`
11-
* `wc -w sample-files/3.txt`
12-
* `wc -c sample-files/3.txt`
13-
* `wc -l sample-files/*`
9+
- `wc sample-files/*`
10+
- `wc -l sample-files/3.txt`
11+
- `wc -w sample-files/3.txt`
12+
- `wc -c sample-files/3.txt`
13+
- `wc -l sample-files/*`
1414

1515
Matching any additional behaviours or flags are optional stretch goals.
1616

implement-shell-tools/wc/wc.py

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import argparse
22
import sys
3-
import os
4-
53

64
def calculate_stats(content, display_name, original_bytes=None):
75
lines = content.count("\n")
86
words = len(content.split())
9-
# If we have the raw bytes, use that length. Otherwise, encode to get byte length.
7+
# Use raw bytes if provided, otherwise encode
108
byte_count = (
119
original_bytes if original_bytes is not None else len(content.encode("utf-8"))
1210
)
@@ -19,51 +17,45 @@ def calculate_stats(content, display_name, original_bytes=None):
1917
}
2018

2119

22-
def print_formatted_report(stats, args, should_show_all_stats):
23-
output_columns = []
24-
25-
def format_col(count):
26-
return str(count).rjust(4)
20+
def print_formatted_report(stats, active_flags):
21+
output_parts = []
2722

28-
if should_show_all_stats:
29-
output_columns.append(format_col(stats["lineCount"]))
30-
output_columns.append(format_col(stats["wordCount"]))
31-
output_columns.append(format_col(stats["byteCount"]))
32-
else:
33-
if args.lines:
34-
output_columns.append(format_col(stats["lineCount"]))
35-
if args.words:
36-
output_columns.append(format_col(stats["wordCount"]))
37-
if args.bytes:
38-
output_columns.append(format_col(stats["byteCount"]))
23+
for flag in active_flags:
24+
# Standard wc uses a width of 8 for numbers
25+
output_parts.append(str(stats[flag]).rjust(8))
3926

40-
# Use a single space between the numbers and the name
41-
print(f"{''.join(output_columns)} {stats['displayName']}")
27+
# Join the numbers and add the display name at the end
28+
result = "".join(output_parts)
29+
print(f"{result} {stats['displayName']}")
4230

4331

4432
def main():
4533
parser = argparse.ArgumentParser(description="A simple Python implementation of wc")
4634
parser.add_argument("files", nargs="*", help="Files to process")
47-
parser.add_argument(
48-
"-l", "--lines", action="store_true", help="print the newline counts"
49-
)
50-
parser.add_argument(
51-
"-w", "--words", action="store_true", help="print the word counts"
52-
)
53-
parser.add_argument(
54-
"-c", "--bytes", action="store_true", help="print the byte counts"
55-
)
35+
parser.add_argument("-l", "--lines", action="store_true", help="print the newline counts")
36+
parser.add_argument("-w", "--words", action="store_true", help="print the word counts")
37+
parser.add_argument("-c", "--bytes", action="store_true", help="print the byte counts")
5638

5739
args = parser.parse_args()
58-
should_show_all_stats = not (args.lines or args.words or args.bytes)
40+
41+
# RESOLVE FLAGS HERE: Create a simple list of keys to display
42+
active_flags = []
43+
if args.lines: active_flags.append("lineCount")
44+
if args.words: active_flags.append("wordCount")
45+
if args.bytes: active_flags.append("byteCount")
46+
47+
# Default behavior: show all if no flags are provided
48+
if not active_flags:
49+
active_flags = ["lineCount", "wordCount", "byteCount"]
50+
5951
all_file_stats = []
6052
exit_code = 0
6153

62-
# NEW: Handle Standard Input if no files are provided
54+
# Handle Standard Input
6355
if not args.files:
6456
stdin_content = sys.stdin.read()
6557
stats = calculate_stats(stdin_content, "")
66-
print_formatted_report(stats, args, should_show_all_stats)
58+
print_formatted_report(stats, active_flags)
6759
return
6860

6961
# Process files
@@ -75,7 +67,7 @@ def main():
7567
stats = calculate_stats(content, file_path, len(raw_bytes))
7668

7769
all_file_stats.append(stats)
78-
print_formatted_report(stats, args, should_show_all_stats)
70+
print_formatted_report(stats, active_flags)
7971
except Exception:
8072
print(f"wc: {file_path}: No such file or directory", file=sys.stderr)
8173
exit_code = 1
@@ -88,11 +80,10 @@ def main():
8880
"byteCount": sum(s["byteCount"] for s in all_file_stats),
8981
"displayName": "total",
9082
}
91-
print_formatted_report(grand_totals, args, should_show_all_stats)
83+
print_formatted_report(grand_totals, active_flags)
9284

9385
if exit_code != 0:
9486
sys.exit(exit_code)
9587

96-
9788
if __name__ == "__main__":
98-
main()
89+
main()

0 commit comments

Comments
 (0)