Skip to content

Commit 7a738ae

Browse files
committed
Implement wc command-line tool in python
1 parent 4f141b3 commit 7a738ae

2 files changed

Lines changed: 111 additions & 1 deletion

File tree

implement-shell-tools/wc/README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Implement `wc`
1+
# Implement `wc` in python
22

33
You should already be familiar with the `wc` command line tool.
44

@@ -15,3 +15,20 @@ It must act the same as `wc` would, if run from the directory containing this RE
1515
Matching any additional behaviours or flags are optional stretch goals.
1616

1717
We recommend you start off supporting no flags for one file, then add support for multiple files, then add support for the flags.
18+
19+
*======Command for testing the script========
20+
21+
* All sample files
22+
python wc.py sample-files/*
23+
24+
* Just lines
25+
python wc.py -l sample-files/3.txt
26+
27+
* Just words
28+
python wc.py -w sample-files/3.txt
29+
30+
* Just characters
31+
python wc.py -c sample-files/3.txt
32+
33+
* Lines with multiple files (to see totals)
34+
python wc.py -l sample-files/*

implement-shell-tools/wc/wc.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import argparse
2+
import sys
3+
import re
4+
5+
6+
def main():
7+
# --------------------------------------------------------
8+
# 1. Set up argparse
9+
# --------------------------------------------------------
10+
parser= argparse.ArgumentParser(
11+
prog="wc",
12+
description ="wc command implementation in python"
13+
)
14+
15+
parser.add_argument("-l", action="store_true", help ="show number of lines only")
16+
parser.add_argument("-w", action="store_true", help="show number of words only")
17+
parser.add_argument("-c", action="store_true", help="show number of characters only")
18+
19+
parser.add_argument("paths", nargs="*", help="file paths to process")
20+
21+
args = parser.parse_args()
22+
23+
# --------------------------------------------------------
24+
# 2. Ensures at least one path exists
25+
# --------------------------------------------------------
26+
if len(args.paths) == 0:
27+
print("wc: no file specified", file=sys.stderr)
28+
sys.exit(1)
29+
30+
totals= {"lines": 0, "words": 0, "chars": 0}
31+
32+
# --------------------------------------------------------
33+
# 3. Loop over each file path and process it
34+
# --------------------------------------------------------
35+
for file_path in args.paths:
36+
try:
37+
with open(file_path, "r", encoding="utf-8") as f:
38+
content = f.read()
39+
except OSError as err:
40+
print(f"wc: cannot read file'{file_path}': {err}", file=sys.stderr)
41+
continue
42+
43+
# --------------------------------------------------------
44+
# 4. Count values
45+
# --------------------------------------------------------
46+
line_count = len(content.split("\n"))
47+
48+
words = [w for w in re.split(r"\s+", content) if w]
49+
word_count = len(words)
50+
51+
char_count = len(content)
52+
53+
totals["lines"] += line_count
54+
totals["words"] += word_count
55+
totals["chars"] +=char_count
56+
57+
# --------------------------------------------------------
58+
# 5. Decide what to print based on flags
59+
# --------------------------------------------------------
60+
no_flags = not args.l and not args.w and not args.c
61+
62+
if no_flags:
63+
print(f"{line_count} {word_count} {char_count} {file_path}")
64+
continue
65+
66+
if args.l:
67+
print(f"{line_count} {file_path}" )
68+
69+
if args.w:
70+
print(f"{word_count} {file_path}")
71+
72+
if args.c:
73+
print(f"{char_count} {file_path}")
74+
75+
76+
# --------------------------------------------------------
77+
# 6. Print totals if there are multiple files
78+
# --------------------------------------------------------
79+
if len(args.paths) > 1:
80+
no_flags = not args.l and not args.w and not args.c
81+
82+
if no_flags:
83+
print(f"{totals['lines']} {totals['words']} {totals['chars']} total")
84+
85+
if args.l:
86+
print(f"{totals['lines']} total")
87+
if args.w:
88+
print(f"{totals['words']} total")
89+
if args.c:
90+
print(f"{totals['chars']} total")
91+
92+
if __name__ == "__main__":
93+
main()

0 commit comments

Comments
 (0)