From 075e95bd6ffd1a2bb4728868beb20b9a132bb935 Mon Sep 17 00:00:00 2001 From: Thomas Kiley Date: Thu, 27 Jul 2023 14:24:36 +0100 Subject: [PATCH 1/6] Add implementation of standard deviation on data --- inflammation-analysis.py | 3 ++- inflammation/models.py | 10 ++++++++++ tests/test_models.py | 13 ++++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/inflammation-analysis.py b/inflammation-analysis.py index e1564317..4c612feb 100644 --- a/inflammation-analysis.py +++ b/inflammation-analysis.py @@ -27,7 +27,8 @@ def main(args): for filename in InFiles: inflammation_data = models.load_csv(filename) - view_data = {'average': models.daily_mean(inflammation_data), 'max': models.daily_max(inflammation_data), 'min': models.daily_min(inflammation_data)} + view_data = {'average': models.daily_mean(inflammation_data), 'max': models.daily_max(inflammation_data), 'min': models.daily_min(inflammation_data), **(models.s_dev(inflammation_data))} + views.visualize(view_data) diff --git a/inflammation/models.py b/inflammation/models.py index 94387ee3..89cfd31e 100644 --- a/inflammation/models.py +++ b/inflammation/models.py @@ -54,3 +54,13 @@ def daily_min(data): """Calculate the daily min of a 2d inflammation data array.""" return np.min(data, axis=0) + +def s_dev(data): + """Computes and returns standard deviation for data.""" + mmm = np.mean(data, axis=0) + devs = [] + for entry in data: + devs.append((entry - mmm) * (entry - mmm)) + + s_dev2 = sum(devs) / len(data) + return {'standard deviation': s_dev2} diff --git a/tests/test_models.py b/tests/test_models.py index 292d00c4..b8adbfb0 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -3,7 +3,7 @@ import numpy as np import numpy.testing as npt import os - +import pytest def test_daily_mean_zeros(): """Test that mean function works for an array of zeros.""" @@ -37,3 +37,14 @@ def test_load_from_json(tmpdir): temp_json_file.write('[{"observations":[1, 2, 3]},{"observations":[4, 5, 6]}]') result = load_json(example_path) npt.assert_array_equal(result, [[1, 2, 3], [4, 5, 6]]) + + +@pytest.mark.parametrize('data, expected_standard_deviation', [ + ([0, 0, 0], 0.0), + ([1.0, 1.0, 1.0], 0), + ([0.0, 2.0], 1.0) +]) +def test_daily_standard_deviation(data, expected_standard_deviation): + from inflammation.models import s_dev + result_data = s_dev(data)['standard deviation'] + npt.assert_approx_equal(result_data, expected_standard_deviation) From e7ac16d3b6a5b919cdbcd0c0e9b3de37810a46c4 Mon Sep 17 00:00:00 2001 From: JBello1610 Date: Mon, 28 Oct 2024 14:35:27 +0000 Subject: [PATCH 2/6] Review changes --- .gitignore | 1 + inflammation/models.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 0e0aa744..e6996bb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # IDEs .vscode/ .idea/ +.venv/ # Intermediate Coverage file .coverage diff --git a/inflammation/models.py b/inflammation/models.py index 89cfd31e..0bfbc491 100644 --- a/inflammation/models.py +++ b/inflammation/models.py @@ -2,8 +2,8 @@ The Model layer is responsible for the 'business logic' part of the software. -Patients' data is held in an inflammation table (2D array) where each row contains -inflammation data for a single patient taken over a number of days +Patients' data is held in an inflammation table (2D array) where each row contains +inflammation data for a single patient taken over a number of days and each column represents a single day across all patients. """ @@ -16,7 +16,8 @@ def load_csv(filename): :param filename: Filename of CSV to load """ - return np.loadtxt(fname=filename, delimiter=',') + return np.loadtxt(fname=filename, delimiter=",") + def load_json(filename): """Load a numpy array from a JSON document. @@ -34,10 +35,9 @@ def load_json(filename): :param filename: Filename of CSV to load """ - with open(filename, 'r', encoding='utf-8') as file: + with open(filename, "r", encoding="utf-8") as file: data_as_json = json.load(file) - return [np.array(entry['observations']) for entry in data_as_json] - + return [np.array(entry["observations"]) for entry in data_as_json] def daily_mean(data): @@ -57,10 +57,10 @@ def daily_min(data): def s_dev(data): """Computes and returns standard deviation for data.""" - mmm = np.mean(data, axis=0) + mean_of_data = np.mean(data, axis=0) devs = [] for entry in data: - devs.append((entry - mmm) * (entry - mmm)) + devs.append((entry - mean_of_data) * (entry - mean_of_data)) s_dev2 = sum(devs) / len(data) - return {'standard deviation': s_dev2} + return {"standard deviation": s_dev2} From ccb962da2fc6b3f3d4c807342040a55de4616eeb Mon Sep 17 00:00:00 2001 From: JBello1610 Date: Mon, 28 Oct 2024 15:21:12 +0000 Subject: [PATCH 3/6] Update s_dev() --- inflammation/models.py | 4 ++-- tests/test_models.py | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/inflammation/models.py b/inflammation/models.py index 0bfbc491..6ab046dc 100644 --- a/inflammation/models.py +++ b/inflammation/models.py @@ -62,5 +62,5 @@ def s_dev(data): for entry in data: devs.append((entry - mean_of_data) * (entry - mean_of_data)) - s_dev2 = sum(devs) / len(data) - return {"standard deviation": s_dev2} + standard_dev = sum(devs) / len(data) + return {"standard deviation": np.sqrt(standard_dev)} diff --git a/tests/test_models.py b/tests/test_models.py index b8adbfb0..c825b1a3 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -5,13 +5,12 @@ import os import pytest + def test_daily_mean_zeros(): """Test that mean function works for an array of zeros.""" from inflammation.models import daily_mean - test_input = np.array([[0, 0], - [0, 0], - [0, 0]]) + test_input = np.array([[0, 0], [0, 0], [0, 0]]) test_result = np.array([0, 0]) # Need to use Numpy testing functions to compare arrays @@ -22,29 +21,33 @@ def test_daily_mean_integers(): """Test that mean function works for an array of positive integers.""" from inflammation.models import daily_mean - test_input = np.array([[1, 2], - [3, 4], - [5, 6]]) + test_input = np.array([[1, 2], [3, 4], [5, 6]]) test_result = np.array([3, 4]) # Need to use Numpy testing functions to compare arrays npt.assert_array_equal(daily_mean(test_input), test_result) + def test_load_from_json(tmpdir): from inflammation.models import load_json - example_path = os.path.join(tmpdir, 'example.json') - with open(example_path, 'w') as temp_json_file: + + example_path = os.path.join(tmpdir, "example.json") + with open(example_path, "w") as temp_json_file: temp_json_file.write('[{"observations":[1, 2, 3]},{"observations":[4, 5, 6]}]') result = load_json(example_path) npt.assert_array_equal(result, [[1, 2, 3], [4, 5, 6]]) -@pytest.mark.parametrize('data, expected_standard_deviation', [ - ([0, 0, 0], 0.0), - ([1.0, 1.0, 1.0], 0), - ([0.0, 2.0], 1.0) -]) +@pytest.mark.parametrize( + "data, expected_standard_deviation", + [ + ([0, 0, 0], 0.0), + ([1.0, 1.0, 1.0], 0), + ([1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 10.0], 2.4088314876309775), + ], +) def test_daily_standard_deviation(data, expected_standard_deviation): from inflammation.models import s_dev - result_data = s_dev(data)['standard deviation'] + + result_data = s_dev(data)["standard deviation"] npt.assert_approx_equal(result_data, expected_standard_deviation) From 5de34cbd2210ad2f2239ce044013f8f1da6d2b73 Mon Sep 17 00:00:00 2001 From: JBello1610 Date: Mon, 28 Oct 2024 15:45:10 +0000 Subject: [PATCH 4/6] Updated README.md file --- README.md | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c9506464..a5891f8c 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,32 @@ -# Introduction +# Inflam +![Continuous Integration build in GitHub Actions](https://github.com/JBello1610/python-intermediate-inflammation/workflows/CI/badge.svg?branch=main) -This is a template software project repository used by the [Intermediate Research Software Development Skills In Python](https://github.com/carpentries-incubator/python-intermediate-development). +Inflam is a data management system written in Python that manages trial data used in clinical inflammation studies. -## Purpose +## Main Features +Here are some key features of Inflam: -This repository is intended to be used as a code template which is copied by learners at [Intermediate Research Software Development Skills In Python](https://github.com/carpentries-incubator/python-intermediate-development) course. -This can be done using the `Use this template` button towards the top right of this repo's GitHub page. +- Provide basic statistical analyses over clinical trial data +- Ability ti woek on trial data in Comma0-Seperated Value (CSV) format. +- Generate plots of trial data. +- Analytical functions and views can be easily extended based on its Model-View-Controller architecture -This software project is not finished, is currently failing to run and contains some code style issues. It is used as a starting point for the course - issues will be fixed and code will be added in a number of places during the course by learners in their own copies of the repository, as course topics are introduced. +## Prerequisites +Inflam requires the following Python packages: -## Tests +- [NumPy](https://www.numpy.org/) - makes use of NumPy's statistical functions. +- [Matplotlib](https://matplotlib.org/stable/index.html) - uses Matplotlib to generate statistical plots -Several tests have been implemented already, some of which are currently failing. -These failing tests set out the requirements for the additional code to be implemented during the workshop. +The following optional packages are required to run Inflam's unit tests: -The tests should be run using `pytest`, which will be introduced during the workshop. +- [pytest](https://docs.pytest.org/stable/) - Inflam's unit tests are written using pytest +- [pytest-cov](https://pypi.org/project/pytest-cov/) - Adds test coverage stats to unit testing + +## Installation +Can be installed and run by cloning this git repository and running the below commands: + +```bash +git clone git@github.com:JBello1610/python-intermediate-inflammation.git +cd python-intermediate-inflammation/ +python inflammation-analysis.py +``` From 3cf42b0653f930306b5a4b788371b6c770929790 Mon Sep 17 00:00:00 2001 From: JBello1610 Date: Mon, 28 Oct 2024 15:47:25 +0000 Subject: [PATCH 5/6] Updated README.md file --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a5891f8c..ea994792 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,11 @@ The following optional packages are required to run Inflam's unit tests: Can be installed and run by cloning this git repository and running the below commands: ```bash -git clone git@github.com:JBello1610/python-intermediate-inflammation.git +git clone git@github.com:JBello1610/ + +python-intermediate-inflammation.git + cd python-intermediate-inflammation/ + python inflammation-analysis.py ``` From aaa0e639720ae47559d03b0f65429f0ff6415de6 Mon Sep 17 00:00:00 2001 From: JBello1610 Date: Mon, 28 Oct 2024 15:48:06 +0000 Subject: [PATCH 6/6] Updated README.md file --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index ea994792..0afb4a03 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,7 @@ The following optional packages are required to run Inflam's unit tests: Can be installed and run by cloning this git repository and running the below commands: ```bash -git clone git@github.com:JBello1610/ - -python-intermediate-inflammation.git +git clone git@github.com:JBello1610/python-intermediate-inflammation.git cd python-intermediate-inflammation/