Initial commit

This commit is contained in:
2023-09-28 14:57:13 -04:00
commit cfa1f6fa3f
2 changed files with 192 additions and 0 deletions

51
rangevote.html Normal file
View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>POST DEMO</title>
</head>
<body>
<form id="my-form" action="/range_vote" method="post" oninput=UpdateValues(event)>
This page is an experiment in voting. Half of the people who visit this site vote using Plurality Voting
where a voter selects their top candidate, and the winner is the candidate with the most votes. The other
half use Range Voting where voters score all familiar candidates based on how happy they would be should
that candidate win. You have been randomly selected to vote using Range Voting.
<br>
<br>
<table>
<tr>
<th>Candidate</th>
<th><span id="spanid"> </th>
<th>Happiness</th>
</tr>
<!-- INJECT0 -->
</table>
<br>
<button type="submit" value="submit">Submit</button>
</form>
</body>
<script>
function CanId(c)
{
let w=c.split(" ");
let lastname=w[w.length-1].toLowerCase();
let id=lastname.split("-");
let rval=id[id.length-1];
return(rval);
}
function UpdateValues(event)
{
let id=event.srcElement.id;
console.log(id);
let slider=document.getElementById(id);
let output=document.getElementById('o-'+CanId(id));
if (slider.value==-1) output.innerHTML="No Opinion";
else output.innerHTML=slider.value+"%";
}
</script>

141
rangevote.js Normal file
View File

@@ -0,0 +1,141 @@
var express = require('express')
var bodyParser = require('body-parser')
var fs=require('fs')
var app = express()
var Candidates=[ "Chris Christie", "Ron DeSantis", "Nikki Haley", "Mike Pence",
"Vivek Ramaswamy", "Tim Scott", "Donald Trump" ];
function CanId(c)
{
let w=c.split(" ");
let lastname=w[w.length-1].toLowerCase();
let id=lastname.split("-");
let rval=id[id.length-1];
return(rval);
}
// Set up data structures for Range Votes and Plur Votes
var RangeVotes=new Map();
var RangePower=new Map();
var RangeResult=new Map();
var PlurVotes=new Map();
var PlurResult=new Map();
for (let c of Candidates)
{
let k=CanId(c);
let v=RangePower.get(k);
if (typeof(v)!='number' || v==NaN || v==Infinity) RangePower.set(k,0);
v=RangeResult.get(k);
if (typeof(v)!='number' || v==NaN || v==Infinity) RangeResult.set(k,0);
v=PlurResult.get(k);
if (typeof(v)!='number' || v==NaN || v==Infinity) PlurResult.set(k,0);
}
// Construct the static page for range voting
var TheHTML="";
for (let c of Candidates)
{
TheHTML=TheHTML+' <tr>'+
' <td>'+c+'</td><td><input type="range" min="-1" max="100" value="-1" id="i-'+CanId(c)+'" name="n-'+CanId(c)+'" /></td><td><span id="o-'+CanId(c)+'">No Opinion</span></td></tr>\n';
}
var TemplateHTML=fs.readFileSync("rangevote.html").toString();
var TemplateSearch="<!-- INJECT0 -->";
var TemplateIndex=TemplateHTML.indexOf(TemplateSearch);
TheHTML=TemplateHTML.substr(0,TemplateIndex)+TheHTML+TemplateHTML.substr(TemplateIndex+TemplateSearch.length,1000000);
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.get('/', (req, res) => {
res.send(TheHTML);
})
function lerp(a,b,c,d,e)
{
if (a<b) a=b;
if (a>c) a=c;
let rval=d+(a-b)*(e-d)/(c-b);
return(rval);
}
function PlurVote(ip,NewChoice)
{
let OldChoice=PlurResult.get(ip);
if (typeof(OldChoice)=='string') PlurResult.set(OldChoice,PlurResult.get(OldChoice)-1);
if (typeof(NewChoice)=='string') PlurResult.set(NewChoice,PlurResult.get(NewChoice)+1);
}
function AddToRangeResult(vote,mult=1)
{
console.log("RangeResult Before "+mult);
console.log(RangeResult);
console.log("RangePower Before "+mult);
console.log(RangePower);
for (let[key,val] of vote) if (key) if (val>=0)
{
RangeResult.set(key,RangeResult.get(key)+val*mult);
RangePower.set(key,RangePower.get(key)+mult);
}
console.log("RangeResult After "+mult);
console.log(RangeResult);
console.log("RangePower After "+mult);
console.log(RangePower);
}
function RangeVote(ip,entries)
{
let r0=null,r1=null;
for (let [key,val] of entries) if (typeof(key)=="string" && val>=0)
{
if (r0) r0=Math.min(r0,val); else r0=val;
if (r1) r1=Math.max(r1,val); else r1=val;
}
if (r1<=r0) return;
let NewVote=new Map()
for (let [key,val] of entries) if (typeof(key)=="string")
{
let id=CanId(key);
console.log(key+' '+id);
let norm=Math.round(lerp(val,r0,r1,0,100));
if (val>=0) NewVote.set(id,norm);
}
let OldVote=RangeVotes.get(ip);
// if (OldVote) AddToRangeResult(OldVote,-1);
console.log("NewVote");
console.log(NewVote);
RangeVotes.set(ip,NewVote);
AddToRangeResult(NewVote,1);
}
// POST /login gets urlencoded bodies
app.post('/range_vote', urlencodedParser, function (req, res) {
RangeVote(req.socket.remoteAddress,Object.entries(req.body));
let str="Results:<br>";
for (let c of Candidates)
{
let key=CanId(c);
if (RangePower.get(key)>0) str=str+c+': '+Math.round(RangeResult.get(key)/RangePower.get(key))+'<br>';
}
res.send(str);
})
app.post('/plur_vote', urlencodedParser, function (req, res) {
// PlurVote(req.socket.remoteAddress,Object.entries(req.body));
res.send("Your Plurality Vote Counted!!!");
})
app.listen(3000,function(req,res) { console.log("Listening for connections"); })