Ctrl K
ComunidadGuías…

scripts/_wb-tech-readiness-projection.cjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
'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 };