From 8ac9923e0b8b6ce73955da1c2bd9bee41b5594a4 Mon Sep 17 00:00:00 2001 From: xadupre Date: Sun, 31 Aug 2025 20:13:54 +0200 Subject: [PATCH 1/2] fix manifest --- MANIFEST.in | 1 - 1 file changed, 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 3ef723e0..5dac992e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,7 +2,6 @@ prune _doc prune _unittests prune _todo prune bin -prune .circleci exclude *.bat exclude *.yml exclude *.git* From 6404692aa0c7838df1adcbcfc0ac4dddf3308bf2 Mon Sep 17 00:00:00 2001 From: xadupre Date: Thu, 4 Sep 2025 23:49:18 +0200 Subject: [PATCH 2/2] notebook seance --- _doc/articles/2025/2025-09-03-ensae.rst | 1 + _doc/articles/2025/2025-11-31-route2025.rst | 3 + _doc/practice/years/2025/index.rst | 9 + .../practice/years/2025/seance1_point2d.ipynb | 314 ++++++++++++++++++ _doc/practice/years/index.rst | 2 + .../test_documentation_notebook.py | 1 + .../ut_xrun_doc/test_normalize_notebook.py | 1 + clean.sh | 6 + 8 files changed, 337 insertions(+) create mode 100644 _doc/practice/years/2025/index.rst create mode 100644 _doc/practice/years/2025/seance1_point2d.ipynb create mode 100644 clean.sh diff --git a/_doc/articles/2025/2025-09-03-ensae.rst b/_doc/articles/2025/2025-09-03-ensae.rst index 8b6ac7b0..786dacd4 100644 --- a/_doc/articles/2025/2025-09-03-ensae.rst +++ b/_doc/articles/2025/2025-09-03-ensae.rst @@ -69,6 +69,7 @@ A qui appartient le code écrit ? * exercices sur des algortihmes :ref:`l-algo` * examens passés :ref:`l-exams` * `Des aspects plus mathématiques d'algorithmes `_ +* :ref:`l-notebook-2025` **Getting Started** diff --git a/_doc/articles/2025/2025-11-31-route2025.rst b/_doc/articles/2025/2025-11-31-route2025.rst index 8a4efe7d..b8c22220 100644 --- a/_doc/articles/2025/2025-11-31-route2025.rst +++ b/_doc/articles/2025/2025-11-31-route2025.rst @@ -5,8 +5,11 @@ Le plan des séances est parfois changé après que celles-ci ont eu lieu. +Notebooks écrits en séances : :ref:`l-notebook-2025`. + Suggestions de sujets pour les séances. + Séance 1 ++++++++ diff --git a/_doc/practice/years/2025/index.rst b/_doc/practice/years/2025/index.rst new file mode 100644 index 00000000..5ef3eca8 --- /dev/null +++ b/_doc/practice/years/2025/index.rst @@ -0,0 +1,9 @@ +.. _l-notebook-2025: + +2025 +==== + +.. toctree:: + :maxdepth: 1 + + seance1_point2d diff --git a/_doc/practice/years/2025/seance1_point2d.ipynb b/_doc/practice/years/2025/seance1_point2d.ipynb new file mode 100644 index 00000000..ed392f28 --- /dev/null +++ b/_doc/practice/years/2025/seance1_point2d.ipynb @@ -0,0 +1,314 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction aux classes\n", + "\n", + "Ce notebook part d'une classe représentant un point en deux dimensions pour aller jusqu'au calcul de la surface d'un polygone quel qu'il soit. La plupart des réponses ont été guidées par LeChat." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class Point2D:\n", + " def __init__(self, x=0, y=0):\n", + " self.x = x\n", + " self.y = y\n", + "\n", + " def __repr__(self):\n", + " return f\"Point2D({self.x}, {self.y})\"\n", + "\n", + " def __eq__(self, other):\n", + " if isinstance(other, Point2D):\n", + " return self.x == other.x and self.y == other.y\n", + " return False\n", + "\n", + " def distance_to(self, other):\n", + " \"\"\"Calcule la distance entre deux points.\"\"\"\n", + " return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5\n", + "\n", + " @staticmethod\n", + " def intersection_point(p1, p2, p3, p4):\n", + " \"\"\"Retourne le point d'intersection des segments p1p2 et p3p4, ou None si pas d'intersection.\"\"\"\n", + " # Calcul des coefficients des droites\n", + " a1 = p2.y - p1.y\n", + " b1 = p1.x - p2.x\n", + " c1 = a1 * p1.x + b1 * p1.y\n", + "\n", + " a2 = p4.y - p3.y\n", + " b2 = p3.x - p4.x\n", + " c2 = a2 * p3.x + b2 * p3.y\n", + "\n", + " det = a1 * b2 - a2 * b1\n", + " if det == 0:\n", + " return None # Droites parallèles\n", + "\n", + " x = (b2 * c1 - b1 * c2) / det\n", + " y = (a1 * c2 - a2 * c1) / det\n", + "\n", + " # Vérifie que le point est bien sur les deux segments\n", + " if (\n", + " min(p1.x, p2.x) <= x <= max(p1.x, p2.x)\n", + " and min(p1.y, p2.y) <= y <= max(p1.y, p2.y)\n", + " and min(p3.x, p4.x) <= x <= max(p3.x, p4.x)\n", + " and min(p3.y, p4.y) <= y <= max(p3.y, p4.y)\n", + " ):\n", + " return Point2D(x, y)\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Point2D(3, 4)\n", + "5.0\n" + ] + } + ], + "source": [ + "p1 = Point2D(3, 4)\n", + "p2 = Point2D(6, 8)\n", + "print(p1) # Affiche : Point2D(3, 4)\n", + "print(p1.distance_to(p2))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "class Polygone:\n", + " def __init__(self, points=None):\n", + " if points is None:\n", + " self.points = []\n", + " else:\n", + " self.points = list(points)\n", + "\n", + " def __repr__(self):\n", + " return f\"Polygone({self.points})\"\n", + "\n", + " def ajouter_point(self, point):\n", + " \"\"\"Ajoute un point au polygone.\"\"\"\n", + " self.points.append(point)\n", + "\n", + " def perimetre(self):\n", + " \"\"\"Calcule le périmètre du polygone.\"\"\"\n", + " if len(self.points) < 2:\n", + " return 0.0\n", + " perimetre = 0.0\n", + " for i in range(len(self.points)):\n", + " p1 = self.points[i]\n", + " p2 = self.points[(i + 1) % len(self.points)]\n", + " perimetre += p1.distance_to(p2)\n", + " return perimetre\n", + "\n", + " def aire(self):\n", + " \"\"\"Calcule l'aire du polygone en utilisant la formule du shoelace.\"\"\"\n", + " if len(self.points) < 3:\n", + " return 0.0\n", + " aire = 0.0\n", + " n = len(self.points)\n", + " for i in range(n):\n", + " x_i, y_i = self.points[i].x, self.points[i].y\n", + " x_j, y_j = self.points[(i + 1) % n].x, self.points[(i + 1) % n].y\n", + " aire += (x_i * y_j) - (x_j * y_i)\n", + " return abs(aire) / 2.0\n", + "\n", + " def tracer(self, titre=\"Polygone\", couleur=\"blue\"):\n", + " \"\"\"Trace le polygone dans un notebook avec les indices des points.\"\"\"\n", + " if len(self.points) < 2:\n", + " print(\"Pas assez de points pour tracer.\")\n", + " return\n", + "\n", + " x = [p.x for p in self.points]\n", + " y = [p.y for p in self.points]\n", + "\n", + " # On ferme le polygone en ajoutant le premier point à la fin\n", + " x.append(self.points[0].x)\n", + " y.append(self.points[0].y)\n", + "\n", + " plt.figure()\n", + " plt.plot(x, y, marker=\"o\", color=couleur)\n", + "\n", + " # Ajout des indices des points\n", + " for i, (xi, yi) in enumerate(zip(x[:-1], y[:-1])):\n", + " plt.text(xi, yi, f\" {i}\", color=\"red\", fontsize=12)\n", + "\n", + " plt.title(titre)\n", + " plt.xlabel(\"X\")\n", + " plt.ylabel(\"Y\")\n", + " plt.grid(True)\n", + " plt.axis(\"equal\")\n", + " plt.show()\n", + "\n", + " def premier_point_intersection_segments(self):\n", + " \"\"\"Retourne les coordonnées du premier point d'intersection entre deux segments,\n", + " ainsi que les indices des premières extrémités de chacun des segments.\n", + " Retourne (None, None, None) si pas d'intersection.\"\"\"\n", + " n = len(self.points)\n", + " for i in range(n):\n", + " for j in range(i + 1, n):\n", + " p1 = self.points[i]\n", + " p2 = self.points[(i + 1) % n]\n", + " p3 = self.points[j]\n", + " p4 = self.points[(j + 1) % n]\n", + " pt_inter = Point2D.intersection_point(p1, p2, p3, p4)\n", + " if pt_inter is not None:\n", + " return pt_inter, i, j\n", + " return None, None, None\n", + "\n", + " def inserer_point_intersection(self, i, j, point):\n", + " \"\"\"Insère le point d'intersection après i et après j dans la liste des points.\n", + " Attention : cela modifie la liste des points du polygone.\n", + " \"\"\"\n", + " if i >= len(self.points) or j >= len(self.points):\n", + " raise ValueError(\"Indices invalides\")\n", + " # On insère d'abord après le plus grand indice pour ne pas décaler l'autre\n", + " if i > j:\n", + " self.points.insert(j + 1, point)\n", + " self.points.insert(i + 2, point) # +2 car la liste a déjà grandi\n", + " else:\n", + " self.points.insert(i + 1, point)\n", + " self.points.insert(j + 2, point) # +2 car la liste a déjà grandi" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Polygone([Point2D(0, 0), Point2D(4, 0), Point2D(4, 3), Point2D(0, 3)])\n", + "14.0\n" + ] + } + ], + "source": [ + "p1 = Point2D(0, 0)\n", + "p2 = Point2D(4, 0)\n", + "p3 = Point2D(4, 3)\n", + "p4 = Point2D(0, 3)\n", + "\n", + "poly = Polygone([p1, p2, p3, p4])\n", + "print(\n", + " poly\n", + ") # Affiche : Polygone([Point2D(0, 0), Point2D(4, 0), Point2D(4, 3), Point2D(0, 3)])\n", + "print(poly.perimetre()) # Affiche : 14.0" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12.0\n" + ] + } + ], + "source": [ + "p1 = Point2D(0, 0)\n", + "p2 = Point2D(4, 0)\n", + "p3 = Point2D(4, 3)\n", + "p4 = Point2D(0, 3)\n", + "\n", + "poly = Polygone([p1, p2, p3, p4])\n", + "print(poly.aire()) # Affiche : 12.0" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0\n" + ] + } + ], + "source": [ + "p1 = Point2D(0, 0)\n", + "p2 = Point2D(0, 1)\n", + "p3 = Point2D(1, 0)\n", + "p4 = Point2D(1, 1)\n", + "\n", + "poly = Polygone([p1, p2, p3, p4])\n", + "print(poly.aire()) # Affiche : 12.0" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "poly.tracer(titre=\"Mon rectangle\", couleur=\"red\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/_doc/practice/years/index.rst b/_doc/practice/years/index.rst index afb27338..69e0eb2f 100644 --- a/_doc/practice/years/index.rst +++ b/_doc/practice/years/index.rst @@ -5,3 +5,5 @@ Notebooks écrits durant les séances :maxdepth: 2 2023/index + 2025/index + diff --git a/_unittests/ut_xrun_doc/test_documentation_notebook.py b/_unittests/ut_xrun_doc/test_documentation_notebook.py index ea872a22..315f3edf 100644 --- a/_unittests/ut_xrun_doc/test_documentation_notebook.py +++ b/_unittests/ut_xrun_doc/test_documentation_notebook.py @@ -171,6 +171,7 @@ def add_test_methods(cls): os.path.join(this, "..", "..", "_doc", "practice", "py-base"), os.path.join(this, "..", "..", "_doc", "practice", "tds-base"), os.path.join(this, "..", "..", "_doc", "practice", "years", "2023"), + os.path.join(this, "..", "..", "_doc", "practice", "years", "2025"), ] for fold in folds: cls.add_test_methods_path( diff --git a/_unittests/ut_xrun_doc/test_normalize_notebook.py b/_unittests/ut_xrun_doc/test_normalize_notebook.py index e508839a..45e7c66e 100644 --- a/_unittests/ut_xrun_doc/test_normalize_notebook.py +++ b/_unittests/ut_xrun_doc/test_normalize_notebook.py @@ -76,6 +76,7 @@ def add_test_methods(cls): os.path.join(this, "..", "..", "_doc", "practice", "py-base"), os.path.join(this, "..", "..", "_doc", "practice", "tds-base"), os.path.join(this, "..", "..", "_doc", "practice", "years", "2023"), + os.path.join(this, "..", "..", "_doc", "practice", "years", "2025"), ] for fold in folds: cls.add_test_methods_path(os.path.normpath(fold)) diff --git a/clean.sh b/clean.sh new file mode 100644 index 00000000..73e51b6f --- /dev/null +++ b/clean.sh @@ -0,0 +1,6 @@ +rm temp_notebooks -rf +rm data.bin +rm essai.txt +rm *.bin +rm *.prof +rm *.log