# Using an EI Python Project Checkout the files from Github. cd /path/to/where/you/want/it git clone https://github.com/danielpi/JGRAB-Processing.git cd JGRAB-Processing Create a virtual environment python3 -m venv .venv source .venv/bin/activate Install the required packages pip install -r requirements.txt Then follow the instructions in the README file for how to use the program. # Creating a Python Project This file describes some best practices for setting up a python project. Create a new repository on Github (should we have a template???) Add a README.md file and fill it in. This file will be rendered on the first page of your github project page. It should contain all the information required for someone to make use of your project. The file is a text file with [Markdown](https://daringfireball.net/projects/markdown/syntax) formatting. ## Virtual Environments Create a [virtual environment](https://docs.python.org/3/library/venv.html) and then [activate](https://docs.python.org/3/tutorial/venv.html) it. This will allow your project to have its own set of independent python packages (avoiding conflicts or dependancy issues). In your project folder type python3 -m venv .venv source .venv/bin/activate This will create a hidden folder called .venv in your project directory. It will ## Setup.py The most important file is `setup.py` which exists at the root of your project directory. For an example, see the [setup.py](https://github.com/pypa/sampleproject/blob/db5806e0a3204034c51b1c00dde7d5eb3fa2532e/setup.py) in the [PyPA sample project](https://github.com/pypa/sampleproject). `setup.py` serves two primary functions: 1. It’s the file where various aspects of your project are configured. The primary feature of `setup.py`is that it contains a global `setup()` function. The keyword arguments to this function are how specific details of your project are defined. The most relevant arguments are explained in [the section below](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#setup-args). 2. It’s the command line interface for running various commands that relate to packaging tasks. To get a listing of available commands, run `python setup.py --help-commands`. Add __init__.py and files. You can then install the program in development mode with pip install -e ./ If everything has worked you can open a python REPL and import your package. ### Project Workflow Use a Make file for creating project workflows https://makefiletutorial.com ## Type Checking Python is a strongly typed, dynamic programming language. This means that types don't need to be specified because they will be inferred by the compiler. This makes the language able to be written quickly, but it does mean that code can be more difficult to reason about. To help in this area type hinting was added, meaning that you can write out the expected type signatures. However by default they won't be checked. To make code easier to follow it is recommended to use [Type Hinting](https://fastapi.tiangolo.com/python-types/) To help catch issues with the code it is recommended to use a [Type Checker](https://www.infoworld.com/article/3575079/4-python-type-checkers-to-keep-your-code-clean.html) such as [Mypy](https://mypy-lang.org) To use Mypy add the following to your make file check: mypy jgrab_processing Then periodically call make check ## Importing 3rd Party Packages In your projects virtual environment install the packages that you need using pip. pip install matplotlib You can check which packages are installed by typing pip freeze To update your requirements file pip freeze > requirements.txt Then you can import them all with pip install -r requirements.txt ### Further Reading - https://docs.python-guide.org/writing/structure/ - https://changhsinlee.com/python-package/ - https://antonz.org/makefile-automation/ - https://packaging.python.org/en/latest/ # Testing https://www.dataquest.io/blog/unit-tests-python/ Create a file in your project folder called test.py You then need to import the unittest framework (a part of Python) and your own code ```python import unittest from myCode import myModule ``` You can then create a class to hold your tests ```python class TestCalculations(unittest.TestCase): ``` Then write a method for each test. Use the assert range of functions from unittest to check calculations made by your code ```python def test_sum(self): calculation = Calculations(8, 2) self.assertEqual(calculation.get_sum(), 10, 'The sum is wrong.') ``` At the bottom of the file add some code so that the unittest.main function will run your tests ```python if __name__ == '__main__': unittest.main() ``` You can then run all of your tests by running the test file ```shell python test.py ``` # Tips, tricks and other oddities ## Why do we use the "-m" switch on the command line sometimes The -m switch tells python that you are providing a module name rather than a file name. This is especially useful for stdlib modules because we often know the module name but not the filename $ python -m venv .venv In the example above the module name is venv, which is part of the python standard library (.venv is the path to a new directory that is required by the venv module). A good explanation from [stack overflow](https://stackoverflow.com/questions/7610001/what-is-the-purpose-of-the-m-switch). The detailed descriptions are included in [PEP338](https://peps.python.org/pep-0338/) and [PEP366](https://peps.python.org/pep-0366/). [Boring Python (Dependency Management)](https://www.b-list.org/weblog/2022/may/13/boring-python-dependencies/) https://alpopkes.com/posts/python/packaging_tools/