diff --git a/.python-version b/.python-version new file mode 100644 index 000000000..58ee0cede --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11.0b5 diff --git a/01_hello/README.md b/01_hello/README.md index 1c36ec96a..32e9440df 100644 --- a/01_hello/README.md +++ b/01_hello/README.md @@ -1,47 +1,2 @@ # 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 - -optional arguments: - -h, --help show this help message and exit - -n str, --name str The name to greet (default: World) -``` - -Run `pytest -xv test.py` (or `make test`) to ensure you pass all the tests: - -``` -$ make test -pytest -xv test.py -============================= test session starts ============================== -... -collected 4 items - -test.py::test_exists PASSED [ 25%] -test.py::test_usage PASSED [ 50%] -test.py::test_default PASSED [ 75%] -test.py::test_input PASSED [100%] - -============================== 4 passed in 0.41s =============================== -``` diff --git a/01_hello/_testhello.py b/01_hello/_testhello.py new file mode 100755 index 000000000..124052113 --- /dev/null +++ b/01_hello/_testhello.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 +# Purpose: Say hello + +import argparse + +parser = argparse.ArgumentParser(description="Say Hello") +parser.add_argument("-n", "--name", metavar="namee", default="World", help="Name to greet") +args = parser.parse_args() +print("Hello, " + args.name + "!") diff --git a/01_hello/hello.py b/01_hello/hello.py new file mode 100755 index 000000000..c57988519 --- /dev/null +++ b/01_hello/hello.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +""" +Author: Noel Tanner +Purpose: Say hello +""" + +import argparse + + +def get_args(): + """Get the command-line arguments""" + + parser = argparse.ArgumentParser(description="Say Hello") + parser.add_argument("-n", "--name", metavar="name", default="World", help="Name to greet") + return parser.parse_args() + + +def main(): + """main""" + + args = get_args() + print("Hello, " + args.name + "!") + + +if __name__ == "__main__": + main() diff --git a/01_hello/hello_test.py b/01_hello/hello_test.py new file mode 100755 index 000000000..f6a903f29 --- /dev/null +++ b/01_hello/hello_test.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""tests for hello.py""" + +import os +from subprocess import getoutput, getstatusoutput + +prg = "./hello.py" + + +# -------------------------------------------------- +def test_exists(): + """exists""" + + assert os.path.isfile(prg) + + +# -------------------------------------------------- +def test_runnable(): + """Runs using python3""" + + out = getoutput(f"python3 {prg}") + assert out.strip() == "Hello, World!" + + +# -------------------------------------------------- +def test_executable(): + """Says 'Hello, World!' by default""" + + out = getoutput(prg) + assert out.strip() == "Hello, World!" + + +# -------------------------------------------------- +def test_usage(): + """usage""" + + for flag in ["-h", "--help"]: + rv, out = getstatusoutput(f"{prg} {flag}") + assert rv == 0 + assert out.lower().startswith("usage") + + +# -------------------------------------------------- +def test_input(): + """test for input""" + + for val in ["Universe", "Multiverse"]: + for option in ["-n", "--name"]: + rv, out = getstatusoutput(f"{prg} {option} {val}") + assert rv == 0 + assert out.strip() == f"Hello, {val}!" diff --git a/01_hello/test.py b/01_hello/test.py old mode 100755 new mode 100644 index d0cedd1c2..651047964 --- a/01_hello/test.py +++ b/01_hello/test.py @@ -1,10 +1,10 @@ -#!/usr/bin/env python3 +#!/Users/noeltanner/.pyenv/shims/python """tests for hello.py""" import os -from subprocess import getstatusoutput, getoutput +from subprocess import getoutput, getstatusoutput -prg = './hello.py' +prg = "./hello.py" # -------------------------------------------------- @@ -18,8 +18,8 @@ def test_exists(): def test_runnable(): """Runs using python3""" - out = getoutput(f'python3 {prg}') - assert out.strip() == 'Hello, World!' + out = getoutput(f"python3 {prg}") + assert out.strip() == "Hello, World!" # -------------------------------------------------- @@ -27,25 +27,25 @@ def test_executable(): """Says 'Hello, World!' by default""" out = getoutput(prg) - assert out.strip() == 'Hello, World!' + assert out.strip() == "Hello, World!" # -------------------------------------------------- def test_usage(): """usage""" - for flag in ['-h', '--help']: - rv, out = getstatusoutput(f'{prg} {flag}') + for flag in ["-h", "--help"]: + rv, out = getstatusoutput(f"{prg} {flag}") assert rv == 0 - assert out.lower().startswith('usage') + assert out.lower().startswith("usage") # -------------------------------------------------- def test_input(): """test for input""" - for val in ['Universe', 'Multiverse']: - for option in ['-n', '--name']: - rv, out = getstatusoutput(f'{prg} {option} {val}') + for val in ["Universe", "Multiverse"]: + for option in ["-n", "--name"]: + rv, out = getstatusoutput(f"{prg} {option} {val}") assert rv == 0 - assert out.strip() == f'Hello, {val}!' + assert out.strip() == f"Hello, {val}!" diff --git a/01_hello/test_hello01_print.py b/01_hello/test_hello01_print.py new file mode 100755 index 000000000..d0cedd1c2 --- /dev/null +++ b/01_hello/test_hello01_print.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""tests for hello.py""" + +import os +from subprocess import getstatusoutput, getoutput + +prg = './hello.py' + + +# -------------------------------------------------- +def test_exists(): + """exists""" + + assert os.path.isfile(prg) + + +# -------------------------------------------------- +def test_runnable(): + """Runs using python3""" + + out = getoutput(f'python3 {prg}') + assert out.strip() == 'Hello, World!' + + +# -------------------------------------------------- +def test_executable(): + """Says 'Hello, World!' by default""" + + out = getoutput(prg) + assert out.strip() == 'Hello, World!' + + +# -------------------------------------------------- +def test_usage(): + """usage""" + + for flag in ['-h', '--help']: + rv, out = getstatusoutput(f'{prg} {flag}') + assert rv == 0 + assert out.lower().startswith('usage') + + +# -------------------------------------------------- +def test_input(): + """test for input""" + + for val in ['Universe', 'Multiverse']: + for option in ['-n', '--name']: + rv, out = getstatusoutput(f'{prg} {option} {val}') + assert rv == 0 + assert out.strip() == f'Hello, {val}!' diff --git a/appendix/SETUP_WINDOWS.pdf b/appendix/SETUP_WINDOWS.pdf deleted file mode 100644 index 93306461d..000000000 Binary files a/appendix/SETUP_WINDOWS.pdf and /dev/null differ diff --git a/extra/02_dna/README.pdf b/extra/02_dna/README.pdf deleted file mode 100644 index 561a59739..000000000 Binary files a/extra/02_dna/README.pdf and /dev/null differ diff --git a/extra/02_spanish/README.pdf b/extra/02_spanish/README.pdf deleted file mode 100644 index ac8e0afca..000000000 Binary files a/extra/02_spanish/README.pdf and /dev/null differ diff --git a/extra/02_strings/README.pdf b/extra/02_strings/README.pdf deleted file mode 100644 index b28d92414..000000000 Binary files a/extra/02_strings/README.pdf and /dev/null differ diff --git a/extra/03_lister/README.pdf b/extra/03_lister/README.pdf deleted file mode 100644 index 7699475a5..000000000 Binary files a/extra/03_lister/README.pdf and /dev/null differ diff --git a/extra/04_days/README.pdf b/extra/04_days/README.pdf deleted file mode 100644 index 3c0edb291..000000000 Binary files a/extra/04_days/README.pdf and /dev/null differ diff --git a/extra/07_proteins/README.pdf b/extra/07_proteins/README.pdf deleted file mode 100644 index b36792308..000000000 Binary files a/extra/07_proteins/README.pdf and /dev/null differ diff --git a/extra/08_rna/README.pdf b/extra/08_rna/README.pdf deleted file mode 100644 index f71653e1c..000000000 Binary files a/extra/08_rna/README.pdf and /dev/null differ diff --git a/extra/09_moog/README.pdf b/extra/09_moog/README.pdf deleted file mode 100644 index a85250e07..000000000 Binary files a/extra/09_moog/README.pdf and /dev/null differ diff --git a/extra/10_whitmans/README.pdf b/extra/10_whitmans/README.pdf deleted file mode 100644 index b02afa4df..000000000 Binary files a/extra/10_whitmans/README.pdf and /dev/null differ diff --git a/notes.md b/notes.md new file mode 100644 index 000000000..3c751f5b5 --- /dev/null +++ b/notes.md @@ -0,0 +1,167 @@ +## Chapter 1 + +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 + +optional arguments: + -h, --help show this help message and exit + -n str, --name str The name to greet (default: World) +``` + +## Python testing +While python does comes with a built-in tester (see unittest) we're going to be using a external library called **pytest**. It's a basic pip install: + +``` +pip install pytest +``` +More info found here: + +https://pypi.org/project/pytest/ + +I always like to make sure a package has installed correctly, so I'll run this to make sure it's installed: + +``` +pip list | grep 'pytest' +``` +The result when I run it shows it's running version 7.1.3: +```bash +pytest 7.1.3 +``` + +In order for the test to run, you'll need to change directory to the same level as the test and the file you'd like to test. In my case I hopped over to the directory 01_hello like so: + +```bash +$pwd +tiny_python_projects/01_hello on  master [!?] via 🐍 v3.11.0b5 ❯ +``` + +Run `pytest -xv test.py` (or `make test`) to ensure you pass all the tests: + +>Quick note - "make test" was provided by the author.The make test is simply a makefile that executes a command. It's the same as "pytest -xv test.py". He uses it to save time typing the same command. + +``` +$ pytest -xv test.py +============================= test session starts ============================== +... +collected 4 items + +test.py::test_exists PASSED [ 25%] +test.py::test_usage PASSED [ 50%] +test.py::test_default PASSED [ 75%] +test.py::test_input PASSED [100%] + +============================== 4 passed in 0.41s =============================== +``` + +## Ch 1 Pt. 9: +https://www.youtube.com/watch?v=aBZhN7ZxezU&list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO&index=9&ab_channel=KenYouens-Clark + +**Running a test** + - the "make test" command just runs pytest -xv test.py + - Same for vsc testing icon it's just a gui version of pytest -xv test.py + +**Dunder name** +So we've used this before. Depending if we (humans) are calling a script vs a python script calling it we'll get different behaviors. We're going to add it to the end: + +```python +if __name__ == '__main__': + main() +``` + +Here's the current lay of the land: +```python +#!/usr/bin/env python3 +# Purpose: Say hello + +import argparse + +def main(): + parser = argparse.ArgumentParser(description="Say Hello") + parser.add_argument("-n", "--name", metavar="name", default="World", help="Name to greet") + return parser.parse_args() + args = get_args() + print("Hello, " + args.name + "!") + + +if __name__ == "__main__": + main() + +``` + +As a general practice it's good to minimize what's in the main function. As such, let's move this parsing outta the main and put it into it's own function. This is the new layout: + +```python +#!/usr/bin/env python3 +# Purpose: Say hello + +import argparse + + +def get_args(): + parser = argparse.ArgumentParser(description="Say Hello") + parser.add_argument("-n", "--name", metavar="name", default="World", help="Name to greet") + return parser.parse_args() + + +def main(): + args = get_args() + print("Hello, " + args.name + "!") + + +if __name__ == "__main__": + main() + +``` + +Main will still be the first thing we'll run because we have the dunder name at the end. + +## Ch 1 Pt. 10 (formatting code): +https://www.youtube.com/watch?v=TOGDMxh5tkk&list=PLhOuww6rJJNP7UvTeF6_tQ1xcubAs9hvO&index=10&ab_channel=KenYouens-Clark + +So our code is ok, but it does not really match the python standards. To help us with this we'll need to install a few more tools. Specifically it will be flake8 and pylint. + +```python +pip install flake8 pylint +``` + +# Chapter 2 + +To start let's cd into 02_crowsnest and run the test. + +There are loads of errors, but the first one we see is this: + +```bash +> assert os.path.isfile(prg) +E AssertionError: assert False +E + where False = ('./crowsnest.py') +``` + +It failed as there is no file. At least we know what to call it. So let's make a file in 02_crowsnest called "crowsnest.py". Rather than building by hand we'll use the new.py file + +```python +bin/new.py 02_crowsnest/crowsnest.py +``` + +Return: Ch2 Pt 2(getting started) +6:52