generated from SABS-R3/software-engineering-projects-pk
-
Notifications
You must be signed in to change notification settings - Fork 0
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 #13 from abbyevewilliams/model.py
Model.py
- Loading branch information
Showing
3 changed files
with
123 additions
and
20 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 |
---|---|---|
@@ -1,34 +1,79 @@ | ||
# | ||
# Model class | ||
# | ||
def checkTypes(value, validTypes): | ||
"""checks that inputs are numbers | ||
Parameters | ||
---------- | ||
value: input variable (any class) | ||
validTypes: list of accepted types | ||
""" | ||
#check that type is '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 | ||
Parameters | ||
---------- | ||
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, | ||
name, | ||
Q_p1=1, | ||
V_c=1, | ||
V_p1=1, | ||
CL=1, | ||
X=1): | ||
V_c = 1, | ||
CL = 1, | ||
X = 1, | ||
Q_p = [], | ||
V_p = []): | ||
self.name = name | ||
self.Q_p1 = Q_p1 | ||
self.V_c = V_c | ||
self.V_p1 = V_p1 | ||
self.Q_p = Q_p | ||
self.CL = CL | ||
self.X = X | ||
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 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) | ||
return "model named " + self.name | ||
|
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 |
---|---|---|
@@ -1,14 +1,72 @@ | ||
import unittest | ||
import unittest.mock as mock | ||
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(name="testing") | ||
self.assertEqual(model.name, "testing") | ||
#test default model creation# | ||
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 | ||
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 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 = 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.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 = 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 mock.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 = pk.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 |