-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from v-Morriss/main
Unit tests for nhspy pandas_spc_calculations
- Loading branch information
Showing
9 changed files
with
566 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Python source | ||
# ------------------------------------------------------------------------- | ||
# Copyright (c) 2023 NHS Python Community. All rights reserved. | ||
# Licensed under the MIT License. See license.txt in the project root for | ||
# license information. | ||
# ------------------------------------------------------------------------- | ||
|
||
# FILE: test_limits_calculations.py | ||
# DESCRIPTION: Tests for the limits_calculations() function. | ||
# Given a list of floats (fix_values) it returns a tuple of floats: | ||
# - mean: The mean of the input values | ||
# - lpl: The lower process limit of the input values | ||
# - upl: The upper process limit of the input values | ||
# - nlpl: The near lower process limit of the input values | ||
# - nupl: The near upper process limit of the input values | ||
|
||
# CONTRIBUTORS: v.Morriss | ||
# CONTACT: - | ||
# CREATED: 9 Jul 2024 | ||
# VERSION: 0.0.1 | ||
|
||
# Imports | ||
# ------------------------------------------------------------------------- | ||
# Python: | ||
import unittest | ||
|
||
# 3rd Party: | ||
import numpy as np | ||
|
||
# Local | ||
from nhspy_plotthedots.pandas_spc_calculations import limits_calculations | ||
# Define tests | ||
# ------------------------------------------------------------------------- | ||
class LimitsCalculations(unittest.TestCase): | ||
def test_increasing_trend(self): | ||
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | ||
expected = (5.5, 2.84, 8.16, 3.7266666666666666, 7.273333333333333) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_decreasing_trend(self): | ||
values = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] | ||
expected = (5.5, 2.84, 8.16, 3.7266666666666666, 7.273333333333333) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_no_trend(self): | ||
values = [1, 2, 3, 4, 5, 4, 3, 2, 1, 2] | ||
expected = (2.7, 0.040000000000000036, 5.36, 0.9266666666666667, 4.473333333333334) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_small_input(self): | ||
values = [1, 2, 3] | ||
expected = (2.0, -0.6600000000000001, 4.66, 0.22666666666666657, 3.7733333333333334) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_large_input(self): | ||
values = list(range(20)) | ||
expected = (9.5, 6.84, 12.16, 7.726666666666667, 11.273333333333333) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_exact_seven_input(self): | ||
values = [3, 1, 4, 1, 5, 9, 2] | ||
expected = (3.5714285714285716, -6.625238095238096, 13.768095238095238, -3.2263492063492065, 10.36920634920635) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_null_input(self): | ||
values = [] | ||
np.isnan(limits_calculations(values)).all() | ||
|
||
def test_mixed_input(self): | ||
values = [1, 2, 3, 2, 1, 2, 3, 4, 5, 6, 7, 4, 3, 2, 1, 2] | ||
expected = (3.0, -0.014666666666666828, 6.014666666666667, 0.9902222222222221, 5.009777777777778) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
def test_negative_input(self): | ||
values = [-1, -2, -3, -2, -1, -2, -3, -4, -5, -6, -7, -4, -3, -2, -1, -2] | ||
expected = (-3.0, -6.014666666666667, 0.014666666666666828, -5.009777777777778, -0.9902222222222221) | ||
self.assertEqual(limits_calculations(values), expected) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
# ------------------------------------------------------------------------- | ||
# Copyright (c) 2023 NHS Python Community. All rights reserved. | ||
# Licensed under the MIT License. See license.txt in the project root for | ||
# license information. | ||
# ------------------------------------------------------------------------- | ||
|
||
# FILE: test_pandas_spc_x_calc.py | ||
|
||
# DESCRIPTION: Tests on the pandas_scp_x_calc() function. Given a pandas DataFrame, | ||
# a string indicating the column name of the values to be analysed, | ||
# and an optional integer representing the number of values after which | ||
# the mean and other calculations should be fixed. It returns a pandas | ||
# DataFrame with the same values and the Statistic Process Control (SPC) values. | ||
# The SCP values const of: | ||
# - mean: The mean of the input values | ||
# - lpl: The lower process limit of the input values | ||
# - upl: The upper process limit of the input values | ||
# - outside_limits: A boolean list representing whether a value is | ||
# outside the process limits | ||
# - relative_to_mean: A list representing the relative value of an | ||
# element to mean | ||
# - close_to_limits: A boolean list representing whether a value is | ||
# close to a limit or not | ||
# - special_cause_flag: A boolean list representing whether a value | ||
# is a special cause or not 'outside_limits' representing whether a | ||
# value is outside the process limits | ||
# | ||
# CONTRIBUTORS: v.Morriss | ||
# CONTACT: - | ||
# CREATED: 9 Jul 2024 | ||
# VERSION: 0.0.1 | ||
|
||
# Imports | ||
# ------------------------------------------------------------------------- | ||
# Python: | ||
import unittest | ||
import math | ||
|
||
# 3rd party: | ||
import pandas as pd | ||
|
||
# Local | ||
from nhspy_plotthedots.pandas_spc_calculations import pandas_spc_x_calc | ||
|
||
# Define tests | ||
# ------------------------------------------------------------------------- | ||
|
||
class TestPandasSpcXCal(unittest.TestCase): | ||
|
||
def test_sample1(self): | ||
df = pd.DataFrame(data = {"column" : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]}) | ||
col = "column" | ||
n_points = 3 | ||
expected = pd.DataFrame(data = | ||
{ | ||
"column" : [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], | ||
"mean" : [2.0] * 8, | ||
"lpl" : [-0.6600000000000001] * 8, | ||
"upl" : [4.66] * 8, | ||
"outside_limits" : [False] * 4 + [True] * 4, | ||
"relative_to_mean" : [-1.0, 0.0] + [1.0] * 6, | ||
"close_to_limits" : [False] * 3 + [True] + [False] * 4, | ||
"special_cause_flag" : [True] * 8, | ||
}) | ||
self.assertTrue(pandas_spc_x_calc(df,col,n_points).equals(expected)) | ||
|
||
def test_sample2(self): | ||
df = pd.DataFrame(data = {"column" : [16.0, 9.0, 4.0, 2.0, 1.0]}) | ||
col = "column" | ||
n_points = 11 | ||
expected = pd.DataFrame(data = | ||
{ | ||
"column" : [16.0, 9.0, 4.0, 2.0, 1.0], | ||
"mean" : [6.4] * 5, | ||
"lpl" : [-3.575000000000001] * 5, | ||
"upl" : [16.375] * 5, | ||
"outside_limits" : [False] * 5, | ||
"relative_to_mean" : [1.0] * 2 + [-1.0] * 3, | ||
"close_to_limits" : [True] + [False] * 4, | ||
"special_cause_flag" : [False] * 5, | ||
}) | ||
self.assertTrue(pandas_spc_x_calc(df,col,n_points).equals(expected)) | ||
|
||
def test_sample3(self): | ||
df = pd.DataFrame(data = {"column" : [1,6,1,8,0,3]}) | ||
col = "column" | ||
n_points = None | ||
expected = pd.DataFrame(data = | ||
{ | ||
"column" : [1,6,1,8,0,3], | ||
"mean" : [3.1666666666666665] * 6, | ||
"lpl" : [-11.729333333333333] * 6, | ||
"upl" : [18.062666666666665] * 6, | ||
"outside_limits" : [False] * 6, | ||
"relative_to_mean" : [-1.0, 1.0, -1.0, 1.0, -1.0, -1.0], | ||
"close_to_limits" : [False] * 6, | ||
"special_cause_flag" : [False] * 6, | ||
}) | ||
self.assertTrue(pandas_spc_x_calc(df,col,n_points).equals(expected)) | ||
|
||
def test_nan(self): | ||
df = pd.DataFrame(data = {"column" : [math.nan]}) | ||
col = "column" | ||
n_points = None | ||
expected = pd.DataFrame(data = | ||
{ | ||
"column" : [math.nan], | ||
"mean" : [math.nan], | ||
"lpl" : [math.nan], | ||
"upl" : [math.nan], | ||
"outside_limits" : [False], | ||
"relative_to_mean" : [math.nan], | ||
"close_to_limits" : [False], | ||
"special_cause_flag" : [False], | ||
}) | ||
self.assertTrue(pandas_spc_x_calc(df,col,n_points).equals(expected)) | ||
|
||
def test_special_cause(self): | ||
pd.set_option('display.max_columns', None) | ||
df = pd.DataFrame(data = {"column" : [1,1,1,1,2]}) | ||
col = "column" | ||
n_points = None | ||
expected = pd.DataFrame(data = | ||
{ | ||
"column" : [1,1,1,1,2], | ||
"mean" : [1.2] * 5, | ||
"lpl" : [1.2] * 5, | ||
"upl" : [1.2] * 5, | ||
"outside_limits" : [True] * 5, | ||
"relative_to_mean" : [-1.0] * 4 + [1.0], | ||
"close_to_limits" : [False] * 5, | ||
"special_cause_flag" : [True] * 5, | ||
}) | ||
self.assertTrue(pandas_spc_x_calc(df,col,n_points).equals(expected)) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Python source | ||
# ------------------------------------------------------------------------- | ||
# Copyright (c) 2023 NHS Python Community. All rights reserved. | ||
# Licensed under the MIT License. See license.txt in the project root for | ||
# license information. | ||
# ------------------------------------------------------------------------- | ||
|
||
# FILE: test_part_of_two_in_three.py | ||
# DESCRIPTION: Tests for the part_of_two_in_three() function. | ||
# part_of_two_in_three(), given two boolean lists, uses zip() | ||
# to iterate over the two input lists and applies logical | ||
# AND to corresponding elements. | ||
|
||
# CONTRIBUTORS: v.Morriss | ||
# CONTACT: - | ||
# CREATED: 9 Jul 2024 | ||
# VERSION: 0.0.1 | ||
|
||
|
||
# Imports | ||
# ------------------------------------------------------------------------- | ||
# Python: | ||
import unittest | ||
|
||
# Local | ||
from nhspy_plotthedots.pandas_spc_calculations import part_of_two_in_three | ||
|
||
# Define tests | ||
# ------------------------------------------------------------------------- | ||
|
||
class PartOfTwoInThree(unittest.TestCase): | ||
|
||
def false(self): | ||
values1 = [False] * 10 | ||
values2 = [False] * 10 | ||
expected = [False] * 10 | ||
self.assertEqual(part_of_two_in_three(values1, values2), expected) | ||
|
||
def true(self): | ||
values1 = [True] * 10 | ||
values2 = [True] * 10 | ||
expected = [True] * 10 | ||
self.assertEqual(part_of_two_in_three(values1, values2), expected) | ||
|
||
def mixed(self): | ||
values1 = [False, True, False, True] | ||
values2 = [False, False, True, True] | ||
expected = [False, False, False, True] | ||
self.assertEqual(part_of_two_in_three(values1, values2), expected) | ||
|
||
def test_null_input(self): | ||
values1 = [] | ||
values2 = [] | ||
expected = [] | ||
self.assertEqual(part_of_two_in_three(values1, values2), expected) | ||
|
||
def left_uneven(self): | ||
values1 = [True, True, True] | ||
values2 = [True] | ||
expected = [True] | ||
self.assertEqual(part_of_two_in_three(values1, values2), expected) | ||
|
||
def right_uneven(self): | ||
values1 = [True] | ||
values2 = [True,True,True] | ||
expected = [True] | ||
self.assertEqual(part_of_two_in_three(values1, values2), expected) | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
Oops, something went wrong.