Skip to content

Instantly share code, notes, and snippets.

@evilz
Created November 21, 2020 11:35
Show Gist options
  • Save evilz/0dbcaad5ade7d9f746bbb954b926a51a to your computer and use it in GitHub Desktop.
Save evilz/0dbcaad5ade7d9f746bbb954b926a51a to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Prerequis\n",
"\n",
"- Visual Studio Code Insider\n",
"- .NET 5\n",
"- .NET Interactive Notebooks extension.\n",
"\n",
"\n",
"Nous allons utiliser une API fournie par le `gouv.fr` : https://geo.api.gouv.fr/decoupage-administratif\n",
"Cette api permet de récuperer les Communes, Départements et Régions Françaises !\n",
"\n",
"Je créer un client à partir d'un swagger en utilisant le Swagger Type Provider disponible en F#.\n",
"On commence par installer le package **nuget** grace à la directive `#r \\\"nuget:xxxxx\\\"`"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"#!fsharp\n",
"#r \"nuget:SwaggerProvider\""
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Installed package SwaggerProvider version 0.10.7"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"C'est ici que l'on devient Data-scientist 🤓\n",
"On va sélectionner toutes les regions et pour chacune toutes les communes puis faire la somme des populations des communes (par région) "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"#!fsharp\n",
"open System\n",
"open System.Collections.Generic\n",
"open SwaggerProvider\n",
"\n",
"let [<Literal>] Schema = \"https://geo.api.gouv.fr/definition.yml\"\n",
"type GeoAPI = OpenApiClientProvider<Schema>\n",
"\n",
"let client = GeoAPI.Client()\n",
"\n",
"let data =\n",
" client.GetRegions().Result\n",
" |> Array.Parallel.map (fun r ->\n",
" let communues = client.GetCommunes(codeRegion= r.Code).Result\n",
" r.Nom, communues |> Array.sumBy(fun c -> c.Population |> Option.defaultValue 0) )\n",
" |> Seq.fold (fun (dic:Dictionary<string,int>) (key, value) ->\n",
" dic.Add(key,value)\n",
" dic )\n",
" (new Dictionary<string,int>())\n",
"data"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/html": "<table><thead><tr><th><i>key</i></th><th>value</th></tr></thead><tbody><tr><td><div class=\"dni-plaintext\">Guadeloupe</div></td><td><div class=\"dni-plaintext\">394110</div></td></tr><tr><td><div class=\"dni-plaintext\">Martinique</div></td><td><div class=\"dni-plaintext\">376480</div></td></tr><tr><td><div class=\"dni-plaintext\">Guyane</div></td><td><div class=\"dni-plaintext\">269352</div></td></tr><tr><td><div class=\"dni-plaintext\">La R&#233;union</div></td><td><div class=\"dni-plaintext\">852924</div></td></tr><tr><td><div class=\"dni-plaintext\">Mayotte</div></td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td><div class=\"dni-plaintext\">&#206;le-de-France</div></td><td><div class=\"dni-plaintext\">12117132</div></td></tr><tr><td><div class=\"dni-plaintext\">Centre-Val de Loire</div></td><td><div class=\"dni-plaintext\">2577866</div></td></tr><tr><td><div class=\"dni-plaintext\">Bourgogne-Franche-Comt&#233;</div></td><td><div class=\"dni-plaintext\">2818338</div></td></tr><tr><td><div class=\"dni-plaintext\">Normandie</div></td><td><div class=\"dni-plaintext\">3335929</div></td></tr><tr><td><div class=\"dni-plaintext\">Hauts-de-France</div></td><td><div class=\"dni-plaintext\">6006870</div></td></tr><tr><td><div class=\"dni-plaintext\">Grand Est</div></td><td><div class=\"dni-plaintext\">5555186</div></td></tr><tr><td><div class=\"dni-plaintext\">Pays de la Loire</div></td><td><div class=\"dni-plaintext\">3737632</div></td></tr><tr><td><div class=\"dni-plaintext\">Bretagne</div></td><td><div class=\"dni-plaintext\">3306529</div></td></tr><tr><td><div class=\"dni-plaintext\">Nouvelle-Aquitaine</div></td><td><div class=\"dni-plaintext\">5935603</div></td></tr><tr><td><div class=\"dni-plaintext\">Occitanie</div></td><td><div class=\"dni-plaintext\">5808435</div></td></tr><tr><td><div class=\"dni-plaintext\">Auvergne-Rh&#244;ne-Alpes</div></td><td><div class=\"dni-plaintext\">7916889</div></td></tr><tr><td><div class=\"dni-plaintext\">Provence-Alpes-C&#244;te d&#39;Azur</div></td><td><div class=\"dni-plaintext\">5021928</div></td></tr><tr><td><div class=\"dni-plaintext\">Corse</div></td><td><div class=\"dni-plaintext\">330455</div></td></tr></tbody></table>"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Y a personne à Mayotte 🙄🤐\n",
"\n",
".NET interactive permet aussi de partager des données entre kernels !\n",
"Je vais vous montrer ça en utilisant nos données F# dans un bloc de C#, et utiliser LINQ pour convertire le dictionnaire en tableau de type anonyme."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"#!share --from fsharp data\n",
"\n",
"using System.Linq;\n",
"var regionPopulation = data.Select(kv => new { Region = kv.Key, Population = kv.Value }).ToArray();"
],
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On peut aussi faire du javascript.\n",
"Je vais utiliser une lib JS `Chart JS` pour présenter le tout dans un bar chart.\n",
"\n",
"On commence par charger le script et créer un fonction de rendu."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"#!javascript\n",
"chartRequire = interactive.configureRequire({\n",
" paths: {\n",
" chartjs: \"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js\"\n",
" }\n",
"});\n",
"\n",
"renderChart = () => {\n",
" chartRequire([\"chartjs\"], chartjs => {\n",
" \n",
" interactive.csharp\n",
" .getVariable(\"regionPopulation\")\n",
" .then(regionPopulation => {\n",
" \n",
" var labels = [];\n",
" var data = [];\n",
" const Tableau20 = ['#4E79A7', '#A0CBE8', '#F28E2B', '#FFBE7D', '#59A14F', '#8CD17D', '#B6992D', '#F1CE63', '#499894', '#86BCB6', '#E15759', '#FF9D9A', '#79706E', '#BAB0AC', '#D37295', '#FABFD2', '#B07AA1', '#D4A6C8', '#9D7660', '#D7B5A6'];\n",
"\n",
" for (const element of regionPopulation) {\n",
" labels.push(element.Region);\n",
" data.push(element.Population);\n",
" }\n",
"\n",
" new Chart(\"regionPopulationChart\", {\n",
" type: 'horizontalBar',\n",
" data: {\n",
" labels: labels,\n",
" datasets: [{\n",
" label: 'Population par région',\n",
" data: data,\n",
" backgroundColor: Tableau20\n",
" }]\n",
" },\n",
" options: {\n",
" scales: {\n",
" yAxes: [{\n",
" ticks: {\n",
" beginAtZero: true\n",
" }\n",
" }]\n",
" }\n",
" }\n",
" });\n",
" });\n",
" });\n",
"};"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/html": "<script type=\"text/javascript\">if (typeof window.createDotnetInteractiveClient === typeof Function) {\r\ncreateDotnetInteractiveClient('http://localhost:60660/').then(function (interactive) {\r\nlet notebookScope = getDotnetInteractiveScope('http://localhost:60660/');\r\nchartRequire = interactive.configureRequire({\n paths: {\n chartjs: \"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js\"\n }\n});\n\nrenderChart = () => {\n chartRequire([\"chartjs\"], chartjs => {\n \n interactive.csharp\n .getVariable(\"regionPopulation\")\n .then(regionPopulation => {\n \n var labels = [];\n var data = [];\n const Tableau20 = ['#4E79A7', '#A0CBE8', '#F28E2B', '#FFBE7D', '#59A14F', '#8CD17D', '#B6992D', '#F1CE63', '#499894', '#86BCB6', '#E15759', '#FF9D9A', '#79706E', '#BAB0AC', '#D37295', '#FABFD2', '#B07AA1', '#D4A6C8', '#9D7660', '#D7B5A6'];\n\n for (const element of regionPopulation) {\n labels.push(element.Region);\n data.push(element.Population);\n }\n\n new Chart(\"regionPopulationChart\", {\n type: 'horizontalBar',\n data: {\n labels: labels,\n datasets: [{\n label: 'Population par région',\n data: data,\n backgroundColor: Tableau20\n }]\n },\n options: {\n scales: {\n yAxes: [{\n ticks: {\n beginAtZero: true\n }\n }]\n }\n }\n });\n });\n });\n};\r\n});\r\n}</script>"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Je vais maintenant utiliser la fonction js et afficher le tout dans un canvas HTML ! 😲"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": [
"#!javascript\n",
"#!html\n",
"<canvas id=\"regionPopulationChart\" width=\"400\" height=\"100\"></canvas>\n",
"\n",
"#!js\n",
"renderChart();"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/html": "\n<canvas id=\"regionPopulationChart\" width=\"400\" height=\"100\"></canvas>\n\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/html": "<script type=\"text/javascript\">if (typeof window.createDotnetInteractiveClient === typeof Function) {\r\ncreateDotnetInteractiveClient('http://localhost:60660/').then(function (interactive) {\r\nlet notebookScope = getDotnetInteractiveScope('http://localhost:60660/');\r\n\nrenderChart();\r\n});\r\n}</script>"
},
"execution_count": 1,
"metadata": {}
}
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "8.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment