Skip to content

Commit 3b7cf4b

Browse files
Address PR review: reduce duplication and fix flag handling
1 parent 3602022 commit 3b7cf4b

File tree

3 files changed

+68
-88
lines changed

3 files changed

+68
-88
lines changed

implement-shell-tools/cat/cat.py

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,25 @@
1313

1414
args = parser.parse_args()
1515

16-
line_number = 0 # Shared counter across all files
16+
line_number = 1 # Shared counter across all files
1717

18-
# Process each file
19-
for path in args.paths: # LEVEL 1: for loop starts
20-
with open(path, "r") as f: # LEVEL 2: inside for loop
21-
content = f.read() # LEVEL 3: inside with block
18+
for path in args.paths:
19+
with open(path, "r") as f:
2220

23-
# Check if numbering is needed
24-
if args.number: # LEVEL 2: inside for loop
25-
lines = content.split("\n") # LEVEL 3: inside if
26-
numbered_lines = []
27-
28-
for index, line in enumerate(lines): # LEVEL 3: inside if
29-
line_number = line_number + 1 # LEVEL 4: inside inner for
30-
numbered_line = f"{line_number:6}\t{line}"
31-
numbered_lines.append(numbered_line)
32-
33-
print("\n".join(numbered_lines)) # LEVEL 3: inside if
34-
35-
elif args.number_nonblank: # LEVEL 2: inside for loop
36-
lines = content.split("\n") # LEVEL 3: inside elif
37-
numbered_lines = []
38-
39-
for line in lines: # LEVEL 3: inside elif
40-
if line.strip() == "": # LEVEL 4: inside inner for
41-
numbered_lines.append(line)
21+
lines = f.read().splitlines()
22+
23+
output = []
24+
for line in lines:
25+
if args.number_nonblank:
26+
if line.strip():
27+
output.append(f"{line_number:6}\t{line}")
28+
line_number += 1
4229
else:
43-
line_number = line_number + 1
44-
numbered_line = f"{line_number:6}\t{line}"
45-
numbered_lines.append(numbered_line)
46-
47-
print("\n".join(numbered_lines))
48-
49-
else: # LEVEL 2: inside for loop
50-
print(content) # LEVEL 3: inside else
30+
output.append(line)
31+
elif args.number:
32+
output.append(f"{line_number:6}\t{line}")
33+
line_number += 1
34+
else:
35+
output.append(line)
36+
37+
print("\n".join(output))

implement-shell-tools/ls/ls.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
import os
22
import argparse
33

4-
# Setup argument parser
5-
parser = argparse.ArgumentParser(
6-
prog="ls",
7-
description="Lists contents of a directory"
8-
)
4+
parser = argparse.ArgumentParser(prog="ls", description="Lists contents of a directory")
95

106
parser.add_argument("-1", dest="one_column", action="store_true", help="List one file per line")
117
parser.add_argument("-a", "--all", action="store_true", help="Include hidden files")
12-
parser.add_argument("path", nargs='?', default=".", help="Directory to list (default: current directory)")
8+
parser.add_argument("paths", nargs='*', default=["."], help="Directories to list")
139

1410
args = parser.parse_args()
1511

16-
# List directory contents
17-
files = os.listdir(args.path)
12+
for path in args.paths:
13+
if len(args.paths) > 1:
14+
print(f"{path}:")
1815

19-
# Filter out hidden files unless -a flag is used
20-
if not args.all:
21-
files = [f for f in files if not f.startswith('.')]
16+
try:
17+
files = os.listdir(path)
18+
if not args.all:
19+
files = [f for f in files if not f.startswith('.')]
20+
21+
files.sort()
2222

23-
for file in files:
24-
print(file)
23+
sep = "\n" if args.one_column else " "
24+
print(sep.join(files))
25+
26+
if len(args.paths) > 1:
27+
print()
28+
29+
except FileNotFoundError:
30+
print(f"ls: cannot access '{path}': No such file or directory")

implement-shell-tools/wc/wc.py

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,42 @@
11
import argparse
22

3-
# Setup argument parser
4-
parser = argparse.ArgumentParser(
5-
prog="wc",
6-
description="Count lines, words, and characters"
7-
)
3+
parser = argparse.ArgumentParser(prog="wc", description="Count lines, words, and characters")
84
parser.add_argument("paths", nargs='+', help="Files to count")
9-
parser.add_argument("-l", "--lines", action="store_true", help="Count lines only")
10-
parser.add_argument("-w", "--words", action="store_true", help="Count words only")
11-
parser.add_argument("-c", "--chars", action="store_true", help="Count characters only")
5+
parser.add_argument("-l", "--lines", action="store_true")
6+
parser.add_argument("-w", "--words", action="store_true")
7+
parser.add_argument("-c", "--chars", action="store_true")
128

139
args = parser.parse_args()
1410

15-
# Track totals
16-
total_lines = 0
17-
total_words = 0
18-
total_chars = 0
11+
# If no flags are provided, the default behavior is to show all three
12+
show_all = not (args.lines or args.words or args.chars)
13+
14+
total_stats = [0, 0, 0] # lines, words, chars
1915

2016
for path in args.paths:
21-
# Read the file
2217
with open(path, "r") as f:
2318
content = f.read()
2419

25-
# Count lines, words, characters
26-
lines = len(content.rstrip('\n').split('\n'))
27-
words = len(content.split())
28-
chars = len(content)
29-
30-
# Add to totals
31-
total_lines += lines
32-
total_words += words
33-
total_chars += chars
34-
35-
if args.lines:
36-
print(f"{lines:8} {path}")
37-
elif args.words:
38-
print(f"{words:8} {path}")
39-
elif args.chars:
40-
print(f"{chars:8} {path}")
41-
else:
42-
print(f"{lines:8}{words:8}{chars:8} {path}")
43-
44-
45-
# Print totals if multiple files
46-
if len(args.paths) > 1:
47-
if args.lines:
48-
print(f"{total_lines:8} total")
49-
elif args.words:
50-
print(f"{total_words:8} total")
51-
elif args.chars:
52-
print(f"{total_chars:8} total")
53-
else:
54-
print(f"{total_lines:8}{total_words:8}{total_chars:8} total")
20+
stats = [
21+
len(content.splitlines()),
22+
len(content.split()),
23+
len(content)
24+
]
25+
26+
for i in range(3):
27+
total_stats[i] += stats[i]
28+
29+
output = []
30+
if args.lines or show_all: output.append(f"{stats[0]:8}")
31+
if args.words or show_all: output.append(f"{stats[1]:8}")
32+
if args.chars or show_all: output.append(f"{stats[2]:8}")
33+
34+
print(f"{''.join(output)} {path}")
5535

36+
if len(args.paths) > 1:
37+
total_output = []
38+
if args.lines or show_all: total_output.append(f"{total_stats[0]:8}")
39+
if args.words or show_all: total_output.append(f"{total_stats[1]:8}")
40+
if args.chars or show_all: total_output.append(f"{total_stats[2]:8}")
41+
42+
print(f"{''.join(total_output)} total")

0 commit comments

Comments
 (0)