The edit to chain.py ensures that if a user only inputs one constraint to a MarkovChain, it will still be able to print the correct error message should the chain fail. The error message relies on the constraints being turned into a Validator object, and previously if the user input a single constraint it did not get turned into a Validator.
The edit to tree.py fixes an issue that occasionally caused recursive_tree_part to generate plans that were imbalanced in population. Here is an example to show why the previous computation was incorrect. Suppose the ideal size is 100, epsilon = .02, and the previous district had size 99. Then the debt=-1, the min_pop=99, and max_pop=102. The pop_target = 100.5, and the new value for epsilon is .015. But then the lower end of the population range is actually (100.5)*(1-.015)=98.9925, and the upper end is 100.5**1+.015)=102.0075. The only change required to fix this is to compute the new value for epsilon using the new population target, not the ideal size.
The edit to
chain.py
ensures that if a user only inputs one constraint to aMarkovChain
, it will still be able to print the correct error message should the chain fail. The error message relies on the constraints being turned into aValidator
object, and previously if the user input a single constraint it did not get turned into aValidator
.The edit to
tree.py
fixes an issue that occasionally causedrecursive_tree_part
to generate plans that were imbalanced in population. Here is an example to show why the previous computation was incorrect. Suppose the ideal size is 100, epsilon = .02, and the previous district had size 99. Then the debt=-1, the min_pop=99, and max_pop=102. The pop_target = 100.5, and the new value for epsilon is .015. But then the lower end of the population range is actually (100.5)*(1-.015)=98.9925, and the upper end is 100.5**1+.015)=102.0075. The only change required to fix this is to compute the new value for epsilon using the new population target, not the ideal size.