def scores_(self) -> NiceDict:
     if self.ballot_.candidate is None:
         if self.count_abstention:
             return NiceDict({c: 0 for c in self.candidates_})
         else:
             return NiceDict()
     scores = NiceDict({c: 0 for c in self.candidates_})
     scores[self.ballot_.candidate] = 1
     return scores
Exemple #2
0
 def _gross_scores_and_weights_quicker_(self) -> dict:
     if not isinstance(self.scorer, ScorerPlurality):
         return self._gross_scores_and_weights_
     # If it is a ScorerPlurality, we have a quicker method.
     gross_scores = NiceDict({c: 0 for c in self.candidates_})
     total_weight = 0
     for ballot, weight, _ in self.profile_converted_.items():
         if ballot.candidate is None:
             if self.scorer.count_abstention:
                 total_weight += weight
             continue
         gross_scores[ballot.candidate] += weight
         total_weight += weight
     weights = NiceDict({c: total_weight for c in self.candidates_})
     return {'gross_scores': gross_scores, 'weights': weights}
    def candidates_indexes_(self) -> NiceDict:
        """
        The candidates as a dictionary.

        :return: a dictionary. To each candidate, it associates its index in :attr:`candidates_as_list_`.
        """
        return NiceDict({c: i for i, c in enumerate(self.candidates_as_list_)})
    def scores_as_floats_(self) -> NiceDict:
        """
        Scores as floats.

        :return: :attr:`scores_` converted to floats.
        """
        return NiceDict({c: float(v) for c, v in self.scores_.items()})
Exemple #5
0
    def detailed_scores_(self) -> list:
        """
        Detailed scores.

        :return: a list of :class:`NiceDict`. The first dictionary gives the scores of the first round, etc.
        """
        n_candidates = len(self.candidates_)
        detailed_scores = []
        for k in range(1, n_candidates + 1):
            self.scorer.k = k
            gross_scores = NiceDict({c: 0 for c in self.candidates_})
            weights = NiceDict({c: 0 for c in self.candidates_})
            for ballot, weight, voter in self.profile_converted_.items():
                for c, value in self.scorer(
                        ballot=ballot, voter=voter,
                        candidates=self.candidates_).scores_.items():
                    gross_scores[c] += weight * value
                    weights[c] += weight
            scores = NiceDict({
                c: my_division(score, weights[c], divide_by_zero=0)
                for c, score in gross_scores.items()
            })
            detailed_scores.append(scores)
            if max(scores.values()) > Fraction(1, 2):
                break
        return detailed_scores
Exemple #6
0
 def scores_(self) -> NiceDict:
     matrix = self.matrix_weighted_majority_
     return NiceDict({
         c: min({
             v
             for (i, j), v in matrix.as_dict_.items() if i == c and j != c
         })
         for c in matrix.candidates_
     })
 def scores_(self) -> NiceDict:
     matrix = self.matrix_weighted_majority_
     return NiceDict({
         c: convert_number(
             sum([
                 v for (i, j), v in matrix.as_dict_.items()
                 if i == c and j != c and v < 0
             ]))
         for c in matrix.candidates_
     })
 def as_dict_(self):
     def convert(x, y):
         if x == y:
             return self.equal
         return self.greater if x > y else self.lower
     weighted_as_dict = self.matrix_weighted_majority_.as_dict_
     return NiceDict({
         (c, d): self.diagonal if c == d else convert(weighted_as_dict[(c, d)], weighted_as_dict[(d, c)])
         for (c, d) in weighted_as_dict.keys()
     })
    def _parse(self, b: dict) -> None:
        """
        For this subclass, the internal representation is of the form {'a': 10, 'b': 7, 'c': 3}, meaning
        that a has evaluation 10; b, 7; and c, 3.

        :param b: a dictionary.
        """
        self._internal_representation = NiceDict(
            {c: convert_number(v)
             for c, v in b.items()})
    def scores_as_floats_(self) -> NiceDict:
        """

        :return: :attr:`scores_`, converted to floats.
        """
        def my_float(x):
            try:
                return float(x)
            except ValueError:
                return x
        return NiceDict({c: (my_float(s), float(x), float(y)) for c, (s, x, y) in self.scores_.items()})
Exemple #11
0
    def detailed_scores_as_floats_(self) -> list:
        """
        Detailed scores, as floats.

        :return: :attr:`detailed_scores_`, converted to floats.
        """
        return [
            NiceDict({c: float(v)
                      for c, v in counting_round.items()})
            for counting_round in self.detailed_scores_
        ]
    def scores_as_floats_(self) -> NiceDict:
        """
        The scores, given as floats.

        :return: :attr:`scores_`, converted to floats.
        :raise ValueError: if the scores cannot be converted to floats.

        Like all conversions to floats, it is advised to use this attribute for display purposes only. For computation,
        you should always use :attr:`scores_`, which usually manipulates fractions and therefore allows for exact
        computation.
        """
        try:
            return NiceDict({c: float(v) for c, v in self.scores_.items()})
        except ValueError:
            raise ValueError('These scores cannot be converted to floats: %r.' % self.scores_)
    def scores_(self) -> NiceDict:
        """
        The scores.

        :return: a :class:`NiceDict` of triples.
        """
        levels_ = NiceDict({c: [] for c in self.candidates_})
        weights_ = NiceDict({c: [] for c in self.candidates_})
        for ballot, weight, voter in self.profile_converted_.items():
            for c, level in self.scorer(ballot=ballot, voter=voter, candidates=self.candidates_).scores_.items():
                levels_[c].append(level)
                weights_[c].append(weight)
        scores_ = NiceDict()
        for c in self.candidates_:
            if not levels_[c]:
                scores_[c] = (self.default_median, 0, 0)
                continue
            indexes = self.scorer.scale.argsort(levels_[c])
            levels_[c] = [levels_[c][i] for i in indexes]
            weights_[c] = [weights_[c][i] for i in indexes]
            total_weight = sum(weights_[c])
            half_total_weight = my_division(total_weight, 2)
            cumulative_weight = 0
            median = None
            for i, weight in enumerate(weights_[c]):
                cumulative_weight += weight
                if cumulative_weight >= half_total_weight:
                    median = levels_[c][i]
                    break
            p = sum([weights_[c][i] for i, level in enumerate(levels_[c]) if self.scorer.scale.gt(level, median)])
            q = sum([weights_[c][i] for i, level in enumerate(levels_[c]) if self.scorer.scale.lt(level, median)])
            if p > q:
                scores_[c] = (median, my_division(p, total_weight), -my_division(q, total_weight))
            else:
                scores_[c] = (median, -my_division(q, total_weight), my_division(p, total_weight))
        return scores_
 def scores_(self) -> NiceDict:
     scores = NiceDict(self.ballot_.as_dict.copy())
     if self.level_absent is not None:
         scores.update({
             c: self.level_absent
             for c in self.candidates_ - self.ballot_.candidates
         })
     if self.level_ungraded is not None:
         scores.update({
             c: self.level_ungraded
             for c in self.ballot_.candidates_not_in_b
         })
     return scores
 def scores_(self) -> NiceDict:
     scores = NiceDict()
     l_points_scheme = len(self.points_scheme)
     for i, c in enumerate(self.ballot_):
         if i < l_points_scheme:
             scores[c] = self.points_scheme[i]
         else:
             if self.points_fill is None:
                 break
             scores[c] = self.points_fill
     if self.points_unordered is not None:
         scores.update({
             c: self.points_unordered
             for c in self.ballot_.candidates_not_in_b
         })
     if self.points_absent is not None:
         scores.update({
             c: self.points_absent
             for c in self.candidates_ - self.ballot_.candidates
         })
     return scores
Exemple #16
0
 def scores_(self) -> NiceDict:
     scores = NiceDict()
     points_remaining = self.k
     # Ordered candidates
     for indifference_class in self.ballot_.as_weak_order[:]:
         n_indifference = len(indifference_class)
         if n_indifference <= points_remaining:
             scores.update({c: 1 for c in indifference_class})
             points_remaining -= n_indifference
         else:
             scores.update({
                 c: my_division(points_remaining, n_indifference)
                 for c in indifference_class
             })
             points_remaining = 0
     # Unordered candidates
     if self.unordered_receive_points is False:
         scores.update({c: 0 for c in self.ballot_.candidates_not_in_b})
     elif self.unordered_receive_points is True:
         unordered = self.ballot_.candidates_not_in_b
         n_unordered = len(unordered)
         if n_unordered <= points_remaining:
             scores.update({c: 1 for c in unordered})
             points_remaining -= n_unordered
         else:
             scores.update({
                 c: my_division(points_remaining, n_unordered)
                 for c in unordered
             })
             points_remaining = 0
     # Absent candidates
     if self.absent_receive_points is False:
         scores.update(
             {c: 0
              for c in self.candidates_ - self.ballot_.candidates})
     elif self.absent_receive_points is True:
         absent = self.candidates_ - self.ballot_.candidates
         n_absent = len(absent)
         if n_absent <= points_remaining:
             scores.update({c: 1 for c in absent})
         else:
             scores.update({
                 c: my_division(points_remaining, n_absent)
                 for c in absent
             })
     return scores
Exemple #17
0
 def scores_(self) -> NiceDict:
     scores = NiceDict()
     points_from_lower_candidates = 0
     # Absent candidates
     if self.absent_give_points or self.absent_receive_points is not None:
         absent = self.candidates_ - self.ballot_.candidates
         n_absent = len(absent)
         if self.absent_receive_points is False:
             scores.update({c: 0 for c in absent})
         if self.absent_receive_points is True:
             points_temp = my_division(n_absent - 1,
                                       2) if self.absent_give_points else 0
             scores.update({c: points_temp for c in absent})
         if self.absent_give_points:
             points_from_lower_candidates += n_absent
     # Unordered candidates
     if self.unordered_give_points or self.unordered_receive_points is not None:
         unordered = self.ballot_.candidates_not_in_b
         n_unordered = len(unordered)
         if self.unordered_receive_points is False:
             scores.update({c: 0 for c in unordered})
         if self.unordered_receive_points is True:
             points_temp = points_from_lower_candidates
             if self.unordered_give_points:
                 points_temp += my_division(n_unordered - 1, 2)
             scores.update({c: points_temp for c in unordered})
         if self.unordered_give_points:
             points_from_lower_candidates += n_unordered
     # Ordered candidates
     for indifference_class in self.ballot_.as_weak_order[::-1]:
         n_indifference = len(indifference_class)
         points_temp = points_from_lower_candidates + my_division(
             n_indifference - 1, 2)
         scores.update({c: points_temp for c in indifference_class})
         points_from_lower_candidates += n_indifference
     return scores
Exemple #18
0
 def _gross_and_weights_(self):
     gross = NiceDict({(c, d): 0
                       for c in self.candidates_ for d in self.candidates_})
     weights = NiceDict({(c, d): 0
                         for c in self.candidates_
                         for d in self.candidates_})
     for ballot, weight, _ in self.profile_converted_.items():
         absent = self.candidates_ - ballot.candidates
         for i_class, indifference_class in enumerate(ballot.as_weak_order):
             indifference_class_as_list = list(indifference_class)
             for i, c in enumerate(indifference_class_as_list):
                 # Deal with other candidates of the indifference class
                 if self.indifference is not None:
                     for d in indifference_class_as_list[i + 1:]:
                         gross[(c, d)] += weight * self.indifference
                         gross[(d, c)] += weight * self.indifference
                         weights[(c, d)] += weight
                         weights[(d, c)] += weight
                 # Deal with ordered candidates with lower ranks
                 if self.higher_vs_lower is not None or self.lower_vs_higher is not None:
                     for lower_indifference_class in ballot.as_weak_order[
                             i_class + 1:]:
                         for d in lower_indifference_class:
                             if self.higher_vs_lower is not None:
                                 gross[(c,
                                        d)] += weight * self.higher_vs_lower
                                 weights[(c, d)] += weight
                             if self.lower_vs_higher is not None:
                                 gross[(d,
                                        c)] += weight * self.lower_vs_higher
                                 weights[(d, c)] += weight
                 # Deal with unordered candidates
                 if self.ordered_vs_unordered is not None or self.unordered_vs_ordered is not None:
                     for d in ballot.candidates_not_in_b:
                         if self.ordered_vs_unordered is not None:
                             gross[(
                                 c,
                                 d)] += weight * self.ordered_vs_unordered
                             weights[(c, d)] += weight
                         if self.unordered_vs_ordered is not None:
                             gross[(
                                 d,
                                 c)] += weight * self.unordered_vs_ordered
                             weights[(d, c)] += weight
                 # Deal with absent candidates
                 if self.ordered_vs_absent is not None or self.absent_vs_ordered is not None:
                     for d in absent:
                         if self.ordered_vs_absent is not None:
                             gross[(c,
                                    d)] += weight + self.ordered_vs_absent
                             weights[(c, d)] += weight
                         if self.absent_vs_ordered is not None:
                             gross[(d,
                                    c)] += weight + self.absent_vs_ordered
                             weights[(d, c)] += weight
         if (self.unordered_vs_unordered is not None
                 or self.unordered_vs_absent is not None
                 or self.absent_vs_unordered is not None):
             unordered_as_list = list(ballot.candidates_not_in_b)
             for i, c in enumerate(unordered_as_list):
                 # Deal with other unordered candidates
                 if self.unordered_vs_unordered is not None:
                     for d in unordered_as_list[i + 1:]:
                         gross[(c,
                                d)] += weight * self.unordered_vs_unordered
                         gross[(d,
                                c)] += weight * self.unordered_vs_unordered
                         weights[(c, d)] += weight
                         weights[(d, c)] += weight
                 # Deal with absent candidates
                 for d in absent:
                     if self.unordered_vs_absent is not None:
                         gross[(c, d)] += weight * self.unordered_vs_absent
                         weights[(c, d)] += weight
                     if self.absent_vs_unordered is not None:
                         gross[(d, c)] += weight * self.absent_vs_unordered
                         weights[(d, c)] += weight
         if self.absent_vs_absent is not None:
             absent_as_list = list(absent)
             for i, c in enumerate(absent_as_list):
                 for d in absent_as_list[i + 1:]:
                     gross[(c, d)] += weight * self.absent_vs_absent
                     gross[(d, c)] += weight * self.absent_vs_absent
                     weights[(c, d)] += weight
                     weights[(d, c)] += weight
     return {'gross': gross, 'weights': weights}
 def as_dict_(self):
     return NiceDict({(c, d): self.as_array_[self.candidates_indexes_[c],
                                             self.candidates_indexes_[d]]
                      for c in self.candidates_ for d in self.candidates_})
 def scores_(self) -> NiceDict:
     m = self.matrix_
     return NiceDict({c: sum([v for (i, j), v in m.as_dict_.items() if i == c and j != c])
                      for c in m.candidates_})