{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Contributing\n", "\n", "Contributions to ObsPlus are welcomed and appreciated. Before proceeding please be aware of our [code of conduct](https://github.com/CDCgov/template/blob/master/code-of-conduct.md).\n", "\n", "\n", "## Getting setup\n", "\n", "The following steps are needed to setup `ObsPlus` for development:\n", "\n", "### 1. Clone ObsPlus\n", "\n", "```bash\n", "git clone https://github.com/niosh-mining/obsplus \n", "```\n", "\n", "### 2. Pull tags\n", "\n", "Make sure to pull all of the latest git tags so the dynamic versioning provided by [versioneer](https://github.com/warner/python-versioneer) works.\n", "\n", "**NOTE:** This step is important if some time has passed since ObsPlus has been cloned\n", "\n", "```bash\n", "git pull origin master --tags\n", "```\n", "\n", "### 3. Create a virtual environment (optional)\n", "\n", "Create and activate a virtual environment so ObsPlus will not mess with the base (or system) python installation.\n", "\n", "If you are using [Anaconda](https://www.anaconda.com/):\n", "\n", "```bash\n", "conda create -n obsplus_dev obspy pandas pre-commit \n", "conda activate obsplus_dev\n", "cd obsplus\n", "```\n", "\n", "### 4. Install ObsPlus in development mode\n", "\n", "```bash\n", "pip install -e .[dev]\n", "```\n", "\n", "### 5. Setup precommit hooks\n", "\n", "ObsPlus uses several [pre-commit](https://pre-commit.com/) hooks to ensure the code stays tidy.\n", "\n", "```bash\n", "pre-commit install -f\n", "```\n", "\n", "## Branching and versioning\n", "\n", "We create new features or bug fixes in their own branches and merge them into master via pull requests. We may switch to a more complex branching model if the need arises.\n", "\n", "If substantial new features have been added since the last release we will bump the minor version. If only bug fixes/minor changes have been made, only the patch version will be bumped. Like most python projects, we loosely follow [semantic versioning](https://semver.org/) in terms that we will not bump the major version until ObsPlus is stable.\n", "\n", "\n", "## Running the tests\n", "\n", "The tests suite is run with [pytest](https://docs.pytest.org/en/stable/). Make sure your current directory is set to the cloned ObsPlus repo and you have followed the development setup instructions listed above. Invoke pytest from the command line:\n", "\n", "```bash\n", "pytest tests\n", "```\n", "\n", "## Building the documentation\n", "\n", "The documentation can be built using the script called \"make_docs.py\" in the scripts directory. If you have followed the instructions above all the required dependencies should be installed.\n", "\n", "```bash\n", "python scripts/make_docs.py\n", "```\n", "\n", "The docs can then be accessed by double clicking on the newly created html index at docs/_build/html/index.html.\n", "\n", "\n", "## General guidelines\n", "\n", "\n", "ObsPlus uses [Black](https://github.com/ambv/black) and [flake8](http://flake8.pycqa.org/en/latest/) for code linting. If you have properly installed ObsPlus' pre-commit hooks they will be invoked automatically when you make a git commit. If any complaints are raised simply address them and try again.\n", "\n", "Use [numpy style docstrings](https://docs.scipy.org/doc/numpy/docs/howto_document.html). All public code (doesn't start with a `_`) should have a \"full\" docstring but private code (starts with a `_`) can have an abbreviated docstring.\n", "\n", "\n", "ObsPlus makes extensive use of Python 3's [type hints](https://docs.python.org/3/library/typing.html). You are encouraged to annotate any public functions/methods with type hints. \n", "\n", "\n", "Prefer `pathlib.Path` to strings when working with paths. However, when dealing with millions of files (e.g., ObsPlus' indexers) strings may be preferred for efficiency.\n", "\n", "\n", "Follow [PEP8's guidelines for imports](https://www.python.org/dev/peps/pep-0008/#imports).\n", "\n", "\n", "### Example functions\n", "\n", "```python\n", "from typing import Optional, Union\n", "\n", "import pandas as pd\n", "\n", "\n", "# example public function\n", "def example_func(df: pd.DataFrame, to_add: Optional[Union[int, float]]) -> pd.DataFrame:\n", " \"\"\"\n", " A simple, one line explanation of what this function does.\n", " \n", " Additional details which might be useful, and are not limited to one line.\n", " In fact, they might span several lines, especially if the author of the\n", " docstring tends to include more details than needed.\n", " \n", " Parameters\n", " ----------\n", " df\n", " A description of this parameter\n", " to_add\n", " A description of this parameter\n", " \n", " Returns\n", " -------\n", " If needed, more information about what this function returns. You shouldn't\n", " simply specify the type here since that is already given by the type annotation.\n", " \n", " Examples\n", " --------\n", " >>> # Examples are included in the doctest style\n", " >>> import numpy as np\n", " >>> import pandas as pd\n", " >>> \n", " >>> df = pd.DataFrame(np.random(10))\n", " >>> out = example_func(df) \n", " \"\"\"\n", " out = df.copy()\n", " if to_add is not None:\n", " out = out + to_add\n", " return out\n", "\n", "\n", "# example private function\n", "def _recombobulate(df, arg1, arg2):\n", " \"\"\" \n", " A private function can have a simple (multi-line) snippet and doesn't need as \n", " much detail or type hinting as a public function.\n", " \"\"\"\n", "```\n", "\n", "\n", "## Working with dataframes\n", "\n", "Column names should be snake_cased whenever possible.\n", "\n", "\n", "Always access columns with getitem and not getattr (ie use `df['column_name']` not `df.column_name`).\n", "\n", "\n", "Prefer creating a new `DataFrame`/`Series` to modifying them inplace. Inplace modifications should require opting in (usually through an `inplace` key word argument).\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" } }, "nbformat": 4, "nbformat_minor": 4 }