Skip to content

Commit b2db318

Browse files
committed
added precis
1 parent 68bf6cd commit b2db318

File tree

52 files changed

+173
-142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+173
-142
lines changed

OUTLINE.md

Lines changed: 40 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,40 @@
1-
# Outline
2-
3-
I aim to have 40-50 programs complete with specs, examples, inputs, and test suites. They won't necessarily have a specific order, but they will be grouped into easiest/harder/hardest categories. As many programs use common ideas (e.g., regular expressions, graphs, infinite loops), there will be an appendix section with explanations of how to explore those ideas.
4-
5-
I have in mind a layout where each program gets four pages:
6-
7-
1 2 3 4
8-
+--------+--------+ +--------+--------+
9-
| | | | | |
10-
| | | | | |
11-
| | | | | |
12-
| illus/ | specs | |solution| notes |
13-
| info | | | | |
14-
| | | | | |
15-
| | | | | |
16-
+--------+--------+ +--------+--------+
17-
18-
1. If a short program, perhaps an illustration; if longer, maybe some background or hints.
19-
2. The `README.md` information (specs, example output)
20-
3. The `solution.py` contents
21-
4. Annotation of the solution with comments on lines, sections
22-
23-
## Programs
24-
25-
26-
The goal is to get the reader to become a *writer* -- to try to solve the problems. One technique in teaching is to first present a problem without showing how to solve it. Once the student engages with the problem, they find they want and need the object of the lesson. Each program is intended to flex some programming technique or idea like playing with lists or contemplating regular expressions or using dictionaries. By using `argparse` for the programs, we also cover validation of user input.
27-
28-
### Easiest
29-
30-
* **article**: Select "a" or "an" depending on the given argument
31-
* **howler**: Uppercase input text so they YELL AT YOU LIKE "HOWLER" MESSAGES IN HARRY POTTER. (Could also be called "OWEN MEANY"?)
32-
* **jump_the_five**: Numeric encryption based on "The Wire."
33-
* **bottles_of_beer**: Produce the "Bottle of Beer on the Wall" song. Explores the basic idea of an algorithm and challenges the programmer to format strings.
34-
* **picnic**: Write the picnic game. Uses input, lists.
35-
* **apples_and_bananas**: Substitute vowels in text, e.g., "bananas" -> "bononos". While the concept is substitution of characters in a string which is actually trivial, it turns out there are many (at least 7) decent ways to accomplish this task!
36-
* **gashlycrumb**: Create a morbid lookup table from text. Naturual use of dictionaries.
37-
* **movie_reader**: Print text character-by-character with pauses like in the movies. How to read text by character, use STDOUT/flush, and pause the program.
38-
* **palindromes**: Find palindromes in text. Reading input, manipulation of strings.
39-
* **ransom_note**: Transform input text into "RaNSom cASe". Manipulation of text.
40-
* **rhymer**: Produce rhyming "words" from input text.
41-
* **rock_paper_scissors**: Write Rock, Paper, Scissors game. Infinite loops, dictionaries.
42-
43-
### Harder
44-
45-
* **abuse**: Generate insults from lists of adjectives and nouns. Use of randomness, sampling, and lists.
46-
* **bacronym**: Retrofit words onto acronyms. Use of randomness and dictionaries.
47-
* **blackjack**: Play Blackjack (card game). Use of randomness, combinations, dictionaries.
48-
* **family_tree**: Use GraphViz to visualize a family tree from text. Parsing text, creating graph structures, creating visual output.
49-
* **gematria**: Calculate numeric values of words from characters. Manipulation of text, use of higher-order functions.
50-
* **guess**: Write a number-guessing game. Use of randomness, validation/coercion of inputs, use of exceptions.
51-
* **kentucky_fryer**: Turn text into Southern American English. Parsing, manipulation of text.
52-
* **mad_libs**: TBD
53-
* **markov_words**: Markov chain to generate words. Use of n-grams/k-mers, graphs, randomness, logging.
54-
* **piggie**: Encode text in Pig Latin. Use of regular expressions, text manipulation.
55-
* **sound**: Use Soundex to find rhyming words from a word list.
56-
* **substring**: Write a game to guess words sharing a common substring. Dictionaries, k-mers/n-grams.
57-
* **tictactoe**: Write a Tic-Tac-Toe game. Randomness, state.
58-
* **twelve_days_of_christmas**: Produce the "12 Days of Christmas" song. Algorihtms, loops.
59-
* **war**: Play the War card game. Combinations, randomness.
60-
* **license_plates**: Explore how a regular expression engine works by creating alternate forms of license plates.
61-
62-
### Hardest
63-
64-
* **anagram**: Find anagrams of text. Combinations, permutations, dictionaries.
65-
* **hangman**: Write a Hangman (word/letter-guessing game). Randomness, game state, infinite loops, user input, validation.
66-
* **markov_chain**: Markov chain to generate text. N-grams at word level, parsing text, list manipulations.
67-
* **morse**: Write a Morse encoder/decoder. Dictionaries, text manipulation.
68-
* **rot13**: ROT13-encode input text. Lists, encryption.
1+
## Outline
2+
1. **article**: Choose the correct article for a given word.
3+
2. **jump_the_five**: Encode all numbers in a given text using a Jump-The-Five algorithm.
4+
3. **picnic**: Manipulate strings and lists based on the number of items present.
5+
4. **wc**: Write a program to count the lines, words, and characters in text.
6+
5. **howler**: Convert all input text to uppercase.
7+
6. **apples_and_bananas**: Substitute vowels in text.
8+
7. **telephone**: Introduce mutations in a string over a given number of iterations.
9+
8. **bottles_of_beer**: Write the "99 Bottles of Beer On The Wall" song.
10+
9. **gashlycrumb**: Retreive a line of text from a file by the first letter.
11+
10. **ransom_note**: Randomly alternate the case of input text to simulate a ransom note.
12+
11. **rhymer**: Substitute alternate consonant prefixes onto a stem to find rhyming "words."
13+
12. **rock_paper_scissors**: Write the "Rock, Paper, Scissors" game.
14+
13. **abuse**: Creating insults by randomly choosing from lists of words.
15+
14. **scrambler**: Randomly shuffle the middle letters of every word in a text leaving the first and last letters in place.
16+
15. **bacronym**: Use dictionaries to organize words by first letter, then randomly choose words to create "meanings" for a given acronym.
17+
16. **wod**: Generate a Workout-Of-the-Day (WOD) from a list of possible exercises.
18+
17. **blackjack**: An abbreviated version of the card game "Blackjack" (AKA "Twenty-One").
19+
18. **family_tree**: Parse a text file containing the description of family trees, visualize the resulting graphs using GraphViz.
20+
19. **gematria**: Numerically encode each word of text by summing the ordinal values of the characters.
21+
20. **histy**: Create a textual histogram showing the frequency of letters in text.
22+
21. **mommys_little_helper**: Find words matching a given pattern to help solve a crossword puzzle. Explores manually finding words and using regular expressions.
23+
22. **kentucky_friar**: Drop the "g" from two-syllable words ending in "-ing"; convert "you" to "y'all."
24+
23. **mad_libs**: Create an interative terminal version of "Mad Libs." Hilarity is sure to ensue.
25+
24. **license_plates**: Find all possible permutations of a licence plate given a confusion matrix. Explore how and verify that regular expressions work.
26+
25. **gibberish**: Use a Markov chain to create new words from a set of training files.
27+
26. **piggy**: Encode text using the Pig Latin algorithm.
28+
27. **soundex_rhymer**: Using the Soundex function to find words ending with a given sound.
29+
28. **tictactoe**: Play a round of Tic-Tac-Toe.
30+
29. **twelve_days_of_christmas**: Write a program that will print the "Twelve Days of Christmas" song up to a given day.
31+
30. **anagram**: Finding anagrams of words.
32+
31. **hangman**: Write an interactive terminal game where the user guesses a word.
33+
32. **first_bank_of_change**: Find all possible combinations of pennies, nickels, dimes, and quarters for an amount between 1 and 100.
34+
33. **pareto**: Model how random events of zero-sum encounters led to inequitable distributions.
35+
34. **runny_babbit**: Introduce Spoonerisms into text by switching the initial consonant sounds of neighboring words.
36+
35. **markov_chain**: Use the Markov chain algorithm to generate novel texts based on training sets.
37+
36. **hamming_chain**: Find paths through words that are separated by a given Hamming distance.
38+
37. **morse**: Encrypt and decrypt text to and from two versions of Morse code.
39+
38. **rot13**: Encode and decode text by rotating the characters through a list.
40+
39. **word_search**: Find all the words hidden in the rows, columns, and diagonals in a block of text.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ I believe you can better learn how to create testable, **reproducible** software
8080

8181
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.
8282

83+
## Code formatting and linting
84+
85+
Every program included has been automatically formatted with `yapf` (Yet Another Python Formatter), a tool from Google that can be customized with a configuration file. I encourage you to adopt and regularly a formatter (see also `black`) *after every modification to your program*. Sometimes I even set up the formatter to format every time I save my program.
86+
87+
I would also encourage you to look at code "linters" like `pylint` to find potential errors in your code that the Python interpreter itself will not compalain about. The `mypy` program can also be used as we introduce type hints.
88+
89+
## Organization
90+
91+
The exercises are roughly arranged from easier to harder.
92+
8393
## Author
8494

8595
Ken Youens-Clark is a Sr. Scientific Programmer in the lab of Dr. Bonnie Hurwitz at the University of Arizona. He started college as a music major at the University of North Texas but changed to English lit for his BA in 1995. He started programming at his first job out of college, working through several languages and companies before landing in bioinformatics in 2001. In 2019 he earned his MS in Biosystems Engineering, and enjoys helping people learn programming. When he's not working, he likes playing music, riding bikes, cooking, and being with his wife and children.

abuse/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Creating insults by randomly choosing from lists of words.

anagram/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Finding anagrams of words.

apples_and_bananas/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Substitute vowels in text.

article/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Choose the correct article for a given word.

bacronym/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use dictionaries to organize words by first letter, then randomly choose words to create "meanings" for a given acronym.

banner/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Create large ASCII letters.

bin/compile.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ def get_args():
5858

5959
return parser.parse_args()
6060

61+
# --------------------------------------------------
62+
def make_outline(dir_name, chapters):
63+
"""Find all the precis.txt files and make OUTLINE.md"""
64+
65+
assert os.path.isdir(dir_name)
66+
67+
outline = open(os.path.join(dir_name, 'OUTLINE.md'), 'wt')
68+
outline.write(f'## Outline\n')
69+
70+
for i, chapter in enumerate(chapters, start=1):
71+
precis = os.path.join(dir_name, chapter, 'precis.txt')
72+
assert os.path.isfile(precis)
73+
text = open(precis).read()
74+
outline.write(f'{i}. **{chapter}**: {text}')
75+
76+
outline.close()
6177

6278
# --------------------------------------------------
6379
def main():
@@ -83,6 +99,9 @@ def main():
8399
die('--appendix "{}" is not a file'.format(appendix))
84100

85101
book_file = os.path.join(out_dir, 'book.md')
102+
chapter_list = list(map(str.rstrip, filter(lambda s: s[0] != '#', open(chapters))))
103+
104+
make_outline(in_dir, chapter_list)
86105

87106
with open(book_file, 'wt') as fh:
88107
#fh.write('\\setcounter{tocdepth}{2}\\tableofcontents\n\\newpage\n\n')
@@ -105,7 +124,7 @@ def main():
105124
fh.write(open(outline).read())
106125
fh.write('\n\\newpage\n\n')
107126

108-
for i, dir_name in enumerate(map(str.rstrip, filter(lambda s: s[0] != '#', open(chapters))), 1):
127+
for i, dir_name in enumerate(chapter_list, 1):
109128
print('Chapter {}: {}'.format(i, dir_name))
110129
readme = os.path.join(in_dir, dir_name, 'README.md')
111130
if os.path.isfile(readme):

blackjack/precis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
An abbreviated version of the card game "Blackjack" (AKA "Twenty-One").

0 commit comments

Comments
 (0)