Skip to content

Commit bf85007

Browse files
committed
more discussion and whatnot
1 parent 43b80fe commit bf85007

File tree

12 files changed

+179
-202
lines changed

12 files changed

+179
-202
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
# Playful Python
1+
---
2+
title: "Playful Python: Learning the language through games and puzzles"
3+
author: Ken Youens-Clark
4+
...
5+
6+
# Introduction
27

38
> "The only way to learn a new programming language is by writing programs in it." - Dennis Ritchie
49

@@ -53,3 +58,7 @@ Your goal is to pass all the tests. The tests are written in an order designed t
5358
## Author
5459

5560
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.
61+
62+
## Copyright
63+
64+
© Ken Youens-Clark 2019

article/Makefile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
.PHONY: pdf test
2-
3-
pdf:
4-
pandoc README.md -o README.pdf
1+
.PHONY: test
52

63
test:
7-
pytest -v test.py
4+
pytest -xv test.py

article/README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Write a Python program called `article.py` that will select `a` or `an` for a given word depending on whether the word starts with a consonant or vowel, respectively.
44

5+
When run with no arguments or the `-h|--help` flags, it should print a usage statement:
6+
57
````
68
$ ./article.py
79
usage: article.py [-h] str
@@ -16,8 +18,26 @@ positional arguments:
1618
1719
optional arguments:
1820
-h, --help show this help message and exit
21+
````
22+
23+
When run with a single positional argument, it should print the correct article and the given argument.
24+
25+
````
1926
$ ./article.py bear
2027
a bear
21-
$ ./article.py octopus
22-
an octopus
28+
$ ./article.py Octopus
29+
an Octopus
2330
````
31+
32+
The tests will only give you words that start with an actual alphabetic character, so you won't have to detect numbers or punctuation or other weird stuff. Still, how might you extend the program to ensure that given argument only starts with one of the 26 characters of the English alphabest?
33+
34+
Hints:
35+
36+
* Start your program with `new.py` and fill in the `get_args` with a single position argument called `word`.
37+
* You can get the first character of the word by indexing it like a list, `word[0]`.
38+
* Unless you want to check both upper- and lowercase letters, you can use either the `str.lower` or `str.upper` method to force the input to one case for checking if the first character is a vowel or consonant.
39+
* There are fewer vowels (five, if you recall), so it's probably easier to check if the first character is one of those.
40+
* You can use the `x in y` syntax to see if the element `x` is `in` the collection `y` where "collection" here is a `list`.
41+
* For the purposes of `x in y`, a string (`str`) is a `list` of characters, so you could ask if a character is in a string.
42+
* Use the `print` function to print out the article joined to the argument. Put a single space in between.
43+
* Run `make test` (or `pytest -xv test.py`) *after every change to your program*to ensure your program compiles and is on the right track.

article/discussion.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
Cf Appendices: argparse, Truthiness
2-
31
As with all the solutions presented, this assumes you have stubbed the program with `new.py` and that you are using the `argparse` module. I suggest putting this logic into a separate function which here is called `get_args` and which I like to define first so that I can see right away when I'm reading the program what the program expects as input. On line 12, I set the `description` for the program that will be displayed with the help documentation. On line 15, I indicate that the program expects just one *positional* argument, no more, no less. Since it is a "word" that I expect, I called the argument `word` which is also how I will access the value on line 25. I use the `metavar` on line 15 to let the user know that this should be a string.
42

53
The `get_args` function will `return` the result of parsing the command line arguments which I put into the variable `args` on line 24. I can now access the `word` by call `args.word`. Note the lack of parentheses -- it's not `args.word()` -- as this is not a function call. Think of it like a slot where the value lives.
@@ -20,7 +18,7 @@ To decide if the given word starts with a vowel, we ask is `word[0].lower() in
2018
'APPLE'
2119
````
2220

23-
The `X in Y` form is a way to ask if element `X` is in the collection `Y`:
21+
The `x in y` form is a way to ask if element `x` is in the collection `y`:
2422

2523
````
2624
>>> 'a' in 'abc'
@@ -33,7 +31,7 @@ True
3331
False
3432
````
3533

36-
The `if` *expression* is different from an `if` *statement*. An expression returns a value, and a statement does not. The `if` expression must have an `else`, but the `if` statement does not have this requirement. The first value is returned if the predicate (the bit after the `if`) evaluates to `True` in a Boolean context (cf. "Truthiness"), otherwise the last value is returned:
34+
The `if` *expression* (also called a "ternary" expression) is different from an `if` *statement*. An *expression* returns a value, and a statement does not. The `if` expression must have an `else`, but the `if` statement does not have this requirement. The first value is returned if the predicate (the bit after the `if`) evaluates to `True` in a Boolean context (cf. "Truthiness"), otherwise the last value is returned:
3735

3836
````
3937
>>> 'Hooray!' if True else 'Shucks!'
@@ -58,4 +56,4 @@ if word[0].lower() in 'aeiou':
5856
article = 'a'
5957
````
6058

61-
59+
Cf. appendices: argparse, Truthiness

bin/compile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def main():
9797
fh.write(open(outline).read())
9898
fh.write('\n\\newpage\n\n')
9999

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

0 commit comments

Comments
 (0)