Skip to content

Commit 843d26b

Browse files
PR for #9: GitHub actions (#12)
* WIP for #9 * starts fixing broken tests for #9 * fixes tests for #9 * removes stray main for #9 * fixes error for #9 * Update .github/workflows/pytest.yml Co-authored-by: jmshapir <[email protected]> * Update .github/workflows/pytest.yml Co-authored-by: jmshapir <[email protected]> * Update .github/workflows/pytest.yml Co-authored-by: jmshapir <[email protected]> * edits test for #9 * changed versions for #9 * Update tests/test_BootstrapReport.py Co-authored-by: jmshapir <[email protected]> * removes stray import for #9 * removes digits for #9 --------- Co-authored-by: jmshapir <[email protected]>
1 parent 8cc064d commit 843d26b

File tree

6 files changed

+173
-168
lines changed

6 files changed

+173
-168
lines changed

.github/workflows/pytest.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Install Python dependencies and run unit tests.
2+
#
3+
# Note: These tests should run quickly; we set a timeout to
4+
# 15 minutes to catch possible hang-ups, should they occur.
5+
6+
name: BootstrapReport Unit Tests
7+
8+
on:
9+
push:
10+
branches: [ main ]
11+
pull_request:
12+
branches: [ main ]
13+
14+
jobs:
15+
build:
16+
runs-on: ${{ matrix.os }}
17+
timeout-minutes: 15
18+
strategy:
19+
matrix:
20+
os: [ ubuntu-latest, windows-latest, macos-latest ]
21+
python-version: [ "3.8", "3.11" ]
22+
steps:
23+
- uses: actions/checkout@v2
24+
- name: Set up Python ${{ matrix.python-version }}
25+
uses: actions/setup-python@v2
26+
with:
27+
python-version: ${{ matrix.python-version }}
28+
architecture: x64
29+
- name: Install dependencies
30+
run: |
31+
python -m pip install --upgrade pip
32+
pip install pytest
33+
pip install matplotlib
34+
pip install scipy
35+
pip install numpy
36+
pip install pandas
37+
pip install seaborn
38+
- name: Test with pytest
39+
run: |
40+
python -m pytest

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ packages = ["BootstrapReport"]
99
name = "BootstrapReport"
1010
version = "0.0.1"
1111
authors = [
12-
{name = "Jesse Shapiro", email = "jesse shapiro@fas.harvard.edu"},
12+
{name = "Jesse Shapiro", email = "jesse_shapiro@fas.harvard.edu"},
1313
{name = "Isaiah Andrews", email = "[email protected]"}
1414
]
1515
description = "A package for checking normality when using bootstraps"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

tests/test_BootstrapReport.py

Lines changed: 117 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -5,146 +5,11 @@
55
from scipy.optimize import minimize
66
import pytest
77
from BootstrapReport.BootstrapReport import ObjectOfInterest
8-
import helpers
8+
import BootstrapReport.helpers as helpers
99
import test_helpers
1010

11-
def test_bandwidth_to_se_ratio():
12-
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
13-
estimate1, se1 = 0, 1
14-
test1 = ObjectOfInterest(estimate1, se1, replicates=test_replicates)
15-
best_bandwidth1, tv_at_best_bwidth1 = test1.get_bias_corrected_tvd(num_sets=2)[1:3]
16-
estimate2, se2 = 0, 10
17-
test2 = ObjectOfInterest(estimate2, se2, replicates=test_replicates)
18-
best_bandwidth2, tv_at_best_bwidth2 = test2.get_bias_corrected_tvd(num_sets=2)[1:3]
19-
20-
assert test_helpers.round_to_2(tv_at_best_bwidth1) == test_helpers.round_to_2(tv_at_best_bwidth2)
21-
assert test_helpers.round_to_2(best_bandwidth1) == test_helpers.round_to_2(best_bandwidth2)
22-
23-
24-
def test_get_bias():
25-
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
26-
estimate, standard_error = 2, 1
27-
test = ObjectOfInterest(estimate=estimate, se=standard_error, replicates=test_replicates)
28-
29-
assert test.get_bias(num_replicates=10, best_bandwidth=1, implied_normal_pdf=lambda x: norm.pdf(x, 2, 1),
30-
lbound=-50, rbound=50, num_sets=5, second_seed=11) == 0.14285730950108239
31-
32-
33-
def test_tv_min_uniform():
34-
tol = 1e-3
35-
theta = np.array([0.01, 0.2, 3, 40, 500])
36-
c = 8.83739357236942583899741126
37-
38-
for t in theta:
39-
40-
def objective(inputs):
41-
def pdf_from_unif(x):
42-
return uniform.pdf(x, loc=0, scale=t)
43-
def pdf_from_normal(x):
44-
return norm.pdf(x, inputs[0], inputs[1])
45-
return helpers.get_tvd(pdf_from_unif, pdf_from_normal)
46-
47-
x0 = (t/2, t/3)
48-
bounds = ((0, t), (0, t))
49-
res = minimize(objective, x0, bounds = bounds)
50-
assert np.isclose(res.x[0], t/2, atol=tol, rtol=tol)
51-
assert np.isclose(res.x[1], t/np.sqrt(c), atol=tol, rtol=tol)
52-
53-
54-
def test_tv_min_normal():
55-
tol = 1e-1
56-
par = np.array([[0,1], [0,10], [-10,1]])
57-
R = 1000
58-
59-
np.random.seed(1)
60-
for p in par:
61-
df = np.random.normal(p[0], p[1], R).tolist()
62-
test = ObjectOfInterest(p[0], p[1], replicates=df)
63-
64-
with pytest.raises(ValueError):
65-
test.get_tv_min()
66-
67-
test.get_bias_corrected_tvd()
68-
69-
res = test.get_tv_min()
70-
assert np.isclose(res.x[0], p[0], atol=tol, rtol=tol)
71-
assert np.isclose(res.x[1], p[1], atol=tol, rtol=tol)
72-
73-
res1 = test.get_tv_min(init_values="ESTIMATES")
74-
assert np.isclose(res1.x[0], res.x[0], atol=tol, rtol=tol)
75-
assert np.isclose(res1.x[1], res.x[1], atol=tol, rtol=tol)
76-
77-
res = test.get_tv_min(init_values="REPLICATES")
78-
assert np.isclose(res.x[0], p[0], atol=tol, rtol=tol)
79-
assert np.isclose(res.x[1], p[1], atol=tol, rtol=tol)
80-
81-
assert hasattr(test, "tvmin_mean")
82-
assert hasattr(test, "tvmin_sd")
83-
assert hasattr(test, "tvmin_solveroutput")
84-
assert hasattr(test, "tvmin")
85-
86-
87-
def test_tv_min_warnings():
88-
89-
par = np.array([0,1])
90-
R = 1000
91-
df = np.random.normal(par[0], par[1], R).tolist()
92-
test = ObjectOfInterest(par[0], par[1], replicates=df)
93-
test.get_bias_corrected_tvd()
94-
95-
with pytest.warns(UserWarning):
96-
test.get_tv_min(bounds=((10, 20), (0, 2)))
97-
with pytest.warns(UserWarning):
98-
test.get_tv_min(bounds=((-1, 1), (0.1, 0.2)))
99-
with pytest.warns(UserWarning):
100-
test.get_tv_min(init_values=(1e-20, 1e-20))
101-
test.get_tv_min()
102-
103-
104-
def test_check_initial_values():
105-
106-
R = 1000
107-
np.random.seed(1)
108-
p = [10,1]
109-
df = np.random.normal(p[0], p[1], R).tolist()
110-
test = ObjectOfInterest(p[0], p[1], replicates=df)
111-
test.get_bias_corrected_tvd()
112-
113-
def test_message(error, arg):
114-
with pytest.raises(error):
115-
test.get_tv_min(init_values=arg)
116-
117-
test_message(TypeError, np.array(["a", 1]))
118-
test_message(ValueError, 1)
119-
test_message(ValueError, [1, 2, 3])
120-
test_message(ValueError, np.array([[1, 2], [1, 3]]))
121-
test_message(ValueError, (np.nan, 1))
122-
test_message(ValueError, (0, np.inf))
123-
test_message(ValueError, (0, 0))
124-
125-
126-
def test_check_optimization_bounds():
127-
128-
R = 1000
129-
np.random.seed(1)
130-
p = [10,1]
131-
df = np.random.normal(p[0], p[1], R).tolist()
132-
test = ObjectOfInterest(p[0], p[1], replicates=df)
133-
test.get_bias_corrected_tvd()
134-
135-
def test_message(error, arg):
136-
with pytest.raises(error):
137-
test.get_tv_min(bounds=arg)
138-
139-
test_message(TypeError, np.array([["a", 1], [0, 1]]))
140-
test_message(ValueError, 1)
141-
test_message(ValueError, ((-1, 1), (0, 20), (0, 2)))
142-
test_message(ValueError, np.array([[0, np.nan], [0, 1]]))
143-
test_message(ValueError, np.array([[-1, 1], [-1, 1]]))
144-
145-
14611
def test_sk_distance():
147-
test_replicates = pd.read_csv('source/lib/BootstrapReport/examples/gamma_replicates.csv')['replicate_value'].values
12+
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
14813
estimate, standard_error = 0, 1
14914
test = ObjectOfInterest(estimate = estimate, se = standard_error, replicates = test_replicates)
15015
test.pp_plot()
@@ -153,7 +18,7 @@ def test_sk_distance():
15318
assert test.pos_dist <= 1 and test.pos_dist >= 0
15419

15520
def test_density_plot():
156-
test_replicates = pd.read_csv('source/lib/BootstrapReport/examples/gamma_replicates.csv')['replicate_value'].values
21+
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
15722
estimate, standard_error = 0, 1
15823
test = ObjectOfInterest(estimate = estimate, se = standard_error, replicates = test_replicates)
15924

@@ -165,7 +30,7 @@ def test_density_plot():
16530
test.density_plot()
16631

16732
def test_crossings():
168-
test_replicates = pd.read_csv('source/lib/BootstrapReport/examples/gamma_replicates.csv')['replicate_value'].values
33+
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
16934
estimate, standard_error = 0, 1
17035
test = ObjectOfInterest(estimate = estimate, se = standard_error, replicates = test_replicates)
17136
# Test function makes it to `savefig` when plotting outfile
@@ -184,7 +49,7 @@ def test_crossings():
18449

18550

18651
def test_pp_plot():
187-
test_replicates = pd.read_csv('source/lib/BootstrapReport/examples/normal_replicates.csv')['replicate_value'].values
52+
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
18853
estimate, standard_error = 12.53787813379, 41.35729698836584
18954
test = ObjectOfInterest(estimate = estimate, se = standard_error, replicates = test_replicates)
19055

@@ -218,10 +83,10 @@ def test_sk_min_normal():
21883
assert np.isclose(res.x[0], p[0], atol=tol, rtol=tol)
21984
assert np.isclose(res.x[1], p[1], atol=tol, rtol=tol)
22085

221-
assert hasattr(test, "vdmin_mean")
222-
assert hasattr(test, "vdmin_sd")
223-
assert hasattr(test, "vdmin_solveroutput")
224-
assert hasattr(test, "vdmin")
86+
assert hasattr(test, "skmin_mean")
87+
assert hasattr(test, "skmin_sd")
88+
assert hasattr(test, "skmin_solveroutput")
89+
assert hasattr(test, "skmin")
22590

22691
def test_sk_min_warnings():
22792

@@ -231,7 +96,114 @@ def test_sk_min_warnings():
23196
test = ObjectOfInterest(par[0], par[1], replicates=df)
23297
test.get_sk_min()
23398

234-
with pytest.warns(UserWarning):
99+
with pytest.raises(ValueError):
235100
test.get_sk_min(bounds=((.5, 1.5), (0, 2)))
236101
with pytest.warns(UserWarning):
237102
test.get_sk_min(bounds=((-1, 1), (0.1, 0.2)))
103+
104+
# TV tests:
105+
def test_bandwidth_to_se_ratio():
106+
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
107+
estimate1, se1 = 0, 1
108+
test1 = ObjectOfInterest(estimate1, se1, replicates=test_replicates)
109+
best_bandwidth1, tv_at_best_bwidth1 = test1.get_bias_corrected_tvd(num_sets=2)[1:3]
110+
estimate2, se2 = 0, 10
111+
test2 = ObjectOfInterest(estimate2, se2, replicates=test_replicates)
112+
best_bandwidth2, tv_at_best_bwidth2 = test2.get_bias_corrected_tvd(num_sets=2)[1:3]
113+
114+
assert test_helpers.round_to_2(tv_at_best_bwidth1) == test_helpers.round_to_2(tv_at_best_bwidth2)
115+
assert test_helpers.round_to_2(best_bandwidth1) == test_helpers.round_to_2(best_bandwidth2)
116+
117+
def test_get_bias():
118+
test_replicates = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
119+
estimate, standard_error = 2, 1
120+
test = ObjectOfInterest(estimate=estimate, se=standard_error, replicates=test_replicates)
121+
target = 0.14286
122+
assert np.isclose(test.get_bias(num_replicates=10, best_bandwidth=1, implied_normal_pdf=lambda x: norm.pdf(x, 2, 1),
123+
lbound=-50, rbound=50, num_sets=5, second_seed=11), target, atol = 0.00001)
124+
125+
def test_tv_min_uniform():
126+
tol = 1e-3
127+
theta = np.array([0.01, 500])
128+
c = 8.83739357236942583899741126
129+
130+
for t in theta:
131+
132+
def objective(inputs):
133+
def pdf_from_unif(x):
134+
return uniform.pdf(x, loc=0, scale=t)
135+
def pdf_from_normal(x):
136+
return norm.pdf(x, inputs[0], inputs[1])
137+
return helpers.get_tvd(pdf_from_unif, pdf_from_normal)
138+
139+
x0 = (t/2, t/3)
140+
bounds = ((0, t), (0, t))
141+
res = minimize(objective, x0, bounds = bounds)
142+
assert np.isclose(res.x[0], t/2, atol=tol, rtol=tol)
143+
assert np.isclose(res.x[1], t/np.sqrt(c), atol=tol, rtol=tol)
144+
145+
def test_tv_min_warnings():
146+
147+
rep = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
148+
test = ObjectOfInterest(3.329153904463066, 2.0256286444979983, replicates=rep)
149+
test.best_bandwidth_value = 0.24656
150+
151+
with pytest.raises(ValueError):
152+
test.get_tv_min(optimization_bounds=((10, 20), (0, 2)))
153+
with pytest.warns(UserWarning):
154+
test.get_tv_min(optimization_bounds=((-1, 1), (0.1, 0.2)))
155+
with pytest.warns(UserWarning):
156+
test.get_tv_min(init_values=(1e-20, 1e-20))
157+
158+
159+
def test_check_initial_values():
160+
161+
rep = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
162+
test = ObjectOfInterest(3.329153904463066, 2.0256286444979983, replicates=rep)
163+
test.best_bandwidth_value = 0.24656
164+
165+
def test_message(error, arg):
166+
with pytest.raises(error):
167+
test.get_tv_min(init_values=arg)
168+
169+
test_message(TypeError, np.array(["a", 1]))
170+
test_message(ValueError, 1)
171+
test_message(ValueError, [1, 2, 3])
172+
test_message(ValueError, np.array([[1, 2], [1, 3]]))
173+
test_message(ValueError, (np.nan, 1))
174+
test_message(ValueError, (0, np.inf))
175+
test_message(ValueError, (0, 0))
176+
177+
178+
def test_check_optimization_bounds():
179+
180+
rep = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
181+
test = ObjectOfInterest(3.329153904463066, 2.0256286444979983, replicates=rep)
182+
test.best_bandwidth_value = 0.24656
183+
184+
def test_message(error, arg):
185+
with pytest.raises(error):
186+
test.get_tv_min(optimization_bounds=arg)
187+
188+
test_message(TypeError, np.array([["a", 1], [0, 1]]))
189+
test_message(ValueError, 1)
190+
test_message(ValueError, ((-1, 1), (0, 20), (0, 2)))
191+
test_message(ValueError, np.array([[0, np.nan], [0, 1]]))
192+
test_message(ValueError, np.array([[-1, 1], [-1, 1]]))
193+
194+
def test_tv_min_normal():
195+
tol = 1e-1
196+
rep = pd.read_csv('examples/gamma_replicates.csv')['replicate_value'].values
197+
test = ObjectOfInterest(3.329153904463066, 2.0256286444979983, replicates=rep)
198+
test.best_bandwidth_value = 0.24656
199+
test.get_tv_min()
200+
201+
res_est = test.get_tv_min(init_values="ESTIMATES")
202+
res_rep = test.get_tv_min(init_values="REPLICATES")
203+
assert np.isclose(res_est.x[0], res_rep.x[0], atol=tol, rtol=tol)
204+
assert np.isclose(res_est.x[1], res_rep.x[1], atol=tol, rtol=tol)
205+
206+
assert hasattr(test, "tvmin_mean")
207+
assert hasattr(test, "tvmin_sd")
208+
assert hasattr(test, "tvmin_solveroutput")
209+
assert hasattr(test, "tvmin")

0 commit comments

Comments
 (0)