BLT editor: Implement BLT export

This commit is contained in:
RunasSudo 2021-01-25 20:41:13 +11:00
parent b109d99054
commit b6327299a2
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
4 changed files with 82 additions and 2 deletions

View File

@ -29,7 +29,7 @@
<button onclick="clickOpenJSON()">Open JSON</button>
<button onclick="clickSaveJSON()">Save JSON</button>
<button onclick="clickImportBLT()">Import BLT</button>
<!--<button>Export BLT</button>-->
<button onclick="clickExportBLT()">Export BLT</button>
<!--GITREV-->
<a href="https://yingtongli.me/blog/2020/12/24/pyrcv2.html">Information and instructions</a>
</div>

View File

@ -145,7 +145,7 @@ async function changeInpFile() {
ballots = [];
for (let ballot of election.ballots) {
let js_ballot = {'value': ballot.value.impl, 'preferences': []};
let js_ballot = {'value': ballot.value.__str__(), 'preferences': []};
for (let i = 0; i < candidates.length; i++) {
js_ballot['preferences'].push('');
}
@ -183,8 +183,62 @@ function clickSaveJSON() {
'ballots': ballots,
};
// Download file
let url = URL.createObjectURL(new File([JSON.stringify(result)], 'ballots.json', {type: 'application/json'}));
let elA = document.createElement('a');
elA.href = url;
elA.download = '';
elA.click();
}
function clickExportBLT() {
let election = py.pyRCV2.model.Election();
let result = window.prompt('Enter the number of seats to elect:', '1');
if (result !== null) {
election.seats = parseInt(result);
} else {
return;
}
result = window.prompt('Enter the name of the election:');
if (result !== null) {
election.name = result;
} else {
return;
}
for (let candidate of candidates) {
let py_candidate = py.pyRCV2.model.Candidate(candidate);
election.candidates.push(py_candidate);
}
// Process ballots
for (let ballot of ballots) {
let py_ballot = py.pyRCV2.model.Ballot(py.pyRCV2.numbers.StringNum(ballot['value']), []);
for (let i = 1; i < candidates.length + 1; i++) {
let candidate = null;
for (let j = 0; j < candidates.length; j++) {
if (ballot.preferences[j].trim() === '' + i) {
candidate = j;
break;
}
}
if (candidate !== null) {
py_ballot.preferences.push(election.candidates[candidate]);
} else {
// No such preference
break;
}
}
election.ballots.push(py_ballot);
}
// Download file
let url = URL.createObjectURL(new File([py.pyRCV2.blt.writeBLT(election)], 'election.blt', {type: 'application/json'}));
let elA = document.createElement('a');
elA.href = url;
elA.download = '';

View File

@ -68,3 +68,26 @@ def readBLT(data):
election.withdrawn = [election.candidates[x] for x in withdrawn]
return election
def writeBLT(election, stringify=str):
lines = []
lines.append('{} {}'.format(len(election.candidates), election.seats))
if len(election.withdrawn) > 0:
lines.append(' '.join(['-{}'.format(election.candidates.index(candidate) + 1) for candidate in election.withdrawn]))
for ballot in election.ballots:
if ballot.preferences:
lines.append('{} {} 0'.format(stringify(ballot.value), ' '.join(str(election.candidates.index(x) + 1) for x in ballot.preferences)))
else:
lines.append('{} 0'.format(stringify(ballot.value)))
lines.append('0')
for candidate in election.candidates:
lines.append('"{}"'.format(candidate.name))
lines.append('"{}"'.format(election.name))
return '\n'.join(lines)

View File

@ -26,3 +26,6 @@ class StringNum(BaseNum):
def _to_impl(cls, value):
"""Implements BaseNum._to_impl"""
return value
def __str__(self):
return self.impl