# Condorcet analysis of Official PEP308 Ballots

Norman Petry npetry at accesscomm.ca
Tue Mar 11 08:27:36 CET 2003

```On Sunday I posted the results of the COMPLEMENTARY vote on PEP308,
which was based on about 100 ranked ballots that I received between
March 3rd and March 9th.  Those results can be viewed here:

http://mail.python.org/pipermail/python-announce-list/2003-March/002102.html

Today, Raymond Hettinger published the ballots from the OFFICIAL vote,
and it occurred to me that this data can be converted to a ranked ballot
by noting that an 'accept' option is one that the voter prefers to the
status-quo (NO TERNARY), and a 'reject' option, regardless of its rank
position is considered by the voter to be worse (ranked lower) than the
status-quo.  Therefore an official ballot like:

A accept  x if C else y
C reject  (if C: x else: y)
I reject  x when C else y

is equivalent to the following ranked ballot:

01  x if C else y
02  NO TERNARY
03  (if C: x else: y)
04  x when C else y
(all other options truncated)

By converting the ballots in this way, I was able to tally them using
the script I wrote for the "complementary" vote, thereby allowing the
two sets of results to be compared.  These converted ballots may be
viewed here:

http://24.72.22.210/pep308ballots.html

The Condorcet results for this set of ballots are shown at the end of
this message.

One obvious advantage of the official data is that it contains over 500
ballots.  This makes the results much more representative of the Python
community's wishes than the ballots from the complementary vote, which
had lower participation.  However, the limited rankings allowed by the
official ballot biases the result in favour of the status-quo, since
voters are only allowed to 'accept' up to 3 options, even if they would
accept many more than this.  With limited rankings, the more
alternatives that are listed, the less likely it is that any change will
be accepted.  This can be seen by comparing the pairwise results for the
top-ranked alternatives in each vote:

COMPLEMENTARY VOTE:

Option "NO TERNARY":
beats option "if C then t else f" [50 - 43]
beats option "(if C: t else: f)" [50 - 45]
beats option "C ? t : f" [54 - 41]

OFFICIAL VOTE:

Option "NO TERNARY":
beats option "(if C: x else: y)" [240 - 175]
beats option "C ? x : y" [270 - 141]
beats option "x if C else y" [276 - 104]

In both cases, the preferred option is the status quo, but in the
complementary vote, the NO TERNARY option has about a 5-10% lead over
the top-ranked ternary proposals.  In the official vote, this lead

Of course, the fact that the status quo is clearly preferred by a
majority in both votes does not necessarily mean that the ternary should
not be implemented.  It is likely that many features that have been
added to Python would not have received the support of a majority when
they were first introduced.  For this reason, the SOCIAL RANKING is
probably a much more useful result than the SINGLE WINNER when trying to
decide how to resolve this issue.

--
Norman Petry

*****

SINGLE WINNER
=============

The Condorcet Winner is: "NO TERNARY".

SOCIAL RANKING (Tideman)
========================

1. NO TERNARY
2. (if C: x else: y)
3. C ? x : y
4. x if C else y
5. if C then x else y
6. C then x else y
7. x when C else y
8. cond(C, x, y)
9. any write-in vote
10. C ? x else y
11. C ? x ! y
12. [x if C else y]
13. C ?? x || y
14. <if C then x else y>
15. C and x else y
16. C -> x else y
17. ifelse C: x else y
18. C -> (x, y)

Kemeny Score: 20011

PAIRWISE COMPARISONS
====================

Option "NO TERNARY":
beats option "(if C: x else: y)" [240 - 175]
beats option "C ? x : y" [270 - 141]
beats option "x if C else y" [276 - 104]
beats option "if C then x else y" [280 - 112]
beats option "C then x else y" [301 - 59]
beats option "x when C else y" [301 - 44]
beats option "cond(C, x, y)" [298 - 43]
beats option "any write-in vote" [308 - 35]
beats option "C ? x else y" [310 - 27]
beats option "C ? x ! y" [313 - 24]
beats option "[x if C else y]" [309 - 14]
beats option "C ?? x || y" [312 - 23]
beats option "<if C then x else y>" [311 - 12]
beats option "C and x else y" [312 - 13]
beats option "C -> x else y" [313 - 7]
beats option "ifelse C: x else y" [314 - 5]
beats option "C -> (x, y)" [313 - 3]

Option "(if C: x else: y)":
beats option "C ? x : y" [191 - 132]
beats option "x if C else y" [208 - 127]
beats option "if C then x else y" [196 - 124]
beats option "C then x else y" [223 - 65]
beats option "x when C else y" [227 - 58]
beats option "cond(C, x, y)" [221 - 45]
beats option "any write-in vote" [217 - 40]
beats option "C ? x else y" [230 - 26]
beats option "C ? x ! y" [227 - 27]
beats option "[x if C else y]" [231 - 19]
beats option "C ?? x || y" [230 - 23]
beats option "<if C then x else y>" [231 - 12]
beats option "C and x else y" [231 - 22]
beats option "C -> x else y" [232 - 19]
beats option "ifelse C: x else y" [233 - 7]
beats option "C -> (x, y)" [232 - 8]

Option "C ? x : y":
beats option "x if C else y" [173 - 138]
beats option "if C then x else y" [174 - 139]
beats option "C then x else y" [190 - 73]
beats option "x when C else y" [199 - 62]
beats option "cond(C, x, y)" [191 - 45]
beats option "any write-in vote" [197 - 46]
beats option "C ? x else y" [199 - 21]
beats option "C ? x ! y" [201 - 16]
beats option "[x if C else y]" [198 - 27]
beats option "C ?? x || y" [198 - 19]
beats option "<if C then x else y>" [201 - 25]
beats option "C and x else y" [200 - 24]
beats option "C -> x else y" [203 - 17]
beats option "ifelse C: x else y" [202 - 9]
beats option "C -> (x, y)" [203 - 8]

Option "x if C else y":
beats option "if C then x else y" [135 - 133]
beats option "C then x else y" [147 - 86]
beats option "x when C else y" [142 - 40]
beats option "cond(C, x, y)" [154 - 57]
beats option "any write-in vote" [150 - 45]
beats option "C ? x else y" [156 - 35]
beats option "C ? x ! y" [157 - 29]
beats option "[x if C else y]" [155 - 28]
beats option "C ?? x || y" [157 - 27]
beats option "<if C then x else y>" [159 - 23]
beats option "C and x else y" [156 - 18]
beats option "C -> x else y" [159 - 19]
beats option "ifelse C: x else y" [159 - 9]
beats option "C -> (x, y)" [159 - 7]

Option "if C then x else y":
beats option "C then x else y" [151 - 74]
beats option "x when C else y" [155 - 67]
beats option "cond(C, x, y)" [164 - 56]
beats option "any write-in vote" [163 - 51]
beats option "C ? x else y" [166 - 34]
beats option "C ? x ! y" [166 - 27]
beats option "[x if C else y]" [166 - 27]
beats option "C ?? x || y" [166 - 27]
beats option "<if C then x else y>" [168 - 16]
beats option "C and x else y" [165 - 20]
beats option "C -> x else y" [167 - 19]
beats option "ifelse C: x else y" [168 - 8]
beats option "C -> (x, y)" [168 - 9]

Option "C then x else y":
beats option "x when C else y" [92 - 67]
beats option "cond(C, x, y)" [96 - 63]
beats option "any write-in vote" [96 - 53]
beats option "C ? x else y" [95 - 36]
beats option "C ? x ! y" [96 - 30]
beats option "[x if C else y]" [97 - 32]
beats option "C ?? x || y" [98 - 28]
beats option "<if C then x else y>" [95 - 25]
beats option "C and x else y" [96 - 20]
beats option "C -> x else y" [98 - 21]
beats option "ifelse C: x else y" [97 - 10]
beats option "C -> (x, y)" [98 - 9]

Option "x when C else y":
beats option "cond(C, x, y)" [70 - 63]
beats option "any write-in vote" [71 - 51]
beats option "C ? x else y" [69 - 37]
beats option "C ? x ! y" [70 - 31]
beats option "[x if C else y]" [69 - 28]
beats option "C ?? x || y" [71 - 29]
beats option "<if C then x else y>" [72 - 24]
beats option "C and x else y" [71 - 24]
beats option "C -> x else y" [72 - 23]
beats option "ifelse C: x else y" [72 - 9]
beats option "C -> (x, y)" [72 - 8]

Option "cond(C, x, y)":
beats option "any write-in vote" [63 - 52]
beats option "C ? x else y" [66 - 35]
beats option "C ? x ! y" [65 - 31]
beats option "[x if C else y]" [65 - 30]
beats option "C ?? x || y" [65 - 28]
beats option "<if C then x else y>" [65 - 24]
beats option "C and x else y" [65 - 24]
beats option "C -> x else y" [65 - 23]
beats option "ifelse C: x else y" [65 - 11]
beats option "C -> (x, y)" [65 - 8]

Option "any write-in vote":
beats option "C ? x else y" [54 - 38]
beats option "C ? x ! y" [53 - 32]
beats option "[x if C else y]" [53 - 30]
beats option "C ?? x || y" [54 - 30]
beats option "<if C then x else y>" [54 - 26]
beats option "C and x else y" [55 - 26]
beats option "C -> x else y" [55 - 21]
beats option "ifelse C: x else y" [55 - 11]
beats option "C -> (x, y)" [55 - 7]

Option "C ? x else y":
beats option "C ? x ! y" [38 - 29]
beats option "[x if C else y]" [38 - 32]
beats option "C ?? x || y" [36 - 28]
beats option "<if C then x else y>" [37 - 26]
beats option "C and x else y" [38 - 25]
beats option "C -> x else y" [38 - 20]
beats option "ifelse C: x else y" [37 - 10]
beats option "C -> (x, y)" [38 - 9]

Option "C ? x ! y":
beats option "[x if C else y]" [32 - 31]
beats option "C ?? x || y" [28 - 27]
beats option "<if C then x else y>" [32 - 26]
beats option "C and x else y" [32 - 26]
beats option "C -> x else y" [32 - 23]
beats option "ifelse C: x else y" [32 - 11]
beats option "C -> (x, y)" [32 - 8]

Option "[x if C else y]":
beats option "C ?? x || y" [32 - 29]
beats option "<if C then x else y>" [29 - 24]
beats option "C and x else y" [32 - 26]
beats option "C -> x else y" [31 - 24]
beats option "ifelse C: x else y" [32 - 10]
beats option "C -> (x, y)" [31 - 8]

Option "C ?? x || y":
beats option "<if C then x else y>" [30 - 25]
beats option "C and x else y" [29 - 25]
beats option "C -> x else y" [30 - 23]
beats option "ifelse C: x else y" [30 - 11]
beats option "C -> (x, y)" [30 - 9]

Option "<if C then x else y>":
beats option "C and x else y" [26 - 25]
beats option "C -> x else y" [26 - 23]
beats option "ifelse C: x else y" [26 - 11]
beats option "C -> (x, y)" [25 - 9]

Option "C and x else y":
beats option "C -> x else y" [25 - 22]
beats option "ifelse C: x else y" [26 - 11]
beats option "C -> (x, y)" [26 - 9]

Option "C -> x else y":
beats option "ifelse C: x else y" [23 - 11]
beats option "C -> (x, y)" [23 - 7]

Option "ifelse C: x else y":
beats option "C -> (x, y)" [11 - 8]

```