This repository has been archived by the owner on Oct 4, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathheredity_test.py
141 lines (112 loc) · 3.84 KB
/
heredity_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
Acceptance tests for heredity.py
Make sure that this file is in the same directory as heredity.py!
'Why do we fall sir? So that we can learn to pick ourselves up.'
- Batman Begins (2005)
"""
from heredity import joint_probability, load_data, normalize, powerset, update
PRECISION = 4
# Test cases provided by Naveena A S. Thank you!
# source: https://edstem.org/us/courses/176/discussion/488564?answer=1263763
def test_family0():
expected = {
"Harry": {
"gene": {2: 0.0092, 1: 0.4557, 0: 0.5351},
"trait": {True: 0.2665, False: 0.7335},
},
"James": {
"gene": {2: 0.1976, 1: 0.5106, 0: 0.2918},
"trait": {True: 1.0000, False: 0.0000},
},
"Lily": {
"gene": {2: 0.0036, 1: 0.0136, 0: 0.9827},
"trait": {True: 0.0000, False: 1.0000},
},
}
predicted = predict_family(0)
return compare(predicted, expected)
def test_family1():
expected = {
"Arthur": {
"gene": {2: 0.0329, 1: 0.1035, 0: 0.8636},
"trait": {True: 0.0000, False: 1.0000},
},
"Charlie": {
"gene": {2: 0.0018, 1: 0.1331, 0: 0.8651},
"trait": {True: 0.0000, False: 1.0000},
},
"Fred": {
"gene": {2: 0.0065, 1: 0.6486, 0: 0.3449},
"trait": {True: 1.0000, False: 0.0000},
},
"Ginny": {
"gene": {2: 0.0027, 1: 0.1805, 0: 0.8168},
"trait": {True: 0.1110, False: 0.8890},
},
"Molly": {
"gene": {2: 0.0329, 1: 0.1035, 0: 0.8636},
"trait": {True: 0.0000, False: 1.0000},
},
"Ron": {
"gene": {2: 0.0027, 1: 0.1805, 0: 0.8168},
"trait": {True: 0.1110, False: 0.8890},
},
}
predicted = predict_family(1)
return compare(predicted, expected)
def test_family2():
expected = {
"Arthur": {
"gene": {2: 0.0147, 1: 0.0344, 0: 0.9509},
"trait": {True: 0.0000, False: 1.0000},
},
"Hermione": {
"gene": {2: 0.0608, 1: 0.1203, 0: 0.8189},
"trait": {True: 0.0000, False: 1.0000},
},
"Molly": {
"gene": {2: 0.0404, 1: 0.0744, 0: 0.8852},
"trait": {True: 0.0768, False: 0.9232},
},
"Ron": {
"gene": {2: 0.0043, 1: 0.2149, 0: 0.7808},
"trait": {True: 0.0000, False: 1.0000},
},
"Rose": {
"gene": {2: 0.0088, 1: 0.7022, 0: 0.2890},
"trait": {True: 1.0000, False: 0.0000},
},
}
predicted = predict_family(2)
return compare(predicted, expected)
# Helper functions
def predict_family(n):
people = load_data(f"data/family{n}.csv")
probabilities = {
person: {"gene": {2: 0, 1: 0, 0: 0}, "trait": {True: 0, False: 0}}
for person in people
}
names = set(people)
for have_trait in powerset(names):
fails_evidence = any(
(
people[person]["trait"] is not None
and people[person]["trait"] != (person in have_trait)
)
for person in names
)
if fails_evidence:
continue
for one_gene in powerset(names):
for two_genes in powerset(names - one_gene):
p = joint_probability(people, one_gene, two_genes, have_trait)
update(probabilities, one_gene, two_genes, have_trait, p)
normalize(probabilities)
return probabilities
def compare(predicted, expected):
for kPerson, vPerson in predicted.items():
for kVariable, vVariable in vPerson.items():
for kOutcome, vOutcome in vVariable.items():
assert (
round(vOutcome, PRECISION) == expected[kPerson][kVariable][kOutcome]
)