Skip to content

Commit 49c33ed

Browse files
committed
Refactor wc.py to streamline file counting and output formatting
1 parent 34e5d9d commit 49c33ed

1 file changed

Lines changed: 54 additions & 23 deletions

File tree

  • implement-shell-tools/wc

implement-shell-tools/wc/wc.py

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,66 @@
11
#!/usr/bin/env python3
22

33
import sys
4-
import os
54

6-
def count_file(file, options):
5+
6+
def count_file(file):
77
try:
88
with open(file, 'r', encoding='utf-8') as f:
99
data = f.read()
1010

11-
lines = data.count('\n') + 1
11+
lines = data.count('\n')
1212
words = len(data.split())
1313
bytes_count = len(data.encode('utf-8'))
1414

15-
results = []
16-
if options['lines'] or not any(options.values()):
17-
results.append(lines)
18-
if options['words'] or not any(options.values()):
19-
results.append(words)
20-
if options['bytes'] or not any(options.values()):
21-
results.append(bytes_count)
22-
23-
print(f"{'\t'.join(map(str, results))}\t{file}")
24-
2515
return lines, words, bytes_count
2616
except FileNotFoundError:
2717
print(f"wc: {file}: No such file or directory", file=sys.stderr)
2818
sys.exit(1)
2919

20+
21+
def selected_keys(options):
22+
if not any(options.values()):
23+
return ['lines', 'words', 'bytes']
24+
25+
keys = []
26+
if options['lines']:
27+
keys.append('lines')
28+
if options['words']:
29+
keys.append('words')
30+
if options['bytes']:
31+
keys.append('bytes')
32+
return keys
33+
34+
35+
def values_for_keys(counts, keys):
36+
lines, words, bytes_count = counts
37+
mapping = {
38+
'lines': lines,
39+
'words': words,
40+
'bytes': bytes_count,
41+
}
42+
return [mapping[key] for key in keys]
43+
44+
45+
def print_rows(rows, keys):
46+
align_columns = len(keys) > 1 or len(rows) > 1
47+
48+
if not align_columns:
49+
values, name = rows[0]
50+
print(f"{values[0]} {name}")
51+
return
52+
53+
widths = []
54+
for index in range(len(keys)):
55+
max_len = max(len(str(values[index])) for values, _ in rows)
56+
widths.append(max(3, max_len))
57+
58+
for values, name in rows:
59+
formatted_values = " ".join(
60+
f"{value:>{width}}" for value, width in zip(values, widths)
61+
)
62+
print(f"{formatted_values} {name}")
63+
3064
def main():
3165
args = sys.argv[1:]
3266
options = {
@@ -54,23 +88,20 @@ def main():
5488
total_lines = 0
5589
total_words = 0
5690
total_bytes = 0
91+
keys = selected_keys(options)
92+
rows = []
5793

5894
for file in files:
59-
lines, words, bytes_count = count_file(file, options)
95+
lines, words, bytes_count = count_file(file)
6096
total_lines += lines
6197
total_words += words
6298
total_bytes += bytes_count
99+
rows.append((values_for_keys((lines, words, bytes_count), keys), file))
63100

64101
if len(files) > 1:
65-
total_results = []
66-
if options['lines'] or not any(options.values()):
67-
total_results.append(total_lines)
68-
if options['words'] or not any(options.values()):
69-
total_results.append(total_words)
70-
if options['bytes'] or not any(options.values()):
71-
total_results.append(total_bytes)
72-
73-
print(f"{'\t'.join(map(str, total_results))}\ttotal")
102+
rows.append((values_for_keys((total_lines, total_words, total_bytes), keys), 'total'))
103+
104+
print_rows(rows, keys)
74105

75106
if __name__ == "__main__":
76107
main()

0 commit comments

Comments
 (0)