Skip to content

Commit

Permalink
Merge pull request #13 from abbyevewilliams/model.py
Browse files Browse the repository at this point in the history
Model.py
  • Loading branch information
SoManyRayquazas authored Oct 24, 2024
2 parents 3c6c6c6 + bcb53d6 commit a200f2d
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 20 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/python-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
71 changes: 58 additions & 13 deletions pkmodel/model.py
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

66 changes: 62 additions & 4 deletions pkmodel/tests/test_model.py
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

0 comments on commit a200f2d

Please sign in to comment.