<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Elections et cartes électorales - énoncé
D'après wikipédia, le Gerrymandering est un terme politique nord-américain pour désigner le découpage des circonscriptions électorales ayant pour objectif de donner l’avantage à un parti, un candidat, ou un groupe donné. Et c'est ce que nous allons faire dans cette séance. C'est un problème tout-à-fait d'actualité 
Step1:  Données
Les données sont de plusieurs types et sont regroupées en trois fichiers 
Step2:  Géolocalisation des circonscription
Step3:  Géolocation des bureaux de vote
Ces données sont importantes afin de pouvoir associer chaque bureau à une circonscription. C'est la donnée la plus compliquée à obtenir car elle nécessite de combiner plusieurs techniques et sources de données pour obtenir une table propre. Le fichier final peut être obtenu comme suit 
Step4:  Ce qui suit explique la façon dont j'ai constuit cette table.
Les bureaux sont assez stables d'une élection à l'autre et cela ne devrait pas trop poser de problèmes si on mélange les données. En revanche, ces données sont assez difficiles à obtenir. open.data.fr propose ces données mais il faut récupérer chaque ville ou chaque région séparément sans garantie de réussir à couvrir tout le territoire. Le site NosDonnes.fr recense bien toutes ces informations mais il n'est pas possible - au moment où j'écris ces lignes - de récupérer ces données sous la forme d'un fichier plat. De plus, certaines régions ne sont disponibles que sous forme de scan d'impressions papier. C'est en lisant l'article Comment redécoupe-t-on la carte électorale? que je suis tombé finalement sur la base constituée pour rédiger l'article Etude sur le redécoupage électoral 
Step5:  On récupère une clé pour utiliser l'API de Bing Maps avec le module keyring. Pour stocker son mot de passe sur la machine, il suffit d'écrire 
Step6:  On regarde les valeurs manquantes.
Step7:  On pourra finalement récupérer la base des géocodes comme ceci 
Step8:  Géolocalisation des villes
Step9:  On conserve les données pour éviter de les reconstuire et faire appel à l'API Bing à nouveau.
Step10:  Géolocation des bureaux de vote avec Cartélec
Le site cartelec recense beaucoup plus de bureaux de vote mais pour les élections 2007. Ils ne devraient pas avoir changé beaucoup.
<ASSISTANT_TASK:>
Python Code:
%matplotlib inline
from jyquickhelper import add_notebook_menu
add_notebook_menu()
Explanation: Elections et cartes électorales - énoncé
D'après wikipédia, le Gerrymandering est un terme politique nord-américain pour désigner le découpage des circonscriptions électorales ayant pour objectif de donner l’avantage à un parti, un candidat, ou un groupe donné. Et c'est ce que nous allons faire dans cette séance. C'est un problème tout-à-fait d'actualité : Primaire de la droite : 10 228 bureaux de vote stratégiquement répartis.
End of explanation
from actuariat_python.data import elections_legislatives_bureau_vote
tour = elections_legislatives_bureau_vote(source='xd')
tour["T2"].sort_values(["Code département", "N° de circonscription Lg"]).head()
Explanation: Données
Les données sont de plusieurs types et sont regroupées en trois fichiers :
Résultat des élections législatives françaises de 2012 au niveau bureau de vote
Countours des circonscriptions des législatives
Localisation des buraux de votes
Localisation des villes
Localisation des bureaux de vote avec Cartelec, cette base requiert la conversion des coordonnées (lire ce notebook)
Il est conseillé de télécharger directement ces données. Les paragraphes suivants expliquent comment ceux-ci ont été récupérés ou construit. Il n'est pas immédiat d'obtenir la localisation des bureaux de vote. Celle-ci n'est d'ailleurs pas complète.
Résultats des élections législatives
End of explanation
from actuariat_python.data import elections_legislatives_circonscription_geo
geo = elections_legislatives_circonscription_geo()
geo.sort_values(["department", "code_circonscription"]).head()
c = list(geo.sort_values(["department", "code_circonscription"])["communes"])[0].split("-")
c.sort()
c[:5]
list(geo.sort_values(["department", "code_circonscription"])["kml_shape"])[:1]
Explanation: Géolocalisation des circonscription
End of explanation
from actuariat_python.data import elections_vote_places_geo
bureau_geo = elections_vote_places_geo()
bureau_geo.head()
Explanation: Géolocation des bureaux de vote
Ces données sont importantes afin de pouvoir associer chaque bureau à une circonscription. C'est la donnée la plus compliquée à obtenir car elle nécessite de combiner plusieurs techniques et sources de données pour obtenir une table propre. Le fichier final peut être obtenu comme suit :
End of explanation
from actuariat_python.data import elections_vote_place_address
bureau = elections_vote_place_address(hide_warning=True)
bureau.head()
Explanation: Ce qui suit explique la façon dont j'ai constuit cette table.
Les bureaux sont assez stables d'une élection à l'autre et cela ne devrait pas trop poser de problèmes si on mélange les données. En revanche, ces données sont assez difficiles à obtenir. open.data.fr propose ces données mais il faut récupérer chaque ville ou chaque région séparément sans garantie de réussir à couvrir tout le territoire. Le site NosDonnes.fr recense bien toutes ces informations mais il n'est pas possible - au moment où j'écris ces lignes - de récupérer ces données sous la forme d'un fichier plat. De plus, certaines régions ne sont disponibles que sous forme de scan d'impressions papier. C'est en lisant l'article Comment redécoupe-t-on la carte électorale? que je suis tombé finalement sur la base constituée pour rédiger l'article Etude sur le redécoupage électoral : évaluer le poids politique de la réforme. Les données sont accessibles sur RegardsCitoyens.fr et en cherchant bien, on trouve le répertoire redécoupage et le fichier 2014041401_resultats.csv.zip. Cependant, la géolocalisation des bureaux n'est pas souvent renseignée. On peut se contenter des fichiers obtenus pour quelques zones seulement : Paris, Gironde, Montpellier, Marseille, Saint-Malo, Nogent-Sur-Marne, Haut-de-Seine, Toulouse, Grand-Poitiers, Calvados. Cette approche risque d'être fastidieuse dans la mesure où les formats pour chaque ville ont de grande chance d'être différent. 
La meilleure option est peut-être de scrapper le site bureaudevote.fr - qui fonctionne bien quand il n'est pas en maintenance - en espérant que les numéros des bureaux de votes correspondent. Le site propose seulement les adresses. Il faudra utiliser une API de geocoding. Quelque soit la source, on supposera alors que tous les bureaux de vote associés au même emplacement feront nécessairement partie de la même circonscription. Bref, l'open data passe aussi par une certaine standardisation !
Certains départements ne sont pas renseignés, la Drôme par exemple. Il faut aller sur d'autres sites comme linternaute.com, accéder à la carte, mais il faudra un peu plus de temps pour récupérer toutes ces informations. Le code proposé ci-dessus récupère les coordonnées des bureaux de vote. Cela prend plusieurs heures et il faut relancer le processus quand il s'arrête pour une erreur de réseau. Il est conseillé de télécharger le résultat. Le géocodeur d'OpenStreetMap n'est pas de très bonne qualité sur la France. Il ne retourne rien dans plus d'un tiers des cas. On peut compléter avec l'API de Bing Maps.
End of explanation
import keyring, os
bing_key = keyring.get_password("bing", "actuariat_python,key")
coders = ["Nominatim"]
if bing_key:
    # si la clé a été trouvée
    coders.append(("bing", bing_key))
len(coders)
import os
if not os.path.exists("bureauxvotegeo.zip"):
    from actuariat_python.data import geocode
    from pyquickhelper.loghelper import fLOG
    fLOG(OutputPrint=True)
    bureau_geo = geocode(bureau, fLOG=fLOG, index=False, encoding="utf-8",
                         exc=False, save_every="bureau.dump.txt", sep="\t", every=100,
                         coders=coders)
else:
    print("Les données ont déjà été geocodées.")
Explanation: On récupère une clé pour utiliser l'API de Bing Maps avec le module keyring. Pour stocker son mot de passe sur la machine, il suffit d'écrire :
import keyring
keyring.get_password("bing", "actuariat_python,key")
End of explanation
import missingno
missingno.matrix(bureau_geo, figsize=(12, 6));
Explanation: On regarde les valeurs manquantes.
End of explanation
from actuariat_python.data import elections_vote_places_geo
places = elections_vote_places_geo()
places.head()
Explanation: On pourra finalement récupérer la base des géocodes comme ceci :
End of explanation
from actuariat_python.data import elections_vote_places_geo
bureau_geo = elections_vote_places_geo()
villes_geo = bureau_geo[["city", "zip", "n"]].groupby(["city", "zip"], as_index=False).count()
villes_geo.head()
from actuariat_python.data import villes_geo
villes_geo = villes_geo(as_df=True)
villes_geo.head()
import keyring, os
bing_key = keyring.get_password("bing", "actuariat_python,key")
coders = []
if bing_key:
    # si la clé a été trouvée
    coders.append(("bing", bing_key))
len(coders)
import os
geocode = True
if geocode:
    if os.path.exists("villes_geo.txt"):
        import pandas
        villes_geo = pandas.read_csv("villes_geo.txt", sep="\t", encoding="utf-8")
    else:
        from actuariat_python.data import geocode
        from pyquickhelper.loghelper import fLOG
        fLOG(OutputPrint=True)
        villes_geo = geocode(villes_geo, fLOG=fLOG, index=False, encoding="utf-8",
                             exc=False, save_every="villes.dump.txt", sep="\t", every=100,
                             coders=coders, country="France")
villes_geo.head()
Explanation: Géolocalisation des villes
End of explanation
villes_geo.to_csv("villes_geo.txt", sep="\t", index=False, encoding="utf-8")
villes_geo.shape
Explanation: On conserve les données pour éviter de les reconstuire et faire appel à l'API Bing à nouveau.
End of explanation
from pyensae.datasource import download_data
shp_vote = download_data("base_cartelec_2007_2010.zip")
shp_vote
# La version 2.0.0.dev de pyshp est buggée. Il vaut mieux ne pas l'utiliser.
import shapefile
if "dev" in shapefile.__version__:
    raise ImportError("Use a different version of pyshp not '{0}'".format(shapefile.__version__))
r = shapefile.Reader("fond0710.shp", encoding="utf8", encodingErrors="ignore")
shapes = r.shapes()
records = r.records()
len(shapes), len(records)
{k[0]: v for k, v in zip(r.fields, records[0])}
shapes[0].points
Explanation: Géolocation des bureaux de vote avec Cartélec
Le site cartelec recense beaucoup plus de bureaux de vote mais pour les élections 2007. Ils ne devraient pas avoir changé beaucoup.
End of explanation
<END_TASK>