diff --git a/html/index.js b/html/index.js
index e38c355..6c20a96 100644
--- a/html/index.js
+++ b/html/index.js
@@ -209,7 +209,7 @@ async function clickCount() {
// Display results
elTd = document.createElement('td');
- elTd.innerText = result.comment;
+ elTd.innerText = result.stage + '. ' + result.comment;
elComment.appendChild(elTd);
for (let [candidate, countCard] of result.candidates) {
@@ -223,8 +223,8 @@ async function clickCount() {
elTd.classList.add('elected');
}
elTd.style.borderTop = '1px solid black';
- if (countCard.transfers != '0.00' && countCard.transfers != '0') {
- elTd.innerText = countCard.transfers;
+ if (countCard.transfers != '0.00') {
+ elTd.innerText = ppVotes(countCard.transfers);
} else {
elTd.innerHTML = ' ';
}
@@ -235,7 +235,7 @@ async function clickCount() {
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.innerText = countCard.votes;
+ elTd.innerText = ppVotes(countCard.votes);
elTr1.querySelector('td:first-child').classList.add('elected');
} else {
elTr1.querySelector('td:first-child').classList.remove('elected');
@@ -248,9 +248,9 @@ async function clickCount() {
elTd.innerText = 'Ex';
} else if (countCard.state === py.pyRCV2.model.CandidateState.EXCLUDING) {
elTd.classList.add('excluded');
- elTd.innerText = countCard.votes;
+ elTd.innerText = ppVotes(countCard.votes);
} else {
- elTd.innerText = countCard.votes;
+ elTd.innerText = ppVotes(countCard.votes);
}
}
@@ -261,8 +261,8 @@ async function clickCount() {
elTd = document.createElement('td');
elTd.classList.add('count');
elTd.style.borderTop = '1px solid black';
- if (result.exhausted.transfers != '0.00' && result.exhausted.transfers != '0') {
- elTd.innerText = result.exhausted.transfers;
+ if (result.exhausted.transfers != '0.00') {
+ elTd.innerText = ppVotes(result.exhausted.transfers);
} else {
elTd.innerHTML = ' ';
}
@@ -270,15 +270,15 @@ async function clickCount() {
elTd = document.createElement('td');
elTd.classList.add('count');
- elTd.innerText = result.exhausted.votes;
+ elTd.innerText = ppVotes(result.exhausted.votes);
elExhausted2.appendChild(elTd);
// Display loss to fraction
elTd = document.createElement('td');
elTd.classList.add('count');
elTd.style.borderTop = '1px solid black';
- if (result.loss_fraction.transfers != '0.00' && result.loss_fraction.transfers != '-0.00' && result.loss_fraction.transfers != '0') {
- elTd.innerText = result.loss_fraction.transfers;
+ if (result.loss_fraction.transfers != '0.00' && result.loss_fraction.transfers != '-0.00') {
+ elTd.innerText = ppVotes(result.loss_fraction.transfers);
} else {
elTd.innerHTML = ' ';
}
@@ -287,9 +287,9 @@ async function clickCount() {
elTd = document.createElement('td');
elTd.classList.add('count');
if (result.loss_fraction.votes == '-0.00') {
- elTd.innerText = '0.00';
+ elTd.innerText = ppVotes('0.00');
} else {
- elTd.innerText = result.loss_fraction.votes;
+ elTd.innerText = ppVotes(result.loss_fraction.votes);
}
elLTF2.appendChild(elTd);
@@ -297,7 +297,7 @@ async function clickCount() {
elTd = document.createElement('td');
elTd.classList.add('count');
elTd.style.borderTop = '1px solid black';
- elTd.innerText = result.total;
+ elTd.innerText = ppVotes(result.total);
elTotal.appendChild(elTd);
// Display quota
@@ -305,7 +305,7 @@ async function clickCount() {
elTd.classList.add('count');
elTd.style.borderTop = '1px solid black';
elTd.style.borderBottom = '1px solid black';
- elTd.innerText = result.quota;
+ elTd.innerText = ppVotes(result.quota);
elQuota.appendChild(elTd);
}
}
@@ -338,6 +338,24 @@ async function clickCount() {
'data': text
}
});
+
+ // Pretty printing helper functions
+ let ppDPs = 2;
+ if (document.getElementById('chkRoundVotes').checked) {
+ let ppDPs2 = parseInt(document.getElementById('txtRoundVotes').value);
+ if (ppDPs2 < ppDPs) {
+ ppDPs = ppDPs2;
+ }
+ }
+ if (document.getElementById('selNumbers').value === 'fixed') {
+ let ppDPs2 = parseInt(document.getElementById('txtDP').value);
+ if (ppDPs2 < ppDPs) {
+ ppDPs = ppDPs2;
+ }
+ }
+ function ppVotes(v) {
+ return parseFloat(v).toFixed(ppDPs);
+ }
}
// Provide a default seed
diff --git a/html/worker.js b/html/worker.js
index 58a02ca..8fdcd7e 100644
--- a/html/worker.js
+++ b/html/worker.js
@@ -18,7 +18,7 @@
importScripts('vendor/BigInt_BigRat-a5f89e2.min.js', 'vendor/big-6.0.0.min.js', 'vendor/sjcl-1.0.8.min.js', 'bundle.js');
-let result, counter, ppDP, tiesPrompt;
+let stage, result, counter, ppDP, tiesPrompt;
onmessage = function(evt) {
if (evt.data.type === 'init') {
@@ -62,9 +62,11 @@ onmessage = function(evt) {
}
// Reset
+ stage = 1;
result = counter.reset();
postMessage({'type': 'result', 'result': {
+ 'stage': stage,
'comment': result.comment,
'candidates': result.candidates.py_items().map(([c, cc]) => [c.py_name, {
'transfers': cc.transfers.pp(ppDP),
@@ -95,6 +97,7 @@ function stepElection() {
while (true) {
try {
result = counter.step();
+ stage += 1;
} catch (ex) {
if (py.isinstance(ex, py.pyRCV2.ties.RequireInput)) {
// Signals we require input to break a tie
@@ -111,6 +114,7 @@ function stepElection() {
break;
} else {
postMessage({'type': 'result', 'result': {
+ 'stage': stage,
'comment': result.comment,
'candidates': result.candidates.py_items().map(([c, cc]) => [c.py_name, {
'transfers': cc.transfers.pp(ppDP),
diff --git a/pyRCV2/cli/stv.py b/pyRCV2/cli/stv.py
index 949e5b2..f746653 100644
--- a/pyRCV2/cli/stv.py
+++ b/pyRCV2/cli/stv.py
@@ -43,8 +43,8 @@ def add_parser(subparsers):
parser.add_argument('--ties', '-t', action='append', choices=['backwards', 'prompt', 'random'], default=None, help='how to resolve ties (default: backwards then random)')
parser.add_argument('--random-seed', default=None, help='arbitrary string used to seed the RNG for random tie breaking')
-def print_step(result):
- print(result.comment)
+def print_step(stage, result):
+ print('{}. {}'.format(stage, result.comment))
for candidate, count_card in result.candidates.items():
state = None
@@ -109,15 +109,17 @@ def main(args):
counter.options['papers'] = 'transferable' if args.transferable_only else 'both'
# Reset
+ stage = 1
result = counter.reset()
- print_step(result)
+ print_step(stage, result)
# Step election
while True:
+ stage += 1
result = counter.step()
if isinstance(result, pyRCV2.model.CountCompleted):
break
- print_step(result)
+ print_step(stage, result)