Commit a206aa0bc4
Unsigned
Layout: unified · split
sampling/README.org added +32
| @@ -0,0 +1,32 @@ | |||
| 1 | #+title: Sampling Tools | ||
| 2 | |||
| 3 | * =sample.py= | ||
| 4 | |||
| 5 | #+begin_src sh | ||
| 6 | python ./sample.py | ||
| 7 | #+end_src | ||
| 8 | |||
| 9 | #+begin_src text | ||
| 10 | Dataframe size (rows, columns): (100, 9) | ||
| 11 | Sample size: 5 | ||
| 12 | Sample: | ||
| 13 | Index Organization Id ... Industry Number of employees | ||
| 14 | 79 80 cBa7EFe5D05Adaf ... Online Publishing 7805 | ||
| 15 | 97 98 E7df80C60Abd7f9 ... Broadcast Media 236 | ||
| 16 | 3 4 2bFC1Be8a4ce42f ... Automotive 921 | ||
| 17 | 42 43 A2D89Ab9bCcAd4e ... Capital Markets / Hedge Fund / Private Equity 3816 | ||
| 18 | 70 71 32BB9Ff4d939788 ... Wireless 6146 | ||
| 19 | |||
| 20 | [5 rows x 9 columns] | ||
| 21 | #+end_src | ||
| 22 | |||
| 23 | * =sample.html= | ||
| 24 | |||
| 25 | This is an interactive web page that allows users to submit their population | ||
| 26 | size, sample size(s), and generate a psuedo-random sample list of numbers to use | ||
| 27 | when sampling against their population. | ||
| 28 | |||
| 29 | Samples can be re-generated and validated using the seed numbers provided during | ||
| 30 | the original generation. | ||
| 31 | |||
| 32 | [[sample-html.png]] | ||
sampling/sample-html.png added
Binary file not shown.
sampling/sample.html added +167
| @@ -0,0 +1,167 @@ | |||
| 1 | <!doctype html> | ||
| 2 | <html lang="en"> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8"> | ||
| 5 | <meta name="viewport" content="width=device-width, initial-scale=1"> | ||
| 6 | <title>Sampling Tool</title> | ||
| 7 | <style> | ||
| 8 | form { | ||
| 9 | display: table; | ||
| 10 | } | ||
| 11 | form div { | ||
| 12 | display: table-row; | ||
| 13 | } | ||
| 14 | label, input { | ||
| 15 | display: table-cell; | ||
| 16 | margin-bottom: 10px; | ||
| 17 | } | ||
| 18 | label { | ||
| 19 | padding-right: 10px; | ||
| 20 | } | ||
| 21 | table { | ||
| 22 | width: 100%; | ||
| 23 | border-collapse: collapse; | ||
| 24 | margin-top: 10px; | ||
| 25 | } | ||
| 26 | table, th, td { | ||
| 27 | border: 1px solid black; | ||
| 28 | } | ||
| 29 | th, td { | ||
| 30 | padding: 5px; | ||
| 31 | text-align: center; | ||
| 32 | } | ||
| 33 | </style> | ||
| 34 | </head> | ||
| 35 | <body> | ||
| 36 | <h1>Sampling Tool</h1> | ||
| 37 | <p>This sampling tool provides a quick and easy way to generate | ||
| 38 | psuedo-random samples within a defined range. Simply enter the size of your | ||
| 39 | population, enter your desired number of samples, and generate!</p> | ||
| 40 | <p>To reproduce and validate a previously-generated sample, please ensure | ||
| 41 | you have entered the seed value correctly when submitting the form. All | ||
| 42 | inputs must match the previously-generated sample's inputs to generate the | ||
| 43 | same output.</p> | ||
| 44 | <form id="sampleForm" onsubmit="return handleFormSubmit(event)"> | ||
| 45 | <div> | ||
| 46 | <label for="populationSize">Population Size*:</label> | ||
| 47 | <input type="number" id="populationSize" name="populationSize" min="1" autofocus required> | ||
| 48 | </div> | ||
| 49 | <div> | ||
| 50 | <label for="sampleSize">Sample Size*:</label> | ||
| 51 | <input type="number" id="sampleSize" name="sampleSize" min="1" required> | ||
| 52 | </div> | ||
| 53 | <div> | ||
| 54 | <label for="replacementSize">Replacement Sample Size:</label> | ||
| 55 | <input type="number" id="replacementSize" name="replacementSize" min="0"> | ||
| 56 | </div> | ||
| 57 | <div> | ||
| 58 | <label for="customSeed">Custom Seed (optional):</label> | ||
| 59 | <input type="number" id="customSeed" name="customSeed" min="0"> | ||
| 60 | </div> | ||
| 61 | <div> | ||
| 62 | <input type="submit" value="Calculate"> | ||
| 63 | </div> | ||
| 64 | <p><i>* Indicates a required field</i></p> | ||
| 65 | </form> | ||
| 66 | <hr> | ||
| 67 | <div id="results"></div> | ||
| 68 | <script> | ||
| 69 | function seededRandom(seed) { | ||
| 70 | let s = seed % 2147483647; | ||
| 71 | return function() { | ||
| 72 | s = (s * 16807) % 2147483647; | ||
| 73 | return (s - 1) / 2147483646; | ||
| 74 | }; | ||
| 75 | } | ||
| 76 | |||
| 77 | function handleFormSubmit(event) { | ||
| 78 | event.preventDefault(); // Prevent the default form submission behavior | ||
| 79 | const customSeedInput = document.getElementById('customSeed').value; | ||
| 80 | const seed = customSeedInput ? parseInt(customSeedInput) : Math.floor(Math.random() * 1000000); // Use custom seed if provided | ||
| 81 | generateSamples(seed); // Call the function with the seed | ||
| 82 | } | ||
| 83 | |||
| 84 | function generateSamples(seed) { | ||
| 85 | const populationSize = parseInt(document.getElementById('populationSize').value); | ||
| 86 | const sampleSize = parseInt(document.getElementById('sampleSize').value); | ||
| 87 | const replacementSize = parseInt(document.getElementById('replacementSize').value || 0); | ||
| 88 | const resultsDiv = document.getElementById('results'); | ||
| 89 | |||
| 90 | // Clear previous results | ||
| 91 | resultsDiv.innerHTML = ''; | ||
| 92 | |||
| 93 | // Validate inputs | ||
| 94 | if (isNaN(populationSize) || isNaN(sampleSize) || populationSize <= 0 || sampleSize <= 0) { | ||
| 95 | alert("Please enter valid numbers for required fields."); | ||
| 96 | return; | ||
| 97 | } | ||
| 98 | if (sampleSize + replacementSize > populationSize) { | ||
| 99 | alert("Not enough unique samples available. Reduce the sample size or replacement size."); | ||
| 100 | return; | ||
| 101 | } | ||
| 102 | |||
| 103 | // Create seeded random function | ||
| 104 | const random = seededRandom(seed); | ||
| 105 | |||
| 106 | // Generate an array of population numbers | ||
| 107 | const population = Array.from({ length: populationSize }, (_, i) => i + 1); | ||
| 108 | |||
| 109 | // Shuffle the population array using the seeded random function | ||
| 110 | const shuffledPopulation = population | ||
| 111 | .map(value => ({ value, sort: random() })) | ||
| 112 | .sort((a, b) => a.sort - b.sort) | ||
| 113 | .map(({ value }) => value); | ||
| 114 | |||
| 115 | // Select original samples | ||
| 116 | const originalSamples = shuffledPopulation.slice(0, sampleSize); | ||
| 117 | |||
| 118 | // Select replacement samples | ||
| 119 | const replacementSamples = shuffledPopulation.slice(sampleSize, sampleSize + replacementSize); | ||
| 120 | |||
| 121 | // Display the seed | ||
| 122 | const seedInfo = document.createElement('p'); | ||
| 123 | seedInfo.textContent = `Seed: ${seed}`; | ||
| 124 | resultsDiv.appendChild(seedInfo); | ||
| 125 | |||
| 126 | // Generate tables | ||
| 127 | const originalTable = createTable(originalSamples, "Original Samples"); | ||
| 128 | const replacementTable = createTable(replacementSamples, "Replacement Samples"); | ||
| 129 | |||
| 130 | // Append tables to the results div | ||
| 131 | resultsDiv.appendChild(originalTable); | ||
| 132 | if (replacementSamples.length > 0) { | ||
| 133 | resultsDiv.appendChild(replacementTable); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | function createTable(dataArray, tableTitle) { | ||
| 138 | const table = document.createElement('table'); | ||
| 139 | const caption = document.createElement('caption'); | ||
| 140 | caption.textContent = tableTitle; | ||
| 141 | table.appendChild(caption); | ||
| 142 | |||
| 143 | const headerRow = document.createElement('tr'); | ||
| 144 | const indexHeader = document.createElement('th'); | ||
| 145 | indexHeader.textContent = 'Index'; | ||
| 146 | const sampleHeader = document.createElement('th'); | ||
| 147 | sampleHeader.textContent = 'Sample'; | ||
| 148 | headerRow.appendChild(indexHeader); | ||
| 149 | headerRow.appendChild(sampleHeader); | ||
| 150 | table.appendChild(headerRow); | ||
| 151 | |||
| 152 | dataArray.forEach((sample, index) => { | ||
| 153 | const row = document.createElement('tr'); | ||
| 154 | const indexCell = document.createElement('td'); | ||
| 155 | const sampleCell = document.createElement('td'); | ||
| 156 | indexCell.textContent = index + 1; | ||
| 157 | sampleCell.textContent = sample; | ||
| 158 | row.appendChild(indexCell); | ||
| 159 | row.appendChild(sampleCell); | ||
| 160 | table.appendChild(row); | ||
| 161 | }); | ||
| 162 | |||
| 163 | return table; | ||
| 164 | } | ||
| 165 | </script> | ||
| 166 | </body> | ||
| 167 | </html> | ||