Skip to content

Commit e5bf829

Browse files
committed
virus
1 parent 98d6352 commit e5bf829

File tree

1 file changed

+269
-0
lines changed

1 file changed

+269
-0
lines changed

tests/virusTest.py

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
import checkpy.tests as t
2+
import checkpy.lib as lib
3+
import checkpy.assertlib as asserts
4+
5+
from _extensions import *
6+
7+
@t.test(1)
8+
def generate_virus_length(test):
9+
def testMethod():
10+
generate_virus = lib.getFunction("generate_virus", test.fileName)
11+
12+
if not isinstance(generate_virus(1), str):
13+
return False, "expected generateVirus() to return a str"
14+
15+
for i in range(10):
16+
if not len(generate_virus(i)) == i:
17+
return False, f"expected generate_virus({i}) to produce a virus of length {i}"
18+
19+
return True
20+
21+
test.test = testMethod
22+
test.description = lambda : "generate_virus() produces viruses of the specified length"
23+
24+
@t.test(1)
25+
def generate_virus_elements(test):
26+
def testMethod():
27+
generate_virus = lib.getFunction("generate_virus", test.fileName)
28+
29+
pairs = "".join([generate_virus(10) for _ in range(100)])
30+
31+
if any([el not in "AGTC" for el in pairs]):
32+
return False
33+
34+
return True
35+
36+
test.test = testMethod
37+
test.description = lambda : "generate_virus() produces viruses consisting only of A, T, G and C"
38+
39+
@t.test(1)
40+
def mutate_length(test):
41+
def testMethod():
42+
generate_virus = lib.getFunction("generate_virus", test.fileName)
43+
mutate = lib.getFunction("mutate", test.fileName)
44+
45+
if not isinstance(mutate("AAAA"), str):
46+
return False, "expected mutate() to return a str"
47+
48+
try:
49+
for i in range(1, 10):
50+
v = generate_virus(i)
51+
if not len(v) == len(mutate(v)):
52+
return False, f"expected mutate() to produce a virus of the same length as the parent"
53+
except ValueError:
54+
return False, "it seems that mutate gives an error, are you sure it works for viruses of length 1?"
55+
56+
return True
57+
58+
test.test = testMethod
59+
test.description = lambda : "mutate() produces viruses of the same length as the parent"
60+
61+
@t.test(1)
62+
def mutate_elements(test):
63+
def testMethod():
64+
generate_virus = lib.getFunction("generate_virus", test.fileName)
65+
mutate = lib.getFunction("mutate", test.fileName)
66+
67+
pairs = "".join([mutate(generate_virus(10)) for _ in range(100)])
68+
69+
if any([el not in "AGTC" for el in pairs]):
70+
return False, "expected mutate() to return only combinations of AGTC"
71+
72+
return True
73+
74+
test.test = testMethod
75+
test.description = lambda : "mutate() produces viruses consisting only of A, T, G and C"
76+
77+
@t.test(1)
78+
def mutate_one_difference(test):
79+
def testMethod():
80+
generate_virus = lib.getFunction("generate_virus", test.fileName)
81+
mutate = lib.getFunction("mutate", test.fileName)
82+
83+
off_by_one = lambda col1, col2 : sum(a != b for a, b in zip(col1, col2)) == 1
84+
85+
for v in [generate_virus(i) for i in range(1, 100)]:
86+
mutated_v = mutate(v)
87+
if not off_by_one(mutated_v, v):
88+
return False, f"expected mutate({v}) to return a virus with only one mutation, not {mutated_v}"
89+
90+
return True
91+
92+
test.test = testMethod
93+
test.description = lambda : "mutate() produces viruses that differ exactly one element from the parent"
94+
95+
@t.test(1)
96+
def kill_no_modify(test):
97+
def testMethod():
98+
generate_virus = lib.getFunction("generate_virus", test.fileName)
99+
kill = lib.getFunction("kill", test.fileName)
100+
101+
if not isinstance(kill(["AAAA"], 0.25), list):
102+
return False, "expected kill() to return a list"
103+
104+
viruses = [generate_virus(4) for i in range(10)]
105+
viruses_copy = viruses[:]
106+
new_viruses = kill(viruses, 1)
107+
108+
if viruses != viruses_copy:
109+
return False, f"the viruses passed in changed from {viruses_copy} to {viruses}"
110+
111+
return True
112+
113+
test.test = testMethod
114+
test.description = lambda : "kill() does not modify the list of viruses it accepts as argument"
115+
116+
@t.test(1)
117+
def kill_no_new(test):
118+
def testMethod():
119+
generate_virus = lib.getFunction("generate_virus", test.fileName)
120+
kill = lib.getFunction("kill", test.fileName)
121+
122+
viruses = [generate_virus(4) for i in range(100)]
123+
new_viruses = kill(viruses, 0.25)
124+
125+
if set(new_viruses).difference(set(viruses)) or len(new_viruses) > len(viruses):
126+
return False, "expected no new viruses"
127+
128+
return True
129+
130+
test.test = testMethod
131+
test.description = lambda : "kill() does not produce any new viruses"
132+
133+
@t.test(1)
134+
def kill_enough(test):
135+
def testMethod():
136+
generate_virus = lib.getFunction("generate_virus", test.fileName)
137+
kill = lib.getFunction("kill", test.fileName)
138+
139+
viruses = [generate_virus(4) for i in range(100)]
140+
avg_pop_size = sum(len(kill(viruses[:], 0.25)) for i in range(1000)) / 1000
141+
142+
if not 70 <= avg_pop_size <= 80:
143+
raise check50.Failure(f"expected roughly 25% of the population to die with mortality_prob of 0.25, but {100 - avg_pop_size}% died!")
144+
145+
return True
146+
147+
test.test = testMethod
148+
test.description = lambda : "kill() kills enough viruses according to mortality probability"
149+
150+
@t.test(1)
151+
def reproduce_parents(test):
152+
def testMethod():
153+
generate_virus = lib.getFunction("generate_virus", test.fileName)
154+
reproduce = lib.getFunction("reproduce", test.fileName)
155+
156+
viruses = [generate_virus(4) for i in range(100)]
157+
new_viruses = reproduce(viruses, 0.25, 0)
158+
159+
if not isinstance(new_viruses, list):
160+
return False, "expected reproduce() to return a list"
161+
162+
if not new_viruses == viruses:
163+
if len(new_viruses) < len(viruses):
164+
return False, "did not expect fewer viruses after reproduce()"
165+
elif len(new_viruses) > len(viruses):
166+
return False, "expected no new viruses"
167+
else:
168+
return False, "did not expect to find different viruses"
169+
170+
return True
171+
172+
test.test = testMethod
173+
test.description = lambda : "reproduce() with reproduction_rate=0 produces no new viruses"
174+
175+
@t.test(1)
176+
def reproduce_avg(test):
177+
def testMethod():
178+
generate_virus = lib.getFunction("generate_virus", test.fileName)
179+
reproduce = lib.getFunction("reproduce", test.fileName)
180+
181+
viruses = [generate_virus(4) for i in range(100)]
182+
new_viruses = reproduce(viruses, 0.25, 0)
183+
184+
n_trials = 1000
185+
avg_pop_size = sum(len(reproduce(viruses[:], 0.25, 0.50)) for _ in range(n_trials)) / n_trials
186+
187+
if not 145 <= avg_pop_size <= 155:
188+
return False, f"expected roughly a 50% increase in population with a reproductionRate of .5, not {avg_pop_size - 100}%"
189+
190+
return True
191+
192+
test.test = testMethod
193+
test.description = lambda : "reproduce() produces enough viruses on avg according to reproduction_rate"
194+
195+
@t.test(1)
196+
def is_resistent_AAA(test):
197+
def testMethod():
198+
if not asserts.fileContainsFunctionDefinitions(test.fileName, 'is_resistant'):
199+
return False, "is_resistant() is not defined (check the spelling!)"
200+
201+
is_resistant = lib.getFunction("is_resistant", test.fileName)
202+
203+
if is_resistant("AAA") != True:
204+
return False, "expected AAA to be resistant"
205+
if is_resistant("AAGGAA") != False:
206+
return False, "expected AAGGAA to not be resistant"
207+
if is_resistant("ATGCAATGCAATGGGCCCCTTTAAACCCT") != True:
208+
return False, "expected ATGCAATGCAATGGGCCCCTTTAAACCCT to be resistant"
209+
210+
return True
211+
212+
test.test = testMethod
213+
test.description = lambda : "is_resistant() works correctly"
214+
215+
@t.test(1)
216+
def simulate_medicine_length(test):
217+
def testMethod():
218+
simulate = lib.getFunction("simulate", test.fileName)
219+
220+
viruses = ["GGGG", "AAAA", "TTTT", "GGGG", "ATGC"] * 20
221+
sim_results = simulate(viruses, 0, 0, 0, 100, 500)
222+
223+
if not isinstance(sim_results, list):
224+
return False, "expected simulate() to return a list"
225+
226+
if not len(sim_results) == 501:
227+
return False, f"expected a list of 501 long with timesteps=500, but found a list {len(sim_results)} long"
228+
229+
return True
230+
231+
test.test = testMethod
232+
test.description = lambda : "simulate() produces a list of the correct length"
233+
234+
@t.test(1)
235+
def simulate_medicine_fluctuations(test):
236+
def testMethod():
237+
simulate = lib.getFunction("simulate", test.fileName)
238+
239+
viruses = ["GGGG", "AAAA", "TTTT", "GGGG", "ATGC"] * 20
240+
241+
for pop_size in simulate(viruses, 0, 0, 0, 100, 500):
242+
if pop_size != 100:
243+
return False, f"expected 100 viruses, but found {pop_size}"
244+
245+
return True
246+
247+
test.test = testMethod
248+
test.description = lambda : "simulate(viruses, 0, 0, 0, 100) shows no fluctuations in population size"
249+
250+
@t.test(1)
251+
def simulate_medicine_avg(test):
252+
def testMethod():
253+
simulate = lib.getFunction("simulate", test.fileName)
254+
255+
viruses = ["GGGG", "AAAA", "TTTT", "GGGG", "ATGC"] * 20
256+
n_trials = 100
257+
timesteps = 1000
258+
259+
avg = lambda : sum(simulate(viruses[:], 0.1, 0.1, 0.5, 100, timesteps)) / timesteps
260+
avg_pop_size = sum(avg() for _ in range(n_trials)) / n_trials
261+
262+
if not 50 <= avg_pop_size <= 75:
263+
return False, f"expected an average population size of roughly 50 to 65, but found {avg_pop_size}"
264+
265+
return True
266+
267+
test.test = testMethod
268+
test.description = lambda : "simulate(viruses, 0.1, 0.1, 0.5, 100) yields reasonable results"
269+
test.timeout = lambda: 120

0 commit comments

Comments
 (0)