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)
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:
pytest 7.1.3In 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:
$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 ===============================
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:
if __name__ == '__main__':
main()Here's the current lay of the land:
#!/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:
#!/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.
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.
pip install flake8 pylintTo start let's cd into 02_crowsnest and run the test.
There are loads of errors, but the first one we see is this:
> assert os.path.isfile(prg)
E AssertionError: assert False
E + where False = <function isfile at 0x102722200>('./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
bin/new.py 02_crowsnest/crowsnest.pyReturn: Ch2 Pt 2(getting started) 6:52