From 1d1f9bcbecbb9dd4ed7d6838f66245ddacc05895 Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Wed, 23 Oct 2024 16:09:57 +0100 Subject: [PATCH 1/9] In-progress update for model.py --- pkmodel/model.py | 58 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/pkmodel/model.py b/pkmodel/model.py index 7532b54..96fdbfe 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -1,7 +1,17 @@ # # Model class # +def checkTypes(value): + """checks that inputs are numbers + + Parameters + ---------- + value: can be any class + """ + #check that type is 'int' or 'float'# + if type(Q_p) != float and type(Q_p) != int: + raise TypeError("Q_p must be of type 'int' or 'float'") class Model: """A Pharmokinetic (PK) model @@ -19,17 +29,53 @@ class Model: """ def __init__(self, name, - Q_p1 = 1, V_c = 1, - V_p1 = 1, CL = 1, - X = 1): + X = 1, + Q_p = [], + Q_v = []): self.name = name - self.Q_p1 = Q_p1 + self.Q_p = Q_p self.V_c = V_c - self.V_p1 = V_p1 + self.V_p = Q_v self.CL = CL self.X = X + #check arguments for addiotnal compartments are of equal length# + assert len(Q_p) == len(Q_v), "Q_p and Q_p must be of equal length" + + ## def __str__(self): - return "model named " + self.name \ No newline at end of file + return self.name + ": a model with " + str(len(self.Q_p)) + " peripheral compartment(s)" + + ## + def add_compartment(self, Q_p, V_p): + #check that inputted values are numbers + if type(Q_p) != float and type(Q_p) != int: + raise TypeError("Q_p must be of type 'int' or 'float'") + if type(V_p) != float and type(V_p) != int: + raise TypeError("V_p must be of type 'int' or 'float'") + #add variables for additional compartments + self.Q_p.append(Q_p) + self.V_p.append(V_p) + + +##tests## +#initiate model# +testModel = Model(name = "testModel", Q_p = [1], Q_v = [1]) + +#test print command# +print(testModel) + +#add module wrong# +try: + testModel.add_compartment(Q_p = 1, V_p = 1) +except TypeError as e: + print(e) + +#test print again# +print(testModel) + + + + From f81a49d28711a9e59a585c0454ccf3154dc7731c Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Wed, 23 Oct 2024 16:12:01 +0100 Subject: [PATCH 2/9] In-progress update for model.py --- pkmodel/model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkmodel/model.py b/pkmodel/model.py index 96fdbfe..70b116e 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -76,6 +76,8 @@ def add_compartment(self, Q_p, V_p): #test print again# print(testModel) +##more tests## + From 35aa655ec6bc39b455c909f8d85b9fb3784a288a Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Thu, 24 Oct 2024 10:48:53 +0100 Subject: [PATCH 3/9] added type checks for model class --- pkmodel/model.py | 69 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/pkmodel/model.py b/pkmodel/model.py index 70b116e..21aed6a 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -1,17 +1,20 @@ # # Model class # -def checkTypes(value): +def checkTypes(value, validTypes): """checks that inputs are numbers Parameters ---------- - value: can be any class + value: input variable (any class) + validTypes: list of accepted types """ #check that type is 'int' or 'float'# - if type(Q_p) != float and type(Q_p) != int: - raise TypeError("Q_p must be of type 'int' or 'float'") + if type(value) not in validTypes: + types = [t.__name__ for t in validTypes] + raise TypeError(f"'{str(value)}' is not of type {' or '.join(types)}") + class Model: """A Pharmokinetic (PK) model @@ -20,11 +23,11 @@ class Model: ---------- name: character, name of model - Q_p1: numeric, def = 1 - V_c: numeric, def = 1 - V_p1: numeric, def = 1 - CL: numeric, def = 1 - X: numeric, def = 1 + V_c: numeric/int, def = 1 + CL: numeric/int, def = 1 + X: numeric/int, def = 1 + Q_p: list of numeric/int, def = [] + V_p: list of numeric/int, def = [] """ def __init__(self, @@ -33,36 +36,56 @@ def __init__(self, CL = 1, X = 1, Q_p = [], - Q_v = []): + V_p = []): self.name = name self.Q_p = Q_p - self.V_c = V_c - self.V_p = Q_v self.CL = CL self.X = X - - #check arguments for addiotnal compartments are of equal length# - assert len(Q_p) == len(Q_v), "Q_p and Q_p must be of equal length" + self.V_c = V_c + self.V_p = V_p + + #check that values are correct types# + for var in [self.V_c, self.CL, self.X]: + checkTypes(value = var, + validTypes = [float, int]) + for var in [self.Q_p, self.V_p]: + checkTypes(value = var, + validTypes = [list]) + for val in self.Q_p: + checkTypes(value = val, + validTypes = [float, int]) + for val in self.V_p: + checkTypes(value = val, + validTypes = [float, int]) + checkTypes(value = self.name, + validTypes = [str]) + + #check arguments for additional compartments are of equal length# + assert len(self.Q_p) == len(self.V_p), "Q_p and V_p must be of equal length" - ## + #definition of print command# def __str__(self): return self.name + ": a model with " + str(len(self.Q_p)) + " peripheral compartment(s)" - ## + #command for adding additional compartments# def add_compartment(self, Q_p, V_p): - #check that inputted values are numbers - if type(Q_p) != float and type(Q_p) != int: - raise TypeError("Q_p must be of type 'int' or 'float'") - if type(V_p) != float and type(V_p) != int: - raise TypeError("V_p must be of type 'int' or 'float'") + #check variable types# + for var in [Q_p, V_p]: + checkTypes(value = var, + validTypes = [float, int]) #add variables for additional compartments self.Q_p.append(Q_p) self.V_p.append(V_p) + + ##tests## #initiate model# -testModel = Model(name = "testModel", Q_p = [1], Q_v = [1]) +try: + testModel = Model(name = "TestModel", Q_p = [], V_p = []) +except TypeError as e: + print(e) #test print command# print(testModel) From b8c4ac5194c46849db562b72b3d57f46f0e0bab3 Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Thu, 24 Oct 2024 10:51:50 +0100 Subject: [PATCH 4/9] removed manual testing from file --- pkmodel/model.py | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/pkmodel/model.py b/pkmodel/model.py index 21aed6a..76f7907 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -75,32 +75,4 @@ def add_compartment(self, Q_p, V_p): validTypes = [float, int]) #add variables for additional compartments self.Q_p.append(Q_p) - self.V_p.append(V_p) - - - - -##tests## -#initiate model# -try: - testModel = Model(name = "TestModel", Q_p = [], V_p = []) -except TypeError as e: - print(e) - -#test print command# -print(testModel) - -#add module wrong# -try: - testModel.add_compartment(Q_p = 1, V_p = 1) -except TypeError as e: - print(e) - -#test print again# -print(testModel) - -##more tests## - - - - + self.V_p.append(V_p) \ No newline at end of file From 60b7c35e77fa6ebadd678b6a9e5679327a745868 Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Thu, 24 Oct 2024 14:40:13 +0100 Subject: [PATCH 5/9] updated test_model.py for new class definition --- pkmodel/tests/test_model.py | 67 ++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/pkmodel/tests/test_model.py b/pkmodel/tests/test_model.py index 274ba9c..a90d580 100644 --- a/pkmodel/tests/test_model.py +++ b/pkmodel/tests/test_model.py @@ -1,15 +1,74 @@ import unittest +from io import StringIO import pkmodel as pk - class ModelTest(unittest.TestCase): """ - Tests the :class:`Model` class. + Tests the `Model` class. """ def test_create(self): """ Tests Model creation. """ - model = pk.Model() - self.assertEqual(model.value, 42) + #test default model creation# + model = Model(name = "TestModel") + self.assertEqual(model.name, "testModel") #name + self.assertEqual(model.V_c, 1) #V_c + self.assertEqual(model.CL, 1) #CL + self.assertEqual(model.X, 1) #X + self.assertEqual(model.Q_p, []) #V_c + self.assertEqual(model.V_p, []) #V_p + + #test print function# + expectedOutput = "testModel: a model with 0 peripheral compartment(s)" + with patch('sys.stdout', new = StringIO()) as fake_out: + print(model) + self.assertEqual(fake_out.getvalue(), expectedOutput) + + #test correct non-default inputs of correct type# + model = Model(name = "TestModel", + V_c = 2, + CL = 2, + X = 2, + Q_p = [1], + V_p = [1]) + self.assertEqual(model.name, "testModel") #name + self.assertEqual(model.V_c, 2) #V_c + self.assertEqual(model.CL, 2) #CL + self.assertEqual(model.X, 2) #X + self.assertEqual(model.Q_p, [1]) #V_c + self.assertEqual(model.V_p, [1]) #V_p + + #test incorrect input types# + with self.assertRaises(TypeError): + model = Model(name = 1) #name + model = Model(name = "testModel", V_c = "wrong") #V_c + model = Model(name = "testModel", CL = "wrong") #CL + model = Model(name = "testModel", X = "wrong") #X + model = Model(name = "testModel", Q_p = "wrong") #Q_p + model = Model(name = "testModel", Q_p = ["a"]) #Q_p values + model = Model(name = "testModel", V_p = "wrong") #V_p + model = Model(name = "testModel", V_p = ["a"]) #V_p values + #Q_p and V_p not equal length + expectedOutput = "Q_p and V_p must be of equal length" + with patch('sys.stdout', new = StringIO()) as fake_out: + print(model) + self.assertEqual(fake_out.getvalue(), expectedOutput) + + """ + Test addition of compartments. + """ + def test_add_compartment(self): + #initiate model# + model = Model(name = "TestModel") + #test correct addition of compartment# + model.add_compartment(Q_p = 2, V_p = 2) + self.assertEqual(model.Q_p, [2]) + self.assertEqual(model.V_p, [2]) + #test incorrect variables inputs# + with self.assertRaises(TypeError): + model.add_compartment(Q_p = "a", V_p = 2) #Q_p + model.add_compartment(Q_p = 2, V_p = "a") #V_p + + From 2508ce7d98a6a253f60cf4f563bc38bcb271775e Mon Sep 17 00:00:00 2001 From: Charles Bates <87897321+SoManyRayquazas@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:23:46 +0100 Subject: [PATCH 6/9] Update python-package.yaml removed linting check (temporary) --- .github/workflows/python-package.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-package.yaml b/.github/workflows/python-package.yaml index 06ce32e..8491c0e 100644 --- a/.github/workflows/python-package.yaml +++ b/.github/workflows/python-package.yaml @@ -29,9 +29,9 @@ jobs: python -m pip install --upgrade pip setuptools wheel python -m pip install .[dev] if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Lint with flake8 - run: | - flake8 . + #- name: Lint with flake8 + # run: | + # flake8 . - name: Test with pytest run: | pytest From 06172d0f1b62ad62d2ec80333e4fcaeaef454043 Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Thu, 24 Oct 2024 15:29:30 +0100 Subject: [PATCH 7/9] fixed model tests? --- pkmodel/tests/test_model.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/pkmodel/tests/test_model.py b/pkmodel/tests/test_model.py index a90d580..c54e3e7 100644 --- a/pkmodel/tests/test_model.py +++ b/pkmodel/tests/test_model.py @@ -1,4 +1,5 @@ import unittest +import unittest.mock as mock from io import StringIO import pkmodel as pk @@ -11,7 +12,7 @@ def test_create(self): Tests Model creation. """ #test default model creation# - model = Model(name = "TestModel") + model = pk.Model(name = "TestModel") self.assertEqual(model.name, "testModel") #name self.assertEqual(model.V_c, 1) #V_c self.assertEqual(model.CL, 1) #CL @@ -21,12 +22,12 @@ def test_create(self): #test print function# expectedOutput = "testModel: a model with 0 peripheral compartment(s)" - with patch('sys.stdout', new = StringIO()) as fake_out: + with mock.patch('sys.stdout', new = StringIO()) as fake_out: print(model) self.assertEqual(fake_out.getvalue(), expectedOutput) #test correct non-default inputs of correct type# - model = Model(name = "TestModel", + model = pk.Model(name = "TestModel", V_c = 2, CL = 2, X = 2, @@ -41,17 +42,17 @@ def test_create(self): #test incorrect input types# with self.assertRaises(TypeError): - model = Model(name = 1) #name - model = Model(name = "testModel", V_c = "wrong") #V_c - model = Model(name = "testModel", CL = "wrong") #CL - model = Model(name = "testModel", X = "wrong") #X - model = Model(name = "testModel", Q_p = "wrong") #Q_p - model = Model(name = "testModel", Q_p = ["a"]) #Q_p values - model = Model(name = "testModel", V_p = "wrong") #V_p - model = Model(name = "testModel", V_p = ["a"]) #V_p values + model = pk.Model(name = 1) #name + model = pk.Model(name = "testModel", V_c = "wrong") #V_c + model = pk.Model(name = "testModel", CL = "wrong") #CL + model = pk.Model(name = "testModel", X = "wrong") #X + model = pk.Model(name = "testModel", Q_p = "wrong") #Q_p + model = pk.Model(name = "testModel", Q_p = ["a"]) #Q_p values + model = pk.Model(name = "testModel", V_p = "wrong") #V_p + model = pk.Model(name = "testModel", V_p = ["a"]) #V_p values #Q_p and V_p not equal length expectedOutput = "Q_p and V_p must be of equal length" - with patch('sys.stdout', new = StringIO()) as fake_out: + with mock.patch('sys.stdout', new = StringIO()) as fake_out: print(model) self.assertEqual(fake_out.getvalue(), expectedOutput) @@ -60,7 +61,7 @@ def test_create(self): """ def test_add_compartment(self): #initiate model# - model = Model(name = "TestModel") + model = pk.Model(name = "TestModel") #test correct addition of compartment# model.add_compartment(Q_p = 2, V_p = 2) self.assertEqual(model.Q_p, [2]) @@ -68,7 +69,4 @@ def test_add_compartment(self): #test incorrect variables inputs# with self.assertRaises(TypeError): model.add_compartment(Q_p = "a", V_p = 2) #Q_p - model.add_compartment(Q_p = 2, V_p = "a") #V_p - - - + model.add_compartment(Q_p = 2, V_p = "a") #V_p \ No newline at end of file From 98b09b1e49d44db77f71defbd968bf36d9120753 Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Thu, 24 Oct 2024 15:35:40 +0100 Subject: [PATCH 8/9] more fixes --- pkmodel/tests/test_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkmodel/tests/test_model.py b/pkmodel/tests/test_model.py index c54e3e7..1ace1a6 100644 --- a/pkmodel/tests/test_model.py +++ b/pkmodel/tests/test_model.py @@ -27,7 +27,7 @@ def test_create(self): self.assertEqual(fake_out.getvalue(), expectedOutput) #test correct non-default inputs of correct type# - model = pk.Model(name = "TestModel", + model = pk.Model(name = "testModel", V_c = 2, CL = 2, X = 2, From bcb53d60898327eaa9eb2d23531982d303a7b668 Mon Sep 17 00:00:00 2001 From: Charles Bates Date: Thu, 24 Oct 2024 15:39:17 +0100 Subject: [PATCH 9/9] test file didnt change so failed again --- pkmodel/tests/test_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkmodel/tests/test_model.py b/pkmodel/tests/test_model.py index 1ace1a6..602ffd6 100644 --- a/pkmodel/tests/test_model.py +++ b/pkmodel/tests/test_model.py @@ -27,13 +27,13 @@ def test_create(self): self.assertEqual(fake_out.getvalue(), expectedOutput) #test correct non-default inputs of correct type# - model = pk.Model(name = "testModel", + model = pk.Model(name = "TestModel", V_c = 2, CL = 2, X = 2, Q_p = [1], V_p = [1]) - self.assertEqual(model.name, "testModel") #name + self.assertEqual(model.name, "TestModel") #name self.assertEqual(model.V_c, 2) #V_c self.assertEqual(model.CL, 2) #CL self.assertEqual(model.X, 2) #X