diff --git a/Makefile b/Makefile index e2f599fe8..0a6738ece 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,16 @@ +.PHONY: docs serve-docs clean install + install: python3 -m pip install -r requirements.txt clean: for name in .pytest_cache __pycache__ .vsidea .idea .mypy_cache; do find . -name $$name -exec rm -rf {} \;; done +docs: + @mkdir -p docs + python3 bin/gen_docs.py + @echo "Docs generated in ./docs" + +serve-docs: + python3 -m http.server --directory docs 8000 | cat + diff --git a/bin/gen_docs.py b/bin/gen_docs.py new file mode 100644 index 000000000..2a4bb21d3 --- /dev/null +++ b/bin/gen_docs.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python3 +""" +Generate Markdown documentation for all public APIs, functions, and components +in this repository without external dependencies. The script uses the Python +standard library `ast` to parse modules and extract docstrings and signatures. + +Outputs a `docs/` tree mirroring the source layout and an `docs/index.md` +containing links, examples, and usage guidance. +""" + +from __future__ import annotations + +import ast +import re +import sys +from dataclasses import dataclass +from pathlib import Path +from typing import Iterable, List, Optional, Tuple + + +REPO_ROOT = Path(__file__).resolve().parents[1] +DOCS_DIR = REPO_ROOT / "docs" + + +@dataclass +class ArgumentSpec: + flags: List[str] + metavar: Optional[str] + help_text: Optional[str] + + +@dataclass +class FunctionDoc: + name: str + args: str + docstring: Optional[str] + + +@dataclass +class ClassDoc: + name: str + docstring: Optional[str] + methods: List[FunctionDoc] + + +@dataclass +class ModuleDoc: + rel_path: Path + module_docstring: Optional[str] + functions: List[FunctionDoc] + classes: List[ClassDoc] + cli_arguments: List[ArgumentSpec] + has_argparse: bool + + +PYTHON_FILE_EXCLUDES = { + "test.py", +} + +DIR_EXCLUDES = { + ".git", + "__pycache__", + ".pytest_cache", + ".mypy_cache", + ".idea", + ".vsidea", + "docker", + "inputs", + "docs", +} + + +def iter_python_files(root: Path) -> Iterable[Path]: + for path in root.rglob("*.py"): + if any(part in DIR_EXCLUDES for part in path.parts): + continue + if path.name in PYTHON_FILE_EXCLUDES: + continue + # Skip this generator + if path == (REPO_ROOT / "bin" / "gen_docs.py"): + continue + yield path + + +def get_function_signature(node: ast.FunctionDef) -> str: + args: List[str] = [] + a = node.args + + def fmt(name: str, default: Optional[str] = None) -> str: + return f"{name}={default}" if default is not None else name + + # Positional-only (Python 3.8+) + for idx, arg in enumerate(a.posonlyargs): + default_idx = idx - (len(a.posonlyargs) - len(a.defaults)) + default_val = None + if default_idx >= 0: + default_val = ast.unparse(a.defaults[default_idx]) if hasattr(ast, "unparse") else "…" + args.append(fmt(arg.arg, default_val)) + if a.posonlyargs: + args.append("/") + + # Regular args + num_regular = len(a.args) + num_defaults = len(a.defaults) + for idx, arg in enumerate(a.args): + default_idx = idx - (num_regular - num_defaults) + default_val = None + if default_idx >= 0: + default_val = ast.unparse(a.defaults[default_idx]) if hasattr(ast, "unparse") else "…" + args.append(fmt(arg.arg, default_val)) + + # Vararg + if a.vararg: + args.append(f"*{a.vararg.arg}") + elif a.kwonlyargs: + args.append("*") + + # Keyword-only + for idx, arg in enumerate(a.kwonlyargs): + default_val = None + if a.kw_defaults[idx] is not None: + default_val = ast.unparse(a.kw_defaults[idx]) if hasattr(ast, "unparse") else "…" + args.append(fmt(arg.arg, default_val)) + + # Kwarg + if a.kwarg: + args.append(f"**{a.kwarg.arg}") + + return f"({', '.join(args)})" + + +def extract_argparse_specs(source: str) -> Tuple[bool, List[ArgumentSpec]]: + has_argparse = "argparse" in source or "ArgumentParser(" in source + specs: List[ArgumentSpec] = [] + if not has_argparse: + return False, specs + + # Very simple heuristic to capture add_argument flag patterns + add_arg_pattern = re.compile(r"add_argument\(([^\)]*)\)") + for m in add_arg_pattern.finditer(source): + arg_str = m.group(1) + # Split on commas that are not inside quotes + parts = re.findall(r"'(?:\\'|[^'])*'|\"(?:\\\"|[^\"])*\"|[^,]+", arg_str) + parts = [p.strip() for p in parts if p.strip()] + flags: List[str] = [] + metavar: Optional[str] = None + help_text: Optional[str] = None + for p in parts: + if p.startswith(("'", '"')): + val = p.strip("'\"") + if val.startswith("-"): + flags.append(val) + elif p.startswith("metavar="): + metavar = p.split("=", 1)[1].strip().strip("'\"") + elif p.startswith("help="): + help_text = p.split("=", 1)[1].strip().strip("'\"") + if flags or help_text or metavar: + specs.append(ArgumentSpec(flags=flags, metavar=metavar, help_text=help_text)) + return True, specs + + +def parse_module(path: Path) -> ModuleDoc: + source = path.read_text(encoding="utf-8") + tree = ast.parse(source) + module_docstring = ast.get_docstring(tree) + + functions: List[FunctionDoc] = [] + classes: List[ClassDoc] = [] + + for node in tree.body: + if isinstance(node, ast.FunctionDef): + if node.name.startswith("_"): + continue + functions.append( + FunctionDoc( + name=node.name, + args=get_function_signature(node), + docstring=ast.get_docstring(node), + ) + ) + elif isinstance(node, ast.ClassDef): + if node.name.startswith("_"): + continue + methods: List[FunctionDoc] = [] + for sub in node.body: + if isinstance(sub, ast.FunctionDef) and not sub.name.startswith("_"): + methods.append( + FunctionDoc( + name=sub.name, + args=get_function_signature(sub), + docstring=ast.get_docstring(sub), + ) + ) + classes.append( + ClassDoc(name=node.name, docstring=ast.get_docstring(node), methods=methods) + ) + + has_argparse, cli_args = extract_argparse_specs(source) + + return ModuleDoc( + rel_path=path.relative_to(REPO_ROOT), + module_docstring=module_docstring, + functions=functions, + classes=classes, + cli_arguments=cli_args, + has_argparse=has_argparse, + ) + + +def read_chapter_readme(path: Path) -> Optional[str]: + for name in ("README.md", "README.adoc"): + readme = path.parent / name + if readme.exists(): + try: + content = readme.read_text(encoding="utf-8") + return "\n".join(content.splitlines()[:25]) + except Exception: + return None + return None + + +def write_module_markdown(doc: ModuleDoc) -> Path: + out_path = DOCS_DIR / doc.rel_path.with_suffix(".md") + out_path.parent.mkdir(parents=True, exist_ok=True) + lines: List[str] = [] + lines.append(f"# {doc.rel_path}") + lines.append("") + if doc.module_docstring: + lines.append(doc.module_docstring.strip()) + lines.append("") + + # CLI usage + if doc.has_argparse: + lines.append("## CLI Usage") + lines.append("") + lines.append("Run this program and see usage:") + lines.append("") + lines.append("```bash") + lines.append(f"python {doc.rel_path} --help") + lines.append("```") + if doc.cli_arguments: + lines.append("") + lines.append("Recognized arguments (parsed heuristically):") + for spec in doc.cli_arguments: + flag_str = ", ".join(spec.flags) if spec.flags else "(positional)" + detail: List[str] = [f"- {flag_str}"] + if spec.metavar: + detail.append(f"metavar: {spec.metavar}") + if spec.help_text: + detail.append(f"help: {spec.help_text}") + lines.append(" - " + "; ".join(detail)) + lines.append("") + + # Public functions + if doc.functions: + lines.append("## Functions") + lines.append("") + for fn in doc.functions: + lines.append(f"### {fn.name}{fn.args}") + if fn.docstring: + lines.append("") + lines.append(fn.docstring.strip()) + lines.append("") + + # Public classes + if doc.classes: + lines.append("## Classes") + lines.append("") + for cl in doc.classes: + lines.append(f"### class {cl.name}") + if cl.docstring: + lines.append("") + lines.append(cl.docstring.strip()) + lines.append("") + if cl.methods: + lines.append("Methods:") + for m in cl.methods: + lines.append(f"- {m.name}{m.args}") + lines.append("") + + # Chapter README snippet + snippet = read_chapter_readme(doc.rel_path) + if snippet: + lines.append("## Chapter Overview (excerpt)") + lines.append("") + lines.append("```") + lines.extend(snippet.splitlines()) + lines.append("```") + + out_path.write_text("\n".join(lines), encoding="utf-8") + return out_path + + +def write_index(modules: List[ModuleDoc]) -> Path: + index = DOCS_DIR / "index.md" + lines: List[str] = [] + lines.append("# Tiny Python Projects – API and Usage Documentation") + lines.append("") + lines.append("This documentation is auto-generated. For each chapter, explore functions, classes, and CLI usage.") + lines.append("") + + # Group by top-level directory (e.g., 01_hello) + by_top: dict[str, List[ModuleDoc]] = {} + for m in modules: + top = m.rel_path.parts[0] if len(m.rel_path.parts) > 1 else "." + by_top.setdefault(top, []).append(m) + + for top in sorted(by_top.keys()): + lines.append(f"## {top}") + lines.append("") + for m in sorted(by_top[top], key=lambda d: str(d.rel_path)): + rel_md = m.rel_path.with_suffix(".md") + lines.append(f"- [{m.rel_path}]({rel_md.as_posix()})") + lines.append("") + + lines.append("---") + lines.append("Generated by `bin/gen_docs.py`.") + index.parent.mkdir(parents=True, exist_ok=True) + index.write_text("\n".join(lines), encoding="utf-8") + return index + + +def main() -> int: + modules: List[ModuleDoc] = [] + for py in iter_python_files(REPO_ROOT): + try: + modules.append(parse_module(py)) + except SyntaxError as ex: # Skip unparsable files + print(f"Skipping {py}: {ex}") + except Exception as ex: + print(f"Error parsing {py}: {ex}") + + written: List[Path] = [] + for m in modules: + written.append(write_module_markdown(m)) + + idx = write_index(modules) + print(f"Wrote {len(written)} module docs and index at {idx}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) + diff --git a/docs/01_hello/hello01_print.md b/docs/01_hello/hello01_print.md new file mode 100644 index 000000000..d5195622c --- /dev/null +++ b/docs/01_hello/hello01_print.md @@ -0,0 +1,31 @@ +# 01_hello/hello01_print.py + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello02_comment.md b/docs/01_hello/hello02_comment.md new file mode 100644 index 000000000..6d2076990 --- /dev/null +++ b/docs/01_hello/hello02_comment.md @@ -0,0 +1,31 @@ +# 01_hello/hello02_comment.py + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello03_shebang.md b/docs/01_hello/hello03_shebang.md new file mode 100644 index 000000000..e0d799e6d --- /dev/null +++ b/docs/01_hello/hello03_shebang.md @@ -0,0 +1,31 @@ +# 01_hello/hello03_shebang.py + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello04_argparse_positional.md b/docs/01_hello/hello04_argparse_positional.md new file mode 100644 index 000000000..fe2bd96cc --- /dev/null +++ b/docs/01_hello/hello04_argparse_positional.md @@ -0,0 +1,42 @@ +# 01_hello/hello04_argparse_positional.py + +## CLI Usage + +Run this program and see usage: + +```bash +python 01_hello/hello04_argparse_positional.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); help: Name to greet + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello05_argparse_option.md b/docs/01_hello/hello05_argparse_option.md new file mode 100644 index 000000000..528639bed --- /dev/null +++ b/docs/01_hello/hello05_argparse_option.md @@ -0,0 +1,42 @@ +# 01_hello/hello05_argparse_option.py + +## CLI Usage + +Run this program and see usage: + +```bash +python 01_hello/hello05_argparse_option.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --name; metavar: name; help: Name to greet + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello06_main_function.md b/docs/01_hello/hello06_main_function.md new file mode 100644 index 000000000..f83153989 --- /dev/null +++ b/docs/01_hello/hello06_main_function.md @@ -0,0 +1,46 @@ +# 01_hello/hello06_main_function.py + +## CLI Usage + +Run this program and see usage: + +```bash +python 01_hello/hello06_main_function.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --name; metavar: name; help: Name to greet + +## Functions + +### main() + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello07_get_args.md b/docs/01_hello/hello07_get_args.md new file mode 100644 index 000000000..6568f1e63 --- /dev/null +++ b/docs/01_hello/hello07_get_args.md @@ -0,0 +1,48 @@ +# 01_hello/hello07_get_args.py + +## CLI Usage + +Run this program and see usage: + +```bash +python 01_hello/hello07_get_args.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --name; metavar: name; help: Name to greet + +## Functions + +### get_args() + +### main() + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/01_hello/hello08_formatted.md b/docs/01_hello/hello08_formatted.md new file mode 100644 index 000000000..270ece497 --- /dev/null +++ b/docs/01_hello/hello08_formatted.md @@ -0,0 +1,55 @@ +# 01_hello/hello08_formatted.py + +Author: Ken Youens-Clark +Purpose: Say hello + +## CLI Usage + +Run this program and see usage: + +```bash +python 01_hello/hello08_formatted.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --name; help: Name to greet + +## Functions + +### get_args() + +Get the command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Chapter 1: Hello, World! + +https://www.youtube.com/playlist?list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO + +Write a program to enthusiastically greet the world: + +``` +$ ./hello.py +Hello, World! +``` + +The program should also accept a name given as an optional `--name` parameter: + +``` +$ ./hello.py --name Universe +Hello, Universe! +``` + +The program should produce documentation for `-h` or `--help`: + +``` +$ ./hello.py -h +usage: hello.py [-h] [-n str] + +Say hello +``` \ No newline at end of file diff --git a/docs/02_crowsnest/solution.md b/docs/02_crowsnest/solution.md new file mode 100644 index 000000000..7d0d49652 --- /dev/null +++ b/docs/02_crowsnest/solution.md @@ -0,0 +1,54 @@ +# 02_crowsnest/solution.py + +Crow's Nest + +## CLI Usage + +Run this program and see usage: + +```bash +python 02_crowsnest/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: word; help: A word + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Crow's Nest + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPBqIwfD-0RedqsitBliLhT + +Write a program that will announce the appearance of something "off the larboard bow" to the captain of the ship. +Note that you need to "a" before a word starting with a consonant: + +``` +$ ./crowsnest.py narwhal +Ahoy, Captain, a narwhal off the larboard bow! +``` + +Or "an" before a word starting with a vowel: + +``` +$ ./crowsnest.py octopus +Ahoy, Captain, an octopus off the larboard bow! +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./crowsnest.py +usage: crowsnest.py [-h] str +crowsnest.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/03_picnic/solution.md b/docs/03_picnic/solution.md new file mode 100644 index 000000000..c010b0c19 --- /dev/null +++ b/docs/03_picnic/solution.md @@ -0,0 +1,55 @@ +# 03_picnic/solution.py + +Picnic game + +## CLI Usage + +Run this program and see usage: + +```bash +python 03_picnic/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Item(s + - - -s, --sorted; help: Sort the items + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Picnic + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMuQohHrNxRjhFTR9UlUOIa + +Write a program that will correctly format the items we're taking on our picnic. +For one item, it should print the one item: + +``` +$ ./picnic.py sandwiches +You are bringing sandwiches. +``` + +For two items, place "and" in between: + +``` +$ ./picnic.py sandwiches chips +You are bringing sandwiches and chips. +``` + +For three or more items, use commas and "and": + +``` +$ ./picnic.py sandwiches chips cake +You are bringing sandwiches, chips, and cake. +``` +``` \ No newline at end of file diff --git a/docs/04_jump_the_five/solution1.md b/docs/04_jump_the_five/solution1.md new file mode 100644 index 000000000..9b2023edc --- /dev/null +++ b/docs/04_jump_the_five/solution1.md @@ -0,0 +1,54 @@ +# 04_jump_the_five/solution1.py + +Jump the Five + +## CLI Usage + +Run this program and see usage: + +```bash +python 04_jump_the_five/solution1.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Input text + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Jump the Five + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNd1Mbu3h6SGfhD-8rRxLTp + +Write a program that will encode any number in a given string using an algorightm to "jump the five" on a standard US telephone keypad such that "1" becomes "9," "4" becomes "6," etc. +The "5" and the "0" will swap with each other. +Here is the entire substitution table: + +``` +1 => 9 +2 => 8 +3 => 7 +4 => 6 +5 => 0 +6 => 4 +7 => 3 +8 => 2 +9 => 1 +0 => 5 +``` + +Encode only the numbers and leave all other text alone: + +``` +$ ./jump.py 867-5309 +``` \ No newline at end of file diff --git a/docs/04_jump_the_five/solution2.md b/docs/04_jump_the_five/solution2.md new file mode 100644 index 000000000..24a204fa5 --- /dev/null +++ b/docs/04_jump_the_five/solution2.md @@ -0,0 +1,54 @@ +# 04_jump_the_five/solution2.py + +Jump the Five + +## CLI Usage + +Run this program and see usage: + +```bash +python 04_jump_the_five/solution2.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Input text + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Jump the Five + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNd1Mbu3h6SGfhD-8rRxLTp + +Write a program that will encode any number in a given string using an algorightm to "jump the five" on a standard US telephone keypad such that "1" becomes "9," "4" becomes "6," etc. +The "5" and the "0" will swap with each other. +Here is the entire substitution table: + +``` +1 => 9 +2 => 8 +3 => 7 +4 => 6 +5 => 0 +6 => 4 +7 => 3 +8 => 2 +9 => 1 +0 => 5 +``` + +Encode only the numbers and leave all other text alone: + +``` +$ ./jump.py 867-5309 +``` \ No newline at end of file diff --git a/docs/04_jump_the_five/solution3.md b/docs/04_jump_the_five/solution3.md new file mode 100644 index 000000000..6eafe814f --- /dev/null +++ b/docs/04_jump_the_five/solution3.md @@ -0,0 +1,54 @@ +# 04_jump_the_five/solution3.py + +Jump the Five + +## CLI Usage + +Run this program and see usage: + +```bash +python 04_jump_the_five/solution3.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Input text + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Jump the Five + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNd1Mbu3h6SGfhD-8rRxLTp + +Write a program that will encode any number in a given string using an algorightm to "jump the five" on a standard US telephone keypad such that "1" becomes "9," "4" becomes "6," etc. +The "5" and the "0" will swap with each other. +Here is the entire substitution table: + +``` +1 => 9 +2 => 8 +3 => 7 +4 => 6 +5 => 0 +6 => 4 +7 => 3 +8 => 2 +9 => 1 +0 => 5 +``` + +Encode only the numbers and leave all other text alone: + +``` +$ ./jump.py 867-5309 +``` \ No newline at end of file diff --git a/docs/04_jump_the_five/solution4.md b/docs/04_jump_the_five/solution4.md new file mode 100644 index 000000000..ec51fdf6a --- /dev/null +++ b/docs/04_jump_the_five/solution4.md @@ -0,0 +1,54 @@ +# 04_jump_the_five/solution4.py + +Jump the Five + +## CLI Usage + +Run this program and see usage: + +```bash +python 04_jump_the_five/solution4.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Input text + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Jump the Five + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNd1Mbu3h6SGfhD-8rRxLTp + +Write a program that will encode any number in a given string using an algorightm to "jump the five" on a standard US telephone keypad such that "1" becomes "9," "4" becomes "6," etc. +The "5" and the "0" will swap with each other. +Here is the entire substitution table: + +``` +1 => 9 +2 => 8 +3 => 7 +4 => 6 +5 => 0 +6 => 4 +7 => 3 +8 => 2 +9 => 1 +0 => 5 +``` + +Encode only the numbers and leave all other text alone: + +``` +$ ./jump.py 867-5309 +``` \ No newline at end of file diff --git a/docs/04_jump_the_five/solution5.md b/docs/04_jump_the_five/solution5.md new file mode 100644 index 000000000..72a0074af --- /dev/null +++ b/docs/04_jump_the_five/solution5.md @@ -0,0 +1,54 @@ +# 04_jump_the_five/solution5.py + +Jump the Five + +## CLI Usage + +Run this program and see usage: + +```bash +python 04_jump_the_five/solution5.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Input text + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Jump the Five + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNd1Mbu3h6SGfhD-8rRxLTp + +Write a program that will encode any number in a given string using an algorightm to "jump the five" on a standard US telephone keypad such that "1" becomes "9," "4" becomes "6," etc. +The "5" and the "0" will swap with each other. +Here is the entire substitution table: + +``` +1 => 9 +2 => 8 +3 => 7 +4 => 6 +5 => 0 +6 => 4 +7 => 3 +8 => 2 +9 => 1 +0 => 5 +``` + +Encode only the numbers and leave all other text alone: + +``` +$ ./jump.py 867-5309 +``` \ No newline at end of file diff --git a/docs/05_howler/solution1.md b/docs/05_howler/solution1.md new file mode 100644 index 000000000..5944b4d54 --- /dev/null +++ b/docs/05_howler/solution1.md @@ -0,0 +1,55 @@ +# 05_howler/solution1.py + +Howler + +## CLI Usage + +Run this program and see usage: + +```bash +python 05_howler/solution1.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input string or file + - - -o, --outfile; metavar: str; help: Output filename + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Howler + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNzo5zqtx0388myQkUKyrQz + +Write a program that uppercases the given text: + +``` +$ ./howler.py 'The quick brown fox jumps over the lazy dog.' +THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. +``` + +If the text names a file, uppercase the contents of the file: + +``` +$ ./howler.py ../inputs/fox.txt +THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. +``` + +If given no arguments, print a brief usage: + +``` +$ ./howler.py +usage: howler.py [-h] [-o str] str +howler.py: error: the following arguments are required: str +``` +``` \ No newline at end of file diff --git a/docs/05_howler/solution2.md b/docs/05_howler/solution2.md new file mode 100644 index 000000000..ab354e00d --- /dev/null +++ b/docs/05_howler/solution2.md @@ -0,0 +1,55 @@ +# 05_howler/solution2.py + +Low-memory Howler + +## CLI Usage + +Run this program and see usage: + +```bash +python 05_howler/solution2.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input string or file + - - -o, --outfile; metavar: str; help: Output filename + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Howler + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNzo5zqtx0388myQkUKyrQz + +Write a program that uppercases the given text: + +``` +$ ./howler.py 'The quick brown fox jumps over the lazy dog.' +THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. +``` + +If the text names a file, uppercase the contents of the file: + +``` +$ ./howler.py ../inputs/fox.txt +THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. +``` + +If given no arguments, print a brief usage: + +``` +$ ./howler.py +usage: howler.py [-h] [-o str] str +howler.py: error: the following arguments are required: str +``` +``` \ No newline at end of file diff --git a/docs/06_wc/solution.md b/docs/06_wc/solution.md new file mode 100644 index 000000000..4a741410d --- /dev/null +++ b/docs/06_wc/solution.md @@ -0,0 +1,54 @@ +# 06_wc/solution.py + +Emulate wc (word count) + +## CLI Usage + +Run this program and see usage: + +```bash +python 06_wc/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# wc (word count) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOGPw5Mu5FyhnumZjb9F6kk + +Write a Python implementation of `wc` (word count). +The program should print lines, words, and characters for each input. +Files are acceptable arguments: + +``` +$ ./wc.py ../inputs/fox.txt + 1 9 45 ../inputs/fox.txt +``` + +As is "standard in" (`STDIN`) if given no arguments: + +``` +$ cat ../inputs/fox.txt | ./wc.py + 1 9 45 +``` + +If given more than one file, also include a summary for each column: + +``` +$ ./wc.py ../inputs/*.txt + 1000 1000 5840 ../inputs/1000.txt +``` \ No newline at end of file diff --git a/docs/07_gashlycrumb/gashlycrumb_interactive.md b/docs/07_gashlycrumb/gashlycrumb_interactive.md new file mode 100644 index 000000000..695cf6cd9 --- /dev/null +++ b/docs/07_gashlycrumb/gashlycrumb_interactive.md @@ -0,0 +1,54 @@ +# 07_gashlycrumb/gashlycrumb_interactive.py + +Interactive Gashlycrumb + +## CLI Usage + +Run this program and see usage: + +```bash +python 07_gashlycrumb/gashlycrumb_interactive.py --help +``` + +Recognized arguments (parsed heuristically): + - - -f, --file; metavar: str; help: Input file + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Gashlycrumb + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWy34-9jlD2ulZxaA7mxV + +Write a program that prints the line from a file starting with a given letter: + +``` +$ ./gashlycrumb.py a +A is for Amy who fell down the stairs. +``` + +By default, the `-f` or `--file` should use the included `gashlycrumb.txt` file, but can be overridden: + +``` +$ ./gashlycrumb.py a -f alternate.txt +A is for Alfred, poisoned to death. +``` + +The structure of the file is such: + +``` +$ head alternate.txt +A is for Alfred, poisoned to death. +B is for Bertrand, consumed by meth. +C is for Cornell, who ate some glass. +``` \ No newline at end of file diff --git a/docs/07_gashlycrumb/solution1.md b/docs/07_gashlycrumb/solution1.md new file mode 100644 index 000000000..f16cc3d71 --- /dev/null +++ b/docs/07_gashlycrumb/solution1.md @@ -0,0 +1,55 @@ +# 07_gashlycrumb/solution1.py + +Lookup tables + +## CLI Usage + +Run this program and see usage: + +```bash +python 07_gashlycrumb/solution1.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); help: Letter(s + - - -f, --file; metavar: FILE; help: Input file + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Gashlycrumb + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWy34-9jlD2ulZxaA7mxV + +Write a program that prints the line from a file starting with a given letter: + +``` +$ ./gashlycrumb.py a +A is for Amy who fell down the stairs. +``` + +By default, the `-f` or `--file` should use the included `gashlycrumb.txt` file, but can be overridden: + +``` +$ ./gashlycrumb.py a -f alternate.txt +A is for Alfred, poisoned to death. +``` + +The structure of the file is such: + +``` +$ head alternate.txt +A is for Alfred, poisoned to death. +B is for Bertrand, consumed by meth. +C is for Cornell, who ate some glass. +``` \ No newline at end of file diff --git a/docs/07_gashlycrumb/solution2_dict_comp.md b/docs/07_gashlycrumb/solution2_dict_comp.md new file mode 100644 index 000000000..3c8681d2b --- /dev/null +++ b/docs/07_gashlycrumb/solution2_dict_comp.md @@ -0,0 +1,55 @@ +# 07_gashlycrumb/solution2_dict_comp.py + +Lookup tables + +## CLI Usage + +Run this program and see usage: + +```bash +python 07_gashlycrumb/solution2_dict_comp.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); help: Letter(s + - - -f, --file; metavar: FILE; help: Input file + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Gashlycrumb + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWy34-9jlD2ulZxaA7mxV + +Write a program that prints the line from a file starting with a given letter: + +``` +$ ./gashlycrumb.py a +A is for Amy who fell down the stairs. +``` + +By default, the `-f` or `--file` should use the included `gashlycrumb.txt` file, but can be overridden: + +``` +$ ./gashlycrumb.py a -f alternate.txt +A is for Alfred, poisoned to death. +``` + +The structure of the file is such: + +``` +$ head alternate.txt +A is for Alfred, poisoned to death. +B is for Bertrand, consumed by meth. +C is for Cornell, who ate some glass. +``` \ No newline at end of file diff --git a/docs/07_gashlycrumb/solution3_dict_get.md b/docs/07_gashlycrumb/solution3_dict_get.md new file mode 100644 index 000000000..703a64c8b --- /dev/null +++ b/docs/07_gashlycrumb/solution3_dict_get.md @@ -0,0 +1,55 @@ +# 07_gashlycrumb/solution3_dict_get.py + +Lookup tables + +## CLI Usage + +Run this program and see usage: + +```bash +python 07_gashlycrumb/solution3_dict_get.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); help: Letter(s + - - -f, --file; metavar: FILE; help: Input file + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Gashlycrumb + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWy34-9jlD2ulZxaA7mxV + +Write a program that prints the line from a file starting with a given letter: + +``` +$ ./gashlycrumb.py a +A is for Amy who fell down the stairs. +``` + +By default, the `-f` or `--file` should use the included `gashlycrumb.txt` file, but can be overridden: + +``` +$ ./gashlycrumb.py a -f alternate.txt +A is for Alfred, poisoned to death. +``` + +The structure of the file is such: + +``` +$ head alternate.txt +A is for Alfred, poisoned to death. +B is for Bertrand, consumed by meth. +C is for Cornell, who ate some glass. +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution1_iterate_chars.md b/docs/08_apples_and_bananas/solution1_iterate_chars.md new file mode 100644 index 000000000..fd0add4fb --- /dev/null +++ b/docs/08_apples_and_bananas/solution1_iterate_chars.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution1_iterate_chars.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution1_iterate_chars.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution2_str_replace.md b/docs/08_apples_and_bananas/solution2_str_replace.md new file mode 100644 index 000000000..e2c14e0cb --- /dev/null +++ b/docs/08_apples_and_bananas/solution2_str_replace.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution2_str_replace.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution2_str_replace.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution3_str_translate.md b/docs/08_apples_and_bananas/solution3_str_translate.md new file mode 100644 index 000000000..3bb269f52 --- /dev/null +++ b/docs/08_apples_and_bananas/solution3_str_translate.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution3_str_translate.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution3_str_translate.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution4_list_comprehension.md b/docs/08_apples_and_bananas/solution4_list_comprehension.md new file mode 100644 index 000000000..07cb805d9 --- /dev/null +++ b/docs/08_apples_and_bananas/solution4_list_comprehension.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution4_list_comprehension.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution4_list_comprehension.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution5.1_no_closure.md b/docs/08_apples_and_bananas/solution5.1_no_closure.md new file mode 100644 index 000000000..31014fb79 --- /dev/null +++ b/docs/08_apples_and_bananas/solution5.1_no_closure.md @@ -0,0 +1,59 @@ +# 08_apples_and_bananas/solution5.1_no_closure.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution5.1_no_closure.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +### new_char(char, vowel) + +Return the given vowel if a char is a vowel else the char + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution5_list_comp_function.md b/docs/08_apples_and_bananas/solution5_list_comp_function.md new file mode 100644 index 000000000..ff67a9257 --- /dev/null +++ b/docs/08_apples_and_bananas/solution5_list_comp_function.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution5_list_comp_function.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution5_list_comp_function.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution6_map_lambda.md b/docs/08_apples_and_bananas/solution6_map_lambda.md new file mode 100644 index 000000000..e61ae7164 --- /dev/null +++ b/docs/08_apples_and_bananas/solution6_map_lambda.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution6_map_lambda.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution6_map_lambda.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution7_map_function.md b/docs/08_apples_and_bananas/solution7_map_function.md new file mode 100644 index 000000000..3ea44c86f --- /dev/null +++ b/docs/08_apples_and_bananas/solution7_map_function.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution7_map_function.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution7_map_function.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/08_apples_and_bananas/solution8_regex.md b/docs/08_apples_and_bananas/solution8_regex.md new file mode 100644 index 000000000..ca65675b6 --- /dev/null +++ b/docs/08_apples_and_bananas/solution8_regex.md @@ -0,0 +1,55 @@ +# 08_apples_and_bananas/solution8_regex.py + +Apples and Bananas + +## CLI Usage + +Run this program and see usage: + +```bash +python 08_apples_and_bananas/solution8_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -v, --vowel; metavar: vowel; help: The vowel to substitute + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Apples and Bananas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMe_qrKzw6jtxzHkTOszozs + +Write a program that will substitute all the vowels in a given text with a single vowel (default "a"): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' +Tha qaack brawn fax jamps avar tha lazy dag. +``` + +The `-v` or `--vowel` can be use to specify another vowel: + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v i +Thi qiick briwn fix jimps ivir thi lizy dig. +``` + +The program should reject a `--vowel` that is not a vowel (a, e, i, o, u): + +``` +$ ./apples.py 'The quick brown fox jumps over the lazy dog.' -v x +usage: apples.py [-h] [-v str] str +apples.py: error: argument -v/--vowel: \ +invalid choice: 'x' (choose from 'a', 'e', 'i', 'o', 'u') +``` \ No newline at end of file diff --git a/docs/09_abuse/solution.md b/docs/09_abuse/solution.md new file mode 100644 index 000000000..3ff060d4e --- /dev/null +++ b/docs/09_abuse/solution.md @@ -0,0 +1,55 @@ +# 09_abuse/solution.py + +Heap abuse + +## CLI Usage + +Run this program and see usage: + +```bash +python 09_abuse/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - -a, --adjectives; metavar: adjectives; help: Number of adjectives + - - -n, --number; metavar: insults; help: Number of insults + - - -s, --seed; metavar: seed; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Abuse + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOWShq53st6NjXacHHaJurn + +Write a Shakesperean insult generator: + +``` +$ ./abuse.py +You foul, filthsome swine! +You foolish, sodden-witted ratcatcher! +You ruinous, bankrupt jolthead! +``` + +The insults are generated by randomly combining these adjectives: + +``` +bankrupt base caterwauling corrupt cullionly detestable dishonest false +filthsome filthy foolish foul gross heedless indistinguishable infected +insatiate irksome lascivious lecherous loathsome lubbery old peevish +rascaly rotten ruinous scurilous scurvy slanderous sodden-witted +thin-faced toad-spotted unmannered vile wall-eyed +``` + +With these nouns: +``` \ No newline at end of file diff --git a/docs/10_telephone/solution1.md b/docs/10_telephone/solution1.md new file mode 100644 index 000000000..328e935cf --- /dev/null +++ b/docs/10_telephone/solution1.md @@ -0,0 +1,56 @@ +# 10_telephone/solution1.py + +Telephone + +## CLI Usage + +Run this program and see usage: + +```bash +python 10_telephone/solution1.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: seed; help: Random seed + - - -m, --mutations; metavar: mutations; help: Percent mutations + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Telephone + +https://www.youtube.com/playlist?list=PLhOuww6rJJNN0T5ZKUFuEDo3ykOs1zxPU + +Write a program that randomly mutates some given text which may be given on the command line: + +``` +$ ./telephone.py 'The quick brown fox jumps over the lazy dog.' +You said: "The quick brown fox jumps over the lazy dog." +I heard : "The qu)ck brown HoN jumps over thf lazy dog." +``` + +Or from a file: + +``` +$ ./telephone.py ../inputs/fox.txt +You said: "The quick brown fox jumps over the lazy dog." +I heard : "=he quick brswn fox jumps over the*[azy dog." +``` + +The program should accept a `-m` or `--mutations` that is a floating point number between 0 and 1 that represents a percentage of mutations to introduce: + +``` +$ ./telephone.py -m .5 ../inputs/fox.txt +You said: "The quick brown fox jumps over the lazy dog." +``` \ No newline at end of file diff --git a/docs/10_telephone/solution2_list.md b/docs/10_telephone/solution2_list.md new file mode 100644 index 000000000..caad01a34 --- /dev/null +++ b/docs/10_telephone/solution2_list.md @@ -0,0 +1,56 @@ +# 10_telephone/solution2_list.py + +Telephone + +## CLI Usage + +Run this program and see usage: + +```bash +python 10_telephone/solution2_list.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: seed; help: Random seed + - - -m, --mutations; metavar: mutations; help: Percent mutations + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Telephone + +https://www.youtube.com/playlist?list=PLhOuww6rJJNN0T5ZKUFuEDo3ykOs1zxPU + +Write a program that randomly mutates some given text which may be given on the command line: + +``` +$ ./telephone.py 'The quick brown fox jumps over the lazy dog.' +You said: "The quick brown fox jumps over the lazy dog." +I heard : "The qu)ck brown HoN jumps over thf lazy dog." +``` + +Or from a file: + +``` +$ ./telephone.py ../inputs/fox.txt +You said: "The quick brown fox jumps over the lazy dog." +I heard : "=he quick brswn fox jumps over the*[azy dog." +``` + +The program should accept a `-m` or `--mutations` that is a floating point number between 0 and 1 that represents a percentage of mutations to introduce: + +``` +$ ./telephone.py -m .5 ../inputs/fox.txt +You said: "The quick brown fox jumps over the lazy dog." +``` \ No newline at end of file diff --git a/docs/11_bottles_of_beer/solution.md b/docs/11_bottles_of_beer/solution.md new file mode 100644 index 000000000..cfb9a3ac2 --- /dev/null +++ b/docs/11_bottles_of_beer/solution.md @@ -0,0 +1,62 @@ +# 11_bottles_of_beer/solution.py + +Bottles of beer song + +## CLI Usage + +Run this program and see usage: + +```bash +python 11_bottles_of_beer/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --num; metavar: number; help: How many bottles + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### verse(bottle) + +Sing a verse + +### test_verse() + +Test verse + +## Chapter Overview (excerpt) + +``` +# 99 Bottles of Beer + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNGDXdGGfp3RDXBMhJwj0Ij + +Write a song that will generate the verses to the song "99 Bottles of Beer": + +``` +$ ./bottles.py | tail + +2 bottles of beer on the wall, +2 bottles of beer, +Take one down, pass it around, +1 bottle of beer on the wall! + +1 bottle of beer on the wall, +1 bottle of beer, +Take one down, pass it around, +No more bottles of beer on the wall! +``` + +If given a `-n` or `--num` argument, generate the verses from that number down to 0: + +``` +$ ./bottles.py -n 2 +2 bottles of beer on the wall, +``` \ No newline at end of file diff --git a/docs/12_ransom/solution1_for_loop.md b/docs/12_ransom/solution1_for_loop.md new file mode 100644 index 000000000..ffeb44be8 --- /dev/null +++ b/docs/12_ransom/solution1_for_loop.md @@ -0,0 +1,63 @@ +# 12_ransom/solution1_for_loop.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution1_for_loop.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/12_ransom/solution2_for_append_list.md b/docs/12_ransom/solution2_for_append_list.md new file mode 100644 index 000000000..a7042fa34 --- /dev/null +++ b/docs/12_ransom/solution2_for_append_list.md @@ -0,0 +1,63 @@ +# 12_ransom/solution2_for_append_list.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution2_for_append_list.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/12_ransom/solution3_for_append_string.md b/docs/12_ransom/solution3_for_append_string.md new file mode 100644 index 000000000..a82b5aabe --- /dev/null +++ b/docs/12_ransom/solution3_for_append_string.md @@ -0,0 +1,63 @@ +# 12_ransom/solution3_for_append_string.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution3_for_append_string.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/12_ransom/solution4_list_comprehension.md b/docs/12_ransom/solution4_list_comprehension.md new file mode 100644 index 000000000..178b06851 --- /dev/null +++ b/docs/12_ransom/solution4_list_comprehension.md @@ -0,0 +1,63 @@ +# 12_ransom/solution4_list_comprehension.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution4_list_comprehension.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/12_ransom/solution5_shorter_list_comp.md b/docs/12_ransom/solution5_shorter_list_comp.md new file mode 100644 index 000000000..95417efe4 --- /dev/null +++ b/docs/12_ransom/solution5_shorter_list_comp.md @@ -0,0 +1,63 @@ +# 12_ransom/solution5_shorter_list_comp.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution5_shorter_list_comp.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/12_ransom/solution6_map.md b/docs/12_ransom/solution6_map.md new file mode 100644 index 000000000..387065d33 --- /dev/null +++ b/docs/12_ransom/solution6_map.md @@ -0,0 +1,63 @@ +# 12_ransom/solution6_map.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution6_map.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/12_ransom/solution7_shorter_map.md b/docs/12_ransom/solution7_shorter_map.md new file mode 100644 index 000000000..638998d82 --- /dev/null +++ b/docs/12_ransom/solution7_shorter_map.md @@ -0,0 +1,63 @@ +# 12_ransom/solution7_shorter_map.py + +Ransom note + +## CLI Usage + +Run this program and see usage: + +```bash +python 12_ransom/solution7_shorter_map.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: int; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### choose(char) + +Randomly choose an upper or lowercase letter to return + +### test_choose() + +Test choose + +## Chapter Overview (excerpt) + +``` +# Ransom + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMxWhckg7FO4cEx57WgHbd_ + +Write a program that will randomly capitalize the letters in a given piece of text a la a ransom note. +The text may be provided on the command line: + +``` +$ ./ransom.py 'The quick brown fox jumps over the lazy dog.' +THe qUICk BrOWn fOX jumPS OVEr THE LAzy DOg. +``` + +Or with a file: + +``` +$ ./ransom.py ../inputs/fox.txt +THE QUicK BRown fox JuMPS OVER THe laZY dog. +``` + +Given no arguments, the program should print a brief usage: + +``` +$ ./ransom.py +usage: ransom.py [-h] [-s int] str +ransom.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/13_twelve_days/solution.md b/docs/13_twelve_days/solution.md new file mode 100644 index 000000000..ceb4b1ff9 --- /dev/null +++ b/docs/13_twelve_days/solution.md @@ -0,0 +1,63 @@ +# 13_twelve_days/solution.py + +Twelve Days of Christmas + +## CLI Usage + +Run this program and see usage: + +```bash +python 13_twelve_days/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --num; metavar: days; help: Number of days to sing + - - -o, --outfile; metavar: FILE; help: Outfile + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### verse(day) + +Create a verse + +### test_verse() + +Test verse + +## Chapter Overview (excerpt) + +``` +# Twelve Days of Christmas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNZEMX12PE1OvSKy02UQoB4 + +Write a program that will generate the verse "The Twelve Days of Christmas" song: + +``` +$ ./twelve_days.py | tail +Ten lords a leaping, +Nine ladies dancing, +Eight maids a milking, +Seven swans a swimming, +Six geese a laying, +Five gold rings, +Four calling birds, +Three French hens, +Two turtle doves, +And a partridge in a pear tree. +``` + +The program should accept a `-n` or `--number` (default 12) to control the number of verses that are generated: + +``` +$ ./twelve_days.py -n 2 +On the first day of Christmas, +``` \ No newline at end of file diff --git a/docs/13_twelve_days/solution_emoji.md b/docs/13_twelve_days/solution_emoji.md new file mode 100644 index 000000000..ac2e01aef --- /dev/null +++ b/docs/13_twelve_days/solution_emoji.md @@ -0,0 +1,63 @@ +# 13_twelve_days/solution_emoji.py + +Twelve Days of Christmas + +## CLI Usage + +Run this program and see usage: + +```bash +python 13_twelve_days/solution_emoji.py --help +``` + +Recognized arguments (parsed heuristically): + - - -n, --num; metavar: days; help: Number of days to sing + - - -o, --outfile; metavar: FILE; help: Outfile + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### verse(day) + +Create a verse + +### test_verse() + +Test verse + +## Chapter Overview (excerpt) + +``` +# Twelve Days of Christmas + +https://www.youtube.com/playlist?list=PLhOuww6rJJNNZEMX12PE1OvSKy02UQoB4 + +Write a program that will generate the verse "The Twelve Days of Christmas" song: + +``` +$ ./twelve_days.py | tail +Ten lords a leaping, +Nine ladies dancing, +Eight maids a milking, +Seven swans a swimming, +Six geese a laying, +Five gold rings, +Four calling birds, +Three French hens, +Two turtle doves, +And a partridge in a pear tree. +``` + +The program should accept a `-n` or `--number` (default 12) to control the number of verses that are generated: + +``` +$ ./twelve_days.py -n 2 +On the first day of Christmas, +``` \ No newline at end of file diff --git a/docs/14_rhymer/solution1_regex.md b/docs/14_rhymer/solution1_regex.md new file mode 100644 index 000000000..e4696cd0f --- /dev/null +++ b/docs/14_rhymer/solution1_regex.md @@ -0,0 +1,62 @@ +# 14_rhymer/solution1_regex.py + +Make rhyming words + +## CLI Usage + +Run this program and see usage: + +```bash +python 14_rhymer/solution1_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: word; help: A word to rhyme + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +### stemmer(word) + +Return leading consonants (if any), and 'stem' of word + +### test_stemmer() + +test the stemmer + +## Chapter Overview (excerpt) + +``` +# Rhymer + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPNn2qa5ATHJ0qd-JUgM_s0 + +Write a program that will create rhyming words for a given word by removing the initial consonant sounds and substituting other sounds. +Note that the given word should not appear in the output, so "cake" will be omitted from this run: + +``` +$ ./rhymer.py cake | head +bake +blake +brake +chake +clake +crake +dake +drake +fake +flake +``` + +The rhyming words will be created by adding all the consonants plus the following consonant clusters: + +``` +bl br ch cl cr dr fl fr gl gr pl pr sc +``` \ No newline at end of file diff --git a/docs/14_rhymer/solution2_no_regex.md b/docs/14_rhymer/solution2_no_regex.md new file mode 100644 index 000000000..7a617b678 --- /dev/null +++ b/docs/14_rhymer/solution2_no_regex.md @@ -0,0 +1,62 @@ +# 14_rhymer/solution2_no_regex.py + +Make rhyming words + +## CLI Usage + +Run this program and see usage: + +```bash +python 14_rhymer/solution2_no_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: A word to rhyme + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +### stemmer(word) + +Return leading consonants (if any), and 'stem' of word + +### test_stemmer() + +test the stemmer + +## Chapter Overview (excerpt) + +``` +# Rhymer + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPNn2qa5ATHJ0qd-JUgM_s0 + +Write a program that will create rhyming words for a given word by removing the initial consonant sounds and substituting other sounds. +Note that the given word should not appear in the output, so "cake" will be omitted from this run: + +``` +$ ./rhymer.py cake | head +bake +blake +brake +chake +clake +crake +dake +drake +fake +flake +``` + +The rhyming words will be created by adding all the consonants plus the following consonant clusters: + +``` +bl br ch cl cr dr fl fr gl gr pl pr sc +``` \ No newline at end of file diff --git a/docs/14_rhymer/solution3_dict_words.md b/docs/14_rhymer/solution3_dict_words.md new file mode 100644 index 000000000..e974f38bc --- /dev/null +++ b/docs/14_rhymer/solution3_dict_words.md @@ -0,0 +1,71 @@ +# 14_rhymer/solution3_dict_words.py + +Make rhyming words + +## CLI Usage + +Run this program and see usage: + +```bash +python 14_rhymer/solution3_dict_words.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: A word to rhyme + - - -w, --wordlist; metavar: FILE + +## Functions + +### get_args() + +get command-line arguments + +### main() + +Make a jazz noise here + +### stemmer(word) + +Return leading consonants (if any), and 'stem' of word + +### test_stemmer() + +test the stemmer + +### read_wordlist(fh) + +Read the wordlist file + +### test_read_wordlist() + +test + +## Chapter Overview (excerpt) + +``` +# Rhymer + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPNn2qa5ATHJ0qd-JUgM_s0 + +Write a program that will create rhyming words for a given word by removing the initial consonant sounds and substituting other sounds. +Note that the given word should not appear in the output, so "cake" will be omitted from this run: + +``` +$ ./rhymer.py cake | head +bake +blake +brake +chake +clake +crake +dake +drake +fake +flake +``` + +The rhyming words will be created by adding all the consonants plus the following consonant clusters: + +``` +bl br ch cl cr dr fl fr gl gr pl pr sc +``` \ No newline at end of file diff --git a/docs/15_kentucky_friar/solution1_regex.md b/docs/15_kentucky_friar/solution1_regex.md new file mode 100644 index 000000000..d92d3569f --- /dev/null +++ b/docs/15_kentucky_friar/solution1_regex.md @@ -0,0 +1,61 @@ +# 15_kentucky_friar/solution1_regex.py + +Kentucky Friar + +## CLI Usage + +Run this program and see usage: + +```bash +python 15_kentucky_friar/solution1_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### fry(word) + +Drop the `g` from `-ing` words, change `you` to `y'all` + +### test_fry() + +Test fry + +## Chapter Overview (excerpt) + +``` +# The Kentucky Friar + +Write a program that will drop the final "g" of two-syllable words ending in "-ing" and also replace any occurrence of the word "you" (case-insensitive) with the word "y'all" so as to transform text into a dialect common to the US Deep South (from which your author hails). +The given text may come from the command line: + +``` +$ ./friar.py 'Do you want to do some cooking with me?' +Do y'all want to do some cookin' with me? +``` + +Or from an input file: + +``` +$ ./friar.py ../inputs/nobody.txt +I'm Nobody! Who are y'all? +Are y'all -- Nobody -- too? +Then there’s a pair of us! +Don't tell! they'd advertise -- y'all know! + +How dreary -- to be -- Somebody! +How public -- like a Frog -- +To tell one's name -- the livelong June -- +To an admirin' Bog! +``` +``` \ No newline at end of file diff --git a/docs/15_kentucky_friar/solution2_re_compile.md b/docs/15_kentucky_friar/solution2_re_compile.md new file mode 100644 index 000000000..7f7b4b3f6 --- /dev/null +++ b/docs/15_kentucky_friar/solution2_re_compile.md @@ -0,0 +1,61 @@ +# 15_kentucky_friar/solution2_re_compile.py + +Kentucky Friar + +## CLI Usage + +Run this program and see usage: + +```bash +python 15_kentucky_friar/solution2_re_compile.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### fry(word) + +Drop the `g` from `-ing` words, change `you` to `y'all` + +### test_fry() + +Test fry + +## Chapter Overview (excerpt) + +``` +# The Kentucky Friar + +Write a program that will drop the final "g" of two-syllable words ending in "-ing" and also replace any occurrence of the word "you" (case-insensitive) with the word "y'all" so as to transform text into a dialect common to the US Deep South (from which your author hails). +The given text may come from the command line: + +``` +$ ./friar.py 'Do you want to do some cooking with me?' +Do y'all want to do some cookin' with me? +``` + +Or from an input file: + +``` +$ ./friar.py ../inputs/nobody.txt +I'm Nobody! Who are y'all? +Are y'all -- Nobody -- too? +Then there’s a pair of us! +Don't tell! they'd advertise -- y'all know! + +How dreary -- to be -- Somebody! +How public -- like a Frog -- +To tell one's name -- the livelong June -- +To an admirin' Bog! +``` +``` \ No newline at end of file diff --git a/docs/15_kentucky_friar/solution3_no_regex.md b/docs/15_kentucky_friar/solution3_no_regex.md new file mode 100644 index 000000000..3f716ee37 --- /dev/null +++ b/docs/15_kentucky_friar/solution3_no_regex.md @@ -0,0 +1,61 @@ +# 15_kentucky_friar/solution3_no_regex.py + +Kentucky Friar + +## CLI Usage + +Run this program and see usage: + +```bash +python 15_kentucky_friar/solution3_no_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### fry(word) + +Drop the `g` from `-ing` words, change `you` to `y'all` + +### test_fry() + +Test fry + +## Chapter Overview (excerpt) + +``` +# The Kentucky Friar + +Write a program that will drop the final "g" of two-syllable words ending in "-ing" and also replace any occurrence of the word "you" (case-insensitive) with the word "y'all" so as to transform text into a dialect common to the US Deep South (from which your author hails). +The given text may come from the command line: + +``` +$ ./friar.py 'Do you want to do some cooking with me?' +Do y'all want to do some cookin' with me? +``` + +Or from an input file: + +``` +$ ./friar.py ../inputs/nobody.txt +I'm Nobody! Who are y'all? +Are y'all -- Nobody -- too? +Then there’s a pair of us! +Don't tell! they'd advertise -- y'all know! + +How dreary -- to be -- Somebody! +How public -- like a Frog -- +To tell one's name -- the livelong June -- +To an admirin' Bog! +``` +``` \ No newline at end of file diff --git a/docs/16_scrambler/solution.md b/docs/16_scrambler/solution.md new file mode 100644 index 000000000..00ef2049f --- /dev/null +++ b/docs/16_scrambler/solution.md @@ -0,0 +1,62 @@ +# 16_scrambler/solution.py + +Scramble the letters of words + +## CLI Usage + +Run this program and see usage: + +```bash +python 16_scrambler/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + - - -s, --seed; metavar: seed; help: Random seed + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### scramble(word) + +For words over 3 characters, shuffle the letters in the middle + +### test_scramble() + +Test scramble + +## Chapter Overview (excerpt) + +``` +# Scrambler + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPcLby3JXlKSo6duCIjh93S + +Write a program that will randomly scramble the middle parts of words of 3 letters or more in a given text which may come from the command line: + +``` +$ ./scrambler.py 'The quick brown fox jumps over the lazy dog.' +The qiuck bwron fox jmpus over the lzay dog. +``` + +Or from an input file: + +``` +$ ./scrambler.py ../inputs/fox.txt +The qucik borwn fox jpmus over the lazy dog. +``` + +The program should accept a `-s` or `--seed` value for the random seed to ensure reproducibility: + +``` +$ ./scrambler.py -s 1 ../inputs/fox.txt +The qicuk bwron fox jupms over the lazy dog. +``` +``` \ No newline at end of file diff --git a/docs/17_mad_libs/solution1_regex.md b/docs/17_mad_libs/solution1_regex.md new file mode 100644 index 000000000..39c8cf9b4 --- /dev/null +++ b/docs/17_mad_libs/solution1_regex.md @@ -0,0 +1,55 @@ +# 17_mad_libs/solution1_regex.py + +Mad Libs + +## CLI Usage + +Run this program and see usage: + +```bash +python 17_mad_libs/solution1_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + - - -i, --inputs; help: Inputs (for testing + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Mad Libs + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPnNx_Emds00y2RX1Tbk59r + +Write a "Mad Libs" program that will read a given file and prompt the user for the parts of speech indicated in angle brackets, e.g., ``, replacing those values and printing the new text a la the beloved "Mad Libs" game. +For example, the input file might look like this: + +``` +$ cat inputs/fox.txt +The quick jumps the lazy . +``` + +When run with this input, the program would prompt the user for "adjective," "noun," etc. +When all the answers have been collected, the new text will be printed: + +``` +$ ./mad.py inputs/fox.txt +Give me an adjective: scary +Give me a noun: chair +Give me a preposition: behind +Give me a noun: sky +The quick scary chair jumps behind the lazy sky. +``` + +In order to test, the program should also accept all the values as `-i` or `--inputs`: +``` \ No newline at end of file diff --git a/docs/17_mad_libs/solution2_no_regex.md b/docs/17_mad_libs/solution2_no_regex.md new file mode 100644 index 000000000..bfcb27474 --- /dev/null +++ b/docs/17_mad_libs/solution2_no_regex.md @@ -0,0 +1,63 @@ +# 17_mad_libs/solution2_no_regex.py + +Mad Libs + +## CLI Usage + +Run this program and see usage: + +```bash +python 17_mad_libs/solution2_no_regex.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + - - -i, --inputs; help: Inputs (for testing + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### find_brackets(text) + +Find angle brackets + +### test_find_brackets() + +Test for finding angle brackets + +## Chapter Overview (excerpt) + +``` +# Mad Libs + +https://www.youtube.com/playlist?list=PLhOuww6rJJNPnNx_Emds00y2RX1Tbk59r + +Write a "Mad Libs" program that will read a given file and prompt the user for the parts of speech indicated in angle brackets, e.g., ``, replacing those values and printing the new text a la the beloved "Mad Libs" game. +For example, the input file might look like this: + +``` +$ cat inputs/fox.txt +The quick jumps the lazy . +``` + +When run with this input, the program would prompt the user for "adjective," "noun," etc. +When all the answers have been collected, the new text will be printed: + +``` +$ ./mad.py inputs/fox.txt +Give me an adjective: scary +Give me a noun: chair +Give me a preposition: behind +Give me a noun: sky +The quick scary chair jumps behind the lazy sky. +``` + +In order to test, the program should also accept all the values as `-i` or `--inputs`: +``` \ No newline at end of file diff --git a/docs/18_gematria/asciitbl.md b/docs/18_gematria/asciitbl.md new file mode 100644 index 000000000..3cfecf5fb --- /dev/null +++ b/docs/18_gematria/asciitbl.md @@ -0,0 +1,64 @@ +# 18_gematria/asciitbl.py + +Make ASCII table + +## CLI Usage + +Run this program and see usage: + +```bash +python 18_gematria/asciitbl.py --help +``` + +Recognized arguments (parsed heuristically): + - - -c, --cols; metavar: int; help: Number of columns + - - -l, --lower; metavar: int; help: Lower chr value + - - -u, --upper; metavar: int; help: Upper chr value + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### cell(n) + +Format a cell + +### chunker(seq, size) + +Chunk a list into bits + +## Chapter Overview (excerpt) + +``` +# Gematria + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMI45XbeSAiLdivKhzygwgr + +Write a program that will encode each word of a given text by summing the ASCII values of the characters. +The text may come from the command line: + +``` +$ ./gematria.py 'The quick brown fox jumps over the lazy dog.' +289 541 552 333 559 444 321 448 314 +``` + +Or from an input file: + +``` +$ ./gematria.py ../inputs/fox.txt +289 541 552 333 559 444 321 448 314 +``` + +When run with no arguments, the program should print a brief usage: + +``` +$ ./gematria.py +usage: gematria.py [-h] str +gematria.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/18_gematria/solution.md b/docs/18_gematria/solution.md new file mode 100644 index 000000000..0519b7f0e --- /dev/null +++ b/docs/18_gematria/solution.md @@ -0,0 +1,62 @@ +# 18_gematria/solution.py + +Gematria + +## CLI Usage + +Run this program and see usage: + +```bash +python 18_gematria/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: text; help: Input text or file + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### word2num(word) + +Sum the ordinal values of all the characters + +### test_word2num() + +Test word2num + +## Chapter Overview (excerpt) + +``` +# Gematria + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMI45XbeSAiLdivKhzygwgr + +Write a program that will encode each word of a given text by summing the ASCII values of the characters. +The text may come from the command line: + +``` +$ ./gematria.py 'The quick brown fox jumps over the lazy dog.' +289 541 552 333 559 444 321 448 314 +``` + +Or from an input file: + +``` +$ ./gematria.py ../inputs/fox.txt +289 541 552 333 559 444 321 448 314 +``` + +When run with no arguments, the program should print a brief usage: + +``` +$ ./gematria.py +usage: gematria.py [-h] str +gematria.py: error: the following arguments are required: str +``` \ No newline at end of file diff --git a/docs/19_wod/manual1.md b/docs/19_wod/manual1.md new file mode 100644 index 000000000..9ae8e11b0 --- /dev/null +++ b/docs/19_wod/manual1.md @@ -0,0 +1,31 @@ +# 19_wod/manual1.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/manual2_list_comprehension.md b/docs/19_wod/manual2_list_comprehension.md new file mode 100644 index 000000000..154786188 --- /dev/null +++ b/docs/19_wod/manual2_list_comprehension.md @@ -0,0 +1,31 @@ +# 19_wod/manual2_list_comprehension.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/manual3_map.md b/docs/19_wod/manual3_map.md new file mode 100644 index 000000000..ef1fb0f41 --- /dev/null +++ b/docs/19_wod/manual3_map.md @@ -0,0 +1,31 @@ +# 19_wod/manual3_map.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/solution1.md b/docs/19_wod/solution1.md new file mode 100644 index 000000000..bf8a5d49b --- /dev/null +++ b/docs/19_wod/solution1.md @@ -0,0 +1,65 @@ +# 19_wod/solution1.py + +Create Workout Of (the) Day (WOD) + +## CLI Usage + +Run this program and see usage: + +```bash +python 19_wod/solution1.py --help +``` + +Recognized arguments (parsed heuristically): + - - -f, --file; metavar: FILE; help: CSV input file of exercises + - - -s, --seed; metavar: seed; help: Random seed + - - -n, --num; metavar: exercises; help: Number of exercises + - - -e, --easy; help: Halve the reps + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### read_csv(fh) + +Read the CSV input + +### test_read_csv() + +Test read_csv + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/solution2.md b/docs/19_wod/solution2.md new file mode 100644 index 000000000..c976a1dce --- /dev/null +++ b/docs/19_wod/solution2.md @@ -0,0 +1,61 @@ +# 19_wod/solution2.py + +Create Workout Of (the) Day (WOD) + +## CLI Usage + +Run this program and see usage: + +```bash +python 19_wod/solution2.py --help +``` + +Recognized arguments (parsed heuristically): + - - -f, --file; metavar: FILE; help: CSV input file of exercises + - - -s, --seed; metavar: seed; help: Random seed + - - -n, --num; metavar: exercises; help: Number of exercises + - - -e, --easy; help: Halve the reps + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### read_csv(fh) + +Read the CSV input + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/unit.md b/docs/19_wod/unit.md new file mode 100644 index 000000000..70e92e6b5 --- /dev/null +++ b/docs/19_wod/unit.md @@ -0,0 +1,37 @@ +# 19_wod/unit.py + +## Functions + +### test_read_csv() + +Test read_csv + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/using_csv1.md b/docs/19_wod/using_csv1.md new file mode 100644 index 000000000..9aa95c51e --- /dev/null +++ b/docs/19_wod/using_csv1.md @@ -0,0 +1,31 @@ +# 19_wod/using_csv1.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/using_csv2.md b/docs/19_wod/using_csv2.md new file mode 100644 index 000000000..31bd62905 --- /dev/null +++ b/docs/19_wod/using_csv2.md @@ -0,0 +1,31 @@ +# 19_wod/using_csv2.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/using_csv3.md b/docs/19_wod/using_csv3.md new file mode 100644 index 000000000..d046879b0 --- /dev/null +++ b/docs/19_wod/using_csv3.md @@ -0,0 +1,31 @@ +# 19_wod/using_csv3.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/19_wod/using_pandas.md b/docs/19_wod/using_pandas.md new file mode 100644 index 000000000..27d73ebb0 --- /dev/null +++ b/docs/19_wod/using_pandas.md @@ -0,0 +1,31 @@ +# 19_wod/using_pandas.py + +## Chapter Overview (excerpt) + +``` +# WOD (Workout of the Day) + +https://www.youtube.com/playlist?list=PLhOuww6rJJNM2jtyu3zw3aIeZ8Ov7hSy- + +Create a program that will read a CSV `-f` or `--file` of exercises (default `exercises.csv`) and create a Workout of the Day: + +``` +$ ./wod.py +Exercise Reps +------------------ ------ +Pushups 74 +Hand-stand pushups 10 +Squats 29 +Burpees 33 +``` + +The program should accept an alternate `--file`: + +``` +$ ./wod.py -f silly-exercises.csv +Exercise Reps +-------------------- ------ +Erstwhile Lunges 18 +Hanging Chads 90 +Red Barchettas 36 +``` \ No newline at end of file diff --git a/docs/20_password/harvest.md b/docs/20_password/harvest.md new file mode 100644 index 000000000..206ea0879 --- /dev/null +++ b/docs/20_password/harvest.md @@ -0,0 +1,57 @@ +# 20_password/harvest.py + +Author : Ken Youens-Clark +Date : 2019-11-23 +Purpose: Harvest parts of speech from texts + +## CLI Usage + +Run this program and see usage: + +```bash +python 20_password/harvest.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + - - -o, --outdir; metavar: str; help: Output directory + - - -l, --limit; metavar: int; help: Limit to this many + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +# Password + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMRNnUQyUkGjpztCBUCiwZt + +Cf. https://xkcd.com/936/ + +Create a program that will randomly combine words from given text(s) to create novel, memorable, unbreakable passwords: + +``` +$ ./password.py +EchinochloaJapeCollinglyRadiotrician +EthanedithiolRefleePrebudgetPolyphonism +BerriChamaecyparisOutdraftArcifera +``` + +By default, the program should read the standard word dictionary `/usr/share/dict/words` for the word list but should also accept optional positional arguments. +The program should create a list of unique words with all non-word characters removed, randomly select some `-w` or `--num_words` for each password, and join the titlecased selections into new passwords: + +``` +$ ./password.py -w 3 scarlet/* +ShouldOfferPeculiar +LongDeathWill +LikeVenerableBear +``` +``` \ No newline at end of file diff --git a/docs/20_password/solution.md b/docs/20_password/solution.md new file mode 100644 index 000000000..0ea1e07bc --- /dev/null +++ b/docs/20_password/solution.md @@ -0,0 +1,69 @@ +# 20_password/solution.py + +Password maker, https://xkcd.com/936/ + +## CLI Usage + +Run this program and see usage: + +```bash +python 20_password/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + - - -n, --num; metavar: num_passwords; help: Number of passwords to generate + - - -w, --num_words; metavar: num_words; help: Number of words to use for password + - - -m, --min_word_len; metavar: minimum; help: Minimum word length + - - -x, --max_word_len; metavar: maximum; help: Maximum word length + - - -s, --seed; metavar: seed; help: Random seed + - - -l, --l33t; help: Obfuscate letters + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +### clean(word) + +Remove non-word characters from word + +### l33t(text) + +l33t + +### ransom(text) + +Randomly choose an upper or lowercase letter to return + +## Chapter Overview (excerpt) + +``` +# Password + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMRNnUQyUkGjpztCBUCiwZt + +Cf. https://xkcd.com/936/ + +Create a program that will randomly combine words from given text(s) to create novel, memorable, unbreakable passwords: + +``` +$ ./password.py +EchinochloaJapeCollinglyRadiotrician +EthanedithiolRefleePrebudgetPolyphonism +BerriChamaecyparisOutdraftArcifera +``` + +By default, the program should read the standard word dictionary `/usr/share/dict/words` for the word list but should also accept optional positional arguments. +The program should create a list of unique words with all non-word characters removed, randomly select some `-w` or `--num_words` for each password, and join the titlecased selections into new passwords: + +``` +$ ./password.py -w 3 scarlet/* +ShouldOfferPeculiar +LongDeathWill +LikeVenerableBear +``` +``` \ No newline at end of file diff --git a/docs/20_password/unit.md b/docs/20_password/unit.md new file mode 100644 index 000000000..8d9db3f4b --- /dev/null +++ b/docs/20_password/unit.md @@ -0,0 +1,44 @@ +# 20_password/unit.py + +## Functions + +### test_clean() + +Test clean + +### test_ransom() + +Test ransom + +### test_l33t() + +Test l33t + +## Chapter Overview (excerpt) + +``` +# Password + +https://www.youtube.com/playlist?list=PLhOuww6rJJNMRNnUQyUkGjpztCBUCiwZt + +Cf. https://xkcd.com/936/ + +Create a program that will randomly combine words from given text(s) to create novel, memorable, unbreakable passwords: + +``` +$ ./password.py +EchinochloaJapeCollinglyRadiotrician +EthanedithiolRefleePrebudgetPolyphonism +BerriChamaecyparisOutdraftArcifera +``` + +By default, the program should read the standard word dictionary `/usr/share/dict/words` for the word list but should also accept optional positional arguments. +The program should create a list of unique words with all non-word characters removed, randomly select some `-w` or `--num_words` for each password, and join the titlecased selections into new passwords: + +``` +$ ./password.py -w 3 scarlet/* +ShouldOfferPeculiar +LongDeathWill +LikeVenerableBear +``` +``` \ No newline at end of file diff --git a/docs/21_tictactoe/solution1.md b/docs/21_tictactoe/solution1.md new file mode 100644 index 000000000..b03993766 --- /dev/null +++ b/docs/21_tictactoe/solution1.md @@ -0,0 +1,64 @@ +# 21_tictactoe/solution1.py + +Tic-Tac-Toe + +## CLI Usage + +Run this program and see usage: + +```bash +python 21_tictactoe/solution1.py --help +``` + +Recognized arguments (parsed heuristically): + - - -b, --board; metavar: board; help: The state of the board + - - -p, --player; metavar: player; help: Player + - - -c, --cell; metavar: cell; help: Cell 1-9 + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### format_board(board) + +Format the board + +### find_winner(board) + +Return the winner + +## Chapter Overview (excerpt) + +``` +# Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNObtig0Kr-jgTJly1x04jgz + +Create a Python program called `tictactoe.py` that will play a single round of the game Tic-Tac-Toe. +The program should accept the following parameters: + +* `-b`|`--board`: The optional state of the board for the play. This will be a string of 9 characters representing the 9 cells of the 3x3 board. The string should be composed only of `X` and `O` to denote a player occupying that cell or `.` to show that the cell is open. The default is 9 '.' as all cells are open. +* `-p`|`--player`: An optional player which must be either `X` or `O`. +* `-c`|`--cell`: An optional cell which must be in the range 1-9 (inclusive). + +Here is the usage the program should print for `-h` or `--help`: + +``` +$ ./tictactoe.py -h +usage: tictactoe.py [-h] [-b str] [-p str] [-c int] + +Tic-Tac-Toe + +optional arguments: + -h, --help show this help message and exit + -b str, --board str The state of the board (default: .........) + -p str, --player str Player (default: None) + -c int, --cell int Cell 1-9 (default: None) +``` +``` \ No newline at end of file diff --git a/docs/21_tictactoe/solution2.md b/docs/21_tictactoe/solution2.md new file mode 100644 index 000000000..b7ac96759 --- /dev/null +++ b/docs/21_tictactoe/solution2.md @@ -0,0 +1,64 @@ +# 21_tictactoe/solution2.py + +Tic-Tac-Toe + +## CLI Usage + +Run this program and see usage: + +```bash +python 21_tictactoe/solution2.py --help +``` + +Recognized arguments (parsed heuristically): + - - -b, --board; metavar: board; help: The state of the board + - - -p, --player; metavar: player; help: Player + - - -c, --cell; metavar: cell; help: Cell 1-9 + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +### format_board(board) + +Format the board + +### find_winner(board) + +Return the winner + +## Chapter Overview (excerpt) + +``` +# Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNObtig0Kr-jgTJly1x04jgz + +Create a Python program called `tictactoe.py` that will play a single round of the game Tic-Tac-Toe. +The program should accept the following parameters: + +* `-b`|`--board`: The optional state of the board for the play. This will be a string of 9 characters representing the 9 cells of the 3x3 board. The string should be composed only of `X` and `O` to denote a player occupying that cell or `.` to show that the cell is open. The default is 9 '.' as all cells are open. +* `-p`|`--player`: An optional player which must be either `X` or `O`. +* `-c`|`--cell`: An optional cell which must be in the range 1-9 (inclusive). + +Here is the usage the program should print for `-h` or `--help`: + +``` +$ ./tictactoe.py -h +usage: tictactoe.py [-h] [-b str] [-p str] [-c int] + +Tic-Tac-Toe + +optional arguments: + -h, --help show this help message and exit + -b str, --board str The state of the board (default: .........) + -p str, --player str Player (default: None) + -c int, --cell int Cell 1-9 (default: None) +``` +``` \ No newline at end of file diff --git a/docs/21_tictactoe/unit.md b/docs/21_tictactoe/unit.md new file mode 100644 index 000000000..5d2c97761 --- /dev/null +++ b/docs/21_tictactoe/unit.md @@ -0,0 +1,49 @@ +# 21_tictactoe/unit.py + +## Functions + +### test_board_no_board() + +makes default board + +### test_board_with_board() + +makes board + +### test_winning() + +test winning boards + +### test_losing() + +test losing boards + +## Chapter Overview (excerpt) + +``` +# Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNObtig0Kr-jgTJly1x04jgz + +Create a Python program called `tictactoe.py` that will play a single round of the game Tic-Tac-Toe. +The program should accept the following parameters: + +* `-b`|`--board`: The optional state of the board for the play. This will be a string of 9 characters representing the 9 cells of the 3x3 board. The string should be composed only of `X` and `O` to denote a player occupying that cell or `.` to show that the cell is open. The default is 9 '.' as all cells are open. +* `-p`|`--player`: An optional player which must be either `X` or `O`. +* `-c`|`--cell`: An optional cell which must be in the range 1-9 (inclusive). + +Here is the usage the program should print for `-h` or `--help`: + +``` +$ ./tictactoe.py -h +usage: tictactoe.py [-h] [-b str] [-p str] [-c int] + +Tic-Tac-Toe + +optional arguments: + -h, --help show this help message and exit + -b str, --board str The state of the board (default: .........) + -p str, --player str Player (default: None) + -c int, --cell int Cell 1-9 (default: None) +``` +``` \ No newline at end of file diff --git a/docs/22_itictactoe/solution1.md b/docs/22_itictactoe/solution1.md new file mode 100644 index 000000000..0bf36ac1c --- /dev/null +++ b/docs/22_itictactoe/solution1.md @@ -0,0 +1,54 @@ +# 22_itictactoe/solution1.py + +Interactive Tic-Tac-Toe using NamedTuple + +## Functions + +### main() + +Make a jazz noise here + +### get_move(state) + +Get the player's move + +### format_board(board) + +Format the board + +### find_winner(board) + +Return the winner + +## Classes + +### class State +## Chapter Overview (excerpt) + +``` +# Interactive Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOlaMDHHIQrvWZn--GGNlHU + +Write a Python program called `itictactoe.py` that will play an interactive game of Tic-Tac-Toe starting from a blank board and iterating between players `X` and `O` until the game is finished due to a draw or a win. +When the game starts, a blank board with cells 1-9 should be shown along with a prompt for the current player (always starting with `X`) to select a cell: + +``` +------------- +| 1 | 2 | 3 | +------------- +| 4 | 5 | 6 | +------------- +| 7 | 8 | 9 | +------------- +Player X, what is your move? [q to quit]: 1 +``` + +If a player tries to select an occupied cell, the move is disallowed and the same player goes until a valid choice is made: + +``` +------------- +| X | 2 | 3 | +------------- +| 4 | 5 | 6 | +``` \ No newline at end of file diff --git a/docs/22_itictactoe/solution2_typed_dict.md b/docs/22_itictactoe/solution2_typed_dict.md new file mode 100644 index 000000000..a1a16647a --- /dev/null +++ b/docs/22_itictactoe/solution2_typed_dict.md @@ -0,0 +1,54 @@ +# 22_itictactoe/solution2_typed_dict.py + +Interactive Tic-Tac-Toe using TypedDict + +## Functions + +### main() + +Make a jazz noise here + +### get_move(state) + +Get the player's move + +### format_board(board) + +Format the board + +### find_winner(board) + +Return the winner + +## Classes + +### class State +## Chapter Overview (excerpt) + +``` +# Interactive Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOlaMDHHIQrvWZn--GGNlHU + +Write a Python program called `itictactoe.py` that will play an interactive game of Tic-Tac-Toe starting from a blank board and iterating between players `X` and `O` until the game is finished due to a draw or a win. +When the game starts, a blank board with cells 1-9 should be shown along with a prompt for the current player (always starting with `X`) to select a cell: + +``` +------------- +| 1 | 2 | 3 | +------------- +| 4 | 5 | 6 | +------------- +| 7 | 8 | 9 | +------------- +Player X, what is your move? [q to quit]: 1 +``` + +If a player tries to select an occupied cell, the move is disallowed and the same player goes until a valid choice is made: + +``` +------------- +| X | 2 | 3 | +------------- +| 4 | 5 | 6 | +``` \ No newline at end of file diff --git a/docs/22_itictactoe/typehints.md b/docs/22_itictactoe/typehints.md new file mode 100644 index 000000000..df42b1a27 --- /dev/null +++ b/docs/22_itictactoe/typehints.md @@ -0,0 +1,36 @@ +# 22_itictactoe/typehints.py + +Demonstrating type hints + +## Classes + +### class State +## Chapter Overview (excerpt) + +``` +# Interactive Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOlaMDHHIQrvWZn--GGNlHU + +Write a Python program called `itictactoe.py` that will play an interactive game of Tic-Tac-Toe starting from a blank board and iterating between players `X` and `O` until the game is finished due to a draw or a win. +When the game starts, a blank board with cells 1-9 should be shown along with a prompt for the current player (always starting with `X`) to select a cell: + +``` +------------- +| 1 | 2 | 3 | +------------- +| 4 | 5 | 6 | +------------- +| 7 | 8 | 9 | +------------- +Player X, what is your move? [q to quit]: 1 +``` + +If a player tries to select an occupied cell, the move is disallowed and the same player goes until a valid choice is made: + +``` +------------- +| X | 2 | 3 | +------------- +| 4 | 5 | 6 | +``` \ No newline at end of file diff --git a/docs/22_itictactoe/typehints2.md b/docs/22_itictactoe/typehints2.md new file mode 100644 index 000000000..258e5fbf9 --- /dev/null +++ b/docs/22_itictactoe/typehints2.md @@ -0,0 +1,36 @@ +# 22_itictactoe/typehints2.py + +Demonstrating type hints + +## Classes + +### class State +## Chapter Overview (excerpt) + +``` +# Interactive Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOlaMDHHIQrvWZn--GGNlHU + +Write a Python program called `itictactoe.py` that will play an interactive game of Tic-Tac-Toe starting from a blank board and iterating between players `X` and `O` until the game is finished due to a draw or a win. +When the game starts, a blank board with cells 1-9 should be shown along with a prompt for the current player (always starting with `X`) to select a cell: + +``` +------------- +| 1 | 2 | 3 | +------------- +| 4 | 5 | 6 | +------------- +| 7 | 8 | 9 | +------------- +Player X, what is your move? [q to quit]: 1 +``` + +If a player tries to select an occupied cell, the move is disallowed and the same player goes until a valid choice is made: + +``` +------------- +| X | 2 | 3 | +------------- +| 4 | 5 | 6 | +``` \ No newline at end of file diff --git a/docs/22_itictactoe/unit.md b/docs/22_itictactoe/unit.md new file mode 100644 index 000000000..d6fcb38f9 --- /dev/null +++ b/docs/22_itictactoe/unit.md @@ -0,0 +1,49 @@ +# 22_itictactoe/unit.py + +## Functions + +### test_board_no_state() + +makes default board + +### test_board_with_state() + +makes board + +### test_winning() + +test winning states + +### test_losing() + +test losing states + +## Chapter Overview (excerpt) + +``` +# Interactive Tic-Tac-Toe + +https://www.youtube.com/playlist?list=PLhOuww6rJJNOlaMDHHIQrvWZn--GGNlHU + +Write a Python program called `itictactoe.py` that will play an interactive game of Tic-Tac-Toe starting from a blank board and iterating between players `X` and `O` until the game is finished due to a draw or a win. +When the game starts, a blank board with cells 1-9 should be shown along with a prompt for the current player (always starting with `X`) to select a cell: + +``` +------------- +| 1 | 2 | 3 | +------------- +| 4 | 5 | 6 | +------------- +| 7 | 8 | 9 | +------------- +Player X, what is your move? [q to quit]: 1 +``` + +If a player tries to select an occupied cell, the move is disallowed and the same player goes until a valid choice is made: + +``` +------------- +| X | 2 | 3 | +------------- +| 4 | 5 | 6 | +``` \ No newline at end of file diff --git a/docs/appendix_argparse/cat_n.md b/docs/appendix_argparse/cat_n.md new file mode 100644 index 000000000..fcf51b890 --- /dev/null +++ b/docs/appendix_argparse/cat_n.md @@ -0,0 +1,42 @@ +# appendix_argparse/cat_n.py + +Python version of `cat -n` + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/cat_n.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/cat_n_manual.md b/docs/appendix_argparse/cat_n_manual.md new file mode 100644 index 000000000..5b7436353 --- /dev/null +++ b/docs/appendix_argparse/cat_n_manual.md @@ -0,0 +1,42 @@ +# appendix_argparse/cat_n_manual.py + +Python version of `cat -n`, manually checking file argument + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/cat_n_manual.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: Input file + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/choices.md b/docs/appendix_argparse/choices.md new file mode 100644 index 000000000..25bf25fa8 --- /dev/null +++ b/docs/appendix_argparse/choices.md @@ -0,0 +1,43 @@ +# appendix_argparse/choices.py + +Choices + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/choices.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: color; help: Color + - - (positional); metavar: size + +## Functions + +### get_args() + +get args + +### main() + +main + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/manual.md b/docs/appendix_argparse/manual.md new file mode 100644 index 000000000..b59aba889 --- /dev/null +++ b/docs/appendix_argparse/manual.md @@ -0,0 +1,42 @@ +# appendix_argparse/manual.py + +Manually check an argument + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/manual.py --help +``` + +Recognized arguments (parsed heuristically): + - - -v, --val; metavar: int; help: Integer value between 1 and 10 + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/nargs+.md b/docs/appendix_argparse/nargs+.md new file mode 100644 index 000000000..d6cc0f298 --- /dev/null +++ b/docs/appendix_argparse/nargs+.md @@ -0,0 +1,42 @@ +# appendix_argparse/nargs+.py + +nargs=+ + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/nargs+.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: int; help: Numbers + +## Functions + +### get_args() + +get args + +### main() + +main + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/nargs2.md b/docs/appendix_argparse/nargs2.md new file mode 100644 index 000000000..1975060fd --- /dev/null +++ b/docs/appendix_argparse/nargs2.md @@ -0,0 +1,42 @@ +# appendix_argparse/nargs2.py + +nargs=2 + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/nargs2.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: int; help: Numbers + +## Functions + +### get_args() + +get args + +### main() + +main + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/one_arg.md b/docs/appendix_argparse/one_arg.md new file mode 100644 index 000000000..a9cc19b8d --- /dev/null +++ b/docs/appendix_argparse/one_arg.md @@ -0,0 +1,42 @@ +# appendix_argparse/one_arg.py + +A single positional argument + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/one_arg.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: name; help: The name to greet + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/appendix_argparse/two_args.md b/docs/appendix_argparse/two_args.md new file mode 100644 index 000000000..d381a5778 --- /dev/null +++ b/docs/appendix_argparse/two_args.md @@ -0,0 +1,43 @@ +# appendix_argparse/two_args.py + +Two positional arguments + +## CLI Usage + +Run this program and see usage: + +```bash +python appendix_argparse/two_args.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: color; help: The color of the garment + - - (positional); metavar: size; help: The size of the garment + +## Functions + +### get_args() + +get args + +### main() + +main + +## Chapter Overview (excerpt) + +``` +https://www.youtube.com/playlist?list=PLhOuww6rJJNNx06soCkb4aMFhuioQ7tY5 + +# Examples of programs using `argparse` + +This is a collection of example programs to show how you can use the standard Python module `argparse` to handle command-line aruguments. + +* `one_arg.py`: one positional argument +* `two_args.py`: two positional arguments +* `nargs2.py`: another way to handle two positional arguments +* `nargs+.py`: one or more positional arguments +* `manual.py`: manually validating an argument inside `get_args` +* `choices.py`: using `choices` to restrict values +* `cat_n.py`: a Python implementation of `cat -n` +``` \ No newline at end of file diff --git a/docs/bin/new.md b/docs/bin/new.md new file mode 100644 index 000000000..6b3cff14b --- /dev/null +++ b/docs/bin/new.md @@ -0,0 +1,46 @@ +# bin/new.py + +Author : Ken Youens-Clark +Purpose: Python program to write a Python program + +## CLI Usage + +Run this program and see usage: + +```bash +python bin/new.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); help: Program name + - - -n, --name + - - -e, --email + - - -p, --purpose + - - -f, --force; help: Overwrite existing + - - (positional); metavar: str; help: A positional argument + - - -a, --arg; metavar: str; help: A named string argument + - - -i, --int; metavar: int; help: A named integer argument + - - -f, --file; metavar: FILE; help: A readable file + - - -o, --on; help: A boolean flag + +## Functions + +### get_args() + +Get arguments + +### main() + +Make a jazz noise here + +### body(args) + +The program template + +### get_defaults() + +Get defaults from ~/.new.py + +## Classes + +### class Args \ No newline at end of file diff --git a/docs/extra/10_whitmans/solution.md b/docs/extra/10_whitmans/solution.md new file mode 100644 index 000000000..6b2505995 --- /dev/null +++ b/docs/extra/10_whitmans/solution.md @@ -0,0 +1,57 @@ +# extra/10_whitmans/solution.py + +Probabalistically subset FASTA files + +## CLI Usage + +Run this program and see usage: + +```bash +python extra/10_whitmans/solution.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: FILE + - - -p, --pct; metavar: reads; help: Percent of reads + - - -s, --seed; metavar: seed; help: Random seed value + - - -o, --outdir; metavar: DIR; help: Output directory + +## Functions + +### get_args() + +get args + +### main() + +Make a jazz noise here + +## Chapter Overview (excerpt) + +``` += Randomly Subset a FASTA file + +Write a Python program called `sampler.py` that will probabilistically sample one or more input FASTA files into an output directory. + +The inputs for this program will be generated by your `moog.py` program. +You can run `make fasta` to create files of 1K, 10K, 100K, and 1M reads in this directory. +You can then use these files for testing your program. + +The parameters for your program are: + +* One or more positional FILE arguments +* `-p`|`--pct`: a `float` value between 0 and 1 which is the percentage of reads to take (default `0.1` or 10%) +* `-s`|`--seed`: an `int` value to use for the random seed (default `None`) +* `-o`|`--outdir`: an `str` value to use for the output directory (default `'out'`). You will need to create this directory if it does not exist. Consult your `transcribe.py` program to see how to do that. + +Here is the usage your program should create for `-h` or `--help`: + +---- +$ ./sampler.py -h +usage: sampler.py [-h] [-p reads] [-s seed] [-o DIR] FILE [FILE ...] + +Probabalistically subset FASTA files + +positional arguments: + FILE Input FASTA file(s) +``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..6d087a1e9 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,171 @@ +# Tiny Python Projects – API and Usage Documentation + +This documentation is auto-generated. For each chapter, explore functions, classes, and CLI usage. + +## 01_hello + +- [01_hello/hello01_print.py](01_hello/hello01_print.md) +- [01_hello/hello02_comment.py](01_hello/hello02_comment.md) +- [01_hello/hello03_shebang.py](01_hello/hello03_shebang.md) +- [01_hello/hello04_argparse_positional.py](01_hello/hello04_argparse_positional.md) +- [01_hello/hello05_argparse_option.py](01_hello/hello05_argparse_option.md) +- [01_hello/hello06_main_function.py](01_hello/hello06_main_function.md) +- [01_hello/hello07_get_args.py](01_hello/hello07_get_args.md) +- [01_hello/hello08_formatted.py](01_hello/hello08_formatted.md) + +## 02_crowsnest + +- [02_crowsnest/solution.py](02_crowsnest/solution.md) + +## 03_picnic + +- [03_picnic/solution.py](03_picnic/solution.md) + +## 04_jump_the_five + +- [04_jump_the_five/solution1.py](04_jump_the_five/solution1.md) +- [04_jump_the_five/solution2.py](04_jump_the_five/solution2.md) +- [04_jump_the_five/solution3.py](04_jump_the_five/solution3.md) +- [04_jump_the_five/solution4.py](04_jump_the_five/solution4.md) +- [04_jump_the_five/solution5.py](04_jump_the_five/solution5.md) + +## 05_howler + +- [05_howler/solution1.py](05_howler/solution1.md) +- [05_howler/solution2.py](05_howler/solution2.md) + +## 06_wc + +- [06_wc/solution.py](06_wc/solution.md) + +## 07_gashlycrumb + +- [07_gashlycrumb/gashlycrumb_interactive.py](07_gashlycrumb/gashlycrumb_interactive.md) +- [07_gashlycrumb/solution1.py](07_gashlycrumb/solution1.md) +- [07_gashlycrumb/solution2_dict_comp.py](07_gashlycrumb/solution2_dict_comp.md) +- [07_gashlycrumb/solution3_dict_get.py](07_gashlycrumb/solution3_dict_get.md) + +## 08_apples_and_bananas + +- [08_apples_and_bananas/solution1_iterate_chars.py](08_apples_and_bananas/solution1_iterate_chars.md) +- [08_apples_and_bananas/solution2_str_replace.py](08_apples_and_bananas/solution2_str_replace.md) +- [08_apples_and_bananas/solution3_str_translate.py](08_apples_and_bananas/solution3_str_translate.md) +- [08_apples_and_bananas/solution4_list_comprehension.py](08_apples_and_bananas/solution4_list_comprehension.md) +- [08_apples_and_bananas/solution5.1_no_closure.py](08_apples_and_bananas/solution5.1_no_closure.md) +- [08_apples_and_bananas/solution5_list_comp_function.py](08_apples_and_bananas/solution5_list_comp_function.md) +- [08_apples_and_bananas/solution6_map_lambda.py](08_apples_and_bananas/solution6_map_lambda.md) +- [08_apples_and_bananas/solution7_map_function.py](08_apples_and_bananas/solution7_map_function.md) +- [08_apples_and_bananas/solution8_regex.py](08_apples_and_bananas/solution8_regex.md) + +## 09_abuse + +- [09_abuse/solution.py](09_abuse/solution.md) + +## 10_telephone + +- [10_telephone/solution1.py](10_telephone/solution1.md) +- [10_telephone/solution2_list.py](10_telephone/solution2_list.md) + +## 11_bottles_of_beer + +- [11_bottles_of_beer/solution.py](11_bottles_of_beer/solution.md) + +## 12_ransom + +- [12_ransom/solution1_for_loop.py](12_ransom/solution1_for_loop.md) +- [12_ransom/solution2_for_append_list.py](12_ransom/solution2_for_append_list.md) +- [12_ransom/solution3_for_append_string.py](12_ransom/solution3_for_append_string.md) +- [12_ransom/solution4_list_comprehension.py](12_ransom/solution4_list_comprehension.md) +- [12_ransom/solution5_shorter_list_comp.py](12_ransom/solution5_shorter_list_comp.md) +- [12_ransom/solution6_map.py](12_ransom/solution6_map.md) +- [12_ransom/solution7_shorter_map.py](12_ransom/solution7_shorter_map.md) + +## 13_twelve_days + +- [13_twelve_days/solution.py](13_twelve_days/solution.md) +- [13_twelve_days/solution_emoji.py](13_twelve_days/solution_emoji.md) + +## 14_rhymer + +- [14_rhymer/solution1_regex.py](14_rhymer/solution1_regex.md) +- [14_rhymer/solution2_no_regex.py](14_rhymer/solution2_no_regex.md) +- [14_rhymer/solution3_dict_words.py](14_rhymer/solution3_dict_words.md) + +## 15_kentucky_friar + +- [15_kentucky_friar/solution1_regex.py](15_kentucky_friar/solution1_regex.md) +- [15_kentucky_friar/solution2_re_compile.py](15_kentucky_friar/solution2_re_compile.md) +- [15_kentucky_friar/solution3_no_regex.py](15_kentucky_friar/solution3_no_regex.md) + +## 16_scrambler + +- [16_scrambler/solution.py](16_scrambler/solution.md) + +## 17_mad_libs + +- [17_mad_libs/solution1_regex.py](17_mad_libs/solution1_regex.md) +- [17_mad_libs/solution2_no_regex.py](17_mad_libs/solution2_no_regex.md) + +## 18_gematria + +- [18_gematria/asciitbl.py](18_gematria/asciitbl.md) +- [18_gematria/solution.py](18_gematria/solution.md) + +## 19_wod + +- [19_wod/manual1.py](19_wod/manual1.md) +- [19_wod/manual2_list_comprehension.py](19_wod/manual2_list_comprehension.md) +- [19_wod/manual3_map.py](19_wod/manual3_map.md) +- [19_wod/solution1.py](19_wod/solution1.md) +- [19_wod/solution2.py](19_wod/solution2.md) +- [19_wod/unit.py](19_wod/unit.md) +- [19_wod/using_csv1.py](19_wod/using_csv1.md) +- [19_wod/using_csv2.py](19_wod/using_csv2.md) +- [19_wod/using_csv3.py](19_wod/using_csv3.md) +- [19_wod/using_pandas.py](19_wod/using_pandas.md) + +## 20_password + +- [20_password/harvest.py](20_password/harvest.md) +- [20_password/solution.py](20_password/solution.md) +- [20_password/unit.py](20_password/unit.md) + +## 21_tictactoe + +- [21_tictactoe/solution1.py](21_tictactoe/solution1.md) +- [21_tictactoe/solution2.py](21_tictactoe/solution2.md) +- [21_tictactoe/unit.py](21_tictactoe/unit.md) + +## 22_itictactoe + +- [22_itictactoe/solution1.py](22_itictactoe/solution1.md) +- [22_itictactoe/solution2_typed_dict.py](22_itictactoe/solution2_typed_dict.md) +- [22_itictactoe/typehints.py](22_itictactoe/typehints.md) +- [22_itictactoe/typehints2.py](22_itictactoe/typehints2.md) +- [22_itictactoe/unit.py](22_itictactoe/unit.md) + +## appendix_argparse + +- [appendix_argparse/cat_n.py](appendix_argparse/cat_n.md) +- [appendix_argparse/cat_n_manual.py](appendix_argparse/cat_n_manual.md) +- [appendix_argparse/choices.py](appendix_argparse/choices.md) +- [appendix_argparse/manual.py](appendix_argparse/manual.md) +- [appendix_argparse/nargs+.py](appendix_argparse/nargs+.md) +- [appendix_argparse/nargs2.py](appendix_argparse/nargs2.md) +- [appendix_argparse/one_arg.py](appendix_argparse/one_arg.md) +- [appendix_argparse/two_args.py](appendix_argparse/two_args.md) + +## bin + +- [bin/new.py](bin/new.md) + +## extra + +- [extra/10_whitmans/solution.py](extra/10_whitmans/solution.md) + +## template + +- [template/template.py](template/template.md) + +--- +Generated by `bin/gen_docs.py`. \ No newline at end of file diff --git a/docs/template/template.md b/docs/template/template.md new file mode 100644 index 000000000..6fa63545f --- /dev/null +++ b/docs/template/template.md @@ -0,0 +1,30 @@ +# template/template.py + +Author : Me +Date : today +Purpose: Rock the Casbah + +## CLI Usage + +Run this program and see usage: + +```bash +python template/template.py --help +``` + +Recognized arguments (parsed heuristically): + - - (positional); metavar: str; help: A positional argument + - - -a, --arg; metavar: str; help: A named string argument + - - -i, --int; metavar: int; help: A named integer argument + - - -f, --file; metavar: FILE; help: A readable file + - - -o, --on; help: A boolean flag + +## Functions + +### get_args() + +Get command-line arguments + +### main() + +Make a jazz noise here diff --git a/notebooks/All_Chapters_Exercises.ipynb b/notebooks/All_Chapters_Exercises.ipynb new file mode 100644 index 000000000..6717682b6 --- /dev/null +++ b/notebooks/All_Chapters_Exercises.ipynb @@ -0,0 +1,40 @@ +from __future__ import annotations + +import subprocess +from pathlib import Path +from typing import Dict, List + +REPO_ROOT = Path('/workspace').resolve() +CHAPTER_PREFIXES = tuple(f"{i:02d}_" for i in range(1, 100)) + + +def discover_chapters(root: Path) -> Dict[str, Path]: + chapters: Dict[str, Path] = {} + for entry in sorted(root.iterdir()): + if entry.is_dir() and entry.name.startswith(CHAPTER_PREFIXES): + chapters[entry.name] = entry + return chapters + + +def list_programs(chapter_dir: Path) -> List[Path]: + programs: List[Path] = [] + for path in chapter_dir.glob('*.py'): + if path.name.startswith('test'): + continue + programs.append(path) + return sorted(programs) + + +def show_help(program: Path) -> str: + proc = subprocess.run(['python3', str(program), '--help'], capture_output=True, text=True) + return proc.stdout or proc.stderr + + +chapters = discover_chapters(REPO_ROOT) +print(f"Discovered {len(chapters)} chapters") +for name, path in chapters.items(): + print(f"- {name}") + programs = list_programs(path) + for prog in programs[:3]: # show up to 3 per chapter for brevity + print(f" • {prog.name} -> help below") + print(show_help(prog)) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 863bd103c..dd9abef0b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,7 @@ mypy pylint pytest yapf +mkdocs +mkdocs-material +pdoc3 +jupyter