def restrict(self, candidates: set = None, **kwargs) -> 'BallotLevels': if kwargs: raise TypeError( "restrict() got an unexpected keyword argument %r" % list(kwargs.keys())[0]) if candidates is None: return self return BallotLevels( {k: v for k, v in self.as_dict.items() if k in candidates}, candidates=NiceSet(self.candidates & candidates), scale=self.scale)
def order_(self) -> list: """ Result of the election as a (weak) order over the candidates. :return: a list of :class:`NiceSet`. The first set contains the candidates that have the best score, the second set contains those with the second best score, etc. """ return [ NiceSet(k for k in self.scores_.keys() if self.scores_[k] == v) for v in sorted(set(self.scores_.values()), key=cmp_to_key(self.compare_scores), reverse=True) ]
def order_(self) -> list: orders = [rule.order_ for rule in self.rules_] # rank_tuples[a] will be (rank in order 0, rank in order 1, ...) rank_tuples = {c: [] for c in self.candidates_} for order in orders: for i, tie_class in enumerate(order): for c in tie_class: rank_tuples[c].append(i) rank_tuples = {k: tuple(v) for k, v in rank_tuples.items()} # Now, sort by lexicographic order of "rank tuples" return [ NiceSet(k for k in rank_tuples.keys() if rank_tuples[k] == v) for v in sorted(set(rank_tuples.values())) ]
def candidates(self) -> NiceSet: """ The candidates. :return: a set of candidates. If the set was not explicitly given, the candidates are inferred from the ballot. >>> BallotOrder('a ~ b > c', candidates={'a', 'b', 'c', 'd', 'e'}).candidates {'a', 'b', 'c', 'd', 'e'} >>> BallotOrder('a ~ b > c').candidates {'a', 'b', 'c'} """ if self._input_candidates is None: return self.candidates_in_b return NiceSet(self._input_candidates)
def order_(self) -> list: matrix = self.matrix_majority_ condorcet_winners = { c for c in matrix.candidates_ if min({ v for (i, j), v in matrix.as_dict_.items() if i == c and j != c }) == 1 } other_candidates = self.candidates_ - condorcet_winners return [ NiceSet(tie_class) for tie_class in [condorcet_winners, other_candidates] if tie_class ]
def __call__(self, ballots: Union[list, Profile] = None, weights: list = None, voters: list = None, candidates: set = None): self.profile_original_ = Profile(ballots, weights=weights, voters=voters) self.profile_converted_ = Profile( [self.converter(b, candidates) for b in self.profile_original_], weights=self.profile_original_.weights, voters=self.profile_original_.voters) if candidates is None: candidates = NiceSet( set().union(*[b.candidates for b in self.profile_converted_])) self.candidates_ = candidates self._check_profile(candidates) self.delete_cache() return self
def eliminated_order_(self): if self.k > 0: n_wanted = self.k else: n_wanted = self.rule_.n_candidates_ + self.k if n_wanted <= 0 or n_wanted >= self.rule_.n_candidates_: return self.rule_.order_ worst_first = [] for tie_class in self.rule_.order_[::-1]: size_class = len(tie_class) if size_class <= n_wanted: worst_first.append(tie_class) n_wanted -= size_class if n_wanted == 0: break else: worst_first.append( NiceSet( self.rule_.tie_break.sort(tie_class)[-1:-1 - n_wanted:-1])) break return worst_first[::-1]
def order_(self) -> list: return [ NiceSet(k for k in self.scores_.keys() if self.scores_[k] == v) for v in sorted(set(self.scores_.values()), reverse=True) ]
def as_weak_order(self) -> list: return [ NiceSet(k for k in self.as_dict.keys() if self.as_dict[k] == v) for v in sorted(set(self.as_dict.values()), reverse=True) ]
def candidates_in_b(self) -> NiceSet: return NiceSet(self.as_dict.keys())