Como funciona la ley d’Hondt usando JavaScript

Hola a todos, hoy os voy a explicar que es la ley d’hondt y como hacer un pequeño ejemplo práctico con JavaScript.

Llegan unas elecciones y el nombre de de d’Hondt empieza a sonar con fuerza, pero ¿Quién es d’Hondt y en que consiste su ley?

Victor d’Hondt fue un jurista belga que creo el sistema conocido como ley d’Hondt que es un método de promedio mayor para asignar escaños en los sistemas de representación proporcional por listas electorales.

Punto de inicio para la ley d’hontd

Para este ejemplo, vamos a partir de que tenemos un numero de escaños a repartir entre 4 candidaturas, pudiendo también indicar el número de votos en blanco y el umbral mínimo de porcentaje de votos.

Si una candidatura no supera el porcentaje de voto, será descartada para repartir escaños.

Los votos en blanco solo afectan al porcentaje de voto, haciendo que partidos pequeños se puedan quedar fuera.

Se pueden indicar los votos nulos si se desea, pero no tiene efectos en nuestro calculo.

Vamos a partir de este formulario ya hecho en nuestro canal de youtube:

Tienes el código en github.

ley d'hondt 1

Recuerda de añadir el fichero main.js y asociarlo en nuestro HTML.

Como nuestro formulario cuando pulsemos el boton de calcular refrescará la página, lo evitaremos asi:


function init() {
    // Obtengo el formulario y hago que no refresque
    document.getElementsByTagName("form")[0].addEventListener("submit", (e) => {
        e.preventDefault();
        calculateSeats()
    })
}

function calculateSeats() {
}

window.onload = init;

Con window.onload, cargamos la función init al iniciar, lo vemos este tutorial:

Cargar función de Javascript al inicio

Algoritmo ley d’Hondt

Los pasos para calcular el algoritmo de la ley d’Hondt:

  1. Obtenemos los valores.
  2. Calculamos el total de votos + votos en blanco y el porcentaje de votos (votos *100 / total)..
  3. Ordenamos los votos de mayor a menor.
  4. Descartamos las candidaturas que no superen el umbral.
  5. Para cada escaño, dividimos el numero de votos entre los escaños + 1 que tiene el partido, el mayor se queda con el escaño.
  6. Mostramos los resultados.

Obteniendo los valores e inicializando nuestro array

Para obtener los valores, cogeremos el formulario y obtendremos el valor de cada uno de los campos.


// Obtengo el formulario
const form = document.getElementsByTagName("form")[0];

// Obtengo los valores
const p1 = parseInt(form.p1.value);
const p2 = parseInt(form.p2.value);
const p3 = parseInt(form.p3.value);
const p4 = parseInt(form.p4.value);
const threshold = parseInt(form.threshold.value);
const votesBlank = parseInt(form.votesBlank.value);
const seats = parseInt(form.seats.value);

Con esto podemos inicializar nuestro array de partidos politicos con los siguientes datos:

  • name: nombre del partido político.
  • votes: votos del partido político.
  • percentage: porcentaje de votos del partido político.
  • seats: numero de escaños del partido político.

// Array de partidos politicos
let pps = [
    {
        name: "A",
        votes: p1,
        percentage: 0,
        seats: 0
    },
    {
        name: "B",
        votes: p2,
        percentage: 0,
        seats: 0
    },
    {
        name: "C",
        votes: p3,
        percentage: 0,
        seats: 0
    },
    {
        name: "D",
        votes: p4,
        percentage: 0,
        seats: 0
    },
];

Total de votos y porcentaje de votos de la ley d’hondt

Después, debemos saber cuantos votos tenemos en total, esto es sencillo, solo debemos sumar el numero de votos en blanco y los votos de los partidos politicos.

// Obtengo el total (votos en blanco + todos los votos de los partidos)
let total = votesBlank + pps.reduce((acum, pp) => pp.votes + acum, 0);

Con esto podemos calcular el porcentaje de voto de cada partido politico.

// Calculo el porcentaje de participacion de cada partido
pps.forEach(pp => pp.percentage = (pp.votes * 100 / total).toFixed(2));

Ordenando los partidos políticos

Lo siguiente, es ordenar nuestros partidos políticos por los votos de mayor a menor. Esto nos ayudara, para dar prioridad a aquellos que mas votos tienen y en caso de descartes no habría problemas.

// Ordeno los partidos politicos
pps.sort((a, b) => b.votes - a.votes);

Descartamos las candidaturas que no superen el umbral

Ahora, tenemos que descartar a aquellas candidaturas que no superen el porcentaje de votos, realmente, con saber cuantos partidos son válidos es suficiente.

// Obtenemos el numero de partidos politicos validos
let numPPs = pps.filter(pp => pp.percentage >= threshold).length;

Calculamos escaños para partido con la ley d’hondt

Vamos con lo importante, para calcular los escaños, haremos lo siguiente:

  1. Recorrer los escaños.
  2. Guardar en una variable el índice del partido político que consigue el escaño y el valor máximo.
  3. Recorro cada partido político.
  4. Si el numero de votos dividido por el numero de escaños que tiene el partido político (sumándole 1) es mayor que el valor máximo elegimos ese partido político.
  5. Aumentamos los escaños del partido político elegido.

// Recorremos los asientos
for (let i = 0; i < seats; i++) {
    
    // indice seleccionado
    let indexPP = 0;
    let highValue = 0;

    // Recorremos el numero de partidos validos
    // Solo mientras el valor maximo sea menor que el numero de votos
    for (let j = 0; j < numPPs && highValue < pps[j].votes; j++) {

        // Si el numero de votos dividido en el numero de escaños (+1)
        // es mayor que el valor maximo, lo selecciono
        if (pps[j].votes / (pps[j].seats + 1) < highValue) {
            highValue = pps[j].votes / (pps[j].seats + 1);
            indexPP = j;
        }

    }

    // Aumentamos los asientos del partido politico seleccionado
    pps[indexPP].seats++;

}

Un detalle, para evitar hacer demasiados calculados, cuando el máximo valor es menor que los votos a mirar, no tiene sentido seguir calculando ya que no va a ser mayor al tener que dividir su valor.

Mostrando resultados

Con todos los datos ya calculados, podemos ya mostrar los resultados. Si el índice es mayor o igual que el numero de partidos validos, significa que esta descartado.

// Total de votos
console.log("Total de votos: " + total);
console.log("--------------------");

// Recorremos los partidos politicos
for (let i = 0; i < pps.length; i++) {

    // Si i es mayor o igual que el numero de partidos politicos validos, esta descartado
    if (i >= numPPs) {
        console.log("Partido " + pps[i].name + " descartado");
    } else {
        // Mostramos la informacion del partido politico
        console.log("Partido " + pps[i].name);
        console.log("votos: " + pps[i].votes);
        console.log("Escaños: " + pps[i].seats);
        console.log("% votos: " + pps[i].percentage);
    }
    console.log("--------------------");

}

Resultados de la ley d’hondt

Por fin, podemos mostrar nuestros resultados por pantalla de la consola del navegador.

En nuestro ejemplo, vamos a repartir 5 escaños con un umbral del 3% con los siguientes votos:

  • Partido A: 100
  • Partido B: 60
  • Partido C: 70
  • Partido D: 40

ley d'hondt 2

Y con un 15% de umbral:

ley d'hondt 3

Y con un 15% de umbral y 140 votos en blanco:

ley d'hondt 4

Te dejo el video donde lo explico paso a paso.

Si necesitas el código completo, lo tienes en github.

Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.

Compartir

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *