const Papa = require('papaparse'); const fs = require('fs'); const loadTsv = name => Papa.parse(fs.readFileSync(name).toString(), { dynamicTyping: true, header: true, skipEmptyLines: true, delimiter: '\t', }).data; const _each = (obj, callable) => { const ret = []; for (let key in obj) { if (obj.hasOwnProperty(key)) { ret.push(callable(obj[key], key)); } } return ret; }; const peselK1 = loadTsv('./data/names/K1.tsv'); const peselK2 = loadTsv('./data/names/K2.tsv'); const peselM1 = loadTsv('./data/names/M1.tsv'); const peselM2 = loadTsv('./data/names/M2.tsv'); const pesel = {} for (let [names, sex, ordinal] of [ [peselK1, 'K', 1], [peselK2, 'K', 2], [peselM1, 'M', 1], [peselM2, 'M', 2], ]) { for (let {name, count} of names) { if (pesel[name] === undefined) { pesel[name] = {K: [0, 0], M: [0, 0]}; } pesel[name][sex][ordinal - 1] = count; } } const calculateBalance = (k, m) => { const balance = k / (k + m); return balance > 0.5 ? 1 - balance : balance; } const allUnisex = {}; const popularUnisex = {}; const allFirstUnisex = {}; const popularFirstUnisex = {}; _each(pesel, (counts, name) => { counts['balanceBoth'] = calculateBalance(counts.K[0] + counts.K[1], counts.M[0] + counts.M[1]); counts['balanceFirst'] = calculateBalance(counts.K[0], counts.M[0]); counts['balanceBothPop'] = counts['balanceBoth'] * (counts.K[0] + counts.K[1] + counts.M[0] + counts.M[1]); counts['balanceFirstPop'] = counts['balanceFirst'] * (counts.K[0] + counts.M[0]); }); let maxBalanceBoth = {balance: 0, name: ''}; let maxBalanceBothPop = {balance: 0, name: ''}; let maxBalanceFirst = {balance: 0, name: ''}; let maxBalanceFirstPop = {balance: 0, name: ''}; const popularMin = 100; _each(pesel, (counts, name) => { if (counts.K[0] + counts.K[1] > 0 && counts.M[0] + counts.M[1] > 0) { allUnisex[name] = counts; } if (counts.K[0] + counts.K[1] >= popularMin && counts.M[0] + counts.M[1] >= popularMin) { popularUnisex[name] = counts; if (counts['balanceBoth'] > maxBalanceBoth.balance) { maxBalanceBoth = {balance: counts['balanceBoth'], name: name}; } } if (counts['balanceBothPop'] > maxBalanceBothPop.balance) { maxBalanceBothPop = {balance: counts['balanceBothPop'], name: name}; } if (counts.K[0] > 0 && counts.M[0] > 0) { allFirstUnisex[name] = counts; } if (counts.K[0] >= popularMin && counts.M[0] >= popularMin) { popularFirstUnisex[name] = counts; if (counts['balanceFirst'] > maxBalanceFirst.balance) { maxBalanceFirst = {balance: counts['balanceFirst'], name: name}; } } if (counts['balanceFirstPop'] > maxBalanceFirstPop.balance) { maxBalanceFirstPop = {balance: counts['balanceFirstPop'], name: name}; } }); const buildTable = (names, both, sortBy) => { names = _each(names, (counts, name) => { return {name, counts} }).sort((a, b) => { return b.counts[sortBy] - a.counts[sortBy]; }) let table = `
Imię | `; table += `Kobiety${both ? ' (pierwsze imię)' : ''} | `; if (both) { table += `Kobiety (drugie imię) | `; } table += `Mężczyźni${both ? ' (pierwsze imię)' : ''} | `; if (both) { table += `Mężczyźni (drugie imię) | `; } table += `Balans | `; table += `Balans × popularność | `; table += `
---|---|---|---|---|---|---|
${name} | `; table += `${counts.K[0]} | `; if (both) { table += `${counts.K[1]} | `; } table += `${counts.M[0]} | `; if (both) { table += `${counts.M[1]} | `; } table += `${counts[both ? 'balanceBoth' : 'balanceFirst'].toFixed(3)} | `; table += `${counts[both ? 'balanceBothPop' : 'balanceFirstPop'].toFixed(0)} | `; table += `