Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b0d3cee

Browse filesBrowse files
committed
hangman
1 parent 86fa973 commit b0d3cee
Copy full SHA for b0d3cee

File tree

Expand file treeCollapse file tree

9 files changed

+1094
-253
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

9 files changed

+1094
-253
lines changed
Open diff view settings
Collapse file

‎README.md‎

Copy file name to clipboardExpand all lines: README.md
+5-1Lines changed: 5 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ Notebooks are great for interactive exploration of data, especially if you want
7474
* Hard to test
7575
* No way to pass in arguments
7676

77-
As I want you to learn
77+
I believe you can better learn how to create testable, **reproducible** software by writing command-line programs that always run from beginning to end and have a test suite. It's difficult to achieve that with Notebooks, but I do encourage you to explore Notebooks on your own.
78+
79+
## Code examples, the REPL
80+
81+
I always love when a language has a good REPL (read-evaluate-print-loop) tool. Python and Haskell both excel in this respect. For simplicity's sake, I show the standard REPL when you execute `python3` on the command-line, but you won't be able to copy and paste the same code examples there. For your own purposes, I suggest using the iPython REPL (`ipython`) instead.
7882

7983
## Author
8084

Collapse file

‎bin/compile.py‎

Copy file name to clipboardExpand all lines: bin/compile.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def main():
9393
fh.write('\n\n\\newpage\n\n')
9494

9595
fh.write('\\setcounter{tocdepth}{2}\\tableofcontents\n\n')
96+
fh.write('\n\\newpage\n\n')
9697

9798
top_readme = 'README.md'
9899
if os.path.isfile(top_readme):
Collapse file

‎book.md‎

Copy file name to clipboardExpand all lines: book.md
+559-169Lines changed: 559 additions & 169 deletions
  • Display the source diff
  • Display the rich diff
Large diffs are not rendered by default.
Collapse file

‎hangman/Makefile‎

Copy file name to clipboard
+4Lines 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 hangman.py test.py
Collapse file

‎hangman/README.md‎

Copy file name to clipboardExpand all lines: hangman/README.md
+71-35Lines changed: 71 additions & 35 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
Write a Python program called `hangman.py` that will play a game of Hangman which is a bit like "Wheel of Fortune" where you present the user with a number of elements indicating the length of a word. For our game, use the underscore `_` to indicate a letter that has not been guessed. The program should take `-n|--minlen` minimum length (default `5`) and `-l|--maxlen` maximum length options (default `10`) to indicate the minimum and maximum lengths of the randomly chosen word taken from the `-w|--wordlist` option (default `/usr/share/dict/words`). It also needs to take `-s|--seed` to for the random seed and the `-m|--misses` number of misses to allow the player.
44

5-
To play, you will initiate an inifinite loop and keep track of the game state, e.g., the word to guess, the letters already guessed, the letters found, the number of misses. As this is an interactive game, I cannot write an test suite, so you can play my version and then try to write one like it. If the user guesses a letter that is in the word, replace the `_` characters with the letter. If the user guesses the same letter twice, admonish them. If the user guesses a letter that is not in the word, increment the misses and let them know they missed. If the user guesses too many times, exit the game and insult them. If they correctly guess the word, let them know and exit the game.
5+
The game is intended to be interactive, but I want you to additionally take an `-i|--inputs` option that is a string of letters to use as guesses so that we can write a test.
6+
7+
When run with the `-h|--help` flags, it should present a usage statement:
68

79
````
810
$ ./hangman.py -h
911
usage: hangman.py [-h] [-l MAXLEN] [-n MINLEN] [-m MISSES] [-s SEED]
10-
[-w WORDLIST]
12+
[-w WORDLIST] [-i INPUTS]
1113
1214
Hangman
1315
@@ -22,42 +24,76 @@ optional arguments:
2224
-s SEED, --seed SEED Random seed (default: None)
2325
-w WORDLIST, --wordlist WORDLIST
2426
Word list (default: /usr/share/dict/words)
25-
$ ./hangman.py
26-
_ _ _ _ _ _ _ _ (Misses: 0)
27+
-i INPUTS, --inputs INPUTS
28+
Input choices (default: )
29+
````
30+
31+
If given a bad `--wordlist`, error out (print the problem and exit with a non-zero status) with a message like so:
32+
33+
````
34+
$ ./hangman.py -w kdfkj
35+
usage: hangman.py [-h] [-l MAXLEN] [-n MINLEN] [-m MISSES] [-s SEED]
36+
[-w WORDLIST] [-i INPUTS]
37+
hangman.py: error: argument -w/--wordlist: can't open 'kdfkj': [Errno 2] \
38+
No such file or directory: 'kdfkj'
39+
````
40+
41+
If given a value less than 1 for `--minlen`, error out:
42+
43+
````
44+
$ ./hangman.py -n -4
45+
usage: hangman.py [-h] [-l MAXLEN] [-n MINLEN] [-m MISSES] [-s SEED]
46+
[-w WORDLIST] [-i INPUTS]
47+
hangman.py: error: --minlen "-4" must be positive
48+
````
49+
50+
If given a `--maxlen` value greater than 20, error out:
51+
52+
````
53+
$ ./hangman.py -l 30
54+
usage: hangman.py [-h] [-l MAXLEN] [-n MINLEN] [-m MISSES] [-s SEED]
55+
[-w WORDLIST] [-i INPUTS]
56+
hangman.py: error: --maxlen "30" must be < 20
57+
````
58+
59+
Error out if the `--minlen` is greater than the `--maxlen`:
60+
61+
````
62+
$ ./hangman.py -l 5 -n 10
63+
usage: hangman.py [-h] [-l MAXLEN] [-n MINLEN] [-m MISSES] [-s SEED]
64+
[-w WORDLIST] [-i INPUTS]
65+
hangman.py: error: --minlen "10" is greater than --maxlen "5"
66+
````
67+
68+
To play, you will initiate an inifinite loop and keep track of the game state, e.g., the word to guess, the letters already guessed, the letters found, the number of misses. As this is an interactive game, you will normally use the `input` function to get a letter from the user. If given `--inputs`, bypass the `input` prompt and instead use those letters in turn.
69+
70+
If the user guesses a letter that is in the word, replace the `_` characters with the letter. If the user guesses the same letter twice, admonish them. If the user guesses a letter that is not in the word, increment the misses and let them know they missed. If the user guesses too many times, exit the game and insult them. If they correctly guess the word, let them know and exit the game.
71+
72+
````
73+
$ ./hangman.py -s 2
74+
_ _ _ _ _ _ _ (Misses: 0)
2775
Your guess? ("?" for hint, "!" to quit) a
28-
_ _ _ _ _ _ _ _ (Misses: 1)
76+
There is no "a"
77+
_ _ _ _ _ _ _ (Misses: 1)
2978
Your guess? ("?" for hint, "!" to quit) i
30-
_ _ _ _ _ _ i _ (Misses: 1)
79+
There is no "i"
80+
_ _ _ _ _ _ _ (Misses: 2)
3181
Your guess? ("?" for hint, "!" to quit) e
32-
_ _ _ _ _ _ i _ (Misses: 2)
82+
_ _ _ _ _ _ e (Misses: 2)
3383
Your guess? ("?" for hint, "!" to quit) o
34-
_ o _ _ _ _ i _ (Misses: 2)
35-
Your guess? ("?" for hint, "!" to quit) u
36-
_ o _ _ _ _ i _ (Misses: 3)
37-
Your guess? ("?" for hint, "!" to quit) y
38-
_ o _ _ _ _ i _ (Misses: 4)
39-
Your guess? ("?" for hint, "!" to quit) c
40-
_ o _ _ _ _ i _ (Misses: 5)
41-
Your guess? ("?" for hint, "!" to quit) d
42-
_ o _ _ _ _ i _ (Misses: 6)
43-
Your guess? ("?" for hint, "!" to quit) p
44-
_ o _ _ _ _ i p (Misses: 6)
45-
Your guess? ("?" for hint, "!" to quit) m
46-
_ o _ _ _ _ i p (Misses: 7)
47-
Your guess? ("?" for hint, "!" to quit) n
48-
_ o _ _ _ _ i p (Misses: 8)
49-
Your guess? ("?" for hint, "!" to quit) s
50-
_ o s _ s _ i p (Misses: 8)
84+
o _ o _ _ _ e (Misses: 2)
85+
Your guess? ("?" for hint, "!" to quit) z
86+
o z o _ _ _ e (Misses: 2)
5187
Your guess? ("?" for hint, "!" to quit) t
52-
_ o s t s _ i p (Misses: 8)
53-
Your guess? ("?" for hint, "!" to quit) h
54-
You win. You guessed "hostship" with "8" misses!
55-
$ ./hangman.py -m 2
56-
_ _ _ _ _ _ _ _ _ _ (Misses: 0)
57-
Your guess? ("?" for hint, "!" to quit) a
58-
_ _ _ _ _ _ a _ _ a (Misses: 0)
59-
Your guess? ("?" for hint, "!" to quit) b
60-
_ _ _ _ _ _ a _ _ a (Misses: 1)
61-
Your guess? ("?" for hint, "!" to quit) c
62-
You lose, loser! The word was "metromania."
88+
o z o t _ _ e (Misses: 2)
89+
Your guess? ("?" for hint, "!" to quit) p
90+
o z o t _ p e (Misses: 2)
91+
Your guess? ("?" for hint, "!" to quit) y
92+
You win. You guessed "ozotype" with "2" misses!
6393
````
94+
95+
Play the `solution.py` a few times to get a feel for how the game should work.
96+
97+
Hints:
98+
99+
* Leverage `get_args` and `argparse` to validate inputs. Use `type=argparse.FileType('r')` for the `--wordlist`. Check the value of `--minlen` and `--maxlen` inside `get_args` and use `parser.error` to error out.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.