BallotOrder

class whalrus.BallotOrder(b: object, candidates: set = None)[source]

Ballot with an ordering.

Parameters:
  • b (object) – The ballot. Cf. examples below for the accepted formats.
  • candidates (set) – The candidates that were available at the moment when the voter cast her ballot. Default: candidates that are explicitly mentioned in the ballot b.

Examples

Most general syntax:

>>> ballot = BallotOrder([{'a', 'b'}, {'c'}], candidates={'a', 'b', 'c', 'd', 'e'})
>>> ballot
BallotOrder([{'a', 'b'}, 'c'], candidates={'a', 'b', 'c', 'd', 'e'})
>>> print(ballot)
a ~ b > c (unordered: d, e)

In the example above, candidates a and b are equally liked, and they are liked better than c. Candidates d and e were available when the voter cast her ballot, but she chose not to include them in her preference order.

Other examples of inputs:

>>> BallotOrder('a ~ b > c')
BallotOrder([{'a', 'b'}, 'c'], candidates={'a', 'b', 'c'})
>>> BallotOrder({'a': 10, 'b': 10, 'c': 7})
BallotOrder([{'a', 'b'}, 'c'], candidates={'a', 'b', 'c'})

The ballot has a set-like behavior in the sense that it implements __len__ and __contains__:

>>> ballot = BallotOrder('a ~ b > c', candidates={'a', 'b', 'c', 'd', 'e'})
>>> len(ballot)
3
>>> 'd' in ballot
False

If the order is strict, then the ballot is also iterable:

>>> ballot = BallotOrder('a > b > c')
>>> for candidate in ballot:
...     print(candidate)
a
b
c
as_strict_order

Strict order format.

It is a list of candidates. For example, ['a', 'b', 'c'] means that a is preferred to b, who is preferred to c.

Raises:ValueError – If the ballot is not a strict order.

Examples

>>> BallotOrder('a > b > c').as_strict_order
['a', 'b', 'c']
Type:list
as_weak_order

Weak order format.

A list of sets. For example, [{'a', 'b'}, {'c'}] means that a and b are equally liked, and they are liked better than c.

Examples

>>> BallotOrder('a ~ b > c', candidates={'a', 'b', 'c', 'd', 'e'}).as_weak_order
[{'a', 'b'}, {'c'}]
Type:list
candidates

the candidates.

If the set was not explicitly given, the candidates are inferred from the ballot.

Examples

>>> BallotOrder('a ~ b > c', candidates={'a', 'b', 'c', 'd', 'e'}).candidates
{'a', 'b', 'c', 'd', 'e'}
>>> BallotOrder('a ~ b > c').candidates
{'a', 'b', 'c'}
Type:NiceSet
candidates_in_b

the candidates that are explicitly mentioned in the ballot.

Examples

>>> BallotOrder('a ~ b > c', candidates={'a', 'b', 'c', 'd', 'e'}).candidates_in_b
{'a', 'b', 'c'}
Type:NiceSet
candidates_not_in_b

the candidates that were available at the moment of the vote, but are not explicitly mentioned in the ballot.

Examples

>>> BallotOrder('a ~ b > c', candidates={'a', 'b', 'c', 'd', 'e'}).candidates_not_in_b
{'d', 'e'}
Type:NiceSet
first(candidates: set = None, **kwargs) → object[source]

The first (= most liked) candidate.

Parameters:
  • candidates (set of candidates) – It can be any set of candidates, not necessarily a subset of self.candidates. Default: self.candidates.
  • kwargs
    • priority: a Priority. Default: Priority.UNAMBIGUOUS.
    • include_unordered: a boolean. If True (default), then unordered candidates are considered present but below the others.
Returns:

The first (= most liked) candidate, chosen in the intersection of self.candidates and the argument candidates. Can return None for an “abstention”.

Return type:

candidate

Examples

>>> print(BallotOrder('a ~ b').first(priority=Priority.ASCENDING))
a
>>> print(BallotOrder('a > b', candidates={'a', 'b', 'c'}).first(candidates={'c'}))
c
>>> print(BallotOrder('a > b', candidates={'a', 'b', 'c'}).first(candidates={'c'},
...                                                              include_unordered=False))
None
is_strict

Whether the ballot is a strict order or not.

True if the order is strict, i.e. if each indifference class contains one element. There can be some unordered candidates.

Examples

>>> BallotOrder('a > b > c').is_strict
True
>>> BallotOrder('a > b > c', candidates={'a', 'b', 'c', 'd', 'e'}).is_strict
True
>>> BallotOrder('a ~ b > c').is_strict
False
Type:bool
last(candidates: set = None, **kwargs) → object[source]

The last (= most disliked) candidate.

Parameters:
  • candidates (set of candidates) – It can be any set of candidates, not necessarily a subset of self.candidates. Default is self.candidates.
  • kwargs
    • priority: a Priority object. Default: Priority.UNAMBIGUOUS.
    • include_unordered: a boolean. If True (default), then unordered candidates are considered present but below the others.
Returns:

The last (= most disliked) candidate, chosen in the intersection of self.candidates and the argument candidates. Can return None for an “abstention”.

Return type:

candidate

Examples

>>> print(BallotOrder('a ~ b').last(priority=Priority.ASCENDING))
b
>>> print(BallotOrder('a > b', candidates={'a', 'b', 'c'}).last())
c
>>> print(BallotOrder('a > b', candidates={'a', 'b', 'c'}).last(include_unordered=False))
b
>>> ballot = BallotOrder('a > b', candidates={'a', 'b', 'c', 'd'})
>>> print(ballot.last(candidates={'c', 'd'}, include_unordered=False))
None
restrict(candidates: set = None, **kwargs) → whalrus.ballots.ballot_order.BallotOrder[source]

Restrict the ballot to less candidates.

Parameters:
  • candidates (set of candidates) – It can be any set of candidates, not necessarily a subset of self.candidates). Default: self.candidates.
  • kwargs – Some options (depending on the subclass).
Returns:

The same ballot, “restricted” to the candidates given.

Return type:

BallotOrder

Examples

Typical usage:

>>> ballot = BallotOrder('a ~ b > c')
>>> ballot
BallotOrder([{'a', 'b'}, 'c'], candidates={'a', 'b', 'c'})
>>> ballot.restrict(candidates={'b', 'c'})
BallotOrder(['b', 'c'], candidates={'b', 'c'})

More general usage:

>>> ballot.restrict(candidates={'b', 'c', 'd'})
BallotOrder(['b', 'c'], candidates={'b', 'c'})

In the last example above, note that d is not in the candidates of the restricted ballot, as she was not available at the moment when the voter cast her ballot.