More ballot scenarios with Codepen

I worked a bit more on some Codepens to both hopefully provide some generally useful tools, and to dig into analyzing some the sorts of ballot scenarios where Score and STAR produce different results.

I am exploring a concept I mentioned earlier, “blurring” which means to take an example ballot set and add a few more ballots which are semi-randomized “middle ground” between all of the ballots in the example. (to produce each of them, it picks a few random ballots from the set, average them, then normalize)

I’m also exploring a method which is Score but using interpolated median. This has the “exaggeration resistant” property as does regular median, but it isn’t so likely to produce a tie that needs to be resolved. It seems to produce results very similar to STAR, but has the nice side effect of having easy to look at results due to their being only one round.

The Codepen is at https://codepen.io/karmatics/pen/jOWQgBJ , and it references the code from a couple other Codepens (such as parsing and writing score ballots).

Here is a screenshot. The ballot sample comes from a post here. You can see that Score has B winning, while STAR and Interpolated Median have A win. (A is the Condorcet winner, as 51% give A a 5). B wins under Score because B is universally liked by everyone (getting a 4 from 100%), and 49% really dislike A.

In the second image, I have created 6 additional “blurred” ballots, which you see in the middle text area. Since these have an element of randomness, they’ll be different every time, but they aren’t completely random. For instance, all of them having B scoring high, and all have C scoring zero. This is consistent with the ballots in the sample.

If you do much less that 6 blurred ballots, it will typically stay with A winning, but if you do much more, B will almost always win.

To me this suggests that the example is unnaturally contrived, since you’d expect in a real world election, the electorate will have some number of people who are more in the middle. Any method like STAR or Condorcet methods seem to require a little bit of “fuzz” in the electorate for them to work well.

Anyway, I’m interested in thoughts on this but mostly I’m hoping that it inspires some people to get interested in doing Codepens, since they are so easy to share and collaborate on. (remember that non-coders can go in and play with different sets of ballots and different amounts of blurring on this one, and as time goes on their should be a ton more things to experiment with)

1 Like

Either that, or a few voters who are willing to compromise i.e. a few voters in the majority willing to vote B=A>C or B>A>C.

Yeah that qualifies as fuzz. I just mean it isn’t two or three voting blocks that everyone votes precisely the same. In the example data I used, every single voter gave B a 4. Every voter gave A and D either 0 or 5. So they were highly polarized, and yet in total agreement about their liking (but not loving) B. Not at all realistic, but STAR handles it rather poorly.

That’s the kind of thing that can be easily compensated for in simulations by adding a bit of fuzz to simulate real world elections, and hopefully you see that STAR would do quite well in reality. Probably the same case with Condorcet, but I guess no one is pushing Condorcet in the real world (still trying to figure out if such things as the interpolated median approach works well).

This is great. This is exactly where I got to when we were doing multimember PR systems to try and evaluate which was "best’. Simulations did provide valuable insights.

If the goal here is to evaluate STAR vs Score can I suggest you add STLR. I know I am get to convince you it is a good method but this may actually help. Often the proof of the pudding is in the eating. If you can simulate one situation where STAR gets the undesirable result until fuzz is added and score always gets the desirable result and then another situation with the inverted results then I would expect that STLR does both properly all the time in both cases. It is a middle ground system designed to get intermediate results. Or maybe you find a huge flaw and I have to stop bothering you about it. Either way its a win for somebody.

1 Like

Thanks, yeah I’d be glad to add STLR. Right now I’m going to add Condorcet (just showing the number of pairwise wins for each candidate), because that’s interesting to me, but I’ll get to STLR soon if someone else doesn’t beat me to it. (these Codepens are really easy to just fork and add something to it)

I added STLR to it. I think I got it right, check it out. https://codepen.io/karmatics/pen/jOWQgBJ

Screenshot shows example scenario where STAR and Score differ in their winners (it is extremely close), and yeah, STLR performs more like Score than STAR.

Clicking “tabulate” several times doesn’t change the result, so I think it’s better to add the “make blurred” function to the “tabulate” button.
You would therefore only have the “tabulate” button with the text field above it in which to insert the number of blurred votes.
Near to the text field you can write that it’s the “blurred votes”

Thanks for posting code. Code makes math concrete.

Thanks for introducing Codepen. I had had a general understanding that people could post snippets so others could easily run them, but hadn’t been aware of the cool features available, particularly the import.

Thanks for posting code in Javascript/Ecmascript (JS). JS runs in the browsers, and for those who want to code on a server side as well, it will work there, too. Also, although it has oddities, JS provides a way to do just about anything one could do with any of the other popular imperative languages. Moreover, both in the browser and server environments, the time management is based on events instead of concurrent sequential processes, which would have invited many hard-to-diagnose defects to pop up in ones systems. So, as I see it, JS is a language of the immediate future, bringing advantages over the other common ones.

I have been thinking in terms of having a slider up, that would adjust the proportions of the hypothetical electorate between two groups of factions. The strategies and voting systems would start calculating from that, but if the person moved the slider before the calculations finish, the ongoing calculations should be abandoned before taking even one more turn around any loop, and should be restarted based on the new setting of the slider. But I am nowhere near realizing this dream.

1 Like

yes, this seems to be working. Thanks

1 Like

I did that first, but decided to separate them. I found value in being able to make the blurred ballots first, inspect them, edit them, etc. prior to tabulating.

More importantly, since this is intended to be instructional as to how to use Codepen to make useful stuff, I thought being separate makes the functions more clear. Remember, the point of Codepen is that you can easily modify them (and reshare your versions)

Here is how easy it is to make that change. In the HTML tab, find this:

<button onclick=‘makeBlurred()’>make blurred</button><br>
<button onclick=‘tabulate()’>tabulate</button>

and change it to this:

<button onclick=‘makeBlurred(); tabulate()’>blur and tabulate</button>

1 Like

Thanks, yeah, JavaScript is amazingly powerful and so easy to share and collaborate.

People complain about the language but especially when you start tapping into the browser APIs and such – the DOM and css, canvas, SVG, WebAudio, WebGl – there are just so many tools that you can get to easily. It would be nice to get a lot of tools in there that can graphically visualize things. (I have a ton of stuff along these lines that could be packaged up into Codepens eventually)

If you want to work on that tool you describe and want help, let me know.

Thank you for your generous offer to collaborate.

The looping techniques we normally use in JS won’t fulfill the requirement to abandon a calculation immediately when an action by the user implies that the outcome of that calculation is no longer wanted. Instead, they will hang the computer/human interaction while grinding in the CPU.

Before I read your sentence and got into thinking about composing this reply, I held the position that the sort of language that can be interpreted in a way that meets that requirement is also the sort of language that can be interpreted in a way that automatically persists the states of interaction and calculation. Since 1980, I have been thinking about implementing a language that could do that. My studies of related prior art and my thinking and finally the desire to do this voting application have come together in my mind to the point where I have begun to try to prototype a solution.

However, in thinking about composing this reply, I have thought of maybe a way to code the responsive voting application before investing the time to implement a whole new (and declarative) language and make transparent persistence work. So I’m now testing whether the shortcut technique I have in mind is as supported as I hope it is by the facilities in the JS ecosystem, specifically the behavior of async functions if they call one another into a nest. My idea is to code the loops in pretty much the conventional way, but use async functions everywhere, and in each loop insert something like “await env.gate();” where the ‘gate’ procedure would return a new, resolved promise every time it is called, if the calculation is still wanted. Otherwise it would return a promise that never gets resolved or rejected, and I hope the whole invocation of the async function would eventually be collected. So testing for memory leak will be part of testing whether the infrastructure supports the technique.

That’s not my experience.

In terms of raw speed, my recent Codepen that processes 40,000 ballots from Maine runs in less than half a second. What takes a long time is opening the spreadsheet in Numbers (free Mac spreadsheet program), which takes half a minute, and then, after converting to 40,000 lines of csv text and opening in a text editor, cutting and pasting it into a browser takes a few seconds. But once it is there, the javascript to actually process parse those ballots and tabulate via a whole variety of methods takes less than half a second. Actually if I run it a second time, it goes a lot faster than that, because it has “warmed up” (Javascript engines do some fancy magic with precompiling and otherwise optimizing things that get used a lot).

However I have also done some things that I actually want to go slow. I’ll show some of my voting simulators soon, where it dynamically visualizes how the algorithm iteratively refines its results after seeing how other people are voting (to simulate the real world situation of people watching polls and such to anticipate how others are likely to vote). In this case, I use a combination of timers and css animations to do this over a second or two, so you can see the process before your eyes. Yes it remains responsive to user interaction. But if I didn’t slow it down like this, it would happen so fast you wouldn’t see a thing. (literally the whole thing would be done in less than 60th of a second)

I don’t know what sort of calculation you are doing that results in the CPU grinding for noticeable amounts of time. Yes, I’ve done some things in Javascript that take a long time. No, they have nothing to do with voting. :slight_smile: But even so, it is quite possible to structure your code so that it doesn’t hang the user interface and so it can be interrupted by a user interaction.

I understand we all have itches we want to scratch, and if you’ve been thinking about this since 1980, by all means I encourage you to go for it. However, I would hope you’d look deeper into Javascript and consider the benefits (more than anything, easy sharability), which you seemed to already acknowledge in a previous post here.