215 lines
8.2 KiB
PHP
215 lines
8.2 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
/* NO INTERFACE here, see html examples for it */
|
||
|
|
||
|
# Quick tour of the main features of Condorcet PHP
|
||
|
|
||
|
// I - Install
|
||
|
use CondorcetPHP\Condorcet\{Candidate, Election, Vote};
|
||
|
|
||
|
require_once __DIR__.'/../__CondorcetAutoload.php';
|
||
|
|
||
|
$start_time = microtime(true);
|
||
|
|
||
|
// II - Create Election
|
||
|
|
||
|
$election1 = new Election;
|
||
|
|
||
|
|
||
|
// III - Manage Candidate
|
||
|
|
||
|
# -A- Add candidates
|
||
|
|
||
|
// A string
|
||
|
$election1->addCandidate('Debussy');
|
||
|
$election1->addCandidate('Caplet');
|
||
|
$election1->addCandidate('A');
|
||
|
$myLutoCandidate = $election1->addCandidate('Lutoslawski'); // Return the CondorcetPHP\Candidate object.
|
||
|
|
||
|
// Automatic name
|
||
|
$myAutomaticCandidate = $election1->addCandidate(); // Return an automatic CondorcetPHP\Candidate
|
||
|
$myAutomaticCandidate->getName(); // return 'B'. Because we have already register the A candidate above.
|
||
|
|
||
|
// An objet
|
||
|
$myMessiaenCandidate = new Candidate('Olivier Messiaen');
|
||
|
|
||
|
$election1->addCandidate($myMessiaenCandidate);
|
||
|
$election1->addCandidate(new Candidate('Ligeti'));
|
||
|
$election1->addCandidate(new Candidate('Koechlin'));
|
||
|
|
||
|
|
||
|
# -B- Change your mind ?
|
||
|
|
||
|
$election1->removeCandidates('A');
|
||
|
$election1->removeCandidates($myAutomaticCandidate);
|
||
|
|
||
|
// Lutoslawski change his name
|
||
|
$myLutoCandidate->setName('Wiltod Lutoslawski'); # Done !
|
||
|
|
||
|
# What was his old names?
|
||
|
$myLutoCandidate->getHistory(); // return the full history with timestamp of this Candidate naming
|
||
|
|
||
|
|
||
|
# -C- Check your candidate list, if you forget it
|
||
|
$election1->getCandidatesList(); // Return an array pupulate by each Candidate objet
|
||
|
$election1->getCandidatesList(true); // Return an array pupulate by each Candidate name as String.
|
||
|
|
||
|
// OK, I need my Debussy (want his candidate object)
|
||
|
$myDebussyCandidate = $election1->getCandidateObjectFromName('Debussy');
|
||
|
|
||
|
|
||
|
// IV - Votes
|
||
|
|
||
|
# -A- Add Votes
|
||
|
|
||
|
$myVote1 = $election1->addVote([
|
||
|
1 => 'Debussy',
|
||
|
2 => ['Caplet', 'Olivier Messiaen'],
|
||
|
3 => 'Ligeti',
|
||
|
4 => ['Wiltod Lutoslawski', 'Koechlin'],
|
||
|
]); // Return the new Vote object
|
||
|
|
||
|
$myVote2 = new Vote([
|
||
|
1 => 'Debussy',
|
||
|
2 => 'Caplet',
|
||
|
3 => 'Olivier Messiaen',
|
||
|
4 => 'Koechlin',
|
||
|
5 => 'Wiltod Lutoslawski',
|
||
|
6 => 'Ligeti',
|
||
|
]);
|
||
|
|
||
|
$election1->addVote($myVote2);
|
||
|
|
||
|
$myVote3 = $election1->addVote('Debussy > Olivier Messiaen = Ligeti > Caplet'); // Last rank rank will be automatically deducted. A vote can not be expressed on a limited number of candidates. Non-expressed candidates are presumed to last Exaequo
|
||
|
|
||
|
// Off course, you can vote by candidate object. Which is recommended. Or mix the two methods.
|
||
|
$myVote4 = $election1->addVote([
|
||
|
$election1->getCandidateObjectFromName('Ligeti'),
|
||
|
$myLutoCandidate,
|
||
|
[$myMessiaenCandidate, 'Koechlin'],
|
||
|
|
||
|
]);
|
||
|
|
||
|
// Finishing with another really nice example.
|
||
|
$myVote5 = new Vote([
|
||
|
1 => $election1->getCandidateObjectFromName('Debussy'),
|
||
|
2 => $election1->getCandidateObjectFromName('Olivier Messiaen'),
|
||
|
3 => [$election1->getCandidateObjectFromName('Wiltod Lutoslawski'), $election1->getCandidateObjectFromName('Ligeti')],
|
||
|
4 => $election1->getCandidateObjectFromName('Koechlin'),
|
||
|
5 => $election1->getCandidateObjectFromName('Caplet'),
|
||
|
]);
|
||
|
|
||
|
$myVote5->addTags('jusGreatVote');
|
||
|
|
||
|
$election1->addVote($myVote5);
|
||
|
|
||
|
// Please note that :
|
||
|
$election1->getCandidateObjectFromName('Olivier Messiaen') === $myMessiaenCandidate; // Return TRUE
|
||
|
|
||
|
|
||
|
// Add some nice tags to my Vote 1 & 2 & 3 (You can do this before or after add register into to the Election)
|
||
|
|
||
|
$myVote1->addTags(['strangeVote', 'greatFrenchVote']); // By Array
|
||
|
$myVote2->addTags('greatFrenchVote,chauvinismVote'); // By String
|
||
|
$myVote3->addTags($myVote1->getTags()); // Copy & Past
|
||
|
|
||
|
|
||
|
// Parsing Vote
|
||
|
$election1->parseVotes("
|
||
|
Ligeti > Wiltod Lutoslawski > Olivier Messiaen = Debussy > Koechlin # A comment. A a line break for the next vote.
|
||
|
greatFrenchVote,chauvinismVote || Olivier Messiaen > Debussy = Caplet > Ligeti # Tags at first, vote at second, separated by '||'
|
||
|
strangeVote || Caplet > Koechlin * 8 # This vote and his tag will be register 8 times.
|
||
|
");
|
||
|
|
||
|
|
||
|
// Adding some random to this election
|
||
|
$VoteModel = $myVote2->getRanking();
|
||
|
|
||
|
for ($i = 0; $i < 95; $i++) {
|
||
|
shuffle($VoteModel);
|
||
|
$election1->addVote($VoteModel);
|
||
|
}
|
||
|
|
||
|
// How Many Vote could I Have now ?
|
||
|
$election1->countVotes(); // Return 110 (int)
|
||
|
|
||
|
|
||
|
# -B- Manage Votes
|
||
|
|
||
|
# 1- Get vote list
|
||
|
// Get the vote list
|
||
|
$election1->getVotesList(); // Returns an array of all votes as object.
|
||
|
|
||
|
// How many Vote with tag "strangeVote" ?
|
||
|
$election1->countVotes('strangeVote'); // Return 10 (int)
|
||
|
// Or without
|
||
|
$election1->countVotes('strangeVote', false); // Return 100 (int)
|
||
|
// Or with this tag OR this tag
|
||
|
$election1->countVotes(['greatFrenchVote', 'chauvinismVote']); // Return 4 (int)
|
||
|
// Or without this tag AND this tag
|
||
|
$election1->countVotes(['greatFrenchVote', 'chauvinismVote'], false); // Return 4 (int)
|
||
|
|
||
|
// Return this 10 votes !
|
||
|
$election1->getVotesList('strangeVote');
|
||
|
// And the others 100 votes without this tags
|
||
|
$election1->getVotesList('strangeVote', false);
|
||
|
// Or with this tag OR this tag
|
||
|
$election1->getVotesList(['greatFrenchVote', 'chauvinismVote']); // Return 4 (int)
|
||
|
// Or without this tag AND this tag
|
||
|
$election1->getVotesList(['greatFrenchVote', 'chauvinismVote'], false); // Return 4 (int)
|
||
|
|
||
|
|
||
|
# 2- Vote objet
|
||
|
$myVote3->getRanking(); // This vote specifies four candidates. Although the election comprises 6. This method return the original input.
|
||
|
$myVote3->getContextualRanking($election1); // Return the full ranking in the context of election 1 (with 6 candidates). It is one that is taken into account when calculating the results of the election 1.
|
||
|
|
||
|
|
||
|
// Change the vote
|
||
|
$myVote1->setRanking([
|
||
|
1 => 'Caplet',
|
||
|
2 => 'Debussy',
|
||
|
3=> 'Koechlin',
|
||
|
]);
|
||
|
|
||
|
|
||
|
// Check the vote history
|
||
|
$myVote1History = $myVote1->getHistory();
|
||
|
|
||
|
|
||
|
# 3- Delete Votes
|
||
|
|
||
|
// Delete a specific vote object
|
||
|
$election1->removeVote($myVote3);
|
||
|
|
||
|
// Delete all vote with tag "strangeVote" or "frenchies"
|
||
|
$election1->removeVotesByTags(['strangeVote', 'chauvinismVote']);
|
||
|
|
||
|
// Count vote
|
||
|
$election1->countVotes(); // Return 98
|
||
|
|
||
|
|
||
|
// V - Get Result
|
||
|
|
||
|
// Natural Condorcet Winner
|
||
|
$election1->getWinner(); // Return NULL if there is not, else return the winner candidate object
|
||
|
$election1->getWinner('Schulze'); // Same thing, but try to resolve winner by Schulze method that extends Condorcet method. Can return an array of winners if there are multiple.
|
||
|
|
||
|
// Natural Condorcet Loser
|
||
|
$election1->getLoser(); // Return NULL if there is not, else return the winner candidate object
|
||
|
$election1->getLoser('Schulze'); // Same thing, but try to resolve loser by Schulze method that extends Condorcet method. Can return an array of winners if there are multiple.
|
||
|
|
||
|
// Advanced Method -
|
||
|
$election1->getResult(); // Result set for defaut method (Should be Schulze Winning). That return a Condorcet/Result object.
|
||
|
$election1->getResult('Copeland'); // Do it with the Copeland method
|
||
|
|
||
|
/* Please note that a Result object is fixed and independent. It does not change automatically when you change the election. You then have requested the production of a new object result. */
|
||
|
|
||
|
// Get an easy game outcome to read and understand (Table populated by string)
|
||
|
$election1->getResult('Schulze')->getResultAsArray(true);
|
||
|
|
||
|
|
||
|
print $firstPart ?? 'Success!
|
||
|
Process in: '. round(microtime(true) - $start_time, 3) . 's';
|