Marble Sampling

by aholdorf

HTML

<div id="settingsDiv">
  Number of marbles (2-10000): <input type="text" id="numMarblesField" value="10"> <br/>
  Number of colors (2-10): <input type="text" id="numColorsField" value="2"> <br/> <br/>
  <input type="button" value="Set Marbles" id="settingsButton">
</div>
<div id="bagDiv" class="left">
  <span id="bagDescription1">Total marbles: 10</span><br/>
  <span id="bagDescription2">Number of colors: 2</span><br/>
  <span id="bagDescription3">Number of marbles left: 10</span><br/>
  <hr/>
  Number to take in sample: <input type="text" id="sampleSizeField" value="3"><br/><br/>
  <input type="button" id="resetButton" value="Return Marbles to Bag"> <input class="right" type="button" id="sampleButton" value="Take Sample"/><br/>
  <span class="hint">(Hit the spacebar to quickly return the sample and draw a new one.)</span>
</div>
<div id="sampleDiv" class="left">
  <span id="sampleHeader">Colors of marbles in the bag:</span><br/><br>
  <div id="sampleMarblesDiv">
  <div class="marble" id="marble1">
  
  </div>
  <div class="marble" id="marble2">
  
  </div>
  </div>
</div>

CSS

.left{
  float: left;
}
.right{
  float: right;
}
.clear{
  clear: both;
}
.hint{
  font-size: 75%;
  font-style: italic;
}
#settingsDiv{
  border-bottom: solid black 1px;
  padding: 20px;
}
#bagDiv{
  border-right: solid black 1px;
  padding: 20px;
  height: 200px;
}
#sampleDiv{
  padding: 20px;
  width: 50%;
}
.marble{
  border: solid black 1px;
  border-radius: 15px;
  width: 20px;
  height: 20px;
  float: left;
  margin-right: 5px;
}

.marbleInfo{
  width: 40%;
  margin: 5px;
  float: left;
}

#marble1{
  background: red;
}
#marble2{
  background: blue;
}
#marble3{
  background: green;
}
#marble4{
  background: yellow;
}
#marble5{
  background: white;
}
#marble6{
  background: pink;
}
#marble7{
  background: orange;
}
#marble8{
  background: #0ff;
}
#marble9{
  background: purple;
}
#marble10{
  background: black;
}

JavaScript

var totalMarbles = 10;
var totalColors = 2;
var bagMarbles = 10;
var sampleSize = 3;
var sample = [];
var bag = [];
var marbles = [];

$(document).ready(function(){
	generateMarbles();
});

function generateMarbles(){
	sample = [];
  bag = [];
  marbles = [];
  var mode = Math.random();
  if(mode < 0.05){
  	evenDistribution();
  }else if(mode < 0.15){
  	uniformDistribution();
  }else{
  	variedDistribution();
  }
  bag = marbles.slice(0);
}

function variedDistribution(){
	for(var i=0;i<totalColors;i++){
  	marbles.push(i+1);
  }
  var numLeft = totalMarbles - totalColors;
  for(var i=0;i<totalColors-1;i++){
  	var thisCount = Math.floor(Math.random()*numLeft*0.5);
    for(var j=0;j<thisCount;j++){
    	marbles.push(i+1);
    }
    numLeft -= thisCount;
  }
  while(numLeft > 0){
  	marbles.push(Math.ceil(Math.random()*totalColors));
    numLeft--;
  }
}

function evenDistribution(){
	for(var i=0;i<totalMarbles;i++){
  	marbles.push((i%totalColors)+1);
  }
}

function uniformDistribution(){
	for(var i=0;i<totalColors;i++){
  	marbles.push(i+1);
  }
  for(var i=totalColors;i<totalMarbles;i++){
  	marbles.push(Math.ceil(Math.random()*totalColors));
  }
}

function resetBag(){
	bagMarbles = totalMarbles;
  sample = [];
  bag = marbles.slice(0);
	$("#sampleHeader").html("Colors of marbles in the bag:");
  $("#sampleMarblesDiv").html("");
  for(var i=0;i<totalColors;i++){
  	$("#sampleMarblesDiv").append("<div class='marble' id='marble" + (i+1) + "'></div>");
  }
	$("#bagDescription1").html("Total marbles: " + totalMarbles);
	$("#bagDescription2").html("Number of colors: " + totalColors);
	$("#bagDescription3").html("Number of marbles left: " + bagMarbles);
}

function updateSample(){
	$("#sampleHeader").html("Sample marbles:");
  var counts = [];
  for(var i=1;i<=totalColors;i++){
  	var thisCount = 0;
    for(var j=0;j<sample.length;j++){
    	if(sample[j] == i){
      	thisCount++;
      }
    }
    counts.push(thisCount);
  }
  $("#sampleMarblesDiv").html("");
 ...