scripts/_wb-tech-readiness-projection.cjs
Rama main · réplica de lectura del repositorio original.
'use strict';
const INDICATORS = {
internet: { indicatorCode: 'IT.NET.USER.ZS', unit: 'percent', max: 100, weight: 30 },
mobile: { indicatorCode: 'IT.CEL.SETS.P2', unit: 'per 100 people', max: 150, weight: 15 },
broadband: { indicatorCode: 'IT.NET.BBND.P2', unit: 'per 100 people', max: 50, weight: 20 },
rdSpend: { indicatorCode: 'GB.XPD.RSDV.GD.ZS', unit: 'percent of GDP', max: 5, weight: 35 },
};
const MIN_COMPONENTS = 3;
function buildWorldBankTechObservations(valuesByKey) {
return Object.fromEntries(Object.entries(INDICATORS).map(([key, indicator]) => {
const observation = valuesByKey?.[key];
if (observation?.value == null || observation?.year == null) return [key, null];
const value = Number(observation?.value);
const year = Number(observation?.year);
if (!Number.isFinite(value) || !Number.isInteger(year)) return [key, null];
return [key, {
value,
year,
unit: indicator.unit,
indicatorCode: indicator.indicatorCode,
source: 'World Bank',
}];
}));
}
function computeWorldBankTechRankings(indicatorData) {
const countries = new Set(Object.values(indicatorData).flatMap(Object.keys));
const entries = [];
for (const country of countries) {
const valuesByKey = Object.fromEntries(
Object.keys(INDICATORS).map(key => [key, indicatorData[key]?.[country]]),
);
const observations = buildWorldBankTechObservations(valuesByKey);
const components = {};
let componentCount = 0;
let totalWeight = 0;
let weightedSum = 0;
for (const [key, { max, weight }] of Object.entries(INDICATORS)) {
const observation = observations[key];
components[key] = observation && observation.value >= 0
? Math.min(100, (observation.value / max) * 100)
: null;
if (components[key] === null) continue;
componentCount += 1;
totalWeight += weight;
weightedSum += components[key] * weight;
}
const score = componentCount >= MIN_COMPONENTS
? Math.round((weightedSum / totalWeight) * 10) / 10
: null;
const countryName = Object.values(valuesByKey).find(value => value?.name)?.name || country;
entries.push({ country, countryName, score, rank: null, componentCount, components, observations });
}
entries.sort((a, b) => (b.score ?? -1) - (a.score ?? -1));
entries.forEach((entry, index) => {
if (entry.score !== null) entry.rank = index + 1;
});
return entries;
}
module.exports = { buildWorldBankTechObservations, computeWorldBankTechRankings };