Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#414 Use method in recursive calls to recursive_seed_part_inner #415

Merged
merged 11 commits into from
Oct 4, 2023
2 changes: 2 additions & 0 deletions gerrychain/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,12 @@
spanning_tree = spanning_tree_fn(graph)

repeat = True
restarts = 0

Check warning on line 256 in gerrychain/tree.py

View check run for this annotation

Codecov / codecov/patch

gerrychain/tree.py#L256

Added line #L256 was not covered by tests
attempts = 0
while max_attempts is None or attempts < max_attempts:
if restarts == node_repeats:
spanning_tree = spanning_tree_fn(graph)
restarts = 0

Check warning on line 261 in gerrychain/tree.py

View check run for this annotation

Codecov / codecov/patch

gerrychain/tree.py#L259-L261

Added lines #L259 - L261 were not covered by tests
h = PopulatedGraph(spanning_tree, populations, pop_target, epsilon)
possible_cuts = balance_edge_fn(h, choice=choice)

Expand All @@ -267,8 +267,8 @@
if not (repeat and len(possible_cuts) == 0):
return possible_cuts

restarts += 1
attempts += 1

Check warning on line 271 in gerrychain/tree.py

View check run for this annotation

Codecov / codecov/patch

gerrychain/tree.py#L270-L271

Added lines #L270 - L271 were not covered by tests

raise RuntimeError(f"Could not find a possible cut after {max_attempts} attempts.")

Expand Down Expand Up @@ -319,7 +319,7 @@
:param choice: :func:`random.choice`. Can be substituted for testing.
:param max_atempts: The max number of attempts that should be made to bipartition.
"""
possible_cuts = _bipartition_tree_random_all(

Check warning on line 322 in gerrychain/tree.py

View check run for this annotation

Codecov / codecov/patch

gerrychain/tree.py#L322

Added line #L322 was not covered by tests
graph=graph,
pop_col=pop_col,
pop_target=pop_target,
Expand Down Expand Up @@ -601,6 +601,7 @@
pop_target,
pop_col,
epsilon,
method,
n=n,
ceil=ceil)

Expand All @@ -624,6 +625,7 @@
pop_target,
pop_col,
epsilon,
method,
n=n,
ceil=ceil
)
Expand Down
39 changes: 39 additions & 0 deletions tests/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,45 @@ def test_recursive_seed_part_returns_within_epsilon_of_target_pop(twelve_by_twel
for part_pop in partition['pop'].values())


def test_recursive_seed_part_uses_method(twelve_by_twelve_with_pop):
calls = 0

def dummy_method(graph, pop_col, pop_target, epsilon, node_repeats):
nonlocal calls
calls += 1
return bipartition_tree(
graph,
pop_col=pop_col,
pop_target=pop_target,
epsilon=epsilon,
node_repeats=node_repeats,
max_attempts=10000,
)

n_districts = 7 # 144/7 ≈ 20.5 nodes/subgraph (1 person/node)
ideal_pop = (
sum(
twelve_by_twelve_with_pop.nodes[node]["pop"]
for node in twelve_by_twelve_with_pop
)
) / n_districts
epsilon = 0.1
result = recursive_seed_part(
twelve_by_twelve_with_pop,
range(n_districts),
ideal_pop,
"pop",
epsilon,
n=5,
ceil=None,
method=dummy_method,
)
# Called at least once for each district besides the last one
# (note that current implementation of recursive_seed_part calls method
# EXACTLY once for each district besides the last one, but that is an
# implementation detail)
assert calls >= n_districts - 1

def test_random_spanning_tree_returns_tree_with_pop_attribute(graph_with_pop):
tree = random_spanning_tree(graph_with_pop)
assert networkx.is_tree(tree)
Expand Down