{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Séance 1 TP — Rappels & prise en main de NetworkX\n",
        "\n",
        "## Objectifs pédagogiques\n",
        "- Réviser les définitions : nœuds, arêtes, graphes dirigés / non-dirigés / pondérés.\n",
        "- Prendre en main `networkx` pour créer un graphe et le visualiser.\n",
        "- Explorer des propriétés simples (degré, nombre de sommets et d’arêtes).\n",
        "- Introduire graphes dirigés et pondérés.\n",
        "\n",
        "## Contexte sociologique\n",
        "Les graphes servent à modéliser les relations sociales :\n",
        "- Graphe non dirigé : relations symétriques (amitié, collaboration).\n",
        "- Graphe dirigé : relations asymétriques (qui suit qui sur Twitter).\n",
        "- Graphe pondéré : intensité des relations (fréquence de contact).\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# %pip install networkx matplotlib\n",
        "\n",
        "import networkx as nx\n",
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Exercice 1 : Créer un graphe non dirigé"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Construisons un mini-réseau social\n",
        "G = nx.Graph()\n",
        "G.add_edges_from([\n",
        "    (\"Alice\", \"Bob\"),\n",
        "    (\"Bob\", \"Claire\"),\n",
        "    (\"Alice\", \"David\"),\n",
        "    (\"Claire\", \"David\"),\n",
        "])\n",
        "\n",
        "print(\"Nœuds :\", list(G.nodes()))\n",
        "print(\"Arêtes:\", list(G.edges()))\n",
        "\n",
        "plt.figure()\n",
        "nx.draw(G, with_labels=True, node_color=\"lightblue\", node_size=1000)\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**Questions :**\n",
        "1. Qui a le plus de voisins / voisines  (ami-e-s) ?\n",
        "2. Quelles sont les relations réciproques ?\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Exercice 2 : Explorer les propriétés du graphe"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "print(\"Nombre de sommets :\", G.number_of_nodes())\n",
        "print(\"Nombre d'arêtes :\", G.number_of_edges())\n",
        "print(\"Degrés de chaque sommet :\", dict(G.degree()))\n",
        "print(\"Degré moyen :\", sum(dict(G.degree()).values())/G.number_of_nodes())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**Question :** Quel est le degré moyen et comment l’interpréter sociologiquement ?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Exercice 3 : Graphe dirigé"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "DG = nx.DiGraph()\n",
        "DG.add_edges_from([\n",
        "    (\"Alice\", \"Bob\"),\n",
        "    (\"Bob\", \"Claire\"),\n",
        "    (\"Claire\", \"Alice\")\n",
        "])\n",
        "\n",
        "plt.figure()\n",
        "nx.draw(DG, with_labels=True, node_color=\"lightgreen\", node_size=1000, arrows=True)\n",
        "plt.show()\n",
        "\n",
        "print(\"Degré sortant :\", dict(DG.out_degree()))\n",
        "print(\"Degré entrant :\", dict(DG.in_degree()))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**Questions :**\n",
        "1. Quelle différence avec le graphe non dirigé ?\n",
        "2. Que représentent les degrés entrants et sortants sociologiquement (ex : followers) ?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Exercice 4 : Graphe pondéré"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "WG = nx.Graph()\n",
        "WG.add_edge(\"Alice\", \"Bob\", weight=5)   # forte relation\n",
        "WG.add_edge(\"Alice\", \"Claire\", weight=1) # relation faible\n",
        "\n",
        "print(\"Arêtes avec poids :\", WG.edges(data=True))\n",
        "\n",
        "# Dessin avec poids visibles\n",
        "pos = nx.spring_layout(WG)\n",
        "nx.draw(WG, pos, with_labels=True, node_color=\"lightcoral\", node_size=1000)\n",
        "labels = nx.get_edge_attributes(WG, \"weight\")\n",
        "nx.draw_networkx_edge_labels(WG, pos, edge_labels=labels)\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**Questions :**\n",
        "1. Comment interpréter le poids d’une relation en sociologie ?\n",
        "2. Donnez un exemple concret (fréquence de discussions, intensité d’une amitié)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.x"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
