Source code for gerrytools.scoring.demographics

from typing import Iterable

from gerrychain import Partition
from gerrychain.updaters import Tally

from .types import DistrictWideScoreValue, Numeric, PlanWideScoreValue


[docs] def demographic_updaters( demographic_keys: Iterable[str], aliases: Iterable[str] = None ): updaters = {} aliases = aliases if aliases else demographic_keys for key, alias in zip(demographic_keys, aliases): updaters[alias] = Tally(key, alias=alias) return updaters
def _tally_pop(part: Partition, pop_col: str) -> DistrictWideScoreValue: return part[pop_col] def _pop_shares( part: Partition, subpop_col: str, totpop_col: str ) -> DistrictWideScoreValue: total_pops = part[totpop_col] return {d: part[subpop_col][d] / pop for d, pop in total_pops.items()} def _gingles_districts( part: Partition, subpop_col: str, totpop_col: str, threshold: float = 0.5 ) -> PlanWideScoreValue: subpop_shares = _pop_shares(part, subpop_col, totpop_col) return sum([share >= threshold for share in subpop_shares.values()]) def _max_deviation(part: Partition, totpop_col: str, pct: bool = False) -> Numeric: totpop_counts = _tally_pop(part, totpop_col) ideal_population = sum(totpop_counts.values()) / len(part) max_deviation = max([abs(pop - ideal_population) for pop in totpop_counts.values()]) return max_deviation / ideal_population if pct else max_deviation