Add constraint support to JS client

This commit is contained in:
RunasSudo 2021-05-21 02:38:40 +10:00
parent 66f0734354
commit 15c6f3debe
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
4 changed files with 31 additions and 5 deletions

View File

@ -128,6 +128,12 @@
<input type="text" id="txtSeed" value=""> <input type="text" id="txtSeed" value="">
</label> </label>
</div> </div>
<div class="subheading">
Constraints:
</div>
<div>
<input type="file" id="conFile">
</div>
</div> </div>
<div class="col-6 cols-12" style="align-self: start;"> <div class="col-6 cols-12" style="align-self: start;">
<div class="col-12 subheading"> <div class="col-12 subheading">

View File

@ -175,10 +175,21 @@ function changePreset() {
} }
async function clickCount() { async function clickCount() {
if (document.getElementById('bltFile').files.length === 0) {
return;
}
// Read BLT file // Read BLT file
let bltFile = document.getElementById('bltFile').files[0]; let bltFile = document.getElementById('bltFile').files[0];
let text = await bltFile.text(); let text = await bltFile.text();
// Read CON file (if applicable)
let conText = null;
if (document.getElementById('conFile').files.length > 0) {
let conFile = document.getElementById('conFile').files[0];
conText = await conFile.text();
}
// Initialise table rows // Initialise table rows
let tblResults = document.getElementById('result'); let tblResults = document.getElementById('result');
tblResults.innerHTML = ''; tblResults.innerHTML = '';
@ -333,7 +344,7 @@ async function clickCount() {
elTd = document.createElement('td'); elTd = document.createElement('td');
elTd.classList.add('count'); elTd.classList.add('count');
if (countCard.state === py.pyRCV2.model.CandidateState.WITHDRAWN || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING) { if (countCard.state === py.pyRCV2.model.CandidateState.WITHDRAWN || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED || countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING || countCard.state === py.pyRCV2.model.CandidateState.DOOMED) {
elTd.classList.add('excluded'); elTd.classList.add('excluded');
} else if (countCard.state === py.pyRCV2.model.CandidateState.ELECTED || countCard.state === py.pyRCV2.model.CandidateState.PROVISIONALLY_ELECTED || countCard.state === py.pyRCV2.model.CandidateState.DISTRIBUTING_SURPLUS) { } else if (countCard.state === py.pyRCV2.model.CandidateState.ELECTED || countCard.state === py.pyRCV2.model.CandidateState.PROVISIONALLY_ELECTED || countCard.state === py.pyRCV2.model.CandidateState.DISTRIBUTING_SURPLUS) {
elTd.classList.add('elected'); elTd.classList.add('elected');
@ -358,7 +369,7 @@ async function clickCount() {
} else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED) { } else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDED) {
elTd.classList.add('excluded'); elTd.classList.add('excluded');
elTd.innerText = 'Ex'; elTd.innerText = 'Ex';
} else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING) { } else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING || countCard.state === py.pyRCV2.model.CandidateState.DOOMED) {
elTd.classList.add('excluded'); elTd.classList.add('excluded');
elTd.innerHTML = ppVotes(countCard.votes); elTd.innerHTML = ppVotes(countCard.votes);
} else { } else {
@ -503,7 +514,8 @@ async function clickCount() {
'round_weights': document.getElementById('chkRoundWeights').checked ? parseInt(document.getElementById('txtRoundWeights').value) : null, 'round_weights': document.getElementById('chkRoundWeights').checked ? parseInt(document.getElementById('txtRoundWeights').value) : null,
}, },
'seed': document.getElementById('txtSeed').value, 'seed': document.getElementById('txtSeed').value,
'data': text 'election': text,
'constraints': conText,
} }
}); });

View File

@ -1,6 +1,6 @@
/* /*
pyRCV2: Preferential vote counting pyRCV2: Preferential vote counting
Copyright © 2020 Lee Yingtong Li (RunasSudo) Copyright © 20202021 Lee Yingtong Li (RunasSudo)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by it under the terms of the GNU Affero General Public License as published by
@ -40,12 +40,18 @@ onmessage = function(evt) {
ppDPs = evt.data.data.ppDPs; ppDPs = evt.data.data.ppDPs;
let election = py.pyRCV2.blt.readBLT(evt.data.data.data); // Load election
let election = py.pyRCV2.blt.readBLT(evt.data.data.election);
let total_ballots = py.pyRCV2.numbers.Num(0); let total_ballots = py.pyRCV2.numbers.Num(0);
for (let b of election.ballots) { for (let b of election.ballots) {
total_ballots.__iadd__(b.value); total_ballots.__iadd__(b.value);
} }
// Load constraints (if applicable)
if (evt.data.data.constraints) {
election.constraints = py.pyRCV2.con.readCON(evt.data.data.constraints, election);
}
// Create counter // Create counter
if (evt.data.data.transfers === 'uig') { if (evt.data.data.transfers === 'uig') {
counter = py.pyRCV2.method.gregory.UIGSTVCounter(election, evt.data.data.options); counter = py.pyRCV2.method.gregory.UIGSTVCounter(election, evt.data.data.options);

View File

@ -15,6 +15,8 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import pyRCV2.blt import pyRCV2.blt
import pyRCV2.con
import pyRCV2.constraints
import pyRCV2.model import pyRCV2.model
import pyRCV2.method, pyRCV2.method.base_stv, pyRCV2.method.gregory, pyRCV2.method.meek import pyRCV2.method, pyRCV2.method.base_stv, pyRCV2.method.gregory, pyRCV2.method.meek
import pyRCV2.numbers import pyRCV2.numbers