Elecciones en Córdoba

En córdoba se ponian 9 bancas de diputados en juego.

¿Qué pasó con Liliana Olivero?

In [1]:
from pyquery import PyQuery

pq = PyQuery('http://www.resultados.gob.ar/resultados/04/DDN04999.htm')

listas = [pq(th).text() for th in pq('table#TVOTOS tbody tr th')]
In [2]:
listas
Out[2]:
['UNION POR CORDOBA',
 'UNION CIVICA RADICAL',
 'FRENTE PARA LA VICTORIA',
 'UNION PRO',
 'FRENTE DE IZQUIERDA Y DE LOS TRABAJADORES',
 'VECINALISMO INDEPENDIENTE',
 'FRENTE PROGRESISTA CIVICO Y SOCIAL',
 'COALICION CIVICA - AFIRMACION PARA UNA REPUBLICA IGUALITARIA (ARI)',
 'ENCUENTRO VECINAL CORDOBA']
In [3]:
votos = [int(pq(td).text().replace('.', '')) for td in pq('table#TVOTOS tbody tr td.votlista')]
In [4]:
votos
Out[4]:
[515848, 440452, 296449, 280819, 145238, 89413, 72414, 61032, 41719]
In [5]:
%load http://tokland.googlecode.com/svn-history/r395/trunk/dhondt/dhondt.py
In [13]:
#!/usr/bin/python
"""
Calculate seats distribution according to the D'Hondt method.

Author: Arnau Sanchez <[email protected]>
Site: http://code.google.com/p/tokland
"""
import operator
from itertools import chain

def merge(*dicts):
    """Merge dictionary d2 into d."""
    return dict(chain.from_iterable(d.iteritems() for d in dicts))

def dhondt(polling, total_seats, min_percentage=5.0):
    """
    Calculate seats distribution according to the D'Hondt method.

    Given a diccionary of (party, votes) pairs and the total seats
    to distribute, return a dictionary of (party, seats) pairs.

    >>> dvotes = {"a": 100, "b": 90, "c": 20, "d": 3}
    >>> sorted(dhondt(dvotes, 10, 5.0).items())
    [('a', 5), ('b', 4), ('c', 1)]
    """
    def _process(dvotes, dvotes_cur, pending_seats, results):
        """Return results for dvotes"""
        if not pending_seats:
            return results
        party, _ = max(dvotes_cur.items(), key=operator.itemgetter(1))
        seats = results[party]+1
        new_dvotes_cur = merge(dvotes_cur, {party: dvotes[party]/(seats+1)})
        new_results = merge(results, {party: seats})
        return _process(dvotes, new_dvotes_cur, pending_seats-1, new_results)
      
    total_votes = sum(polling.values())
    dvotes = dict((party, votes) for (party, votes) in polling.items() 
                  if float(100*votes) / total_votes >= min_percentage)
    return _process(dvotes, dvotes, total_seats, dict.fromkeys(dvotes, 0))
In [14]:
dvotos = dict(zip(listas, votos))
In [15]:
sorted(dhondt(dvotos, 9, 0.0).items(), key=operator.itemgetter(1), reverse=True)
Out[15]:
[('UNION CIVICA RADICAL', 3),
 ('UNION POR CORDOBA', 3),
 ('FRENTE PARA LA VICTORIA', 2),
 ('UNION PRO', 1),
 ('FRENTE PROGRESISTA CIVICO Y SOCIAL', 0),
 ('VECINALISMO INDEPENDIENTE', 0),
 ('FRENTE DE IZQUIERDA Y DE LOS TRABAJADORES', 0),
 ('ENCUENTRO VECINAL CORDOBA', 0),
 ('COALICION CIVICA - AFIRMACION PARA UNA REPUBLICA IGUALITARIA (ARI)', 0)]

Votos afirmativos y recurridos

In [26]:
afirmativos = int(pq('table.tablin tbody tr td.vot').eq(0).text().replace('.', ''))
recurridos = int(pq('table.tablin tbody tr td.vot').eq(3).text().replace('.', ''))
In [27]:
afirmativos, recurridos
Out[27]:
(1943384, 2139)

Experimento 1: Votos recurridos del FIT / FIT con votos de menos

In [18]:
experimento1 = dvotos.copy()
FIT = 'FRENTE DE IZQUIERDA Y DE LOS TRABAJADORES'
for votos_recurridos in xrange(1, recurridos + 1):
    experimento1[FIT] = experimento1[FIT] + 1
    if dhondt(experimento1, 9, 0.0)[FIT] == 1:
       print "Si %d votos recurridos fuesen del FIT, Liliana Olivero sería de diputada" % votos_recurridos
       break
else:
    print "aún si los %d votos recurridos fuesen del FIT, Liliana no entra" % recurridos
Si 1580 votos recurridos fuesen del FIT, Liliana Olivero sería de diputada

Experimento 2: UCR con votos "de más"

In [19]:
experimento2 = dvotos.copy()
FIT = 'FRENTE DE IZQUIERDA Y DE LOS TRABAJADORES'
UCR = 'UNION CIVICA RADICAL'
for voto_ucr in xrange(1, experimento2[UCR] + 1):
    experimento2[UCR] = experimento2[UCR] - 1
    if dhondt(experimento2, 9, 0.0)[FIT] == 1:
       print "Si la UCR obtuviese %d votos menos, Liliana Olivero sería de diputada" % voto_ucr
       break
Si la UCR obtuviese 4739 votos menos, Liliana Olivero sería de diputada

Experimento 3: Votos del FIT anotados por error a la UCR

In [22]:
experimento3 = dvotos.copy()
FIT = 'FRENTE DE IZQUIERDA Y DE LOS TRABAJADORES'
UCR = 'UNION CIVICA RADICAL'
for voto_ucr in xrange(1, experimento2[UCR] + 1):
    experimento3[UCR] = experimento3[UCR] - 1
    experimento3[FIT] = experimento3[FIT] + 1
    if dhondt(experimento3, 9, 0.0)[FIT] == 1:
       print "Si %d votos de la UCR fuesen del FIT, Liliana Olivero sería de diputada" % voto_ucr
       break
Si 1185 votos de la UCR fuesen del FIT, Liliana Olivero sería de diputada
In [28]:
(1185 / float(afirmativos)) * 100
Out[28]:
0.060976111772043

0.06 % de los votos válidos es la diferencia que tercia entre Mestre y Olivero. Es muy poco. El FIT en muchas escuelas sólo tenia fiscales generales y en muchas otras ni siquiera eso.

En la próxima entrega, analizaremos mesa por mesa para ver qué encontramos.