From 69b06d99904932df2d3ebf6e39d5c89b15967920 Mon Sep 17 00:00:00 2001 From: LegrandNico Date: Fri, 24 May 2024 10:59:58 +0200 Subject: [PATCH 1/3] rename to cardioception --- .github/workflows/pypi.yml | 2 +- README.md | 22 +++++++++++----------- docs/source/cite.md | 2 +- docs/source/index.md | 6 +++--- docs/source/measuring.md | 8 ++++---- docs/source/stats.md | 8 ++++---- docs/source/user_guide.md | 2 +- setup.py | 4 ++-- tests/test_reports.py | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 78f4d6f..eb99669 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest environment: name: pypi - url: https://pypi.org/p/cardioception-toolbox + url: https://pypi.org/p/cardioception permissions: id-token: write # IMPORTANT: mandatory for trusted publishing steps: diff --git a/README.md b/README.md index c1c1a1c..1d3f9ae 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -[![GitHub license](https://img.shields.io/github/license/LegrandNico/cardioception-toolbox)](https://github.com/LegrandNico/cardioception-toolbox/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/LegrandNico/cardioception-toolbox)](https://github.com/LegrandNico/cardioception-toolbox/releases/) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![pip](https://badge.fury.io/py/cardioception-toolbox.svg)](https://badge.fury.io/py/cardioception-toolbox) [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) +[![GitHub license](https://img.shields.io/github/license/LegrandNico/cardioception)](https://github.com/LegrandNico/cardioception/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/LegrandNico/cardioception)](https://github.com/LegrandNico/cardioception/releases/) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![pip](https://badge.fury.io/py/cardioception.svg)](https://badge.fury.io/py/cardioception) [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) *** # Cardioception toolbox -cardioception +cardioception The Cardioception Python Toolbox is a fork of the [original cardioception repository](https://github.com/embodied-computation-group/Cardioception) that I ([Nicolas Legrand](https://github.com/LegrandNico/)) created while working in [the ECG lab](https://www.the-ecg.org/) from 2019 to 2022. My previous lab has taken full control of the repository since then, meaning that I am unfortunately unable to maintain it as it should be. This repository allows me to pursue the maintenance of the package, aiming to provide reliable and robust tasks to measure cardiac interoception, together with computational modelling tools to analyse data gathered with these tasks. @@ -36,7 +36,7 @@ If you have questions regarding the tasks, want to report a bug or discuss data ## Using the Python Package Index * The most recent version can be installed uing: - `pip install cardioception-toolbox` + `pip install cardioception` * The current development branch can be installed using `pip install git+https://github.com/LegrandNico/Cardioception.git` @@ -118,7 +118,7 @@ parameters['win'].close() This minimal example will run the Heart Rate Discrimination task with a total of 10 trials using a Psi staircase. -We provide standard scripts in the [wrappers](https://github.com/LegrandNico/cardioception-toolbox/tree/master/wrappers) folder that can be adapted to your needs. We recommend copying this script in your local task folder if you want to parametrize it to fit your needs. The tasks can then easily be executed by running the corresponding wrapper file (e.g. in a terminal). +We provide standard scripts in the [wrappers](https://github.com/LegrandNico/cardioception/tree/master/wrappers) folder that can be adapted to your needs. We recommend copying this script in your local task folder if you want to parametrize it to fit your needs. The tasks can then easily be executed by running the corresponding wrapper file (e.g. in a terminal). ## Creating a shortcut (Windows) @@ -136,7 +136,7 @@ pause ## The Heartbeat Counting task - + This module is an implementation of the classic "heartbeat counting task" (HCT)1,2 in which participants attend to their heartbeats in intervals of various lengths. Afterwards, the participant indicates the number of counted heartbeats, and a score is computed to represent their accuracy. In the original version1, the task started with a resting period of 60 seconds and consisted of three estimation sessions (25, 35, and 45 seconds) interleaved with resting periods of 30 seconds in the following order: @@ -144,7 +144,7 @@ By default, this task implements the version used in recent publications 4< ## The Heart Rate Discrimination task - + This task implements an adaptive psychophysical procedure for estimating participants' ability to discriminate their heart rate. In each trial, participants attend to their heartbeat sensations for five seconds and estimate their average heart rate. Immediately following this period, a cardiac feedback stimulus of 5 tones is played at a particular BPM frequency. The frequency is determined as their estimated average BPM plus or minus an intensity value that is updated by an adaptive staircase procedure (up/down or psi). @@ -169,8 +169,8 @@ You can also analyze the results in [Google Colab](https://colab.research.google | Notebook | Colab | nbViewer | | --- | ---| --- | -| Heartbeat Counting task report | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/cardioception/notebooks/HeartBeatCounting.ipynb) | -| Heart Rate Discrimination task report | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/cardioception/notebooks/HeartRateDiscrimination.ipynb) | +| Heartbeat Counting task report | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/cardioception/notebooks/HeartBeatCounting.ipynb) | +| Heart Rate Discrimination task report | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/cardioception/notebooks/HeartRateDiscrimination.ipynb) | ## Bayesian modeling @@ -178,8 +178,8 @@ More advanced subject and group-level Bayesian modelling approaches are describe | Notebook | Colab | nbViewer | | --- | ---| --- | -| Fitting the psychometric function (single subject) | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/docs/source/examples/psychophysics/1-psychophysics_subject_level.ipynb) | -| Fitting the psychometric function (group level) | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/docs/source/examples/psychophysics/2-psychophysics_group_level.ipynb) | +| Fitting the psychometric function (single subject) | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/docs/source/examples/psychophysics/1-psychophysics_subject_level.ipynb) | +| Fitting the psychometric function (group level) | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/docs/source/examples/psychophysics/2-psychophysics_group_level.ipynb) | # References @@ -193,7 +193,7 @@ More advanced subject and group-level Bayesian modelling approaches are describe This package is a fork of the original [Cardioception](https://github.com/embodied-computation-group/Cardioception) repository and is maintained by [Nicolas Legrand](https://github.com/LegrandNico). - + # Credit diff --git a/docs/source/cite.md b/docs/source/cite.md index 05d9de0..6ca7d7d 100644 --- a/docs/source/cite.md +++ b/docs/source/cite.md @@ -1,6 +1,6 @@ # How to cite? -If you are using the [cardioception toolbox](https://github.com/LegrandNico/cardioception-toolbox) for your research, we ask you to cite the following paper in the final publication: +If you are using the [cardioception toolbox](https://github.com/LegrandNico/cardioception) for your research, we ask you to cite the following paper in the final publication: * Legrand, N., Nikolova, N., Correa, C., Brændholt, M., Stuckert, A., Kildahl, N., Vejlø, M., Fardo, F., & Allen, M. (2021). The Heart Rate Discrimination Task: A psychophysical method to estimate the accuracy and precision of interoceptive beliefs. Biological Psychology, 108239. diff --git a/docs/source/index.md b/docs/source/index.md index 8f5ba9d..a15c82d 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -1,10 +1,10 @@ # Cardioception toolbox -[![GitHub license](https://img.shields.io/github/license/LegrandNico/cardioception-toolbox)](https://github.com/LegrandNico/cardioception-toolbox/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/LegrandNico/cardioception-toolbox)](https://github.com/LegrandNico/cardioception-toolbox/releases/) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![pip](https://badge.fury.io/py/cardioception-toolbox.svg)](https://badge.fury.io/py/cardioception-toolbox) [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) +[![GitHub license](https://img.shields.io/github/license/LegrandNico/cardioception)](https://github.com/LegrandNico/cardioception/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/LegrandNico/cardioception)](https://github.com/LegrandNico/cardioception/releases/) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![pip](https://badge.fury.io/py/cardioception.svg)](https://badge.fury.io/py/cardioception) [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/) --- -cardioception +cardioception ```{important} The Cardioception Python Toolbox is a fork of the [original cardioception repository](https://github.com/embodied-computation-group/Cardioception) that I ([Nicolas Legrand](https://github.com/LegrandNico/)) created while working in [the ECG lab](https://www.the-ecg.org/) from 2019 to 2022. My previous lab has taken full control of the repository since then, meaning that I am unfortunately unable to maintain it as it should be. This repository allows me to pursue the maintenance of the package, aiming to provide reliable and robust tasks to measure cardiac interoception, together with computational modelling tools to analyse data gathered with these tasks. @@ -26,7 +26,7 @@ These tasks can run using minimal experimental settings: a computer and a record If you have questions regarding the tasks, want to report a bug or discuss data analysis, please ask on the public discussion page in this repository. -If you want to report a bug, you can open an issue on the [GitHub page](https://github.com/LegrandNico/cardioception-toolbox). +If you want to report a bug, you can open an issue on the [GitHub page](https://github.com/LegrandNico/cardioception). ## Development diff --git a/docs/source/measuring.md b/docs/source/measuring.md index 1b281b3..e391821 100644 --- a/docs/source/measuring.md +++ b/docs/source/measuring.md @@ -1,14 +1,14 @@ # Measuring cardiac interoception -Cardiac interoception has been largely investigated using the heartbeat counting task (also known as the heartbeat tracking task) that was formally introduced more than 40 years ago {cite:p}`1981:schandry`. This task comes with several variants that can concern task instruction, experimental design or the scores derived to measure cardiac interoceptive accuracy and metacognition. Here, we describe the heartbeat counting task together with the heart rate discrimination task, that was recently proposed {cite:p}`2022:legrand` and is also implemented in [cardioception](https://github.com/LegrandNico/cardioception-toolbox). +Cardiac interoception has been largely investigated using the heartbeat counting task (also known as the heartbeat tracking task) that was formally introduced more than 40 years ago {cite:p}`1981:schandry`. This task comes with several variants that can concern task instruction, experimental design or the scores derived to measure cardiac interoceptive accuracy and metacognition. Here, we describe the heartbeat counting task together with the heart rate discrimination task, that was recently proposed {cite:p}`2022:legrand` and is also implemented in [cardioception](https://github.com/LegrandNico/cardioception). ## The Heart Beat Counting task In the classic "heartbeat counting task" {cite:p}`1981:schandry,1978:dale` participants attend to their heartbeats in intervals of various lengths and are asked to count the number of heartbeats they can effectively feel during this period. An accuracy score is then derived by comparing the reported number of heartbeats and the true number of heartbeats. In the original version {cite:p}`1981:schandry`, the task started with a resting period of 60 seconds and consisted of three estimation sessions (25, 35, and 45 seconds) interleaved with resting periods of 30 seconds. -![hbc](https://raw.githubusercontent.com/LegrandNico/cardioception-toolbox/master/docs/source/images/HeartBeatCounting.png) +![hbc](https://raw.githubusercontent.com/LegrandNico/cardioception/master/docs/source/images/HeartBeatCounting.png) -By default, [Cardioception](https://github.com/LegrandNico/cardioception-toolbox) implements the version used in recent publications {cite:p}`2013:hart` in which a training trial of 20 seconds is proposed, after which the 6 experimental trials of different time windows (25, 30, 35,40, 45 and 50s) occurred in a randomized order. The trial length, the condition (`'Rest'`, `'Count'`, `'Training'`), and the randomization can be controlled in the parameters dictionary. This behaviour can be controlled using the `"taskVersion"` parameter. +By default, [Cardioception](https://github.com/LegrandNico/cardioception) implements the version used in recent publications {cite:p}`2013:hart` in which a training trial of 20 seconds is proposed, after which the 6 experimental trials of different time windows (25, 30, 35,40, 45 and 50s) occurred in a randomized order. The trial length, the condition (`'Rest'`, `'Count'`, `'Training'`), and the randomization can be controlled in the parameters dictionary. This behaviour can be controlled using the `"taskVersion"` parameter. ### Instructions @@ -32,7 +32,7 @@ After each counting response, the participant is prompted to rate their subjecti The **Heart Rate Discrimination Task** {cite:p}`2022:legrand` implements an adaptive psychophysical measure of cardiac interoception where participants have to estimate the frequency of their heart rate by comparing it to tones that can be faster or slower. By manipulating the difference between the true heart rate and the presented tone using different staircase procedures, the bias (threshold) and precision (slope) of the psychometric function can be estimated either online or offline, together with metacognitive efficiency. -![hrd](https://raw.githubusercontent.com/LegrandNico/cardioception-toolbox/master/docs/source/images/HeartRateDiscrimination.png) +![hrd](https://raw.githubusercontent.com/LegrandNico/cardioception/master/docs/source/images/HeartRateDiscrimination.png) ### Staircases diff --git a/docs/source/stats.md b/docs/source/stats.md index 15c495d..15eaa2b 100644 --- a/docs/source/stats.md +++ b/docs/source/stats.md @@ -57,8 +57,8 @@ examples/templates/* | Notebook | Colab | | --- | ---| -| {ref}`hbc_template` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/docs/source/examples/templates/HeartBeatCounting.ipynb) -| {ref}`hrd_template` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/docs/source/examples/templates/HeartRateDiscrimination.ipynb) +| {ref}`hbc_template` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/docs/source/examples/templates/HeartBeatCounting.ipynb) +| {ref}`hrd_template` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/docs/source/examples/templates/HeartRateDiscrimination.ipynb) ## Bayesian modelling of psychophysics @@ -76,5 +76,5 @@ examples/psychophysics/* | Notebook | Colab | | --- | ---| -| {ref}`psychophysics_subject_level` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/docs/source/examples/psychophysics/1-psychophysics_subject_level.ipynb) -| {ref}`psychophysics_group_level` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception-toolbox/blob/master/docs/source/examples/psychophysics/2-psychophysics_group_level.ipynb) +| {ref}`psychophysics_subject_level` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/docs/source/examples/psychophysics/1-psychophysics_subject_level.ipynb) +| {ref}`psychophysics_group_level` | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LegrandNico/cardioception/blob/master/docs/source/examples/psychophysics/2-psychophysics_group_level.ipynb) diff --git a/docs/source/user_guide.md b/docs/source/user_guide.md index 4e969fb..fb03ebd 100644 --- a/docs/source/user_guide.md +++ b/docs/source/user_guide.md @@ -90,7 +90,7 @@ parameters['win'].close() This minimal example will run the Heart Rate Discrimination task with a total of 10 trials using a Psi staircase. -We provide standard scripts in the [wrappers](https://github.com/LegrandNico/cardioception-toolbox/tree/master/wrappers) folder that can be adapted to your needs. We recommend copying this script in your local task folder if you want to parametrize it to fit your needs. The tasks can then easily be executed by running the corresponding wrapper file (e.g. in a terminal). +We provide standard scripts in the [wrappers](https://github.com/LegrandNico/cardioception/tree/master/wrappers) folder that can be adapted to your needs. We recommend copying this script in your local task folder if you want to parametrize it to fit your needs. The tasks can then easily be executed by running the corresponding wrapper file (e.g. in a terminal). ### Creating a shortcut (Windows) diff --git a/setup.py b/setup.py index ef7d77b..1741fb7 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ def get_version(rel_path): LONG_DESCRIPTION = """Measuring cardiac interoception with Psychopy. """ -DISTNAME = "cardioception-toolbox" +DISTNAME = "cardioception" MAINTAINER = "Nicolas Legrand" MAINTAINER_EMAIL = "nicolas.legrand@cas.au.dk" @@ -47,7 +47,7 @@ def get_version(rel_path): long_description=LONG_DESCRIPTION, license=read("LICENSE"), version=get_version("cardioception/__init__.py"), - url="https://github.com/LegrandNico/cardioception-toolbox", + url="https://github.com/LegrandNico/cardioception", install_requires=get_requirements(), include_package_data=True, packages=find_packages(), diff --git a/tests/test_reports.py b/tests/test_reports.py index 94ad4de..ab32cef 100644 --- a/tests/test_reports.py +++ b/tests/test_reports.py @@ -13,7 +13,7 @@ def test_preprocessing(self): """Test the preprocessing function""" # load the main result data frame results = pd.read_csv( - "https://raw.githubusercontent.com/LegrandNico/cardioception-toolbox/master/docs/source/examples/templates/data/HRD/HRD_final.txt" + "https://raw.githubusercontent.com/LegrandNico/cardioception/master/docs/source/examples/templates/data/HRD/HRD_final.txt" ) preprocessing(results=results) From 2168a3bef0f7ae5229bb9048f6973b2bfc321d75 Mon Sep 17 00:00:00 2001 From: LegrandNico Date: Fri, 24 May 2024 11:00:08 +0200 Subject: [PATCH 2/3] add participant_id in the report function --- cardioception/reports.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cardioception/reports.py b/cardioception/reports.py index 3d93e26..a55939e 100644 --- a/cardioception/reports.py +++ b/cardioception/reports.py @@ -304,20 +304,23 @@ def preprocessing(results: Union[PathLike, pd.DataFrame]) -> pd.DataFrame: def report( - result_path: PathLike, report_path: Optional[PathLike] = None, task: str = "HRD" + result_path: PathLike, report_path: Optional[PathLike] = None, task: str = "HRD", + participant_id: str = "sub-01" ): """From the results folders, create HTML reports of behavioural and physiological data. Parameters ---------- - resultPath : PathLike + resultPath : Path variable. Where the results are stored (one participant only). - reportPath : PathLike, optional + reportPath : Where the HTML report should be saved. If `None`, default will be in the provided `resultPath`. - task : str, optional + task : The task ("HRD" or "HBC"), by default "HRD". + participant_id : + The participant ID used in the filename. """ from papermill import execute_notebook @@ -325,7 +328,7 @@ def report( if report_path is None: report_path = result_path temp_notebook = Path(report_path, "temp.ipynb") - htmlreport = Path(report_path, f"{task}_report.html") + htmlreport = Path(report_path, f"{participant_id}-{task}_report.html") if task == "HRD": template = "HeartRateDiscrimination.ipynb" From d0904507909b785f94916958f235f79f830872f0 Mon Sep 17 00:00:00 2001 From: LegrandNico Date: Fri, 24 May 2024 11:02:48 +0200 Subject: [PATCH 3/3] renaming --- .gitignore | 2 +- README.md | 2 +- docs/source/index.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f489674..084cb51 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ .pytest_cache /htmlcov /dist -/cardioception_toolbox.egg-info +/cardioception.egg-info /build docs/source/auto_examples docs/source/generated diff --git a/README.md b/README.md index 1d3f9ae..90d8105 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ *** -# Cardioception toolbox +# Cardioception cardioception diff --git a/docs/source/index.md b/docs/source/index.md index a15c82d..1b13fb0 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -1,4 +1,4 @@ -# Cardioception toolbox +# Cardioception [![GitHub license](https://img.shields.io/github/license/LegrandNico/cardioception)](https://github.com/LegrandNico/cardioception/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/LegrandNico/cardioception)](https://github.com/LegrandNico/cardioception/releases/) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) [![pip](https://badge.fury.io/py/cardioception.svg)](https://badge.fury.io/py/cardioception) [![black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) [![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)