diff --git a/.github/workflows/auto-author-assign.yml b/.github/workflows/auto-author-assign.yml new file mode 100644 index 0000000..d77c56d --- /dev/null +++ b/.github/workflows/auto-author-assign.yml @@ -0,0 +1,15 @@ +# .github/workflows/auto-author-assign.yml +name: Auto Author Assign + +on: + pull_request_target: + types: [opened, reopened] + +permissions: + pull-requests: write + +jobs: + assign-author: + runs-on: ubuntu-latest + steps: + - uses: toshimaru/auto-author-assign@v1.6.2 \ No newline at end of file diff --git a/README.md b/README.md index fe4525d..b21dd28 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,25 @@ # SPEI -![PyPI](https://img.shields.io/pypi/v/spei?style=flat-square) ![PyPi Supported Python Versions](https://img.shields.io/pypi/pyversions/spei?style=flat-square) ![Code Size](https://img.shields.io/github/languages/code-size/martinvonk/spei?style=flat-square) ![PyPi Downloads](https://img.shields.io/pypi/dm/spei?style=flat-square) ![License](https://img.shields.io/pypi/l/spei?style=flat-square) +[![PyPI](https://img.shields.io/pypi/v/spei?style=flat-square)](https://pypi.org/project/spei/) +[![PyPi Supported Python Versions](https://img.shields.io/pypi/pyversions/spei?style=flat-square)](https://pypi.org/project/spei/) +[![Code Size](https://img.shields.io/github/languages/code-size/martinvonk/spei?style=flat-square)](https://pypi.org/project/spei/) +[![CodacyGrade](https://img.shields.io/codacy/grade/908b566912314666b84e1add22ea7d66?style=flat-square)](https://app.codacy.com/gh/martinvonk/SPEI/) +[![PyPi Downloads](https://img.shields.io/pypi/dm/spei?style=flat-square) ![License](https://img.shields.io/pypi/l/spei?style=flat-square)](https://pypi.org/project/spei/) + +[![Tests](https://img.shields.io/github/actions/workflow/status/martinvonk/spei/tests.yml?style=flat-square)](https://github.com/martinvonk/SPEI/actions/workflows/tests.yml) +[![CodacyCoverage](https://img.shields.io/codacy/coverage/908b566912314666b84e1add22ea7d66?style=flat-square)](https://app.codacy.com/gh/martinvonk/SPEI/) +[![MyPy](https://img.shields.io/badge/type_checker-mypy-2A6DB2?style=flat-square)](https://mypy-lang.org/) +[![Format: isort](https://img.shields.io/badge/imports-isort-ef8336?style=flat-square)](https://pycqa.github.io/isort/index.html) +[![Format: Black](https://img.shields.io/badge/code_style-black-black?style=flat-square)](https://github.com/psf/black) +[![Linter: flake8](https://img.shields.io/badge/linter-flake8-yellowgreen?style=flat-square)](https://flake8.pycqa.org/) +[![Linter: ruff](https://img.shields.io/badge/linter-ruff-red?style=flat-square)](https://github.com/charliermarsh/ruff) -![Tests](https://img.shields.io/github/actions/workflow/status/martinvonk/spei/tests.yml?style=flat-square) -![CodacyGrade](https://img.shields.io/codacy/grade/908b566912314666b84e1add22ea7d66?style=flat-square) -![CodacyCoverage](https://img.shields.io/codacy/coverage/908b566912314666b84e1add22ea7d66?style=flat-square) -![MyPy](https://img.shields.io/badge/%20type_checker-mypy-%231674b1?style=flat-square) -![Black](https://img.shields.io/badge/code%20style-black-black?style=flat-square) SPEI is a simple Python package to calculate drought indices for time series such as the SPI (Standardized Precipitation Index), SPEI (Standardized Precipitation Evaporation Index) and SGI (Standardized Groundwater Index). This package uses popular Python packages such as Pandas and Scipy to make it easy and versitile for the user to calculate the drought indices. Pandas Series are great for dealing with time series; providing interpolation, rolling average and other manipulation options. SciPy enables us to use all different kinds of [distributions](https://docs.scipy.org/doc/scipy/reference/stats.html#probability-distributions) to fit the data. For the calculation of potential evaporation, take a look at [pyet](https://github.com/phydrus/pyet). This is another great package that uses pandas Series to calculate different kinds of potential evaporation time series. -Please feel free to contribute or ask questions! +Please feel free to contribute or ask questions! If you happen to use this package, please refer to [pypi.org/project/spei](https://pypi.org/project/spei/) or the [github repository](https://github.com/martinvonk/spei). ## Available Drought Indices | Drought Index | Abbreviation | Literature | diff --git a/doc/_static/logo.png b/doc/_static/logo.png new file mode 100644 index 0000000..4e30a51 Binary files /dev/null and b/doc/_static/logo.png differ diff --git a/doc/_static/logo.pptx b/doc/_static/logo.pptx new file mode 100644 index 0000000..926c97f Binary files /dev/null and b/doc/_static/logo.pptx differ diff --git a/doc/_static/make_logo.py b/doc/_static/make_logo.py new file mode 100644 index 0000000..79212a8 --- /dev/null +++ b/doc/_static/make_logo.py @@ -0,0 +1,10 @@ +import matplotlib.pyplot as plt +from numpy import meshgrid, linspace + +fig, ax = plt.subplots(figsize=(27, 9)) +x, y = meshgrid((0, 100), linspace(0, 0.1, 1000)) +ax.contourf(x, y, y, cmap=plt.get_cmap("seismic_r"), levels=linspace(0, 0.1, 1000)) +ax.set_yticks([]) +ax.set_axis_off() + +fig.savefig("bg.png", dpi=1200, bbox_inches="tight", pad_inches=0) diff --git a/pyproject.toml b/pyproject.toml index ac90c62..cdf611c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ homepage = "https://github.com/martinvonk/spei" repository = "https://github.com/martinvonk/spei" [project.optional-dependencies] -linting = ["flake8"] +linting = ["flake8", "ruff"] formatting = ["black[jupyter]", "isort"] typing = ["mypy", "pandas-stubs"] pytesting = ["pytest>=7", "pytest-cov", "pytest-sugar"] @@ -54,6 +54,9 @@ ignore_missing_imports = true [tool.pytest.ini_options] pythonpath = ["src"] +[tool.ruff] +line-length = 88 + [tool.tox] legacy_tox_ini = """ [tox] @@ -86,7 +89,8 @@ legacy_tox_ini = """ basepython = python3.9 extras = linting commands = - flake8 src --max-line-length=88 + flake8 src --max-line-length=88 --ignore=E203,W503,W504 + ruff check src [testenv:coverage] description = get coverage report xml diff --git a/src/spei/_version.py b/src/spei/_version.py index f9aa3e1..e19434e 100644 --- a/src/spei/_version.py +++ b/src/spei/_version.py @@ -1 +1 @@ -__version__ = "0.3.2" +__version__ = "0.3.3" diff --git a/src/spei/utils.py b/src/spei/utils.py index 770928b..93ed57e 100644 --- a/src/spei/utils.py +++ b/src/spei/utils.py @@ -1,4 +1,4 @@ -# Type Hinting +import logging from typing import List, Optional, Tuple, Union from numpy import std @@ -24,7 +24,7 @@ def validate_series(series: Series) -> Series: if not isinstance(series, Series): if isinstance(series, DataFrame): if len(series.columns) == 1: - print( + logging.warning( "Please convert series of type pandas.DataFrame to a" "pandas.Series using DataFrame.squeeze(). Now done automatically." ) @@ -43,8 +43,8 @@ def validate_index(index: Index) -> DatetimeIndex: index = index.copy() if not isinstance(index, DatetimeIndex): - print( - f"Expected the index to be a DatetimeIndex. Automatically converted" + logging.info( + f"Expected the index to be a DatetimeIndex. Automatically converted " f"{type(index)} using pd.to_datetime(Index)" ) index = DatetimeIndex(to_datetime(index)) diff --git a/tests/test_validate.py b/tests/test_validate.py index aded2b9..1c7432e 100644 --- a/tests/test_validate.py +++ b/tests/test_validate.py @@ -1,19 +1,20 @@ import pytest +import logging from pandas import DataFrame, Series, to_datetime from spei.utils import validate_index, validate_series -def test_validate_index(capfd) -> None: - series = Series([1, 2, 3], index=[1, 2, 3]) +def test_validate_index(caplog) -> None: + caplog.set_level(logging.INFO) + series = Series([1, 2, 3], index=["2018", "2019", "2020"]) validate_index(series.index) - index = series.index msg = ( - f"Expected the index to be a DatetimeIndex. Automatically converted" - f"{type(index)} using pd.to_datetime(Index)\n" + f"Expected the index to be a DatetimeIndex. Automatically converted " + f"{type(series.index)} using pd.to_datetime(Index)\n" ) - out, _ = capfd.readouterr() - assert out == msg + print(f"{caplog.text=}") + assert msg in caplog.text def test_validate_series() -> None: @@ -21,15 +22,14 @@ def test_validate_series() -> None: validate_series([1, 2, 3]) -def test_validate_series_df_1d(capfd) -> None: +def test_validate_series_df_1d(caplog) -> None: df = DataFrame({"s": [1, 2, 3]}, index=to_datetime([1, 2, 3])) validate_series(df) msg = ( "Please convert series of type pandas.DataFrame to a" "pandas.Series using DataFrame.squeeze(). Now done automatically.\n" ) - out, _ = capfd.readouterr() - assert out == msg + assert msg in caplog.text def test_validate_series_df_2d() -> None: