Skip to content

Commit 77d1288

Browse files
committed
moves testing project into the main repo
1 parent 258989c commit 77d1288

16 files changed

+392
-0
lines changed

testing_project/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10.6

testing_project/LICENSE.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
The material in this repository is released under the
2+
CC Attribution-Share Alike 4.0 International
3+
license.
4+
5+
Full license text available at
6+
https://creativecommons.org/licenses/by-sa/4.0/

testing_project/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Testing Project
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import numpy as np
2+
import pytest
3+
4+
5+
# add a commandline option to pytest
6+
def pytest_addoption(parser):
7+
"""Add random seed option to py.test.
8+
"""
9+
parser.addoption('--seed', dest='seed', type=int, action='store',
10+
help='set random seed')
11+
12+
13+
# configure pytest to automatically set the rnd seed if not passed on CLI
14+
def pytest_configure(config):
15+
seed = config.getvalue("seed")
16+
# if seed was not set by the user, we set one now
17+
if seed is None or seed == ('NO', 'DEFAULT'):
18+
config.option.seed = int(np.random.randint(2 ** 31 - 1))
19+
20+
21+
def pytest_report_header(config):
22+
return f'Using random seed: {config.option.seed}'
23+
24+
25+
@pytest.fixture
26+
def random_state(request):
27+
random_state = np.random.RandomState(request.config.option.seed)
28+
return random_state
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import pytest
2+
3+
4+
def test_for_loop_simple():
5+
cases = [1, 2, 3]
6+
for a in cases:
7+
assert a > 0
8+
9+
10+
@pytest.mark.parametrize('a', [1, 2, 3])
11+
def test_parametrize_simple(a):
12+
# This test will be run 3 times, with a=1, a=2, and a=3
13+
assert a > 0
14+
15+
16+
def test_for_loop_multiple():
17+
cases = [(1, 'hi', 'hi'), (2, 'no', 'nono')]
18+
for a, b, expected in cases:
19+
result = b * a
20+
assert result == expected
21+
22+
23+
@pytest.mark.parametrize('a, b, expected', [(1, 'hi', 'hi'), (2, 'no', 'nono')])
24+
def test_parametrize_multiple(a, b, expected):
25+
# This test will be run 2 times, with a=1, b='hi', expected='hi'
26+
# and a=2, b='no', expected='nono'
27+
result = b * a
28+
assert result == expected

testing_project/logistic.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Your code goes here

testing_project/logistic_fit.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import numpy as np
2+
3+
from logistic import iterate_f
4+
5+
6+
def fit_r(xs):
7+
""" Takes a population trajectory and returns the value of r that generated it.
8+
9+
By far not the most efficient method, but it always finds the optimal value of r with 1/1000
10+
precision.
11+
12+
Parameters
13+
----------
14+
xs : list of float
15+
A population trajectory.
16+
17+
Returns
18+
-------
19+
r: float
20+
The value of r that generated the population trajectory.
21+
"""
22+
xs = np.asarray(xs)
23+
x0 = xs[0]
24+
it = len(xs) - 1
25+
26+
def error(r):
27+
return np.linalg.norm(xs - iterate_f(it, x0, r))
28+
29+
errors = []
30+
for r in np.linspace(0, 4, 4001):
31+
errors.append((r, error(r)))
32+
return min(errors, key=lambda x: x[1])[0]

testing_project/plot_logistic.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""Usage:
2+
```
3+
plot_trajectory(100, 3.6, 0.1)
4+
plot_bifurcation(2.5, 4.2, 0.001)
5+
```
6+
"""
7+
import numpy as np
8+
from matplotlib import pyplot as plt
9+
10+
from logistic import iterate_f
11+
12+
13+
def plot_trajectory(n, r, x0, fname="single_trajectory.png"):
14+
"""
15+
Saves a plot of a single trajectory of the logistic function
16+
17+
inputs
18+
n: int (number of iterations)
19+
r: float (r value for the logistic function)
20+
x0: float (between 0 and 1, starting point for the iteration)
21+
fname: str (filename to which to save the image)
22+
23+
returns
24+
fig, ax (matplotlib objects)
25+
"""
26+
xs = iterate_f(n, x0, r)
27+
fig, ax = plt.subplots(figsize=(10, 5))
28+
ax.plot(list(range(n)), xs)
29+
fig.suptitle('Logistic Function')
30+
31+
fig.savefig(fname)
32+
return fig, ax
33+
34+
35+
def plot_bifurcation(start, end, step, fname="bifurcation.png", it=100000,
36+
last=300):
37+
"""
38+
Saves a plot of the bifurcation diagram of the logistic function. The
39+
`start`, `end`, and `step` parameters define for which r values to
40+
calculate the logistic function. If you space them too closely, it might
41+
take a very long time, if you dont plot enough, your bifurcation diagram
42+
won't be informative. Choose wisely!
43+
44+
inputs
45+
start, end, step: float (which r values to calculate the logistic
46+
function for)
47+
fname: str (filename to which to save the image)
48+
it: int (how many iterations to run for each r value)
49+
last: int (how many of the last iterates to plot)
50+
51+
52+
returns
53+
fig, ax (matplotlib objects)
54+
"""
55+
r_range = np.arange(start, end, step)
56+
x = []
57+
y = []
58+
59+
for r in r_range:
60+
xs = iterate_f(it, 0.1, r)
61+
all_xs = xs[len(xs) - last::].copy()
62+
unique_xs = np.unique(all_xs)
63+
y.extend(unique_xs)
64+
x.extend(np.ones(len(unique_xs)) * r)
65+
66+
fig, ax = plt.subplots(figsize=(20, 10))
67+
ax.scatter(x, y, s=0.1, color='k')
68+
ax.set_xlabel("r")
69+
fig.savefig(fname)
70+
return fig, ax

testing_project/pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# pytest.ini
2+
[pytest]
3+
norecursedirs = *
4+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import numpy as np
2+
import pytest
3+
4+
5+
# add a commandline option to pytest
6+
def pytest_addoption(parser):
7+
"""Add random seed option to py.test.
8+
"""
9+
parser.addoption('--seed', dest='seed', type=int, action='store',
10+
help='set random seed')
11+
12+
13+
# configure pytest to automatically set the rnd seed if not passed on CLI
14+
def pytest_configure(config):
15+
seed = config.getvalue("seed")
16+
# if seed was not set by the user, we set one now
17+
if seed is None or seed == ('NO', 'DEFAULT'):
18+
config.option.seed = int(np.random.randint(2 ** 31 - 1))
19+
20+
21+
def pytest_report_header(config):
22+
return f'Using random seed: {config.option.seed}'
23+
24+
25+
@pytest.fixture
26+
def random_state(request):
27+
random_state = np.random.RandomState(request.config.option.seed)
28+
return random_state

0 commit comments

Comments
 (0)