diff --git a/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-01-Introduction-Python.ipynb b/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-01-Introduction-Python.ipynb index 23f66a63e9..75007ecc8b 100644 --- a/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-01-Introduction-Python.ipynb +++ b/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-01-Introduction-Python.ipynb @@ -16,7 +16,7 @@ "source": [ "# Z3-Python 01 — Introduction a la resolution de contraintes SMT\n", "\n", - "**Navigation** : [Index](README.md) | [Z3-Python-02 Sudoku >>](Z3-02-Sudoku-Python.ipynb) | [Twin C# 01](Z3-01-Introduction-CSharp.ipynb)\n", + "**Navigation** : [Index](README.md) | [Z3-Python-01b (style declaratif) >>](Z3-01b-Style-Declaratif-Linq.ipynb) | [Twin C# 01](Z3-01-Introduction-CSharp.ipynb)\n", "\n", "## Objectifs d'apprentissage\n", "\n", diff --git a/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-08-Ordonnancement-Python.ipynb b/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-08-Ordonnancement-Python.ipynb index a53d12877f..0d08d6c5f2 100644 --- a/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-08-Ordonnancement-Python.ipynb +++ b/MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-08-Ordonnancement-Python.ipynb @@ -5,10 +5,10 @@ "id": "c0", "metadata": { "papermill": { - "duration": 0.003723, - "end_time": "2026-09-26T19:41:57.904939", + "duration": 0.003977, + "end_time": "2026-10-02T01:37:30.633951+00:00", "exception": false, - "start_time": "2026-09-26T19:41:57.901216", + "start_time": "2026-10-02T01:37:30.629974+00:00", "status": "completed" }, "tags": [] @@ -16,7 +16,7 @@ "source": [ "# Z3-Python-08 : Ordonnancement de tâches (Job-Shop Scheduling)\n", "\n", - "[← Serie Z3-Python](README.md) | [Z3-Python-01b (style declaratif LINQ) →](Z3-01b-Style-Declaratif-Linq.ipynb)\n", + "[← Serie Z3-Python](README.md) | [Z3-Python-09 (énigme d'Einstein) →](Z3-09-Enigme-Einstein-Python.ipynb)\n", "\n", "## Le problème\n", "\n", @@ -37,16 +37,16 @@ "id": "c1", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:57.913749Z", - "iopub.status.busy": "2026-09-26T19:41:57.913522Z", - "iopub.status.idle": "2026-09-26T19:41:58.997932Z", - "shell.execute_reply": "2026-09-26T19:41:58.996551Z" + "iopub.execute_input": "2026-10-02T01:37:30.643245Z", + "iopub.status.busy": "2026-10-02T01:37:30.642974Z", + "iopub.status.idle": "2026-10-02T01:37:31.316551Z", + "shell.execute_reply": "2026-10-02T01:37:31.315465Z" }, "papermill": { - "duration": 1.08961, - "end_time": "2026-09-26T19:41:58.999188", + "duration": 0.678936, + "end_time": "2026-10-02T01:37:31.317486+00:00", "exception": false, - "start_time": "2026-09-26T19:41:57.909578", + "start_time": "2026-10-02T01:37:30.638550+00:00", "status": "completed" }, "tags": [] @@ -81,10 +81,10 @@ "id": "c2", "metadata": { "papermill": { - "duration": 0.003295, - "end_time": "2026-09-26T19:41:59.007472", + "duration": 0.003144, + "end_time": "2026-10-02T01:37:31.326651+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.004177", + "start_time": "2026-10-02T01:37:31.323507+00:00", "status": "completed" }, "tags": [] @@ -109,16 +109,16 @@ "id": "c3", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.015059Z", - "iopub.status.busy": "2026-09-26T19:41:59.014480Z", - "iopub.status.idle": "2026-09-26T19:41:59.022051Z", - "shell.execute_reply": "2026-09-26T19:41:59.020526Z" + "iopub.execute_input": "2026-10-02T01:37:31.334104Z", + "iopub.status.busy": "2026-10-02T01:37:31.333669Z", + "iopub.status.idle": "2026-10-02T01:37:31.339325Z", + "shell.execute_reply": "2026-10-02T01:37:31.338206Z" }, "papermill": { - "duration": 0.012878, - "end_time": "2026-09-26T19:41:59.023179", + "duration": 0.010636, + "end_time": "2026-10-02T01:37:31.340217+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.010301", + "start_time": "2026-10-02T01:37:31.329581+00:00", "status": "completed" }, "tags": [] @@ -157,10 +157,10 @@ "id": "af7a5d35", "metadata": { "papermill": { - "duration": 0.003324, - "end_time": "2026-09-26T19:41:59.031538", + "duration": 0.003334, + "end_time": "2026-10-02T01:37:31.346866+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.028214", + "start_time": "2026-10-02T01:37:31.343532+00:00", "status": "completed" }, "tags": [] @@ -183,10 +183,10 @@ "id": "c4", "metadata": { "papermill": { - "duration": 0.005989, - "end_time": "2026-09-26T19:41:59.041905", + "duration": 0.003438, + "end_time": "2026-10-02T01:37:31.353901+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.035916", + "start_time": "2026-10-02T01:37:31.350463+00:00", "status": "completed" }, "tags": [] @@ -205,16 +205,16 @@ "id": "c5", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.054990Z", - "iopub.status.busy": "2026-09-26T19:41:59.054346Z", - "iopub.status.idle": "2026-09-26T19:41:59.065515Z", - "shell.execute_reply": "2026-09-26T19:41:59.063778Z" + "iopub.execute_input": "2026-10-02T01:37:31.364138Z", + "iopub.status.busy": "2026-10-02T01:37:31.363807Z", + "iopub.status.idle": "2026-10-02T01:37:31.370190Z", + "shell.execute_reply": "2026-10-02T01:37:31.369150Z" }, "papermill": { - "duration": 0.019932, - "end_time": "2026-09-26T19:41:59.067173", + "duration": 0.013282, + "end_time": "2026-10-02T01:37:31.371137+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.047241", + "start_time": "2026-10-02T01:37:31.357855+00:00", "status": "completed" }, "tags": [] @@ -258,10 +258,10 @@ "id": "c6", "metadata": { "papermill": { - "duration": 0.005395, - "end_time": "2026-09-26T19:41:59.078694", + "duration": 0.004169, + "end_time": "2026-10-02T01:37:31.378907+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.073299", + "start_time": "2026-10-02T01:37:31.374738+00:00", "status": "completed" }, "tags": [] @@ -284,16 +284,16 @@ "id": "c7", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.092876Z", - "iopub.status.busy": "2026-09-26T19:41:59.092268Z", - "iopub.status.idle": "2026-09-26T19:41:59.165931Z", - "shell.execute_reply": "2026-09-26T19:41:59.164258Z" + "iopub.execute_input": "2026-10-02T01:37:31.388533Z", + "iopub.status.busy": "2026-10-02T01:37:31.388181Z", + "iopub.status.idle": "2026-10-02T01:37:31.414737Z", + "shell.execute_reply": "2026-10-02T01:37:31.413628Z" }, "papermill": { - "duration": 0.083555, - "end_time": "2026-09-26T19:41:59.167610", + "duration": 0.033384, + "end_time": "2026-10-02T01:37:31.415932+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.084055", + "start_time": "2026-10-02T01:37:31.382548+00:00", "status": "completed" }, "tags": [] @@ -357,10 +357,10 @@ "id": "5f602514", "metadata": { "papermill": { - "duration": 0.00522, - "end_time": "2026-09-26T19:41:59.178214", + "duration": 0.004439, + "end_time": "2026-10-02T01:37:31.425144+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.172994", + "start_time": "2026-10-02T01:37:31.420705+00:00", "status": "completed" }, "tags": [] @@ -387,10 +387,10 @@ "id": "c8", "metadata": { "papermill": { - "duration": 0.006387, - "end_time": "2026-09-26T19:41:59.190189", + "duration": 0.004184, + "end_time": "2026-10-02T01:37:31.433930+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.183802", + "start_time": "2026-10-02T01:37:31.429746+00:00", "status": "completed" }, "tags": [] @@ -409,16 +409,16 @@ "id": "c9", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.203021Z", - "iopub.status.busy": "2026-09-26T19:41:59.202555Z", - "iopub.status.idle": "2026-09-26T19:41:59.211778Z", - "shell.execute_reply": "2026-09-26T19:41:59.210061Z" + "iopub.execute_input": "2026-10-02T01:37:31.445005Z", + "iopub.status.busy": "2026-10-02T01:37:31.444643Z", + "iopub.status.idle": "2026-10-02T01:37:31.450738Z", + "shell.execute_reply": "2026-10-02T01:37:31.449614Z" }, "papermill": { - "duration": 0.018002, - "end_time": "2026-09-26T19:41:59.213479", + "duration": 0.013256, + "end_time": "2026-10-02T01:37:31.451684+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.195477", + "start_time": "2026-10-02T01:37:31.438428+00:00", "status": "completed" }, "tags": [] @@ -467,10 +467,10 @@ "id": "41adc3b0", "metadata": { "papermill": { - "duration": 0.004753, - "end_time": "2026-09-26T19:41:59.223660", + "duration": 0.004191, + "end_time": "2026-10-02T01:37:31.459896+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.218907", + "start_time": "2026-10-02T01:37:31.455705+00:00", "status": "completed" }, "tags": [] @@ -491,10 +491,10 @@ "id": "c10", "metadata": { "papermill": { - "duration": 0.005419, - "end_time": "2026-09-26T19:41:59.234533", + "duration": 0.004535, + "end_time": "2026-10-02T01:37:31.468416+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.229114", + "start_time": "2026-10-02T01:37:31.463881+00:00", "status": "completed" }, "tags": [] @@ -513,16 +513,16 @@ "id": "c11", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.248273Z", - "iopub.status.busy": "2026-09-26T19:41:59.247781Z", - "iopub.status.idle": "2026-09-26T19:41:59.581315Z", - "shell.execute_reply": "2026-09-26T19:41:59.580143Z" + "iopub.execute_input": "2026-10-02T01:37:31.479112Z", + "iopub.status.busy": "2026-10-02T01:37:31.478835Z", + "iopub.status.idle": "2026-10-02T01:37:31.724019Z", + "shell.execute_reply": "2026-10-02T01:37:31.723149Z" }, "papermill": { - "duration": 0.342087, - "end_time": "2026-09-26T19:41:59.582267", + "duration": 0.251557, + "end_time": "2026-10-02T01:37:31.724716+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.240180", + "start_time": "2026-10-02T01:37:31.473159+00:00", "status": "completed" }, "tags": [] @@ -579,10 +579,10 @@ "id": "c370df18", "metadata": { "papermill": { - "duration": 0.003361, - "end_time": "2026-09-26T19:41:59.589200", + "duration": 0.005686, + "end_time": "2026-10-02T01:37:31.735473+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.585839", + "start_time": "2026-10-02T01:37:31.729787+00:00", "status": "completed" }, "tags": [] @@ -602,10 +602,10 @@ "id": "c12", "metadata": { "papermill": { - "duration": 0.006171, - "end_time": "2026-09-26T19:41:59.598647", + "duration": 0.004147, + "end_time": "2026-10-02T01:37:31.745081+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.592476", + "start_time": "2026-10-02T01:37:31.740934+00:00", "status": "completed" }, "tags": [] @@ -623,10 +623,10 @@ "id": "c13", "metadata": { "papermill": { - "duration": 0.00473, - "end_time": "2026-09-26T19:41:59.607419", + "duration": 0.003444, + "end_time": "2026-10-02T01:37:31.752328+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.602689", + "start_time": "2026-10-02T01:37:31.748884+00:00", "status": "completed" }, "tags": [] @@ -645,16 +645,16 @@ "id": "c14", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.620005Z", - "iopub.status.busy": "2026-09-26T19:41:59.619570Z", - "iopub.status.idle": "2026-09-26T19:41:59.626897Z", - "shell.execute_reply": "2026-09-26T19:41:59.625122Z" + "iopub.execute_input": "2026-10-02T01:37:31.762230Z", + "iopub.status.busy": "2026-10-02T01:37:31.761862Z", + "iopub.status.idle": "2026-10-02T01:37:31.766408Z", + "shell.execute_reply": "2026-10-02T01:37:31.765498Z" }, "papermill": { - "duration": 0.015871, - "end_time": "2026-09-26T19:41:59.627994", + "duration": 0.011601, + "end_time": "2026-10-02T01:37:31.767837+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.612123", + "start_time": "2026-10-02T01:37:31.756236+00:00", "status": "completed" }, "tags": [] @@ -687,10 +687,10 @@ "id": "c15", "metadata": { "papermill": { - "duration": 0.005117, - "end_time": "2026-09-26T19:41:59.636580", + "duration": 0.004873, + "end_time": "2026-10-02T01:37:31.776939+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.631463", + "start_time": "2026-10-02T01:37:31.772066+00:00", "status": "completed" }, "tags": [] @@ -698,9 +698,9 @@ "source": [ "### Exercice 2 -- Contrainte d'urgence (deadline)\n", "\n", - "**Objectif** : imposer que le job `J0` termine avant $t = 7$ (deadline). Ajoutez cette contrainte au modèle et verifyez que le makespan optimal augmente (la deadline force un ordonnancement moins efficace).\n", + "**Objectif** : le job `J1` vient de passer urgent : imposez qu'il termine avant $t = 6$ (dans l'ordonnancement optimal exhibé plus haut, J1 termine à $t = 8$). Ajoutez cette contrainte au modèle et verifyez que le makespan optimal augmente — mesuré au solveur, Cmax passe de 8 à 9 : la deadline force un ordonnancement moins efficace.\n", "\n", - "**Indices** : la fin de J0 est `start[\"J0\"][-1] + duree_derniere_op` ; ajoutez `opt.add(... <= 7)` avant `opt.minimize`. Modifiez `solve_jobshop` ou créez une variante." + "**Indices** : la fin de J1 est `start[\"J1\"][-1] + duree_derniere_op` ; ajoutez `opt.add(... <= 6)` avant `opt.minimize`. Modifiez `solve_jobshop` ou créez une variante." ] }, { @@ -709,16 +709,16 @@ "id": "c16", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.647617Z", - "iopub.status.busy": "2026-09-26T19:41:59.647322Z", - "iopub.status.idle": "2026-09-26T19:41:59.652445Z", - "shell.execute_reply": "2026-09-26T19:41:59.650962Z" + "iopub.execute_input": "2026-10-02T01:37:31.786527Z", + "iopub.status.busy": "2026-10-02T01:37:31.786141Z", + "iopub.status.idle": "2026-10-02T01:37:31.791545Z", + "shell.execute_reply": "2026-10-02T01:37:31.790332Z" }, "papermill": { - "duration": 0.014053, - "end_time": "2026-09-26T19:41:59.654305", + "duration": 0.01142, + "end_time": "2026-10-02T01:37:31.792486+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.640252", + "start_time": "2026-10-02T01:37:31.781066+00:00", "status": "completed" }, "tags": [] @@ -728,22 +728,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "Exercice 2 a completer : mesurer le surcout d'une deadline sur J0.\n" + "Exercice 2 a completer : mesurer le surcout d'une deadline sur J1.\n" ] } ], "source": [ - "# Exercice 2 : ajoutez une deadline (J0 doit terminer avant t=7).\n", - "# Indice : opt.add(start[\"J0\"][-1] + jobs[\"J0\"][-1][1] <= 7) avant opt.minimize.\n", - "# Etape 1 : copiez solve_jobshop en solve_jobshop_deadline(jobs, machines, deadline_j0=7).\n", + "# Exercice 2 : ajoutez une deadline (J1 doit terminer avant t=6).\n", + "# Indice : opt.add(start[\"J1\"][-1] + jobs[\"J1\"][-1][1] <= 6) avant opt.minimize.\n", + "# Etape 1 : copiez solve_jobshop en solve_jobshop_deadline(jobs, machines, deadline_j1=6).\n", "# Etape 2 : resolvez et comparez le Cmax a opt_cmax (sans deadline).\n", "\n", - "def solve_jobshop_deadline(jobs, machine_names, deadline_j0=7):\n", - " \"\"\"Job-shop avec une deadline sur J0.\"\"\"\n", + "def solve_jobshop_deadline(jobs, machine_names, deadline_j1=6):\n", + " \"\"\"Job-shop avec une deadline sur J1.\"\"\"\n", " # TODO etudiant : modeliser + ajouter la deadline + minimiser\n", " return None\n", "\n", - "print(\"Exercice 2 a completer : mesurer le surcout d'une deadline sur J0.\")" + "print(\"Exercice 2 a completer : mesurer le surcout d'une deadline sur J1.\")" ] }, { @@ -751,10 +751,10 @@ "id": "c17", "metadata": { "papermill": { - "duration": 0.004922, - "end_time": "2026-09-26T19:41:59.663244", + "duration": 0.00403, + "end_time": "2026-10-02T01:37:31.802276+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.658322", + "start_time": "2026-10-02T01:37:31.798246+00:00", "status": "completed" }, "tags": [] @@ -773,16 +773,16 @@ "id": "c18", "metadata": { "execution": { - "iopub.execute_input": "2026-09-26T19:41:59.677465Z", - "iopub.status.busy": "2026-09-26T19:41:59.676783Z", - "iopub.status.idle": "2026-09-26T19:41:59.682916Z", - "shell.execute_reply": "2026-09-26T19:41:59.681556Z" + "iopub.execute_input": "2026-10-02T01:37:31.812724Z", + "iopub.status.busy": "2026-10-02T01:37:31.812285Z", + "iopub.status.idle": "2026-10-02T01:37:31.817787Z", + "shell.execute_reply": "2026-10-02T01:37:31.816594Z" }, "papermill": { - "duration": 0.015625, - "end_time": "2026-09-26T19:41:59.684541", + "duration": 0.012547, + "end_time": "2026-10-02T01:37:31.818718+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.668916", + "start_time": "2026-10-02T01:37:31.806171+00:00", "status": "completed" }, "tags": [] @@ -816,10 +816,10 @@ "id": "c19", "metadata": { "papermill": { - "duration": 0.006428, - "end_time": "2026-09-26T19:41:59.697666", + "duration": 0.00462, + "end_time": "2026-10-02T01:37:31.828497+00:00", "exception": false, - "start_time": "2026-09-26T19:41:59.691238", + "start_time": "2026-10-02T01:37:31.823877+00:00", "status": "completed" }, "tags": [] @@ -869,18 +869,18 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.13" + "version": "3.13.7" }, "papermill": { "default_parameters": {}, - "duration": 4.394621, - "end_time": "2026-09-26T19:42:00.046437", + "duration": 3.590764, + "end_time": "2026-10-02T01:37:32.287546+00:00", "environment_variables": {}, "exception": null, "input_path": "MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-08-Ordonnancement-Python.ipynb", - "output_path": "MyIA.AI.Notebooks/SymbolicAI/SMT/Z3-API/Z3-08-Ordonnancement-Python.ipynb", + "output_path": "Z3-08-Ordonnancement-Python.ipynb", "parameters": {}, - "start_time": "2026-09-26T19:41:55.651816", + "start_time": "2026-10-02T01:37:28.696782+00:00", "version": "2.6.0" } }, diff --git a/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction.yaml b/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction.yaml index 08947804bf..6f22ee891a 100644 --- a/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction.yaml +++ b/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction.yaml @@ -6,6 +6,7 @@ bridge_verdict: SOTA-OK bridge_verdict_reason: "Z3 EST le moteur SOTA SMT, branche NATIVEMENT des deux cotes : Microsoft.Z3 (NuGet officiel, `#r \"nuget: Microsoft.Z3\"` + `using Microsoft.Z3;`, API Context ctx.MkSolver/MkConst) et pyz3 (pip z3-solver, `from z3 import *`, API fonctionnelle Solver()/Int()) sont les deux bindings de la meme lib C++ Z3 sous-jacente — pas un pont intermediaire type IKVM/PythonNet. Parite firsthand sur le concept central (SMT de base, contrainte insatisfiable) cellule 5 des deux notebooks : Python pyz3 `s.check() -> unsat` (x>5 ET x<3) == C# Microsoft.Z3 `s.check() -> UNSATISFIABLE`, meme verdict du meme moteur. Aucune asymetrie de machinerie a corriger." known_differences: + - "2026-10-02 lane myia-po-2024:CoursIA-2 : nav Python seul -- fleche avant 01->01b retablie (ordre canonique de la serie, fix #17419 ; l'ancienne fleche erronee de Z3-08 vers 01b etait son seul rattachement). 01b est Python-only, aucun equivalent C# a faire evoluer. Edition markdown-only, aucune cellule code touchee, sorties C.2 inchangees." - "Python : pyz3 (z3-solver), `from z3 import *`, API fonctionnelle (Solver(), Int('x'), s.check() -> sat/unsat)." - "C# : Microsoft.Z3 .NET, `using Microsoft.Z3;`, API orientee Context (ctx.MkSolver(), ctx.MkConst(...), Status.TRUE)." - "Concept demontre (SMT de base, x>=10 & x<=2 -> unsat) verifie firsthand cote Python (NB-01 CLEAN)." diff --git a/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction/0009-2026-10-02-myia-po-2024-CoursIA-2.yaml b/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction/0009-2026-10-02-myia-po-2024-CoursIA-2.yaml new file mode 100644 index 0000000000..a28dfb3910 --- /dev/null +++ b/scripts/notebook_tools/twin_pairs.d/z3-python-01-introduction/0009-2026-10-02-myia-po-2024-CoursIA-2.yaml @@ -0,0 +1,6 @@ +date: '2026-10-02' +by: myia-po-2024:CoursIA-2 +python_sha: 75007ecc8b1a43c8d66d52394830eb3d7f9bbc11 +csharp_sha: 0530f828918f4df7f69e62e5bf61582df8142558 +content_python_sha: 4c8990a8980101257a5248576cb3c94d781d00e249d0bbd11ce33259a97f30e4 +content_csharp_sha: 2f2ab65fc8a47bf6810e3ba09857765384d064a92fb978d63bf48ee6c55e58cf