Skip to content

Commit 84e498d

Browse files
committed
word count
1 parent c6fd28a commit 84e498d

File tree

7 files changed

+290
-35
lines changed

7 files changed

+290
-35
lines changed

bin/chapters.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
article
22
jump_the_five
33
picnic
4+
wc
45
howler
56
apples_and_bananas
67
telephone

book.md

Lines changed: 130 additions & 35 deletions
Large diffs are not rendered by default.

playful_python.pdf

2.66 KB
Binary file not shown.

wc/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.PHONY: test
2+
3+
test:
4+
pytest -xv test.py

wc/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Words Count
2+
3+
Write a Python program called `wc.py` that will emulate the venerable `wc` program in Unix that counts the lines, words, and characters in the given file arguments.
4+
5+
````
6+
$ ./wc.py
7+
usage: wc.py [-h] FILE [FILE ...]
8+
wc.py: error: the following arguments are required: FILE
9+
$ ./wc.py -h
10+
usage: wc.py [-h] FILE [FILE ...]
11+
12+
Argparse Python script
13+
14+
positional arguments:
15+
FILE Input file(s)
16+
17+
optional arguments:
18+
-h, --help show this help message and exit
19+
````
20+
21+
22+
23+
````
24+
$ ./wc.py ../inputs/scarlet.txt
25+
7035 68061 396320 ../inputs/scarlet.txt
26+
$ ./wc.py ../inputs/*.txt
27+
1000 1000 5840 ../inputs/1000.txt
28+
100 100 657 ../inputs/1945-boys.txt
29+
100 100 684 ../inputs/1945-girls.txt
30+
872 7652 45119 ../inputs/const.txt
31+
2476 7436 41743 ../inputs/dickinson.txt
32+
1 9 45 ../inputs/fox.txt
33+
25 278 1476 ../inputs/gettysburg.txt
34+
37 91 499 ../inputs/issa.txt
35+
9 51 248 ../inputs/nobody.txt
36+
1 16 65 ../inputs/now.txt
37+
6 71 413 ../inputs/preamble.txt
38+
7035 68061 396320 ../inputs/scarlet.txt
39+
17 118 661 ../inputs/sonnet-29.txt
40+
3 7 45 ../inputs/spiders.txt
41+
9 34 192 ../inputs/the-bustle.txt
42+
37842 48990 369949 ../inputs/uscities.txt
43+
176 1340 8685 ../inputs/usdeclar.txt
44+
````

wc/solution.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env python3
2+
"""Emulate wc (word count)"""
3+
4+
import argparse
5+
6+
7+
# --------------------------------------------------
8+
def get_args():
9+
"""Get command-line arguments"""
10+
11+
parser = argparse.ArgumentParser(
12+
description='Argparse Python script',
13+
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
14+
15+
parser.add_argument('file',
16+
metavar='FILE',
17+
nargs='+',
18+
type=argparse.FileType('r'),
19+
help='Input file(s)')
20+
21+
return parser.parse_args()
22+
23+
24+
# --------------------------------------------------
25+
def main():
26+
"""Make a jazz noise here"""
27+
28+
args = get_args()
29+
30+
for fh in args.file:
31+
lines, words, chars = 0, 0, 0
32+
for line in fh:
33+
lines += 1
34+
chars += len(line)
35+
words += len(line.split())
36+
37+
print('{:8}{:8}{:8} {}'.format(lines, words, chars, fh.name))
38+
39+
40+
# --------------------------------------------------
41+
if __name__ == '__main__':
42+
main()

wc/test.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env python3
2+
"""tests for wc.py"""
3+
4+
import os
5+
import random
6+
import re
7+
import string
8+
from subprocess import getstatusoutput
9+
10+
prg = './wc.py'
11+
fox = '../inputs/fox.txt'
12+
sonnet = '../inputs/sonnet-29.txt'
13+
14+
15+
# --------------------------------------------------
16+
def test_exists():
17+
"""exists"""
18+
19+
assert os.path.isfile(prg)
20+
21+
22+
# --------------------------------------------------
23+
def test_usage():
24+
"""usage"""
25+
26+
for flag in ['-h', '--help']:
27+
rv, out = getstatusoutput('{} {}'.format(prg, flag))
28+
assert rv == 0
29+
assert re.match("usage", out, re.IGNORECASE)
30+
31+
32+
# --------------------------------------------------
33+
def random_string():
34+
"""generate a random string"""
35+
36+
k = random.randint(5, 10)
37+
return ''.join(random.choices(string.ascii_letters + string.digits, k=k))
38+
39+
40+
# --------------------------------------------------
41+
def test_bad_file():
42+
"""bad_file"""
43+
44+
bad = random_string()
45+
rv, out = getstatusoutput('{} {}'.format(prg, bad))
46+
assert rv != 0
47+
assert re.search(f"No such file or directory: '{bad}'", out)
48+
49+
50+
# --------------------------------------------------
51+
def test_fox():
52+
"""Test on fox"""
53+
54+
rv, out = getstatusoutput('{} {}'.format(prg, fox))
55+
56+
assert rv == 0
57+
assert out.rstrip() == ' 1 9 45 ../inputs/fox.txt'
58+
59+
60+
# --------------------------------------------------
61+
def test_more():
62+
"""Test on more than one file"""
63+
64+
rv, out = getstatusoutput('{} {} {}'.format(prg, fox, sonnet))
65+
66+
expected = (' 1 9 45 ../inputs/fox.txt\n'
67+
' 17 118 661 ../inputs/sonnet-29.txt')
68+
assert rv == 0
69+
assert out.rstrip() == expected

0 commit comments

Comments
 (0)