Skip to content

Developing a calculator for the panachage electoral system.

Notifications You must be signed in to change notification settings

davidboers/panachage

Repository files navigation

Panachage

It's pronounced /ˌpænəˈʃɑːʒ/, or (pana-SHAHJ). It's a French word for "blend," or "mixture."

The panachage is a system of proportional representation used in parliamentary elections in Switzerland, Liechtenstein, Luxembourg, and elsewhere. It is a superior, albeit complicated variant of the party list system of proportional representation.

  • What is proportional representation? A system used in many countries to elect parliaments and other legislative bodies. Members are elected in multi-member constituencies, and seats are distributed between political parties in proportion to the share of the popular vote they receive in each constituency. For example, a party that wins 50% of the vote will ideally win half of the seats at stake. Read more.
  • What is a party list? In most PR systems, voters select a predetermined party list. The number of candidates to be elected from each list is determined according to a formula that takes into account the proportion of the votes that party received. Panachage is an example of a party list system. Different countries have different ways of determining which candidates on a list will fill a party's seats. In the panachage system, the candidates are ranked in the order of the number of preferential votes they receive. Read more.
  • What makes panachage different? Under most party list systems, voters must choose a single party list. Under panachage, they may split their vote between multiple parties. Each may cast as many votes as there are seats to fill, giving them far more choice than under traditional PR. Read more.

Voting under Panachage.

The voter may cast their ballot in one of three ways:

  • Choosing a single party list, without making any adjustments. This counts as a single preferential vote for each candidate on the list. Because each preferential vote also counts as a vote for the party, the party will receive a number of votes equal to the number of seats available. If the aren't enough candidates on the list to fill all seats, extra votes will be given to the party to ensure that the vote is of maximum value. This is called a Full List vote.
  • Choosing a party list, and striking out the names of certain candidates, and adding the names of others. Depending on the country, the voter may be able to duplicate their vote for a candidate on the chosen list this way, but casting more than two votes for the same candidate is usually prohibited. Every time the voter strikes out a candidate, they may add another. If there aren't enough candidates to fill all seats, the voter may also add additional names for each blank place on the list. The number of preference votes cast by the voter cannot exceed the number of seats available. If the voter does not use all available preference votes, additional votes are added to the list at large until the voter has cast the maximum number of votes. This is called a Partial List vote.
  • Choosing a blank list. In Switzerland and some other jurisdictions, the voter may choose a ballot paper without a party specification, and write down the names of candidates from different lists, up to the number of seats. No candidate's name may appear more than twice. If the voter does not exhaust their votes, no additional votes are added to any list, meaning this method risks undermining the value of the voter's ballot. This is called a Free Vote.

This repository includes a sandbox for learning how to write the vote expressions. In bin/, use the miniparser.exe as follows:

$ miniparser "b|103,104,106,201"
| List: 1   ALV: 0        | List: 2   ALV: 0
| 1   | 101   | 0     |   | 1   | 201   | 1     |
| 2   | 102   | 0     |   | 2   | 202   | 0     |
| 3   | 103   | 1     |   | 3   | 203   | 0     |
| 4   | 104   | 1     |   | 4   | 204   | 0     |
| 5   | 105   | 0     |   | 5   | 205   | 0     |
| 6   | 106   | 1     |   | 6   | 206   | 0     |
| Party total | 3     |   | Party total | 1     |

This example shows a free vote for candidates 103, 104, 106, and 201. The ALV at the top stands for "at-large votes", or votes that are cast for a party but not a particular candidate.

Click here for resources from the Swiss Government on how to vote in Federal Elections. The videos and pdf guides are in German, French and Italian only.

Party lists under Panachage.

Usually, party list will have enough candidates to fill all the seats available, especially with major parties. A party may leave spots blank if they choose. Unlike most party list systems however, party lists under panachage cannot include surplus candidates; the list cannot contain more names than there are seats to fill. In Switzerland, parties may present multiple lists, allowing them to stand more candidates.

Example

Below is an example of how to write a small program using the library:

#include "../votes.tab.h"     // Vote file parser, link with -lvotefile
#include "../partylist.tab.h" // Party list file parser, link with -lpartylistfile
#include "../ham.h"           // Highest averages method library, link with -lham
#include "../display.cpp"     // Display results

// If you use either the vote file or party list file parser, you will also need to link -lyacc_tools

using namespace panachage;

int main(void)
{
    const int max_4_candidates = 2; // Voters cannot allocate more than 2 votes to a single candidate
    const int seats = 10;           // 10 seats up for grabs.
    Vote::config = {max_4_candidates, seats};
    partylist a = parsePartyListFile("lista.txt"); // Import a party list
    partylist b = parsePartyListFile("listb.txt"); // Import another party list
    std::vector<partylist *> listsp = {&a, &b};
    std::vector<Vote *> votes;
    parseVoteFile("votes.txt", &votes, listsp); // Parse 'votes.txt'
    for (Vote *v : votes)                       // Vote objects are created as the 'votes.txt' is parsed
    {
        if (!v->validate()) // Don't count invalid votes
        {
            std::cout << "Vote on line " << v->getLnParsed() << " is invalid" << std::endl;
            continue;
        }

        v->count(listsp); // Count vote by modifying the relevant partylist object
    }
    displayAllCandidates(listsp); // Display number of votes for each candidate
    std::vector<partylist> lists;
    const int partyc = listsp.size();
    party parties[partyc];
    for (int i = 0; i < partyc; i++)
    {
        partylist *plist = listsp[i];
        lists.push_back(*plist);
        parties[i] = plist->toCParty();
    }
    ham(partyc, parties, seats, dhondt);       // Allocate the seats
    electedCandidates(lists, partyc, parties); // Display list of elected candidates
}

About

Developing a calculator for the panachage electoral system.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published