// Reproduces the saved analyses of the us-state-girls-sports-laws dataset // from state_laws.csv. Usage: node compare_state_laws.js state_laws.csv const fs = require('fs'); const file = process.argv[2] || 'state_laws.csv'; function parseCsv(text) { const rows = []; let row = [], cell = '', q = false; for (let i = 0; i < text.length; i++) { const c = text[i]; if (q) { if (c === '"' && text[i+1] === '"') { cell += '"'; i++; } else if (c === '"') q = false; else cell += c; } else if (c === '"') q = true; else if (c === ',') { row.push(cell); cell = ''; } else if (c === '\n') { row.push(cell); rows.push(row); row = []; cell = ''; } else if (c !== '\r') cell += c; } if (cell || row.length) { row.push(cell); rows.push(row); } const [h, ...body] = rows; return body.map(r => Object.fromEntries(h.map((k, i) => [k, r[i]]))); } const all = parseCsv(fs.readFileSync(file, 'utf8')); const laws = all.filter(r => r.abbrev !== 'WA'); const count = f => laws.filter(f).length; // Each dimension: how many enacted measures go further than IL26-638 (stricter), // match it (same), or go less far (looser). const dims = [ ['Covers college sports', count(r => r.covers_college === 'yes'), 0], ['Lets harmed students sue', count(r => r.private_right_of_action !== 'no'), 0], ['Penalizes noncomplying schools', count(r => r.penalty_on_noncomplying_schools === 'yes'), 0], ["Also bars girls from boys' teams", count(r => r.also_bars_girls_from_boys_teams === 'yes'), 0], ['Applies at every grade (no grade floor)', 0, count(r => r.grade_floor !== '')], ['Every girl must submit proof of sex', 0, count(r => r.routine_proof_required === 'none')], ["Every girl needs a provider's sign-off", 0, count(r => r.provider_role !== 'required_all_athletes')], ['Routine check limited to anatomy, genes or testosterone', 0, count(r => !(r.medical_bases_listed === 'yes' && r.routine_proof_required !== 'none'))], ]; const comparison = []; for (const [dimension, stricter, looser] of dims) { comparison.push({ dimension, comparison: 'Stricter than I-638', states: stricter }); comparison.push({ dimension, comparison: 'Same as I-638', states: laws.length - stricter - looser }); comparison.push({ dimension, comparison: 'Looser than I-638', states: looser }); } const methods = {}; for (const r of laws) methods[r.k12_verification] = (methods[r.k12_verification] || 0) + 1; console.log(JSON.stringify({ n: laws.length, comparison, methods }, null, 1));