to inside the heading
tag for that section.
* Also changed display so that when the interval is zero, one die
is displayed instead of a range that looks like "0-0", "1-1",
etc. (these now are "0", "1", etc.
2008-02-14: Release initial version 1.0.
*/
//version number goes here
$version = "1.2";
//jump out of PHP to print HTML header, title and intro
?>
Dice Binning Calculator
Dice Binning Calculator for Post-Election Audits
Joseph Lorenzo Hall
(joehall@berkeley.edu), UC Berkeley School of Information
To increase the transparency of the 1% manual tally process, a few
California counties have begun to use 10-sided dice to produce
publicly-verifiable random numbers
(See Cordero,
Wagner and Dill 2006). Unfortunately, using 10-sided dice to 1)
select from only a few precincts or 2) to select from many precincts
can require a lot of re-rolling of the dice. To increase the
efficiency of the process, Cordero et al. suggest "binning" the dice
rolls so that each precinct has a range of corresponding
values, of equal width, that allow a higher percentage of
dice rolls to "hit". This calculator implements this idea. It can
also output the binning data in a form that is easily pasteable into a
spreadsheet. Please click here for source code and
licensing information.
Settings
Results
(This is the quantity of random numbers $numdice $worddice can produce.)";
$comm2 = "(This is the number of random numbers per bin.)";
$comm3 = "(This is the number of random numbers that will require a re-roll.)";
/* if 1) user doesn't want pasteable results and 2) as long as we have
no errors, print some metadata about the calculation. */
if ($csv == 0 && $skipall == 0) {
print "
\n";
print "
Range is $range. $comm1
\n";
print "
Rounded interval is $intervalr. $comm2
\n";
print "
Interval modulus is $intmod ($intmodp% of rolls). $comm3
\n";
print "
\n";
}
/* if user doesn't want pasteable results and doesn't need to use more
dice (in which case no results are displayed), display link that
will produce pasteable results. */
if ($csv == 0 && $skipall == 0) {
print "
\n";
}
/* if the user *does* want pasteable results and if there are no
errors, then display the instructions for copying and pasting the
pasteable results into a spreadsheet. */
if ($csv == 1 && $skipall == 0) {
//jump out of PHP
?>
Here are the steps necessary to paste the bins below into a column
of a spreadsheet (We need to insert a new column, format that column
and then copy and paste the data below.):
Open the spreadsheet.
In your spreadsheet, click on the column header for the column
to the right of where you want the new column.
In the spreadsheet menu, select "Insert" -> "Columns". This will
insert a new column.
With the new column selected, choose "Format" -> "Cells...". In
the number tab select "Text" and click "OK". (We're text-formatting
this column because some spreadsheet programs interpret numers like
"7-13" as dates.)
With your mouse, select all the bins below on this page. Copy
the selection (Ctrl-C on Windows PCs or Cmd-C on Macs).
In the spreadsheet again, click on the first cell of the column
you just created. Paste the selection (Ctrl-V on Windows PCs or
Cmd-V on Macs).
\n";
} else {
print "Roll $range1-$range2, pick precinct $pick \n";
}
} else {
//if the interval is only 1, don't print a range
if ($intervalr == 1) {
print "$range1 \n";
} else {
print "$range1-$range2 \n";
}
}
}
/* If the interval isn't round (has modulus of zero), there will be
some extra numbers that won't correspond to precincts and where
the user will need to reroll. */
$maxmin = $range-$intmod; //beginning of reroll range
$maxmax = $range-1; //end of reroll range
//print differently if no rerolls are needed
if ($intmod != 0) {
//of course, need this to look different if pasteable
if ($csv == 0) {
print "Roll $maxmin-$maxmax, reroll dice \n";
} else {
print "$maxmin-$maxmax -> reroll \n";
}
} else {
print "No rerolls needed \n";
}
}
/* print an error notice if they need to use more dice... however
don't print if we have a validation error so that they take a
higher precedence. */
if ($err_int && !$err_numdice && !$err_numprec && !$err_csv) {
print "
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
You need to increase the number of dice.
The range must be greater than the number of precincts.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
";
}
//print an error notice if numdice didn't validate
if ($err_numdice) {
print "
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The number of dice you provided is invalid.
It must be a positive integer.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
";
}
//print an error notice if numprec didn't validate
if ($err_numprec) {
print "
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The number of precincts you provided is invalid.
It must be a positive integer.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
";
}
//print an error notice if csv doesn't pass validation
if ($err_csv) {
print "
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The value for the pasteable flag (\"csv\") you've
provided is invalid. It must be a 1 or 0.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
";
}
//set up stuff to get timestamp on this here file
$f = "dicebins.php"; //file location
$attribs = stat("$f"); //get file attributes
//parse modification date attribute using date() function
$ftime = date("Y-m-d H:i:s T",$attribs[10]);
/* if pasteable flag is not set or if we have a csv value validation
error, print source and licensing info. */
if ($csv == 0 || $err_csv) {
?>
Source Code, Licensing, Version, Etc.
The source code to this script is available here, licensed under the BSD license (see source for license text).
This is version of dicebins.php (as of ).
\n\n";
/* ******************************** */
/* FUNCTIONS BELOW, NO MORE DISPLAY */
/* ******************************** */
//function to check for a valid positive integer
function validDigits($var)
{
//it's not valid if it is empty
if(IsEmpty($var)) return false;
//if it is numeric and not a float, then it's an integer
if(is_numeric($var) && !preg_match('/[^\d]+/',$var)) return true;
return false; //must not be digits
}
//function to check if var is empty or not
function IsEmpty($var)
{
if(!isset($var)) return true; //if not set, it's empty
$type=gettype($var); //get the type in a string
//check against empty versions of each type
if($type == "string" && trim($var) == '') return true;
if($type == "array" && $var == array()) return true;
if($type == "object" && $var == (object)0) return true;
if($type == "NULL") return true;
return false; //must not be empty
}
?>