├── README.md ├── TD ├── .gitkeep ├── TD1 │ └── td1_tableaux.ipynb ├── TD2 │ ├── 2_gui.ipynb │ └── images │ │ ├── cible.png │ │ ├── degrade_gris.png │ │ ├── degrade_rouge_bleu.png │ │ ├── fenetre_couleur.png │ │ └── mon_dessin.png ├── TD3 │ └── td_dict.ipynb ├── TD4 │ ├── files │ │ ├── .DS_Store │ │ └── zadig.txt │ └── td_file.ipynb └── TD5 │ └── td_table_hachage.ipynb ├── cours ├── 01_tableaux │ └── cours_tableaux.ipynb ├── 02_interface_graphique │ ├── 02_gui.ipynb │ ├── 800px-TkInterColorCharts.png │ ├── exo.png │ └── grid.png ├── 03_dictionnaire │ ├── cours_dict.ipynb │ └── files │ │ ├── bdp.json │ │ └── coursjava.json ├── 04_fichier │ └── cours_file.ipynb ├── 05_hachage │ └── cours_table_hachage.ipynb ├── 06_modularité │ └── cours_modularite.ipynb └── 0_cours_git │ ├── aideCoursGit.txt │ ├── fichier_free_of_rights.png │ ├── folder_free_of_rights.png │ ├── logo_uvsq.jpg │ ├── pc_free_of_rights.png │ ├── server_free_of_rights.png │ └── slides_cours_git.pdf └── projets ├── .gitkeep ├── Blackjack.pdf ├── Projet-2048.pdf ├── ProjetStatsRegLin_Enonce ├── ProjetStatsRegLin.pdf ├── exemple.txt └── villes_virgule.csv ├── Projet_Puissance 4.pdf ├── Sujet_fourmi.pdf ├── mastermind.pdf ├── pendu.pdf ├── projetCryptoIN200.pdf ├── sudoku.pdf ├── sujet de projet.pdf └── taquin.pdf /README.md: -------------------------------------------------------------------------------- 1 | # S2-python : Les notebooks + les projets 2 | 3 | # Le planning prévisionnel 2024/2025 4 | 5 | * Semaine du 10 février : pas de TD, cours 1 (rappel tableau +git) 6 | * Semaine du 17 février : TD1 (td et répartition des projets) + cours 2 (IHM) 7 | * Semaine du 24 février : Vacances 8 | * Semaine du 3 mars : TD2 (IHM), cours 3 (dict) 9 | * Semaine du 10 mars : TD3 (dict), ---> CC1 en TD 10 | * Semaine du 17 mars : TD4 (Projet + évaluation intermédiaire du projet), ---> CC2 , cours 4 (file, prog. modulaire) 11 | * Semaine 24 mars : TD5 (file), cours 5 (fct. hachage), 12 | * Semaine 31 mars : TD6 (hachage), 13 | * Semaine du 7er avril : pas de TD, Contrôle Amphi. ---> CC3 14 | * semaine 14 avril TD 7 (Projet), 15 | * semaine 21 avril vacances 16 | * Semaine 5 mai, TD 8 (soutenance projet). ---> CC4 17 | 18 | 19 | 20 | 21 | 22 | 23 | ---- 24 | * 6 CM : 25 | * 0_Rappel_tableaux (complexité) et GIT 26 | * 2_gui (TK) 27 | * 1_Dictionnaires 28 | * 3_FichiersTexte 29 | * 4 Modularité 30 | * Fonction de Hachage 31 | * 5-Contrôle 32 | 33 | # Les projets 34 | 35 | * dans chaque groupe, il faudra désigner 36 | * un responsable GitHub: c'est lui qui hébergera le projet sur son compte GitHub et invitera les autres membres; il vérifiera, entre autres, que les commits qui sont poussés sont bien fonctionnels, et qu'ils ne contiennent que des sources du projet 37 | * un responsable de la qualité du code: vérifier que les règles de style sont bien respectées, ainsi que les bonnes pratiques de programmation (nommage des fonctions et variables, docstring dans les fonctions, etc.) 38 | 39 | # Consignes pour le projet 40 | Dans le fichier README doivent apparaître les informations suivantes: le groupe de TD (filière et numéro), les noms de tous les étudiants du groupe de projet, l'url de dépôt du projet sur github; et un fichier README doit documenter l'utilisation du programme. 41 | 42 | * Une note sera donnée à la suite de la soutenance; cette note comprendra une partie collective et une partie individuelle qui tiendra compte des réponses aux questions et de la contribution de chacun, ainsi qu'aux apports de chacun au projet; 43 | 44 | * La note finale tiendra également compte de la qualité du code et du respect des consignes. 45 | 46 | * Les règles de programmation sont : 47 | 48 | * le projet doit être écrit d'une manière structurée et modulaire 49 | * il faut utiliser la librairie tkinter pour l'interface graphique 50 | 51 | **Dernières remarques** 52 | * le programme que vous fournirez doit impérativement s'exécuter sans erreurs. Ainsi, il convient de le tester et de le corriger progressivement. 53 | Les parties du programme qui ne fonctionnent pas peuvent être laissées en commentaires pour montrer le travail réalisé sans nuire à son exécution; 54 | * vos chargés de TD sont là pour vous aider donc n'hésitez pas à les contacter, et à n'hésitez pas non plus à prendre des initiatives par rapport au sujet; 55 | * si vous êtes amenés à copier une partie de code d'un autre groupe ou bien d'une source sur internet, cela doit être mentionné explicitement en commentaire de la partie concernée. **Tout plagiat ou référence qui n'est pas citée** sera sanctionné par la note 0 (pour détecter le plagiat nous utilisons des logiciels qui testent la similarité de code; noter que le changement du nom des objets ne dupe pas ces logiciels). 56 | 57 | 58 | # Environnement de programmation 59 | --- 60 | 61 | * On utilise le même environnement que pour IN100 (voir le [manuel d'installation](https://github.com/uvsq-info/l1-python/blob/master/INSTALL.md)) 62 | * Sur le campus, prêt d'ordinateur par la BU (cartable numérique) 63 | * Si vous ne parvenez pas à installer l'environnement, vous pouvez programmer en ligne sur le site [https://repl.it/](https://repl.it/) 64 | * créer un compte 65 | * créer un "new REPL" et choisir le langage Tkinter (en fait Python3 avec tkinter) 66 | 67 | 68 | # Travailler en groupe sur un projet 69 | --- 70 | 71 | * pédagogie adaptée à l'informatique pour acquérir de l'autonomie en programmation 72 | * ne pas hésiter à chercher des ressources sur internet 73 | * utile quel que soit le langage de programmation 74 | * groupes de 3-4 étudiants choisis par votre chargé de TD et qui sont fixes pour le semestre; vous ne pouvez pas en changer; 75 | * ne fonctionne que s'il y a une bonne communication dans le groupe 76 | * apprentissage par les pairs 77 | * utilisation d'outils adaptés: visio, forum, chat... par exemple discord est adapté pour tout ça, et git bien sûr 78 | * les enseignants sont là pour vous aider, encore faut-il les contacter, et pas (que) au dernier moment 79 | 80 | # Evaluation (à titre indicatif, ceci peut changer) 81 | 82 | --- 83 | * 3 évaluations en TD: 84 | * CC1. Evaluation sur 5 85 | * CC2. Evaluation sur 5 (évaluation intermédiaire du projet) 86 | * soutenance de projet 87 | * Un QCM au dernier créneau de cours 88 | 89 | * 4 notes au total: cc1 (contrôle sur table en TD), cc2=1 (note intermédiaire du projet); cc3 soutenance projet = 2, CC4 (amphi) = 3. Les notes prises en compte cc2,cc3, max(cc1,cc4) 90 | 91 | * le niveau d'exigence sera plus élevé que celui du cours IN100 92 | 93 | 94 | ## faire au cours du premier TD 95 | * Constitution des groupes par l'enseignant 96 | * Vérifier les installations de l'environnement / usage du cartable numérique 97 | -------------------------------------------------------------------------------- /TD/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/.gitkeep -------------------------------------------------------------------------------- /TD/TD1/td1_tableaux.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "deletable": false, 7 | "editable": false, 8 | "run_control": { 9 | "frozen": true 10 | } 11 | }, 12 | "source": [ 13 | "# TD : Listes en python " 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "deletable": false, 20 | "editable": false, 21 | "run_control": { 22 | "frozen": true 23 | } 24 | }, 25 | "source": [ 26 | "## Exercice 1 : Insertion dans un tableau" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "deletable": false, 33 | "editable": false, 34 | "run_control": { 35 | "frozen": true 36 | } 37 | }, 38 | "source": [ 39 | "Définir une fonction `insertion_tableau` prenant en paramètre une liste `L`, une valeur `v` et un indice `i` et insérant la valeur `v` à l'indice `i` dans `L` (fonction comparable à `L.insert(i,v)` définie en Python). \n", 40 | "\n", 41 | "Cette fonction ne doit pas utiliser la fonction `L.insert`, seule la fonction `L.append` est permise pour augmenter la taille du tableau." 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": { 48 | "tags": [ 49 | "answer" 50 | ] 51 | }, 52 | "outputs": [], 53 | "source": [ 54 | "############################## \n", 55 | "# Saisir votre code ici. #\n", 56 | "##############################\n", 57 | "\n", 58 | "\n" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": { 64 | "deletable": false, 65 | "editable": false, 66 | "run_control": { 67 | "frozen": true 68 | } 69 | }, 70 | "source": [ 71 | "Quelle est la complexité asymptotique de la fonction `insertion_tableau` ?" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": { 77 | "deletable": false, 78 | "run_control": { 79 | "frozen": false 80 | }, 81 | "tags": [ 82 | "answer" 83 | ] 84 | }, 85 | "source": [ 86 | "**Réponse :** Écrire votre réponse ici.\n", 87 | "\n", 88 | "\n" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": { 94 | "deletable": false, 95 | "editable": false, 96 | "run_control": { 97 | "frozen": true 98 | } 99 | }, 100 | "source": [ 101 | "## Exercice 2 : suppression d'un élément dans un tableau\n", 102 | "\n", 103 | "Définir la fonction `suppression_tableau` prenant en paramètre un tableau et un indice et supprimant dans le tableau l'élément se trouvant à l'indice donné (fonction similaire à `L.pop(i)`). \n", 104 | "\n", 105 | "Pour supprimer un élément, la fonction peut juste appeler la fonction `L.pop()` (sans argument) pour supprimer la dernière case." 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": { 112 | "tags": [ 113 | "answer" 114 | ] 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "############################## \n", 119 | "# Saisir votre code ici. #\n", 120 | "##############################\n", 121 | "\n", 122 | "\n" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": { 128 | "deletable": false, 129 | "editable": false, 130 | "run_control": { 131 | "frozen": true 132 | } 133 | }, 134 | "source": [ 135 | "Quelle est la complexité de la fonction `suppression_tableau` ?" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": { 141 | "deletable": false, 142 | "run_control": { 143 | "frozen": false 144 | }, 145 | "tags": [ 146 | "answer" 147 | ] 148 | }, 149 | "source": [ 150 | "**Réponse :** Écrire votre réponse ici.\n", 151 | "\n", 152 | "\n" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": { 158 | "deletable": false, 159 | "editable": false, 160 | "run_control": { 161 | "frozen": true 162 | } 163 | }, 164 | "source": [ 165 | "## Exercice 3 : Copie d'un tableau" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": { 171 | "deletable": false, 172 | "editable": false, 173 | "run_control": { 174 | "frozen": true 175 | } 176 | }, 177 | "source": [ 178 | "Définir la fonction `copie_tableau` retournant une copie du tableau `L` passé en paramètre (fonction comparable à `L.copy()`). \n", 179 | "\n", 180 | "Cette fonction ne doit pas utiliser la fonction `L.copy`, seule la fonction `L.append` est permise pour augmenter la taille du tableau." 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": { 187 | "tags": [ 188 | "answer" 189 | ] 190 | }, 191 | "outputs": [], 192 | "source": [ 193 | "############################## \n", 194 | "# Saisir votre code ici. #\n", 195 | "##############################\n", 196 | "\n", 197 | "\n" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": { 203 | "deletable": false, 204 | "editable": false, 205 | "run_control": { 206 | "frozen": true 207 | } 208 | }, 209 | "source": [ 210 | "Quelle est la complexité asymptotique de la fonction `copie_tableau` ?" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": { 216 | "deletable": false, 217 | "run_control": { 218 | "frozen": false 219 | }, 220 | "tags": [ 221 | "answer" 222 | ] 223 | }, 224 | "source": [ 225 | "**Réponse :** Écrire votre réponse ici.\n", 226 | "\n", 227 | "\n" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": { 233 | "deletable": false, 234 | "editable": false, 235 | "run_control": { 236 | "frozen": true 237 | } 238 | }, 239 | "source": [ 240 | "## Exercice 4 : Fonctions sur des listes (tableaux) triées ou non triées" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": { 246 | "deletable": false, 247 | "editable": false, 248 | "run_control": { 249 | "frozen": true 250 | } 251 | }, 252 | "source": [ 253 | "Les questions de cet exercice ont pour objet de manipuler les listes/tableaux en Python et de comparer ce qui se passe si on travaille avec des tableaux triés ou des tableaux quelconques. Pour chacune des fonctions à implémenter, on définira deux versions : \n", 254 | "\n", 255 | "* une première version prendra en paramètre une liste de nombres quelconques. Pour plus d'efficacité, la fonction pourra modifier l'ordre des éléments dans la liste,\n", 256 | "\n", 257 | "* la seconde version prendra en paramètre une liste de nombres triés dans l'ordre croissant ; la liste devra rester triée." 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "deletable": false, 264 | "editable": false, 265 | "run_control": { 266 | "frozen": true 267 | } 268 | }, 269 | "source": [ 270 | "### Question 1 : Minimum d'un tableau" 271 | ] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": { 276 | "deletable": false, 277 | "editable": false, 278 | "run_control": { 279 | "frozen": true 280 | } 281 | }, 282 | "source": [ 283 | "* Définir la fonction `minimum_tableau` prenant en paramètre un tableau de nombres et retournant le minimum." 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "metadata": { 290 | "tags": [ 291 | "answer" 292 | ] 293 | }, 294 | "outputs": [], 295 | "source": [ 296 | "############################## \n", 297 | "# Saisir votre code ici. #\n", 298 | "##############################\n", 299 | "\n", 300 | "\n" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": { 306 | "deletable": false, 307 | "editable": false, 308 | "run_control": { 309 | "frozen": true 310 | } 311 | }, 312 | "source": [ 313 | "* Définir la fonction `minimum_tableau_trie` prenant en paramètre un tableau de nombres triés dans l'ordre croissant et retournant le minimum." 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": null, 319 | "metadata": { 320 | "tags": [ 321 | "answer" 322 | ] 323 | }, 324 | "outputs": [], 325 | "source": [ 326 | "############################## \n", 327 | "# Saisir votre code ici. #\n", 328 | "##############################\n", 329 | "\n", 330 | "\n" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": { 336 | "deletable": false, 337 | "editable": false, 338 | "run_control": { 339 | "frozen": true 340 | } 341 | }, 342 | "source": [ 343 | "- Quelle est la complexité dans le pire des cas de chacune de ces fonctions ?" 344 | ] 345 | }, 346 | { 347 | "cell_type": "markdown", 348 | "metadata": { 349 | "deletable": false, 350 | "run_control": { 351 | "frozen": false 352 | }, 353 | "tags": [ 354 | "answer" 355 | ] 356 | }, 357 | "source": [ 358 | "**Réponse :** Écrire votre réponse ici.\n", 359 | "\n", 360 | "\n" 361 | ] 362 | }, 363 | { 364 | "cell_type": "markdown", 365 | "metadata": { 366 | "deletable": false, 367 | "editable": false, 368 | "run_control": { 369 | "frozen": true 370 | } 371 | }, 372 | "source": [ 373 | "### Question 2 : Ajout d'un élément" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": { 379 | "deletable": false, 380 | "editable": false, 381 | "run_control": { 382 | "frozen": true 383 | } 384 | }, 385 | "source": [ 386 | "* Définir la fonction `ajouter_tableau` ajoutant un nombre à un tableau de nombres." 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": null, 392 | "metadata": { 393 | "tags": [ 394 | "answer" 395 | ] 396 | }, 397 | "outputs": [], 398 | "source": [ 399 | "############################## \n", 400 | "# Saisir votre code ici. #\n", 401 | "##############################\n", 402 | "\n", 403 | "\n" 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": { 409 | "deletable": false, 410 | "editable": false, 411 | "run_control": { 412 | "frozen": true 413 | } 414 | }, 415 | "source": [ 416 | "* Définir la fonction `ajouter_tableau_trie` ajoutant un nombre à un tableau trié." 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": null, 422 | "metadata": { 423 | "tags": [ 424 | "answer" 425 | ] 426 | }, 427 | "outputs": [], 428 | "source": [ 429 | "############################## \n", 430 | "# Saisir votre code ici. #\n", 431 | "##############################\n", 432 | "\n", 433 | "\n" 434 | ] 435 | }, 436 | { 437 | "cell_type": "markdown", 438 | "metadata": { 439 | "deletable": false, 440 | "editable": false, 441 | "run_control": { 442 | "frozen": true 443 | } 444 | }, 445 | "source": [ 446 | "- Quelle est la complexité dans le pire des cas de chacune de ces fonctions ?" 447 | ] 448 | }, 449 | { 450 | "cell_type": "markdown", 451 | "metadata": { 452 | "deletable": false, 453 | "run_control": { 454 | "frozen": false 455 | }, 456 | "tags": [ 457 | "answer" 458 | ] 459 | }, 460 | "source": [ 461 | "**Réponse :** Écrire votre réponse ici.\n", 462 | "\n", 463 | "\n" 464 | ] 465 | }, 466 | { 467 | "cell_type": "markdown", 468 | "metadata": { 469 | "deletable": false, 470 | "editable": false, 471 | "run_control": { 472 | "frozen": true 473 | } 474 | }, 475 | "source": [ 476 | "### Question 3 : Suppression d'un élément" 477 | ] 478 | }, 479 | { 480 | "cell_type": "markdown", 481 | "metadata": { 482 | "deletable": false, 483 | "editable": false, 484 | "run_control": { 485 | "frozen": true 486 | } 487 | }, 488 | "source": [ 489 | "* Définir la fonction `supprimer_tableau` prenant en paramètre un tableau et un indice `id` et supprimant dans le tableau la valeur d'indice `id`.\n", 490 | "\n", 491 | " On utilisera pour cela la fonction `L.pop()` qui supprime la dernière case d'un tableau, mais pas la fonction `L.pop(i)`" 492 | ] 493 | }, 494 | { 495 | "cell_type": "code", 496 | "execution_count": null, 497 | "metadata": { 498 | "tags": [ 499 | "answer" 500 | ] 501 | }, 502 | "outputs": [], 503 | "source": [ 504 | "############################## \n", 505 | "# Saisir votre code ici. #\n", 506 | "##############################\n", 507 | "\n", 508 | "\n" 509 | ] 510 | }, 511 | { 512 | "cell_type": "markdown", 513 | "metadata": { 514 | "deletable": false, 515 | "editable": false, 516 | "run_control": { 517 | "frozen": true 518 | } 519 | }, 520 | "source": [ 521 | "* Définir la fonction `supprimer_tableau_trie` prenant en paramètre un tableau trié et un indice `id` et supprimant dans le tableau la valeur d'indice `id`." 522 | ] 523 | }, 524 | { 525 | "cell_type": "code", 526 | "execution_count": null, 527 | "metadata": { 528 | "tags": [ 529 | "answer" 530 | ] 531 | }, 532 | "outputs": [], 533 | "source": [ 534 | "############################## \n", 535 | "# Saisir votre code ici. #\n", 536 | "##############################\n", 537 | "\n", 538 | "\n" 539 | ] 540 | }, 541 | { 542 | "cell_type": "markdown", 543 | "metadata": { 544 | "deletable": false, 545 | "editable": false, 546 | "run_control": { 547 | "frozen": true 548 | } 549 | }, 550 | "source": [ 551 | "- Quelle est la complexité dans le pire des cas de chacune de ces fonctions ?" 552 | ] 553 | }, 554 | { 555 | "cell_type": "markdown", 556 | "metadata": { 557 | "deletable": false, 558 | "run_control": { 559 | "frozen": false 560 | }, 561 | "tags": [ 562 | "answer" 563 | ] 564 | }, 565 | "source": [ 566 | "**Réponse :** Écrire votre réponse ici.\n", 567 | "\n", 568 | "\n" 569 | ] 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": { 574 | "deletable": false, 575 | "editable": false, 576 | "run_control": { 577 | "frozen": true 578 | } 579 | }, 580 | "source": [ 581 | "## Exercice 5 : Réarrangement de tableau**" 582 | ] 583 | }, 584 | { 585 | "cell_type": "markdown", 586 | "metadata": { 587 | "deletable": false, 588 | "editable": false, 589 | "run_control": { 590 | "frozen": true 591 | } 592 | }, 593 | "source": [ 594 | "### Question 1\n", 595 | "\n", 596 | "Écrire une fonction `deplacer(T, k)` prenant en paramètre un tableau `T` et une valeur `k` et permutant les valeurs du tableau `T` de manière à ce que toutes les valeurs strictement inférieures à `k` soient au début de tableau. " 597 | ] 598 | }, 599 | { 600 | "cell_type": "markdown", 601 | "metadata": { 602 | "deletable": false, 603 | "editable": false, 604 | "run_control": { 605 | "frozen": true 606 | } 607 | }, 608 | "source": [ 609 | "**Remarque :** L'ordre des éléments dans le tableau n'a pas d'importance tant que les éléments strictement inférieurs à `k` sont placés au début du tableau." 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "execution_count": null, 615 | "metadata": { 616 | "tags": [ 617 | "answer" 618 | ] 619 | }, 620 | "outputs": [], 621 | "source": [ 622 | "############################## \n", 623 | "# Saisir votre code ici. #\n", 624 | "##############################\n", 625 | "\n", 626 | "\n" 627 | ] 628 | }, 629 | { 630 | "cell_type": "markdown", 631 | "metadata": { 632 | "deletable": false, 633 | "editable": false, 634 | "run_control": { 635 | "frozen": true 636 | } 637 | }, 638 | "source": [ 639 | "### Question 2\n", 640 | "\n", 641 | "Définir une fonction de tests unitaires de la fonction `deplacer`." 642 | ] 643 | }, 644 | { 645 | "cell_type": "code", 646 | "execution_count": null, 647 | "metadata": { 648 | "tags": [ 649 | "answer" 650 | ] 651 | }, 652 | "outputs": [], 653 | "source": [ 654 | "############################## \n", 655 | "# Saisir votre code ici. #\n", 656 | "##############################\n", 657 | "\n", 658 | "\n" 659 | ] 660 | } 661 | ], 662 | "metadata": { 663 | "celltoolbar": "Format de la Cellule Texte Brut", 664 | "kernelspec": { 665 | "display_name": "Python 3", 666 | "language": "python", 667 | "name": "python3" 668 | }, 669 | "language_info": { 670 | "codemirror_mode": { 671 | "name": "ipython", 672 | "version": 3 673 | }, 674 | "file_extension": ".py", 675 | "mimetype": "text/x-python", 676 | "name": "python", 677 | "nbconvert_exporter": "python", 678 | "pygments_lexer": "ipython3", 679 | "version": "3.8.5" 680 | }, 681 | "toc": { 682 | "base_numbering": 1, 683 | "nav_menu": {}, 684 | "number_sections": false, 685 | "sideBar": false, 686 | "skip_h1_title": false, 687 | "title_cell": "Table of Contents", 688 | "title_sidebar": "Contents", 689 | "toc_cell": false, 690 | "toc_position": {}, 691 | "toc_section_display": false, 692 | "toc_window_display": false 693 | } 694 | }, 695 | "nbformat": 4, 696 | "nbformat_minor": 5 697 | } 698 | -------------------------------------------------------------------------------- /TD/TD2/2_gui.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Interface graphique\n", 8 | "\n", 9 | "\n", 10 | "Ce [site](http://tkinter.fdex.eu/index.html) recense les méthodes utilisables dans les différents widgets, et permet de retrouver rapidement des informations à leur sujet.\n" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "## 1. Prise en main\n", 18 | "\n", 19 | "---\n", 20 | "\n", 21 | "1. Recopier le contenu du fichier `exemple03.py` depuis le répertoire `examples\\gui` du projet `L1-PYHTON` dans le fichier `debut.py`.\n", 22 | "\n", 23 | "2. Exécuter ce programme et comprendre ce qu'il fait.\n", 24 | "\n", 25 | "3. Retirer la condition \n", 26 | "```python\n", 27 | "if __name__ == '__main__':\n", 28 | "```\n", 29 | "et remplacer la fonction `canvas.pack()` par la fonction de positionnement des widgets que l'on a vue en cours. Puis testez votre programme.\n", 30 | "\n", 31 | "4. Importer la librairie `tkinter` avec l'instruction\n", 32 | "```python\n", 33 | "import tkinter as tk\n", 34 | "```\n", 35 | "au lieu de \n", 36 | "```python\n", 37 | "from tkinter import *\n", 38 | "```\n", 39 | "et modifier le programme pour qu'il fonctionne avec cette nouvelle manière de faire.\n", 40 | "\n", 41 | "5. Modifier le programme pour que la ligne qui s'affiche devienne verticale tout en conservant les cercles à ses extrémités.\n" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "---\n", 49 | "\n", 50 | "## 2. Dessins aléatoires\n", 51 | "\n", 52 | "Cet exercice est à traiter dans un script `dessin.py`.\n", 53 | "\n", 54 | "\n", 55 | "1. Créer la fenêtre graphique correspondant à la figure suivante:\n", 56 | "\n", 57 | "![](images/mon_dessin.png)\n", 58 | "\n", 59 | "\n", 60 | "c'est-à-dire que la fenêtre est composée de:\n", 61 | "* 4 widgets Button\n", 62 | "* 1 widget Canvas dont le fond est noir\n", 63 | "* titre à la fenêtre\n", 64 | "\n", 65 | "**Indication:** pour placer un widget sur plusieurs lignes (resp. colonnes), il faut utiliser le paramètre `rowspan` (resp. `columnspan`).\n" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "2. Modifier le style par défaut des boutons, par exemple, en modifiant les couleurs, en ajoutant des marges, en changeant la taille de la police. Pour savoir ce qu'il est possible de faire, consultez le site indiqué au début du sujet." 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "3. Dans les paramètres de création du canevas, chercher comment augmenter l'épaisseur du bord du widget, et comment le mettre en relief. Puis faites le." 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "4. Ajouter un lien (paramètre `command` du widget Button) entre le bouton `Cercle` et une fonction qui affiche un disque de diamètre 100 en bleu à un endroit choisi au hasard dans le canevas. Le cercle doit être inclu intégralement dans le canevas." 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "5. Faites pareil pour le bouton `Carré` qui doit afficher un carré rouge de côté 100, et puis pour `Croix` qui doit afficher une croix jaune inscrite dans un carré de côté 100 (les carrés dont on parle ont leur cotés horizontaux et verticaux)." 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "6. Faire en sorte que le bouton `Choisir une couleur` demande une couleur à l'utilisateur dans le terminal. Ensuite, les objets qui s'affichent doivent être de cette couleur, qui peut être modifiée par l'utilisateur autant de fois qu'il le souhaite. Tant que l'utilisateur n'a pas choisi de couleur, la couleur est bleue. On rappelle les couleurs prédéfinies: white, black, red, green, blue, cyan, yellow." 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "## 3. Cible en couleur\n", 108 | "\n", 109 | "---\n", 110 | "\n", 111 | "Dans un fichier `cible.py`, écrire le programme qui affiche la figure suivante:\n", 112 | "\n", 113 | "![](images/cible.png)\n", 114 | "\n", 115 | "Dans l'ordre les couleurs sont blue, green, black, yellow, magenta, red.\n", 116 | "Vous choisissez la taille d'image et le nombre de cercles que vous voulez. Mais le programme doit afficher une telle figure pour n'importe quelles valeurs choisies.\n" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "## 4. Couleurs\n", 124 | "\n", 125 | "---\n", 126 | "Les questions qui suivent sont à traiter dans un fichier `couleurs.py`.\n", 127 | "\n", 128 | "On rappelle que les couleurs sont codées par leur 3 composantes rouge, vert et bleu auxquelles on associe des valeurs comprises entre 0 et 255. La fonction suivante retourne une couleur dans le format attendu par Python à partir de ces 3 composantes.\n" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "def get_color(r, g, b):\n", 138 | " \"\"\" Retourne une couleur à partir de ses composantes r, g, b entre 0 et 255\"\"\"\n", 139 | " return '#{:02x}{:02x}{:02x}'.format(r, g, b)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "Cette fonction est à recopier au début de votre programme pour pouvoir l'utiliser ensuite.\n", 147 | "\n", 148 | "1. Créer la fenêtre graphique suivante (on demande juste de conserver la disposition des widgets les uns par rapport aux autres):\n", 149 | "\n", 150 | "![](images/fenetre_couleur.png)\n", 151 | "\n", 152 | "La taille du canvas doit être 256x256.\n", 153 | "\n", 154 | "2. Ecrire la fonction\n", 155 | "\n", 156 | "```python\n", 157 | "def draw_pixel(i, j, color)\n", 158 | "```\n", 159 | "qui colorie le pixel `(i, j)` du canvas de la couleur color. La tester en allumant en blanc le pixel du milieu du canevas.\n", 160 | "\n", 161 | "**⚠️** Par défaut, lorsqu'on dessine un rectangle dans un canvas, celui-ci a une bordure noire de 1 pixel. Utilisez le paramètre `width=0` pour la supprimer.\n", 162 | "\n", 163 | "3. Ecrire la fonction \n", 164 | "```python\n", 165 | "def ecran_aleatoire()\n", 166 | "```\n", 167 | "qui est appelée par le bouton `aleatoire` et qui remplit le canevas de manière à ce que chaque pixel soit d'une couleur choisie au hasard.\n", 168 | "\n", 169 | "3. Ecrire la fonction \n", 170 | "```python\n", 171 | "def degrade_gris()\n", 172 | "```\n", 173 | "qui affiche le dégradé de gris comme sur la figure suivante quand on clique sur le bouton correspondant:\n", 174 | "\n", 175 | "![](images/degrade_gris.png)\n", 176 | "\n", 177 | "4. Ecrire la fonction \n", 178 | "```python\n", 179 | "def degrade_2D()\n", 180 | "```\n", 181 | "qui affiche le dégradé de rouge et bleu comme sur la figure suivante quand on clique sur le bouton correspondant:\n", 182 | "\n", 183 | "![](images/degrade_rouge_bleu.png)\n", 184 | "\n", 185 | "\n", 186 | "\n" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "## 5. Fonction undo\n", 194 | "\n", 195 | "---\n", 196 | "\n", 197 | "Reprendre le programme de l'exercice 2. On va le compléter en ajoutant la possibilité d'annuler des dessins qui ont été faits dans l'ordre inverse de leur création. Cette fonctionnalité est souvent présente dans les logiciels d'édition de texte ou d'image, par exemple dans VSCode dans le menu \"Edit\" de la barre de menu, ou bien en tapant CTRL+Z. Pour faire cela, on va utiliser une liste contenant tous les objets dessinés, et il suffira de les supprimer à partir de la fin de la liste.\n", 198 | "\n", 199 | "\n", 200 | "1. Dans le programme de l'exercice 2, ajouter un bouton \"Undo\" à côté du bouton \"Choisir une couleur\". Ce bouton doit être lié à la fonction `def undo()` que l'on écrira plus tard.\n", 201 | "\n", 202 | "2. Ajouter une variable globale appelée `objets`. Elle doit contenir une liste qui doit être initialisée vide. Ensuite, ajouter le code qui, à chaque création d'objet (cercle, carré ou croix), l'ajoute à la liste. \n", 203 | "\n", 204 | "3. Ecrivez maintenant la fonction `undo()` en utilisant la méthode `.delete()` du canevas, et tester votre fonction.\n", 205 | "\n", 206 | "4. Faire en sorte que, si l'on clique sur \"Undo\" alors que le dessin est vide, aucune erreur n'est générée.\n", 207 | "\n", 208 | "5. Les croix posent un problème car il faut cliquer 2 fois sur \"Undo\" pour supprimer les 2 lignes. Afin d'améliorer notre fonction `undo()`, récupérer le type de l'objet à supprimer avec la méthode `.type(objet)` du canevas. Cette méthode retourne `\"line\"` si l'objet passé en argument est une ligne. Puis utiliser cette information pour ne pas avoir à cliquer 2 fois pour supprimer les croix. \n", 209 | "\n", 210 | "**Remarque:** en fait, il vaudrait mieux utiliser la possibilité d'utiliser des \"tags\" sur les objets pour pouvoir grouper les deux lignes d'une croix dans le même tag, et les supprimer ensemble.\n", 211 | "\n", 212 | "\n" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": {}, 218 | "source": [ 219 | "## 6. Avec des clics\n", 220 | "\n", 221 | "---\n", 222 | "\n", 223 | "Traiter cet exercice dans un fichier `clic.py`.\n", 224 | "\n", 225 | "1. Dans le fichier `clic1.py`, créer une fenêtre graphique qui contient un canevas de taille 500x500 et de couleur noire. Quand on clique sur le canevas, un pixel de couleur rouge s'affiche à l'endroit où l'on a cliqué.\n", 226 | "\n", 227 | "\n" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "2. Copier le contenu du fichier `clic1.py` dans le fichier `clic2.py`. Modifier le fichier `clic2.py` de manière à faire les choses suivantes: \n", 235 | " * afficher une ligne verticale en blanc qui sépare l'écran en 2 parties égales\n", 236 | " * si l'utilisateur clique à gauche de la ligne afficher un cercle bleu et s'il est à droite, afficher un cercle rouge. Dans les deux cas, le cercle sera centré là où l'utilisateur a cliqué. Le rayon du cercle est 50." 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": {}, 242 | "source": [ 243 | "3. Copier le contenu du fichier `clic2.py` dans le fichier `clic3.py`. Modifier le fichier `clic3.py` de manière à faire les choses suivantes: \n", 244 | " * afficher une ligne verticale en blanc qui sépare l'écran en 2 parties égales\n", 245 | " * à chaque fois que l'utilisateur a fait 2 clics, s'ils sont du même côté alors afficher une ligne bleue reliant les deux points où l'utilisateur a cliqué, sinon une ligne rouge. " 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "metadata": {}, 251 | "source": [ 252 | "4. Copier le contenu du fichier `clic3.py` dans le fichier `clic4.py`. Modifier le fichier `clic4.py` de manière à faire les choses suivantes: \n", 253 | " * dessiner un carré vide au centre de l'écran (taille et couleur au choix au choix)\n", 254 | " * à chaque clic, le carré se remplit et se vide alternativement\n", 255 | " * au bout de 10 clics, la fenêtre se ferme (utiliser la fonction `racine.destroy()`)" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": {}, 261 | "source": [ 262 | "5. Copier le contenu du fichier `clic4.py` dans le fichier `clic5.py`. Modifier le fichier `clic5.py` de manière à faire les choses suivantes: \n", 263 | " * pour les 8 premiers clics de l'utilisateur, on affiche un cercle rouge centré sur le point cliqué par l'utilisateur, et de rayon 50\n", 264 | " * au neuvième clic, tous les cercles deviennent jaunes\n", 265 | " * au dizième clic, tous les cercles disparaissent et on recommence au début" 266 | ] 267 | } 268 | ], 269 | "metadata": { 270 | "kernelspec": { 271 | "display_name": "Python 3", 272 | "language": "python", 273 | "name": "python3" 274 | }, 275 | "language_info": { 276 | "codemirror_mode": { 277 | "name": "ipython", 278 | "version": 3 279 | }, 280 | "file_extension": ".py", 281 | "mimetype": "text/x-python", 282 | "name": "python", 283 | "nbconvert_exporter": "python", 284 | "pygments_lexer": "ipython3", 285 | "version": "3.8.5" 286 | }, 287 | "toc": { 288 | "base_numbering": 1, 289 | "nav_menu": {}, 290 | "number_sections": false, 291 | "sideBar": false, 292 | "skip_h1_title": false, 293 | "title_cell": "Table of Contents", 294 | "title_sidebar": "Contents", 295 | "toc_cell": false, 296 | "toc_position": {}, 297 | "toc_section_display": false, 298 | "toc_window_display": false 299 | } 300 | }, 301 | "nbformat": 4, 302 | "nbformat_minor": 1 303 | } 304 | -------------------------------------------------------------------------------- /TD/TD2/images/cible.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/TD2/images/cible.png -------------------------------------------------------------------------------- /TD/TD2/images/degrade_gris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/TD2/images/degrade_gris.png -------------------------------------------------------------------------------- /TD/TD2/images/degrade_rouge_bleu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/TD2/images/degrade_rouge_bleu.png -------------------------------------------------------------------------------- /TD/TD2/images/fenetre_couleur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/TD2/images/fenetre_couleur.png -------------------------------------------------------------------------------- /TD/TD2/images/mon_dessin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/TD2/images/mon_dessin.png -------------------------------------------------------------------------------- /TD/TD3/td_dict.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#
Dictionnaires - TD
" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Exercice 1 : Test de de compréhension*" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "* Soit le dictionnaire suivant représentant des informations sur les étudiants inscrits au cours" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "cours = {'nom cours': 'Java',\n", 31 | " 'theme': 'Algorithmique',\n", 32 | " 'etudiants': [{'nom': 'Martin', 'prenom': 'Jean', 'Dept': '95'},\n", 33 | " {'nom': 'Mohamed', 'prenom': 'Ali', 'Dept': '93'},\n", 34 | " {'nom': 'Durand', 'prenom': 'Bertrand', 'Dept': '95'}]}" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "* Que permettent de faire les commandes suivantes ?" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "print(list(cours.values()))" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "print(list(cours))" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "print(cours['theme'])" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "tabE=cours['etudiants']\n", 78 | "etud= tabE[0]\n", 79 | "print(etud['nom'])" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "**REPONSE**" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "* Comment peut-on avoir les informations sur les étudiants inscrits à ce cours ?" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "#-------------------------#\n", 103 | "# Écrire le code ici #\n", 104 | "#-------------------------#\n", 105 | "\n", 106 | "\n" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "deletable": false, 113 | "editable": false, 114 | "run_control": { 115 | "frozen": true 116 | } 117 | }, 118 | "source": [ 119 | "* Qu'affiche le programme suivant ?" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": null, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "etds=cours['etudiants']\n", 129 | "tmp1=etds[1]\n", 130 | "print(tmp1)\n", 131 | "pr=tmp1['Dept']\n", 132 | "print(pr)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "**REPONSE**" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": { 145 | "deletable": false, 146 | "editable": false, 147 | "run_control": { 148 | "frozen": true 149 | } 150 | }, 151 | "source": [ 152 | "* Qu'affiche cette instruction ?" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "print (cours['etudiants'][1]['Dept'])" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "**REPONSE**" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": { 174 | "deletable": false, 175 | "editable": false, 176 | "run_control": { 177 | "frozen": true 178 | } 179 | }, 180 | "source": [ 181 | "## Exercice 2 : Planètes et satellites \n", 182 | "### Question 1 : Définition d'un dictionnaire" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": { 188 | "deletable": false, 189 | "editable": false, 190 | "run_control": { 191 | "frozen": true 192 | } 193 | }, 194 | "source": [ 195 | "Définir le dictionnaire `lunes` représenté ci-dessous. Ce dictionnaire stocke le nombre de satellites de chaque planète. Dans un premier temps, définir de façon littérale le dictionnaire pour les 4 premiers couples ``clef:valeur`` puis ajouter successivement les 4 derniers couples.\n", 196 | "\n", 197 | "clef| \"Mercure\"|\"Vénus\"|\"Terre\"|\"Mars\"|\"Jupiter\"|\"Saturne\"|\"Uranus\"|\"Neptune\"|\n", 198 | "----|----------|-------|-------|------|---------|---------|--------|---------|\n", 199 | "valeur |0|0|1|2|63|61|27|11|\n" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": null, 205 | "metadata": {}, 206 | "outputs": [], 207 | "source": [ 208 | "#-------------------------#\n", 209 | "# Écrire le code ici #\n", 210 | "#-------------------------#\n", 211 | "\n", 212 | "\n" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": { 218 | "deletable": false, 219 | "editable": false, 220 | "run_control": { 221 | "frozen": true 222 | } 223 | }, 224 | "source": [ 225 | "### Question 2 : Exploration d'un dictionnaire\n", 226 | "\n", 227 | "A partir du dictionnaire défini à la question précédente, proposer un programme permettant de:\n", 228 | "- modifier le dictionnaire précédent pour corriger une erreur qui s'est glissée dans l'énoncé : la planète `Neptune` comporte en fait 13 satellites,\n", 229 | "- afficher le nombre de satellites de la Terre,\n", 230 | "- afficher la liste des planètes,\n", 231 | "- afficher le nombre de satellites de chque planète,\n", 232 | "- afficher le nombre total de satellites." 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": null, 238 | "metadata": {}, 239 | "outputs": [], 240 | "source": [ 241 | "#-------------------------#\n", 242 | "# Écrire le code ici #\n", 243 | "#-------------------------#\n", 244 | "\n", 245 | "\n" 246 | ] 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "metadata": { 251 | "deletable": false, 252 | "editable": false, 253 | "run_control": { 254 | "frozen": true 255 | } 256 | }, 257 | "source": [ 258 | "## Exercice 3 : Gestion d'un stock " 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": { 264 | "deletable": false, 265 | "editable": false, 266 | "run_control": { 267 | "frozen": true 268 | } 269 | }, 270 | "source": [ 271 | "L'objectif est concevoir un programme permettant de gérer un stock d'articles. Pour cela, on doit pouvoir :\n", 272 | "- ajouter une référence (prix, quantité, et couleur) dans le stock,\n", 273 | "- calculer le prix total du stock.\n", 274 | "\n", 275 | "### Question 1 : Saisie d'une référence\n", 276 | "Créer une fonction ``ajout_reference()`` sans paramètre qui renvoie un dictionnaire dont les couples ``clef:valeur`` sont:\n", 277 | "\n", 278 | "| Clef | Valeur (type) |\n", 279 | "-------|----------|\n", 280 | "|\"Prix\"| float|\n", 281 | "|\"Quantité\"| int|\n", 282 | "|\"Couleur\"| string|\n", 283 | "\n", 284 | "La fonction demandera à l'utilisateur de saisir itérativement au clavier les différentes valeurs." 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": null, 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [ 293 | "#-------------------------#\n", 294 | "# Écrire le code ici #\n", 295 | "#-------------------------#\n", 296 | "\n", 297 | "\n" 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": { 303 | "deletable": false, 304 | "editable": false, 305 | "run_control": { 306 | "frozen": true 307 | } 308 | }, 309 | "source": [ 310 | "### Question 2 : Saisie et évaluation d'un stock\n", 311 | "Ecrire le programme principal permettant, de saisir des références tant que l'utilisateur le souhaite, de les ajouter au fur et à mesure dans un tableau, puis en fin de saisie, d'afficher le montant total du stock.\n", 312 | "On utilisera la fonction définie à la question précédente." 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": null, 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "#-------------------------#\n", 322 | "# Écrire le code ici #\n", 323 | "#-------------------------#\n", 324 | "\n", 325 | "\n" 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": { 331 | "deletable": false, 332 | "editable": false, 333 | "run_control": { 334 | "frozen": true 335 | } 336 | }, 337 | "source": [ 338 | "## Exercice 4 : Dictionnaire français-anglais " 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": {}, 344 | "source": [ 345 | "### Question 1 : Création d'un dictionnaire\n", 346 | "\n", 347 | "Choisir 5 mots de la langue française et créer un dictionnaire qui associe à chacun de ces mots\n", 348 | "sa traduction en anglais.\n", 349 | "Ajouter une entrée au dictionnaire (un nouveau mot et sa définition)." 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [ 358 | "#-------------------------#\n", 359 | "# Écrire le code ici #\n", 360 | "#-------------------------#\n", 361 | "\n" 362 | ] 363 | }, 364 | { 365 | "cell_type": "markdown", 366 | "metadata": {}, 367 | "source": [ 368 | "### Question 2 : Fonction d'ajout \n", 369 | "Écrire une fonction `ajoute(mot1, mot2, dico)` qui prend en paramètre un mot en français, sa traduction\n", 370 | "en anglais et ajoute ces deux mots dans le dictionnaire `dico` uniquement si `mot1` n’est pas déjà une clé\n", 371 | "du dictionnaire.\n", 372 | "\n", 373 | "Tester cette fonction avec des valeurs judicieusement choisies." 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [ 382 | "#-------------------------#\n", 383 | "# Écrire le code ici #\n", 384 | "#-------------------------#\n" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "### Question 3 : Affichage des valeurs\n", 392 | "Écrire une fonction qui affiche à l’écran toutes les valeurs correspondant aux clés qui sont dans\n", 393 | "votre dictionnaire et l'utiliser pour réaliser l'affichage des mots anglais du dictionnaire qui a été crée." 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": null, 399 | "metadata": {}, 400 | "outputs": [], 401 | "source": [ 402 | "#-------------------------#\n", 403 | "# Écrire le code ici #\n", 404 | "#-------------------------#\n" 405 | ] 406 | }, 407 | { 408 | "cell_type": "markdown", 409 | "metadata": {}, 410 | "source": [ 411 | "### Question 4 : Suppression d'entrées du dictionnaire\n", 412 | "Écrire une fonction `supprime(car, dico)` qui prend en paramètre un caractère `car` et un dictionnaire\n", 413 | "`dico` et supprime du dictionnaire toutes les entrées correspondant à des clés qui commencent par la\n", 414 | "lettre `car`.\n", 415 | "\n", 416 | "Tester cette fonction sur le dictionnaire." 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": null, 422 | "metadata": {}, 423 | "outputs": [], 424 | "source": [ 425 | "#-------------------------#\n", 426 | "# Écrire le code ici #\n", 427 | "#-------------------------#\n", 428 | "\n" 429 | ] 430 | }, 431 | { 432 | "cell_type": "markdown", 433 | "metadata": {}, 434 | "source": [ 435 | "## Exercice 5 : Codage de Morse" 436 | ] 437 | }, 438 | { 439 | "cell_type": "markdown", 440 | "metadata": {}, 441 | "source": [ 442 | "Le Morse est un schéma de codage qui utilise des tirets et des points pour représenter les chiffres et les lettres. \n", 443 | "\n", 444 | "Le dictionnaire ci-dessous donne la correspondance entre les lettres et les chiffres, les tirets et les points. " 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": null, 450 | "metadata": {}, 451 | "outputs": [], 452 | "source": [ 453 | "morse_code_dict = {'A':'.-' , 'B':'-...' , 'C':'-.-.' , 'D':'-..' , 'E':'.' , 'F':'..-.' , 'G':'--.' , \n", 454 | " 'H':'....' , 'I':'..' , 'J':'.---' , 'K':'-.-' , 'L':'.-..' , 'M':'--' , 'N':'-.' , \n", 455 | " 'O':'---' , 'P':'.--.' , 'Q':'--.-' , 'R':'.-.' , 'S':'...' , 'T':'-' , 'U':'..-' , \n", 456 | " 'V':'...-' , 'W':'.--' , 'X':'-..-' , 'Y':'-.--' , 'Z':'--..' , '0':'-----', '1':'.----', \n", 457 | " '2':'..---', '3':'...--', '4':'....-', '5':'.....', '6':'-....', '7':'--...', '8':'---..', \n", 458 | " '9':'----.'}" 459 | ] 460 | }, 461 | { 462 | "cell_type": "markdown", 463 | "metadata": {}, 464 | "source": [ 465 | "Ecrire une fonction qui prend en paramètre un texte, transforme les minuscules en majuscules et traduit chaque lettre et chaque chiffre du texte en code Morse, en laissant un espace entre chaque suite de tirets et de points. La fonction ignorera tous les caractères qui ne sont pas des lettres ou des chiffres. \n", 466 | "\n", 467 | "Utiliser cette fonction pour coder en Morse `Hello world !`.\n", 468 | "\n", 469 | "**Rappel** : \n", 470 | "\n", 471 | "- La méthode `chaine.upper()` retourne la chaine de caractères obtenue à partir de `chaine`en remplaçant les lettres minuscules par des lettres majuscules.\n", 472 | "- La méthode `chaine.isalnum()` retoune `True` si tous les caractères de `chaine`sont alphanumériques (lettres ou chiffres) et qu'il y a au moins un caractère et `False` dans le cas contraire." 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": null, 478 | "metadata": {}, 479 | "outputs": [], 480 | "source": [ 481 | "#-------------------------#\n", 482 | "# Écrire le code ici #\n", 483 | "#-------------------------#\n", 484 | "\n" 485 | ] 486 | } 487 | ], 488 | "metadata": { 489 | "celltoolbar": "Format de la Cellule Texte Brut", 490 | "kernelspec": { 491 | "display_name": "Python 3", 492 | "language": "python", 493 | "name": "python3" 494 | }, 495 | "language_info": { 496 | "codemirror_mode": { 497 | "name": "ipython", 498 | "version": 3 499 | }, 500 | "file_extension": ".py", 501 | "mimetype": "text/x-python", 502 | "name": "python", 503 | "nbconvert_exporter": "python", 504 | "pygments_lexer": "ipython3", 505 | "version": "3.8.5" 506 | }, 507 | "latex_envs": { 508 | "LaTeX_envs_menu_present": true, 509 | "autoclose": false, 510 | "autocomplete": true, 511 | "bibliofile": "biblio.bib", 512 | "cite_by": "apalike", 513 | "current_citInitial": 1, 514 | "eqLabelWithNumbers": true, 515 | "eqNumInitial": 1, 516 | "hotkeys": { 517 | "equation": "Ctrl-E", 518 | "itemize": "Ctrl-I" 519 | }, 520 | "labels_anchors": false, 521 | "latex_user_defs": false, 522 | "report_style_numbering": false, 523 | "user_envs_cfg": false 524 | }, 525 | "toc": { 526 | "base_numbering": 1, 527 | "nav_menu": {}, 528 | "number_sections": true, 529 | "sideBar": true, 530 | "skip_h1_title": false, 531 | "title_cell": "Table of Contents", 532 | "title_sidebar": "Contents", 533 | "toc_cell": false, 534 | "toc_position": {}, 535 | "toc_section_display": true, 536 | "toc_window_display": false 537 | } 538 | }, 539 | "nbformat": 4, 540 | "nbformat_minor": 2 541 | } 542 | -------------------------------------------------------------------------------- /TD/TD4/files/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/TD/TD4/files/.DS_Store -------------------------------------------------------------------------------- /TD/TD4/td_file.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#
Fichiers texte - TD
" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Exercice 1 : Écriture/Lecture dans un fichier\n", 15 | "\n", 16 | "### Question 1\n", 17 | "Définir un programme qui écrit dans un fichier tous les entiers inférieurs à 10 000. Chaque entier est sur une ligne différente du fichier. Puis faire un programme qui lit le contenu de ce fichier et mémorise toutes les valeurs dans un tableau." 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "#-------------------------#\n", 27 | "# Écrire le code ici #\n", 28 | "#-------------------------#\n", 29 | "\n", 30 | "\n" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "### Question 2\n", 38 | "Refaire la même chose qu'à la question précédente, mais cette fois-ci tous les entiers sont sur une même ligne et sont séparés par un `;`." 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "#-------------------------#\n", 48 | "# Écrire le code ici #\n", 49 | "#-------------------------#\n", 50 | "\n", 51 | "\n" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "## Exercice 2: Lecture/Écriture dans un fichier\n", 59 | "\n", 60 | "### Question 1: Écriture dans un fichier\n", 61 | "Définir un programme qui écrit dans un fichier nommé `'prenoms.txt'` les prénoms contenus dans le tableau initial de l'exercice précédant. Chaque prénom sera écrit sur une ligne différente:" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 1, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "#-------------------------#\n", 71 | "# Écrire le code ici #\n", 72 | "#-------------------------#\n", 73 | "\n" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "### Question 2: Lecture dans un fichier\n", 81 | "\n", 82 | "Définir un programme qui lit les prénoms du fichier `'prenoms.txt'` et qui affiche en plus du prénom lu le nombre de caractères qui le constitue. Chaque prénom et son nombre de caractère seront affichés sur une ligne différente et séparés par une virgule." 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "#-------------------------#\n", 92 | "# Écrire le code ici #\n", 93 | "#-------------------------#\n", 94 | "\n" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "### Question 3: Lecture et Ecriture dans un fichier\n", 102 | "\n", 103 | "Définir un programme qui, au moyen d'une seule boucle, lit les prénoms du fichier `prenoms.txt` et qui écrit dans un fichier `prenoms.csv` en plus du prénom le nombre de caractère qui le constitue. Sur chaque ligne du fichier le prénom et sa longueur sont séparé par une virgule." 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "#-------------------------#\n", 113 | "# Écrire le code ici #\n", 114 | "#-------------------------#\n" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "## Exercice 3 : JSON\n", 122 | "\n", 123 | "Écrire un programme permettant à partir d’un fichier texte en français d’en déduire la fréquence d’apparition des caractères qu’il contient. Le résultat de cette analyse sera consigné dans un fichier JSON `files/statistiques.json`. Pour des statistiques fiables, on utilisera un texte assez long disponible dans le fichier `files/zadig.txt`." 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": null, 129 | "metadata": {}, 130 | "outputs": [], 131 | "source": [ 132 | "#-------------------------#\n", 133 | "# Écrire le code ici #\n", 134 | "#-------------------------#\n", 135 | "\n", 136 | "\n" 137 | ] 138 | } 139 | ], 140 | "metadata": { 141 | "kernelspec": { 142 | "display_name": "Python 3", 143 | "language": "python", 144 | "name": "python3" 145 | }, 146 | "language_info": { 147 | "codemirror_mode": { 148 | "name": "ipython", 149 | "version": 3 150 | }, 151 | "file_extension": ".py", 152 | "mimetype": "text/x-python", 153 | "name": "python", 154 | "nbconvert_exporter": "python", 155 | "pygments_lexer": "ipython3", 156 | "version": "3.8.5" 157 | }, 158 | "latex_envs": { 159 | "LaTeX_envs_menu_present": true, 160 | "autoclose": false, 161 | "autocomplete": true, 162 | "bibliofile": "biblio.bib", 163 | "cite_by": "apalike", 164 | "current_citInitial": 1, 165 | "eqLabelWithNumbers": true, 166 | "eqNumInitial": 1, 167 | "hotkeys": { 168 | "equation": "Ctrl-E", 169 | "itemize": "Ctrl-I" 170 | }, 171 | "labels_anchors": false, 172 | "latex_user_defs": false, 173 | "report_style_numbering": false, 174 | "user_envs_cfg": false 175 | }, 176 | "toc": { 177 | "base_numbering": 1, 178 | "nav_menu": {}, 179 | "number_sections": true, 180 | "sideBar": true, 181 | "skip_h1_title": false, 182 | "title_cell": "Table of Contents", 183 | "title_sidebar": "Contents", 184 | "toc_cell": false, 185 | "toc_position": {}, 186 | "toc_section_display": true, 187 | "toc_window_display": false 188 | } 189 | }, 190 | "nbformat": 4, 191 | "nbformat_minor": 2 192 | } 193 | -------------------------------------------------------------------------------- /TD/TD5/td_table_hachage.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "deletable": false, 7 | "editable": false, 8 | "run_control": { 9 | "frozen": true 10 | } 11 | }, 12 | "source": [ 13 | "# TD : Tables de hachage" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "deletable": false, 20 | "editable": false, 21 | "run_control": { 22 | "frozen": true 23 | } 24 | }, 25 | "source": [ 26 | "## Exercice 1 : Opérations de base dans une 1ère table de hachage " 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "deletable": false, 33 | "editable": false, 34 | "run_control": { 35 | "frozen": true 36 | } 37 | }, 38 | "source": [ 39 | "On utilise comme table de hachage un tableau de 10 cases où la case d'indice `i` contient l'ensemble des nombres terminant par le chiffre `i`." 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "deletable": false, 46 | "editable": false, 47 | "run_control": { 48 | "frozen": true 49 | } 50 | }, 51 | "source": [ 52 | "### Question 1 : La recherche\n", 53 | "\n", 54 | "- Définir une fonction `rechercher` qui prend en paramètre une table de hachage et un entier et renvoie `True` si l'entier est dans la table, et `False` sinon. " 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": { 61 | "tags": [ 62 | "answer" 63 | ] 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "############################## \n", 68 | "# Saisir votre code ici. #\n", 69 | "##############################\n", 70 | "\n", 71 | "\n" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": { 77 | "deletable": false, 78 | "editable": false, 79 | "run_control": { 80 | "frozen": true 81 | } 82 | }, 83 | "source": [ 84 | "### Question 2 : L'ajout \n", 85 | "\n", 86 | "- Définir une fonction `ajouter` qui prend en paramètre une table de hachage et un entier et ajoute cet entier dans la table s'il n'existe pas. " 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "metadata": { 93 | "tags": [ 94 | "answer" 95 | ] 96 | }, 97 | "outputs": [], 98 | "source": [ 99 | "############################## \n", 100 | "# Saisir votre code ici. #\n", 101 | "##############################\n", 102 | "\n", 103 | "\n" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": { 109 | "deletable": false, 110 | "editable": false, 111 | "run_control": { 112 | "frozen": true 113 | } 114 | }, 115 | "source": [ 116 | "### Question 3 : La suppression\n", 117 | "\n", 118 | "- Définir une fonction `supprimer` qui prend en paramètre une table de hachage et un entier et supprime cet entier dans la table s'il est présent.\n", 119 | "\n", 120 | "**Remarque :** On utilisera la fonction `L.pop()` qui supprime le dernier élément de la table `L`." 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "metadata": { 127 | "tags": [ 128 | "answer" 129 | ] 130 | }, 131 | "outputs": [], 132 | "source": [ 133 | "############################## \n", 134 | "# Saisir votre code ici. #\n", 135 | "##############################\n", 136 | "\n", 137 | "\n" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "deletable": false, 144 | "editable": false, 145 | "run_control": { 146 | "frozen": true 147 | } 148 | }, 149 | "source": [ 150 | "## Exercice 2 : Opérations de base dans une 2ème table de hachage " 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": { 156 | "deletable": false, 157 | "editable": false, 158 | "run_control": { 159 | "frozen": true 160 | } 161 | }, 162 | "source": [ 163 | "### Question 1 : La recherche \n", 164 | "\n", 165 | "- Définir une fonction `rechercher2` qui prend en paramètre une table de hachage et une valeur et renvoie `True` si la valeur est dans la table, et `False` sinon. On ne fait pas d'hypothèse sur le nombre de cases de la table. La fonction de hachage est celle définie en cours.\n", 166 | "\n", 167 | "**Remarque :** Si la valeur que l'on veut stocker dans la table est entière, il suffit de transformer l'entier en une chaîne de caractères avec `str(entier)`." 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": null, 173 | "metadata": { 174 | "tags": [ 175 | "removeFromLatex" 176 | ] 177 | }, 178 | "outputs": [], 179 | "source": [ 180 | "# Fonction de hachage définie en cours\n", 181 | "\n", 182 | "def hachage(str):\n", 183 | " nombre = 0\n", 184 | " i = 0\n", 185 | " while i < len(str):\n", 186 | " nombre += ord(str[i])\n", 187 | " i += 1\n", 188 | " return nombre" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": { 195 | "tags": [ 196 | "answer" 197 | ] 198 | }, 199 | "outputs": [], 200 | "source": [ 201 | "############################## \n", 202 | "# Saisir votre code ici. #\n", 203 | "##############################\n", 204 | "\n", 205 | "\n" 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "metadata": { 211 | "deletable": false, 212 | "editable": false, 213 | "run_control": { 214 | "frozen": true 215 | } 216 | }, 217 | "source": [ 218 | "### Question 2 : L'ajout \n", 219 | "\n", 220 | "- Définir une fonction `ajouter2` qui prend en paramètre une table de hachage et une valeur et ajoute cette valeur dans la table si elle n'existe pas. On ne fait pas d'hypothèse sur le nombre de cases de la table. La fonction de hachage est celle définie en cours." 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": null, 226 | "metadata": { 227 | "tags": [ 228 | "answer" 229 | ] 230 | }, 231 | "outputs": [], 232 | "source": [ 233 | "############################## \n", 234 | "# Saisir votre code ici. #\n", 235 | "##############################\n", 236 | "\n", 237 | "\n" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": { 243 | "deletable": false, 244 | "editable": false, 245 | "run_control": { 246 | "frozen": true 247 | } 248 | }, 249 | "source": [ 250 | "### Question 3 : La suppression \n", 251 | "- Définir une fonction `supprimer2` qui prend en paramètre une table de hachage et un entier et supprime cet entier dans la table s'il existe. \n", 252 | "\n", 253 | "On ne fait pas d'hypothèse sur le nombre de cases de la table. La fonction de hachage est celle définie en cours.\n", 254 | "\n", 255 | "**Remarque :** on utilisera la fonction `L.pop()` qui supprime le dernier élément de la table `L`." 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": null, 261 | "metadata": { 262 | "tags": [ 263 | "answer" 264 | ] 265 | }, 266 | "outputs": [], 267 | "source": [ 268 | "############################## \n", 269 | "# Saisir votre code ici. #\n", 270 | "##############################\n", 271 | "\n", 272 | "\n" 273 | ] 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "metadata": { 278 | "deletable": false, 279 | "editable": false, 280 | "run_control": { 281 | "frozen": true 282 | } 283 | }, 284 | "source": [ 285 | "## Exercice 3 : Hachage fermé (ou à adressage ouvert)\n", 286 | "\n", 287 | "\n", 288 | "Dans cet exercice, on suppose que l'on stocke dans les cases de la table de hachage des valeurs et non des tableaux de valeurs (on peut donc mettre au plus une valeur dans chaque case de la table). Il faut alors une méthode pour gérer les *collisions* (cas où plusieurs éléments à stocker ont la même valeur de hachage).\n", 289 | "\n", 290 | "Lorque l'on essaie d'insérer un nouvel est élément et que la case où on veut le mettre est déjà occupée, il faut essayer de le placer dans une autre case, et ainsi de suite jusqu'à en trouver une libre. On dit alors que l'on *sonde* la table pour trouver une case libre. Dans ces conditions, la fonction de hachage prend un argument supplémentaire qui compte le nombre de tentatives infructueuses pour trouver une case libre.\n", 291 | "\n", 292 | "### Question 1 : Sondage linéaire \n", 293 | "\n", 294 | "Dans le cas du *sondage linéaire*, on avance dans le tableau d'un nombre fixe de cases (souvent une case) à chaque fois jusqu'à trouver une case vide. Si le pas est un, la fonction de hachage s'écrit $h(k,i)= h_1(k)+i$ où $h_1$ est un fonction de hachage simple et $i$ est le nombre de tentatives pour trouver une case vide.\n", 295 | "\n", 296 | "- Éxécuter à la main l'algorithme d'insertion dans une table de taille `m=9` des valeurs 5, 28, 19, 15, 20, 33, 12, 17 en utilsant la fonction $h_1(k)=k \\mod 9$.\n", 297 | "- Écrire les fonctions permettant d'insérer et de rechercher une valeur dans une table de hachage de taille `m` avec la fonction de hachage à sondage linéaire qui vient d'être décrite. \n", 298 | "- Que se passe-t-il si l'on supprime des valeurs dans la table ? Comment peut-on résoudre ce problème ?" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": { 304 | "deletable": false, 305 | "run_control": { 306 | "frozen": false 307 | }, 308 | "tags": [ 309 | "answer" 310 | ] 311 | }, 312 | "source": [ 313 | "**Réponse :** Écrire votre réponse ici.\n", 314 | "\n", 315 | "\n" 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": null, 321 | "metadata": { 322 | "tags": [ 323 | "answer" 324 | ] 325 | }, 326 | "outputs": [], 327 | "source": [ 328 | "############################## \n", 329 | "# Saisir votre code ici. #\n", 330 | "##############################\n", 331 | "\n", 332 | "\n" 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": { 338 | "deletable": false, 339 | "run_control": { 340 | "frozen": false 341 | }, 342 | "tags": [ 343 | "answer" 344 | ] 345 | }, 346 | "source": [ 347 | "**Réponse :** Écrire votre réponse ici.\n", 348 | "\n", 349 | "\n" 350 | ] 351 | }, 352 | { 353 | "cell_type": "markdown", 354 | "metadata": { 355 | "deletable": false, 356 | "editable": false, 357 | "run_control": { 358 | "frozen": true 359 | } 360 | }, 361 | "source": [ 362 | "### Question 2 : Double hachage\n", 363 | "\n", 364 | "Le sondage linéaire présente un gros inconvénient. Même si la fonction de hachage répartit les clés uniformément dans la table, la résolution des collisions a tendance à former des \"paquets\" de valeurs ce qui conduit à rapidement augmenter le nombre de recherches infructueuses.\n", 365 | "\n", 366 | "Une solution pour résoudre le problème des \"paquets\" est de modifier la méthode de sondage pour que les cases sondées soient éloignées de manière variable. Le double hachage est l'une des meilleurs méthodes connues pour cela. Il utilise une fonction de hachage de la forme $h(k,i)=h_1(k)+ih_2(k) \\mod m$ où $h_1$ et $h_2$ sont des fonctions de hachage auxiliaires simples.\n", 367 | "\n", 368 | "- Insérer les valeurs de la Question 1 dans une table de taille $m=13$ en utilisant un double hachage où $h_1(k)= k \\mod 13$ et $h_2(k)=1+ (k \\mod 12).$ \n", 369 | "- Que se passe-t-il si $h_2(k)$ et $m$ ne sont pas premiers entre eux ? En quoi est-ce gênant ? Comment y remédier ? " 370 | ] 371 | }, 372 | { 373 | "cell_type": "markdown", 374 | "metadata": { 375 | "deletable": false, 376 | "run_control": { 377 | "frozen": false 378 | }, 379 | "tags": [ 380 | "answer" 381 | ] 382 | }, 383 | "source": [ 384 | "**Réponse :** Écrire votre réponse ici.\n", 385 | "\n", 386 | "\n" 387 | ] 388 | } 389 | ], 390 | "metadata": { 391 | "celltoolbar": "Éditer les Méta-Données", 392 | "kernelspec": { 393 | "display_name": "Python 3", 394 | "language": "python", 395 | "name": "python3" 396 | }, 397 | "language_info": { 398 | "codemirror_mode": { 399 | "name": "ipython", 400 | "version": 3 401 | }, 402 | "file_extension": ".py", 403 | "mimetype": "text/x-python", 404 | "name": "python", 405 | "nbconvert_exporter": "python", 406 | "pygments_lexer": "ipython3", 407 | "version": "3.8.5" 408 | }, 409 | "toc": { 410 | "base_numbering": 1, 411 | "nav_menu": {}, 412 | "number_sections": false, 413 | "sideBar": false, 414 | "skip_h1_title": false, 415 | "title_cell": "Table of Contents", 416 | "title_sidebar": "Contents", 417 | "toc_cell": false, 418 | "toc_position": {}, 419 | "toc_section_display": false, 420 | "toc_window_display": false 421 | } 422 | }, 423 | "nbformat": 4, 424 | "nbformat_minor": 5 425 | } 426 | -------------------------------------------------------------------------------- /cours/02_interface_graphique/800px-TkInterColorCharts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/02_interface_graphique/800px-TkInterColorCharts.png -------------------------------------------------------------------------------- /cours/02_interface_graphique/exo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/02_interface_graphique/exo.png -------------------------------------------------------------------------------- /cours/02_interface_graphique/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/02_interface_graphique/grid.png -------------------------------------------------------------------------------- /cours/03_dictionnaire/cours_dict.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "#
Dictionnaires
" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "slide" 19 | } 20 | }, 21 | "source": [ 22 | "Les dictionnaires sont des structures de données qui, comme les tableaux, permettent de stocker des collections de valeurs. Ils sont utiles dans de nombreuses situations où les tableaux n'offrent plus assez de souplesse ou d'expressivité pour structurer un jeu de données. La particularité principale qui distingue les dictionnaires des tableaux, est que les données sont stockées sous forme de couples **(clef:valeur)**.\n" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": { 28 | "slideshow": { 29 | "slide_type": "subslide" 30 | } 31 | }, 32 | "source": [ 33 | "Dans un tableau\n", 34 | "\"Drawing\"\n", 35 | "on accède aux éléments par leur indice " 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": { 42 | "scrolled": true, 43 | "slideshow": { 44 | "slide_type": "subslide" 45 | } 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "tab_astro = [\"Terre\", \"Lune\", \"Soleil\"]\n", 50 | "print( tab_astro[1] )" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": { 56 | "slideshow": { 57 | "slide_type": "slide" 58 | } 59 | }, 60 | "source": [ 61 | "Dans un dictionnaire, **il n'y a pas de notion d'ordre et donc pas de position**. Pour accéder à une valeur, on utilise un autre moyen : une clef unique associée à chaque valeur lors de la définition du dictionnaire.\n", 62 | "\"Drawing\"\n", 63 | "Ainsi la commande `print(dic_astro['Satellite'] )` affichera \"Lune\".\n", 64 | "\n" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": { 70 | "slideshow": { 71 | "slide_type": "subslide" 72 | } 73 | }, 74 | "source": [ 75 | "Les dictionnaires sont aussi appelés **tableaux associatifs** dans le sens où ils associent des valeurs à des clefs (et non à des positions). Dans le dictionnaire `dico_astro` précédent, trois couples `clef:valeur` sont définis: `'Planete':'Terre'`, ``'Satellite':'Lune'`` et``'Etoile':'Soleil'``.\n", 76 | "\n", 77 | "On accède donc différemment aux valeurs stockées dans un tableau et dans un dictionnaire. La façon dont on veut accéder aux valeurs stockées va conditionner le choix entre une structure de données ou l'autre. \n", 78 | "\n", 79 | "Pour certains jeux de données, l'utilisation d'un tableau est naturelle car il y a une correspondance simple entre la valeur et sa position. Pour d'autres jeux de données, cette correspondance n'est pas évidente. Dans de nombreux cas, il sera avantageux d'utiliser des dictionnaires." 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": { 85 | "slideshow": { 86 | "slide_type": "slide" 87 | } 88 | }, 89 | "source": [ 90 | "## Définition d'un dictionnaire" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": { 96 | "slideshow": { 97 | "slide_type": "subslide" 98 | } 99 | }, 100 | "source": [ 101 | "Il existe deux façons de définir un dictionnaire.\n", 102 | "La première consiste à donner littéralement l'ensemble des couples `clef-valeur` lors de sa déclaration. La collection de couples `clef-valeur` est donnée entre accolades, et chaque couple est séparé par une virgule. Un couple `clef-valeur` est spécifié littéralement en donnant la clef suivie de la valeur qui lui est associée, les deux étant séparés par deux points, soit\n", 103 | "\n", 104 | "``dico={clef_1:valeur_1 , clef_2:valeur_2 , ...}``" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 1, 110 | "metadata": { 111 | "slideshow": { 112 | "slide_type": "subslide" 113 | } 114 | }, 115 | "outputs": [], 116 | "source": [ 117 | "dico_astro={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": { 123 | "slideshow": { 124 | "slide_type": "subslide" 125 | } 126 | }, 127 | "source": [ 128 | "La deuxième façon de définir un dictionnaire, consiste à déclarer un dictionnaire vide (`{}`), puis à le remplir. Par exemple, on peut définir le dictionnaire vide `dico_astro2`de la manière suivante :\n", 129 | "\n", 130 | "``dico_astro2 = {}``\n", 131 | "\n" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": { 137 | "slideshow": { 138 | "slide_type": "subslide" 139 | } 140 | }, 141 | "source": [ 142 | "L'ajout de nouveaux couples ``clef:valeur`` au dictionnaire ``dico_astro2`` ainsi initialisé se fait avec la syntaxe suivante:\n", 143 | "\n", 144 | "``dico_astro2[clef] = valeur``\n", 145 | "\n", 146 | "On obtient ainsi la suite d'intrusctions ci-dessous :" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 2, 152 | "metadata": { 153 | "slideshow": { 154 | "slide_type": "subslide" 155 | } 156 | }, 157 | "outputs": [ 158 | { 159 | "name": "stdout", 160 | "output_type": "stream", 161 | "text": [ 162 | "{'Planete': 'Terre', 'Satellite': 'Lune', 'Etoile': 'Soleil'}\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "dico_astro2 = {}\n", 168 | "dico_astro2['Planete']= 'Terre'\n", 169 | "dico_astro2['Satellite']= 'Lune'\n", 170 | "dico_astro2['Etoile']= 'Soleil'\n", 171 | "print(dico_astro2) " 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": { 177 | "slideshow": { 178 | "slide_type": "slide" 179 | } 180 | }, 181 | "source": [ 182 | "## Manipulation d'un dictionnaire" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": { 188 | "slideshow": { 189 | "slide_type": "subslide" 190 | } 191 | }, 192 | "source": [ 193 | "Les clefs des dictionnaires jouent en quelque sorte le rôle des indices dans les tableaux :\n", 194 | "\n", 195 | "- elles permettent d'accéder à une valeur stockée dans le dictionnaire,\n", 196 | "- elles permettent de modifier une valeur stockée dans le dictionnaire.\n", 197 | "\n", 198 | "Pour illustrer cela, on considère le tableau et le dictionnaires décrits précédemment et qui peuvent être définis de la manière suivante: \n" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 4, 204 | "metadata": { 205 | "slideshow": { 206 | "slide_type": "subslide" 207 | } 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "tab_astr=['Terre', 'Lune', 'Soleil']\n", 212 | "dico_astr={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}" 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": { 218 | "slideshow": { 219 | "slide_type": "slide" 220 | } 221 | }, 222 | "source": [ 223 | "### Accéder à une valeur" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": { 229 | "slideshow": { 230 | "slide_type": "subslide" 231 | } 232 | }, 233 | "source": [ 234 | " Dans un tableau la valeur correspondant à l'indice de position $i$ est accessible en faisant suivre le nom du tableau de l'indice donné entre crochets : " 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": 5, 240 | "metadata": { 241 | "slideshow": { 242 | "slide_type": "subslide" 243 | } 244 | }, 245 | "outputs": [ 246 | { 247 | "name": "stdout", 248 | "output_type": "stream", 249 | "text": [ 250 | "Lune\n" 251 | ] 252 | } 253 | ], 254 | "source": [ 255 | "print(tab_astr[1])" 256 | ] 257 | }, 258 | { 259 | "cell_type": "markdown", 260 | "metadata": { 261 | "slideshow": { 262 | "slide_type": "subslide" 263 | } 264 | }, 265 | "source": [ 266 | "- Dans un dictionnaire c'est la même chose, à la différence que l'indice de position est remplacé par la clef : " 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 6, 272 | "metadata": { 273 | "slideshow": { 274 | "slide_type": "subslide" 275 | } 276 | }, 277 | "outputs": [ 278 | { 279 | "name": "stdout", 280 | "output_type": "stream", 281 | "text": [ 282 | "Lune\n" 283 | ] 284 | } 285 | ], 286 | "source": [ 287 | "print(dico_astr['Satellite'])" 288 | ] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "metadata": { 293 | "slideshow": { 294 | "slide_type": "subslide" 295 | } 296 | }, 297 | "source": [ 298 | "**Lorsqu'on instancie une valeur d'un tableau avec un indice qui dépasse sa taille, l'interpréteur affiche un message d'erreur. Il en est de même si on utilise une clef non contenue dans le dictionnaire lors d'une instanciation.**\n", 299 | "\n", 300 | "L'instruction ci-dessous produit ainsi un message signalant une erreur de syntaxe." 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 7, 306 | "metadata": { 307 | "slideshow": { 308 | "slide_type": "subslide" 309 | } 310 | }, 311 | "outputs": [ 312 | { 313 | "ename": "KeyError", 314 | "evalue": "'Galaxie'", 315 | "output_type": "error", 316 | "traceback": [ 317 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 318 | "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", 319 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdico_astr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Galaxie'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 320 | "\u001b[0;31mKeyError\u001b[0m: 'Galaxie'" 321 | ] 322 | } 323 | ], 324 | "source": [ 325 | "print(dico_astr['Galaxie'])" 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": { 331 | "slideshow": { 332 | "slide_type": "slide" 333 | } 334 | }, 335 | "source": [ 336 | "### Modifier une valeur" 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": { 342 | "slideshow": { 343 | "slide_type": "subslide" 344 | } 345 | }, 346 | "source": [ 347 | "Pour modifier une valeur, on peut affecter une nouvelle valeur à la clef correspondant" 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "execution_count": 8, 353 | "metadata": { 354 | "scrolled": true, 355 | "slideshow": { 356 | "slide_type": "subslide" 357 | } 358 | }, 359 | "outputs": [ 360 | { 361 | "name": "stdout", 362 | "output_type": "stream", 363 | "text": [ 364 | "{'Planete': 'Terre', 'Satellite': 'Lune', 'Etoile': 'Soleil'}\n", 365 | "{'Planete': 'Mars', 'Satellite': 'Lune', 'Etoile': 'Soleil'}\n" 366 | ] 367 | } 368 | ], 369 | "source": [ 370 | "dico_astr={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}\n", 371 | "print(dico_astr)\n", 372 | "dico_astr['Planete']='Mars'\n", 373 | "print(dico_astr)" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": { 379 | "slideshow": { 380 | "slide_type": "slide" 381 | } 382 | }, 383 | "source": [ 384 | "### Ajouter une valeur" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": { 390 | "slideshow": { 391 | "slide_type": "subslide" 392 | } 393 | }, 394 | "source": [ 395 | "Pour ajouter une valeur dans un dictionnaire, on peut affecter une valeur à une clef non encore utilisée." 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 9, 401 | "metadata": { 402 | "scrolled": true, 403 | "slideshow": { 404 | "slide_type": "subslide" 405 | } 406 | }, 407 | "outputs": [ 408 | { 409 | "name": "stdout", 410 | "output_type": "stream", 411 | "text": [ 412 | "{'Planete': 'Terre', 'Satellite': 'Lune', 'Etoile': 'Soleil'}\n", 413 | "{'Planete': 'Terre', 'Satellite': 'Lune', 'Etoile': 'Soleil', 'Galaxie': 'Voie Lactee'}\n" 414 | ] 415 | } 416 | ], 417 | "source": [ 418 | "dico_astr={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}\n", 419 | "print(dico_astr)\n", 420 | "dico_astr['Galaxie'] = 'Voie Lactee'\n", 421 | "print(dico_astr)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "metadata": { 427 | "slideshow": { 428 | "slide_type": "subslide" 429 | } 430 | }, 431 | "source": [ 432 | "La syntaxe utilisée pour ajouter une valeur à un dictionnaire est la même que celle employée pour modifier la valeur associée à une clef existante. Pour ajouter une valeur (ou plus exactement ajouter un couple `clef:valeur`, il faut impérativement que la clef ne soit pas encore utilisée dans le dictionnaire. En d'autres termes :\n", 433 | "- Si on utilise une clef existante, la syntaxe conduit à changer la valeur associée à la clef, et le dictionnaire ne change pas de taille,\n", 434 | "- Si on utilise une nouvelle clef, la syntaxe ajoute un couple `clef:valeur` au dictionnaire et augmente sa taille." 435 | ] 436 | }, 437 | { 438 | "cell_type": "markdown", 439 | "metadata": { 440 | "slideshow": { 441 | "slide_type": "slide" 442 | } 443 | }, 444 | "source": [ 445 | "## Quelques fonctions liées à l'utilisation de dictionnaires " 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": { 451 | "slideshow": { 452 | "slide_type": "subslide" 453 | } 454 | }, 455 | "source": [ 456 | "### Accéder à la liste des clefs et des valeurs" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "metadata": { 462 | "slideshow": { 463 | "slide_type": "subslide" 464 | } 465 | }, 466 | "source": [ 467 | "* **list()** : dans certains cas, il peut être utile d'avoir accès à la liste des clefs d'un dictionnaire. Cela est réalisé par \n", 468 | "la méthode ``list()`` qui renvoie un tableau dont les éléments sont les clefs du dictionnaire auquel la méthode s'applique." 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": 10, 474 | "metadata": { 475 | "slideshow": { 476 | "slide_type": "subslide" 477 | } 478 | }, 479 | "outputs": [ 480 | { 481 | "name": "stdout", 482 | "output_type": "stream", 483 | "text": [ 484 | "['Planete', 'Satellite', 'Etoile']\n" 485 | ] 486 | } 487 | ], 488 | "source": [ 489 | "dico_astr={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}\n", 490 | "print(list(dico_astr))" 491 | ] 492 | }, 493 | { 494 | "cell_type": "markdown", 495 | "metadata": { 496 | "slideshow": { 497 | "slide_type": "subslide" 498 | } 499 | }, 500 | "source": [ 501 | "* **values()** : on peut utiliser la méthode `values()` qui renvoie un tableau dont les éléments sont les valeurs du dictionnaire à laquelle la méthode s'applique :\n", 502 | "\n", 503 | "* **list()** : on utilise alors la fonction `list()`pour extraire les éléments du résultat et en faire un tableau exploitable. " 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": 11, 509 | "metadata": { 510 | "slideshow": { 511 | "slide_type": "subslide" 512 | } 513 | }, 514 | "outputs": [ 515 | { 516 | "name": "stdout", 517 | "output_type": "stream", 518 | "text": [ 519 | "['Terre', 'Lune', 'Soleil']\n" 520 | ] 521 | } 522 | ], 523 | "source": [ 524 | "dico_astr={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}\n", 525 | "print(list(dico_astr.values()))\n" 526 | ] 527 | }, 528 | { 529 | "cell_type": "markdown", 530 | "metadata": { 531 | "slideshow": { 532 | "slide_type": "slide" 533 | } 534 | }, 535 | "source": [ 536 | "### Supprimer une entrée (clef-valeur)" 537 | ] 538 | }, 539 | { 540 | "cell_type": "markdown", 541 | "metadata": { 542 | "slideshow": { 543 | "slide_type": "subslide" 544 | } 545 | }, 546 | "source": [ 547 | "L'instruction `del(mondico[cl])` permet de supprimer du dictionnaire `mondico` la clef `cl` et la valeur associée." 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "execution_count": 12, 553 | "metadata": { 554 | "slideshow": { 555 | "slide_type": "subslide" 556 | } 557 | }, 558 | "outputs": [ 559 | { 560 | "name": "stdout", 561 | "output_type": "stream", 562 | "text": [ 563 | "{'Planete': 'Terre', 'Satellite': 'Lune'}\n" 564 | ] 565 | } 566 | ], 567 | "source": [ 568 | "dico_astr={'Planete':'Terre', 'Satellite':'Lune', 'Etoile':'Soleil'}\n", 569 | "del(dico_astr['Etoile'])\n", 570 | "print(dico_astr)" 571 | ] 572 | }, 573 | { 574 | "cell_type": "markdown", 575 | "metadata": { 576 | "slideshow": { 577 | "slide_type": "slide" 578 | } 579 | }, 580 | "source": [ 581 | "## Les clefs des dictionnaires" 582 | ] 583 | }, 584 | { 585 | "cell_type": "markdown", 586 | "metadata": { 587 | "slideshow": { 588 | "slide_type": "subslide" 589 | } 590 | }, 591 | "source": [ 592 | "**Attention** : Les clés ne sont pas obligatoirement des chaînes de caractères." 593 | ] 594 | }, 595 | { 596 | "cell_type": "code", 597 | "execution_count": 13, 598 | "metadata": { 599 | "slideshow": { 600 | "slide_type": "subslide" 601 | } 602 | }, 603 | "outputs": [ 604 | { 605 | "name": "stdout", 606 | "output_type": "stream", 607 | "text": [ 608 | "{1: 'Terre', 2: 'Lune', 3: 'Soleil'}\n" 609 | ] 610 | } 611 | ], 612 | "source": [ 613 | "dico_astr={1:'Terre', 2:'Lune', 3:'Soleil'}\n", 614 | "print(dico_astr)" 615 | ] 616 | }, 617 | { 618 | "cell_type": "markdown", 619 | "metadata": { 620 | "slideshow": { 621 | "slide_type": "subslide" 622 | } 623 | }, 624 | "source": [ 625 | "Ce fonctionnement ressemble à celui d’un tableau mais ce n’est pas le cas.\n", 626 | "Si on supprime par exemple l’indice 2, les clés d’indice supérieur à l’indice supprimé ne sont pas décalées pour autant. " 627 | ] 628 | }, 629 | { 630 | "cell_type": "code", 631 | "execution_count": 14, 632 | "metadata": { 633 | "slideshow": { 634 | "slide_type": "subslide" 635 | } 636 | }, 637 | "outputs": [ 638 | { 639 | "name": "stdout", 640 | "output_type": "stream", 641 | "text": [ 642 | "{2: 'Lune', 3: 'Soleil'}\n" 643 | ] 644 | } 645 | ], 646 | "source": [ 647 | "del(dico_astr[1])\n", 648 | "print(dico_astr) " 649 | ] 650 | }, 651 | { 652 | "cell_type": "markdown", 653 | "metadata": { 654 | "slideshow": { 655 | "slide_type": "subslide" 656 | } 657 | }, 658 | "source": [ 659 | "Un même dictionnaire peut admettre des clefs de différents types." 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "execution_count": null, 665 | "metadata": { 666 | "slideshow": { 667 | "slide_type": "subslide" 668 | } 669 | }, 670 | "outputs": [], 671 | "source": [ 672 | "semaine={}\n", 673 | "semaine[1]='Lundi'\n", 674 | "semaine['couleur']='rouge'\n", 675 | "print(semaine)" 676 | ] 677 | }, 678 | { 679 | "cell_type": "markdown", 680 | "metadata": { 681 | "slideshow": { 682 | "slide_type": "slide" 683 | } 684 | }, 685 | "source": [ 686 | "# Fusionner deux dictionnaires" 687 | ] 688 | }, 689 | { 690 | "cell_type": "markdown", 691 | "metadata": { 692 | "slideshow": { 693 | "slide_type": "subslide" 694 | } 695 | }, 696 | "source": [ 697 | "La méthode `.copy()` permet de copier le dictionnaire et la méthode `.update(..)` permet de concaténer le dictionnaire passé en paramètre à celui auquel est appliqué la méthode." 698 | ] 699 | }, 700 | { 701 | "cell_type": "code", 702 | "execution_count": 15, 703 | "metadata": { 704 | "slideshow": { 705 | "slide_type": "subslide" 706 | } 707 | }, 708 | "outputs": [ 709 | { 710 | "name": "stdout", 711 | "output_type": "stream", 712 | "text": [ 713 | "{'a': 100, 'b': 200, 'x': 300, 'y': 200}\n" 714 | ] 715 | } 716 | ], 717 | "source": [ 718 | "dic1 = {'a': 100, 'b': 200}\n", 719 | "dic2 = {'x': 300, 'y': 200}\n", 720 | "dic=dic1.copy()\n", 721 | "dic.update(dic2)\n", 722 | "print(dic)" 723 | ] 724 | }, 725 | { 726 | "cell_type": "markdown", 727 | "metadata": { 728 | "slideshow": { 729 | "slide_type": "slide" 730 | } 731 | }, 732 | "source": [ 733 | "# Construire un dictionnaire à partir de deux tableaux " 734 | ] 735 | }, 736 | { 737 | "cell_type": "markdown", 738 | "metadata": { 739 | "slideshow": { 740 | "slide_type": "subslide" 741 | } 742 | }, 743 | "source": [ 744 | "Pour construire un dictionnaire il est possible de fusionner deux tableaux en utilisant la fonction `zip(clefs, valeurs)` " 745 | ] 746 | }, 747 | { 748 | "cell_type": "code", 749 | "execution_count": 16, 750 | "metadata": { 751 | "slideshow": { 752 | "slide_type": "subslide" 753 | } 754 | }, 755 | "outputs": [ 756 | { 757 | "name": "stdout", 758 | "output_type": "stream", 759 | "text": [ 760 | "{'red': '#FF0000', 'green': '#008000', 'blue': '#0000FF'}\n" 761 | ] 762 | } 763 | ], 764 | "source": [ 765 | "keys = ['red', 'green', 'blue']\n", 766 | "values = ['#FF0000','#008000', '#0000FF']\n", 767 | "color_dictionary = dict(zip(keys, values))\n", 768 | "print(color_dictionary)" 769 | ] 770 | }, 771 | { 772 | "cell_type": "markdown", 773 | "metadata": { 774 | "slideshow": { 775 | "slide_type": "slide" 776 | } 777 | }, 778 | "source": [ 779 | "# Existence d'une clé" 780 | ] 781 | }, 782 | { 783 | "cell_type": "markdown", 784 | "metadata": { 785 | "slideshow": { 786 | "slide_type": "subslide" 787 | } 788 | }, 789 | "source": [ 790 | "Pour vérifier si une clé existe dans un dictionnaire, on peut utiliser le test d’appartenance avec l'instruction `in` qui renvoie un booléen :" 791 | ] 792 | }, 793 | { 794 | "cell_type": "code", 795 | "execution_count": 17, 796 | "metadata": { 797 | "slideshow": { 798 | "slide_type": "subslide" 799 | } 800 | }, 801 | "outputs": [ 802 | { 803 | "name": "stdout", 804 | "output_type": "stream", 805 | "text": [ 806 | "La clé 'red' existe \n", 807 | "La clé 'red' existe \n" 808 | ] 809 | } 810 | ], 811 | "source": [ 812 | "cles=list(color_dictionary)\n", 813 | "\n", 814 | "i=0\n", 815 | "while i" 847 | ] 848 | }, 849 | { 850 | "cell_type": "code", 851 | "execution_count": 18, 852 | "metadata": { 853 | "slideshow": { 854 | "slide_type": "subslide" 855 | } 856 | }, 857 | "outputs": [ 858 | { 859 | "name": "stdout", 860 | "output_type": "stream", 861 | "text": [ 862 | "{'Satellites': 1, 'Rayon': 6378.137, 'Tellurique': True, 'Oceans': ['Pacifique', 'Atlantique', 'Indien'], 'Superficie': {'Pacifique': 49.7, 'Atlantique': 29.5, 'Indien': 20.4}}\n" 863 | ] 864 | } 865 | ], 866 | "source": [ 867 | "terre= {}\n", 868 | "terre['Satellites']= 1\n", 869 | "terre['Rayon']= 6378.137\n", 870 | "terre['Tellurique']= True\n", 871 | "terre['Oceans']= ['Pacifique', 'Atlantique', 'Indien']\n", 872 | "terre['Superficie']= {'Pacifique':49.7, 'Atlantique':29.5,'Indien':20.4}\n", 873 | "print(terre)" 874 | ] 875 | }, 876 | { 877 | "cell_type": "markdown", 878 | "metadata": { 879 | "slideshow": { 880 | "slide_type": "slide" 881 | } 882 | }, 883 | "source": [ 884 | "# Tableau de dictionnaires" 885 | ] 886 | }, 887 | { 888 | "cell_type": "markdown", 889 | "metadata": { 890 | "slideshow": { 891 | "slide_type": "subslide" 892 | } 893 | }, 894 | "source": [ 895 | "En créant un tableau de dictionnaires qui possèdent les mêmes clés, on obtient une structure qui ressemble à une base de données." 896 | ] 897 | }, 898 | { 899 | "cell_type": "code", 900 | "execution_count": 20, 901 | "metadata": { 902 | "slideshow": { 903 | "slide_type": "subslide" 904 | } 905 | }, 906 | "outputs": [ 907 | { 908 | "name": "stdout", 909 | "output_type": "stream", 910 | "text": [ 911 | "{'nom': 'Jean', 'prenom': 'Martin'}\n", 912 | "[{'nom': 'Jean', 'prenom': 'Martin'}, {'BDP': 12, 'Sys': 14, 'web': 18}]\n" 913 | ] 914 | } 915 | ], 916 | "source": [ 917 | "fiche=[]\n", 918 | "id={}\n", 919 | "notes={}\n", 920 | "id['nom']= \"Jean\"\n", 921 | "id['prenom'] =\"Martin\"\n", 922 | "notes['BDP']= 12\n", 923 | "notes['Sys']= 14\n", 924 | "notes['web']= 18\n", 925 | "fiche.append(id)\n", 926 | "fiche.append(notes)\n", 927 | "print(fiche[0])\n", 928 | "print(fiche)" 929 | ] 930 | }, 931 | { 932 | "cell_type": "markdown", 933 | "metadata": { 934 | "slideshow": { 935 | "slide_type": "slide" 936 | } 937 | }, 938 | "source": [ 939 | "## Récapitulatif et comparaison Dictionnaire/Tableau" 940 | ] 941 | }, 942 | { 943 | "cell_type": "markdown", 944 | "metadata": { 945 | "slideshow": { 946 | "slide_type": "subslide" 947 | } 948 | }, 949 | "source": [ 950 | "| Opération | Tableau | Dictionnaire |\n", 951 | "|-----------|-------------------|---------------|\n", 952 | "|Définition d'un conteneur vide | t=[] | d={} |\n", 953 | "|Définition d'un littéral | t=[val_1, val_2, ...]| d={clef_1:val_1,clef_2:val_2, ...}|\n", 954 | "|Appel d'une valeur | t[indice]| d[clef]|\n", 955 | "|Ajout d'une valeur| t.append(nlle_val)|d[clef]=nlle_val |\n", 956 | "|Modification d'une valeur| t[indice]=nlle_val|d[clef]=nlle_val |\n", 957 | "|Nombre d'éléments| len(t)|len(d) |\n", 958 | "|Suppression d'un élément| del(t[indice])|del(d[clef]) |" 959 | ] 960 | }, 961 | { 962 | "cell_type": "markdown", 963 | "metadata": { 964 | "slideshow": { 965 | "slide_type": "slide" 966 | } 967 | }, 968 | "source": [ 969 | "# Le format JSON" 970 | ] 971 | }, 972 | { 973 | "cell_type": "markdown", 974 | "metadata": { 975 | "slideshow": { 976 | "slide_type": "subslide" 977 | } 978 | }, 979 | "source": [ 980 | "Le format JavaScript Object Notation (JSON) est issu de la notation des objets dans le langage JavaScript. c'est un format de données très répandu permettant de stocker des données sous une forme structurée. Il ne comporte que des associations clés→valeurs (à l’instar des dictionnaires), ainsi que des listes ordonnées de valeurs (comme les listes en Python). Une valeur peut être une autre association clés→valeurs, une liste de valeurs, un entier, un nombre réel, une chaîne de caractères, un booléen ou une valeur nulle.Sa syntaxe est similaire à celle des dictionnaires Python." 981 | ] 982 | }, 983 | { 984 | "cell_type": "code", 985 | "execution_count": null, 986 | "metadata": { 987 | "slideshow": { 988 | "slide_type": "subslide" 989 | } 990 | }, 991 | "outputs": [], 992 | "source": [ 993 | "{\n", 994 | " \"nom cours\" : \"BDP\",\n", 995 | " \"theme\" : \"Algorithmique\",\n", 996 | " \"etudiants\" : [\n", 997 | " {\n", 998 | " \"nom\" : \"Martin\",\n", 999 | " \"prenom\" : \"Jean\",\n", 1000 | " \"Dept\" : \"95\" \n", 1001 | " },\n", 1002 | " {\n", 1003 | " \"nom\" : \"Mohamed\",\n", 1004 | " \"prenom\" : \"Ali\",\n", 1005 | " \"Dept\" : \"93\" \n", 1006 | " },\n", 1007 | " {\n", 1008 | " \"nom\" : \"Lina\",\n", 1009 | " \"prenom\" : \"Bertrand\",\n", 1010 | " \"Dept\" : \"95\" \n", 1011 | " }\n", 1012 | " ]\n", 1013 | "\n", 1014 | "}" 1015 | ] 1016 | }, 1017 | { 1018 | "cell_type": "markdown", 1019 | "metadata": { 1020 | "slideshow": { 1021 | "slide_type": "slide" 1022 | } 1023 | }, 1024 | "source": [ 1025 | "## Lecture et écriture de fichier JSON" 1026 | ] 1027 | }, 1028 | { 1029 | "cell_type": "markdown", 1030 | "metadata": { 1031 | "slideshow": { 1032 | "slide_type": "subslide" 1033 | } 1034 | }, 1035 | "source": [ 1036 | "Pour manipuler les fichiers JSON, on utilise le module `json` de Python." 1037 | ] 1038 | }, 1039 | { 1040 | "cell_type": "markdown", 1041 | "metadata": { 1042 | "slideshow": { 1043 | "slide_type": "subslide" 1044 | } 1045 | }, 1046 | "source": [ 1047 | "### Lire un fichier JSON" 1048 | ] 1049 | }, 1050 | { 1051 | "cell_type": "markdown", 1052 | "metadata": { 1053 | "slideshow": { 1054 | "slide_type": "subslide" 1055 | } 1056 | }, 1057 | "source": [ 1058 | "La fonction `loads(texteJSON)` permet de décoder le texte JSON passé en argument et de le transformer en dictionnaire ou une liste" 1059 | ] 1060 | }, 1061 | { 1062 | "cell_type": "code", 1063 | "execution_count": 21, 1064 | "metadata": { 1065 | "slideshow": { 1066 | "slide_type": "subslide" 1067 | } 1068 | }, 1069 | "outputs": [ 1070 | { 1071 | "name": "stdout", 1072 | "output_type": "stream", 1073 | "text": [ 1074 | "{'nom cours': 'BDP', 'theme': 'Algorithmique', 'etudiants': [{'nom': 'Martin', 'prenom': 'Jean', 'Dept': '95'}, {'nom': 'Mohamed', 'prenom': 'Ali', 'Dept': '93'}, {'nom': 'Lina', 'prenom': 'Bertrand', 'Dept': '95'}]}\n" 1075 | ] 1076 | } 1077 | ], 1078 | "source": [ 1079 | "#import json\n", 1080 | "from json import *\n", 1081 | "fichier = open (\"./files/bdp.json\",\"r\")\n", 1082 | "strjson=fichier.read()\n", 1083 | "fichier.close()\n", 1084 | "#cours = json.loads(strjson)\n", 1085 | "cours = loads(strjson)\n", 1086 | "print (cours)" 1087 | ] 1088 | }, 1089 | { 1090 | "cell_type": "markdown", 1091 | "metadata": { 1092 | "slideshow": { 1093 | "slide_type": "subslide" 1094 | } 1095 | }, 1096 | "source": [ 1097 | "Ainsi il est possible d'accéder aux éléments du dictionnaire comme suit : " 1098 | ] 1099 | }, 1100 | { 1101 | "cell_type": "code", 1102 | "execution_count": 22, 1103 | "metadata": { 1104 | "slideshow": { 1105 | "slide_type": "subslide" 1106 | } 1107 | }, 1108 | "outputs": [ 1109 | { 1110 | "name": "stdout", 1111 | "output_type": "stream", 1112 | "text": [ 1113 | "BDP\n" 1114 | ] 1115 | } 1116 | ], 1117 | "source": [ 1118 | "print(cours['nom cours'])" 1119 | ] 1120 | }, 1121 | { 1122 | "cell_type": "code", 1123 | "execution_count": 23, 1124 | "metadata": { 1125 | "slideshow": { 1126 | "slide_type": "fragment" 1127 | } 1128 | }, 1129 | "outputs": [ 1130 | { 1131 | "name": "stdout", 1132 | "output_type": "stream", 1133 | "text": [ 1134 | "Algorithmique\n" 1135 | ] 1136 | } 1137 | ], 1138 | "source": [ 1139 | "print (cours['theme'])" 1140 | ] 1141 | }, 1142 | { 1143 | "cell_type": "code", 1144 | "execution_count": 24, 1145 | "metadata": { 1146 | "slideshow": { 1147 | "slide_type": "fragment" 1148 | } 1149 | }, 1150 | "outputs": [ 1151 | { 1152 | "name": "stdout", 1153 | "output_type": "stream", 1154 | "text": [ 1155 | "[{'nom': 'Martin', 'prenom': 'Jean', 'Dept': '95'}, {'nom': 'Mohamed', 'prenom': 'Ali', 'Dept': '93'}, {'nom': 'Lina', 'prenom': 'Bertrand', 'Dept': '95'}]\n" 1156 | ] 1157 | } 1158 | ], 1159 | "source": [ 1160 | "identite=cours['etudiants']\n", 1161 | "print(identite)" 1162 | ] 1163 | }, 1164 | { 1165 | "cell_type": "markdown", 1166 | "metadata": { 1167 | "slideshow": { 1168 | "slide_type": "subslide" 1169 | } 1170 | }, 1171 | "source": [ 1172 | "Comme le resultat de la variable `identite` est un tableau, alors il est possible d'accéder aux éléments en utilisant l'accès direct ou en utilisant les boucles. " 1173 | ] 1174 | }, 1175 | { 1176 | "cell_type": "code", 1177 | "execution_count": 25, 1178 | "metadata": { 1179 | "slideshow": { 1180 | "slide_type": "subslide" 1181 | } 1182 | }, 1183 | "outputs": [ 1184 | { 1185 | "name": "stdout", 1186 | "output_type": "stream", 1187 | "text": [ 1188 | "{'nom': 'Martin', 'prenom': 'Jean', 'Dept': '95'}\n", 1189 | "3\n" 1190 | ] 1191 | } 1192 | ], 1193 | "source": [ 1194 | "iddico=identite[0]\n", 1195 | "print (iddico)\n", 1196 | "print(len(iddico))" 1197 | ] 1198 | }, 1199 | { 1200 | "cell_type": "code", 1201 | "execution_count": 26, 1202 | "metadata": { 1203 | "slideshow": { 1204 | "slide_type": "fragment" 1205 | } 1206 | }, 1207 | "outputs": [ 1208 | { 1209 | "name": "stdout", 1210 | "output_type": "stream", 1211 | "text": [ 1212 | "{'nom': 'Martin', 'prenom': 'Jean', 'Dept': '95'}\n", 1213 | "{'nom': 'Mohamed', 'prenom': 'Ali', 'Dept': '93'}\n", 1214 | "{'nom': 'Lina', 'prenom': 'Bertrand', 'Dept': '95'}\n" 1215 | ] 1216 | } 1217 | ], 1218 | "source": [ 1219 | "i=0\n", 1220 | "while (i\n", 1313 | "La fonction `dump(dictionnaire, fichier, indent=n)` permet d'enregistrer en texte au format JSON le dictionnaire directement dans le fichier précédemment ouvert, avec une éventuelle indentation." 1314 | ] 1315 | }, 1316 | { 1317 | "cell_type": "code", 1318 | "execution_count": 30, 1319 | "metadata": { 1320 | "slideshow": { 1321 | "slide_type": "subslide" 1322 | } 1323 | }, 1324 | "outputs": [], 1325 | "source": [ 1326 | "from json import *\n", 1327 | "cours2 = {'nom cours': 'Java',\n", 1328 | " 'theme': 'Algorithmique',\n", 1329 | " 'etudiants': [{'nom': 'Martin', 'prenom': 'Jean', 'Dept': '95'},\n", 1330 | " {'nom': 'Mohamed', 'prenom': 'Ali', 'Dept': '93'},\n", 1331 | " {'nom': 'dupond', 'prenom': 'Bertrand', 'Dept': '95'}]}" 1332 | ] 1333 | }, 1334 | { 1335 | "cell_type": "code", 1336 | "execution_count": 31, 1337 | "metadata": { 1338 | "slideshow": { 1339 | "slide_type": "subslide" 1340 | } 1341 | }, 1342 | "outputs": [ 1343 | { 1344 | "name": "stdout", 1345 | "output_type": "stream", 1346 | "text": [ 1347 | "{\n", 1348 | " \"etudiants\": [\n", 1349 | " {\n", 1350 | " \"Dept\": \"95\",\n", 1351 | " \"nom\": \"Martin\",\n", 1352 | " \"prenom\": \"Jean\"\n", 1353 | " },\n", 1354 | " {\n", 1355 | " \"Dept\": \"93\",\n", 1356 | " \"nom\": \"Mohamed\",\n", 1357 | " \"prenom\": \"Ali\"\n", 1358 | " },\n", 1359 | " {\n", 1360 | " \"Dept\": \"95\",\n", 1361 | " \"nom\": \"dupond\",\n", 1362 | " \"prenom\": \"Bertrand\"\n", 1363 | " }\n", 1364 | " ],\n", 1365 | " \"nom cours\": \"Java\",\n", 1366 | " \"theme\": \"Algorithmique\"\n", 1367 | "}\n" 1368 | ] 1369 | } 1370 | ], 1371 | "source": [ 1372 | "fichier2 = open (\"./files/coursjava.json\",\"w\")\n", 1373 | "\n", 1374 | "cours2_json = dumps(cours2,sort_keys=True,indent=4)\n", 1375 | "print(cours2_json)\n", 1376 | "\n", 1377 | "dump(cours2, fichier2, indent=4)\n", 1378 | "\n", 1379 | "fichier2.close()" 1380 | ] 1381 | }, 1382 | { 1383 | "cell_type": "code", 1384 | "execution_count": null, 1385 | "metadata": {}, 1386 | "outputs": [], 1387 | "source": [] 1388 | } 1389 | ], 1390 | "metadata": { 1391 | "celltoolbar": "Diaporama", 1392 | "kernelspec": { 1393 | "display_name": "Python 3", 1394 | "language": "python", 1395 | "name": "python3" 1396 | }, 1397 | "language_info": { 1398 | "codemirror_mode": { 1399 | "name": "ipython", 1400 | "version": 3 1401 | }, 1402 | "file_extension": ".py", 1403 | "mimetype": "text/x-python", 1404 | "name": "python", 1405 | "nbconvert_exporter": "python", 1406 | "pygments_lexer": "ipython3", 1407 | "version": "3.8.5" 1408 | }, 1409 | "latex_envs": { 1410 | "LaTeX_envs_menu_present": true, 1411 | "autoclose": false, 1412 | "autocomplete": true, 1413 | "bibliofile": "biblio.bib", 1414 | "cite_by": "apalike", 1415 | "current_citInitial": 1, 1416 | "eqLabelWithNumbers": true, 1417 | "eqNumInitial": 1, 1418 | "hotkeys": { 1419 | "equation": "Ctrl-E", 1420 | "itemize": "Ctrl-I" 1421 | }, 1422 | "labels_anchors": false, 1423 | "latex_user_defs": false, 1424 | "report_style_numbering": false, 1425 | "user_envs_cfg": false 1426 | }, 1427 | "toc": { 1428 | "base_numbering": 1, 1429 | "nav_menu": {}, 1430 | "number_sections": false, 1431 | "sideBar": false, 1432 | "skip_h1_title": false, 1433 | "title_cell": "Table of Contents", 1434 | "title_sidebar": "Contents", 1435 | "toc_cell": false, 1436 | "toc_position": {}, 1437 | "toc_section_display": false, 1438 | "toc_window_display": false 1439 | } 1440 | }, 1441 | "nbformat": 4, 1442 | "nbformat_minor": 2 1443 | } 1444 | -------------------------------------------------------------------------------- /cours/03_dictionnaire/files/bdp.json: -------------------------------------------------------------------------------- 1 | { 2 | "nom cours" : "BDP", 3 | "theme" : "Algorithmique", 4 | "etudiants" : [ 5 | { 6 | "nom" : "Martin", 7 | "prenom" : "Jean", 8 | "Dept" : "95" 9 | }, 10 | { 11 | "nom" : "Mohamed", 12 | "prenom" : "Ali", 13 | "Dept" : "93" 14 | }, 15 | { 16 | "nom" : "Lina", 17 | "prenom" : "Bertrand", 18 | "Dept" : "95" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /cours/03_dictionnaire/files/coursjava.json: -------------------------------------------------------------------------------- 1 | { 2 | "nom cours": "Java", 3 | "theme": "Algorithmique", 4 | "etudiants": [ 5 | { 6 | "nom": "Martin", 7 | "prenom": "Jean", 8 | "Dept": "95" 9 | }, 10 | { 11 | "nom": "Mohamed", 12 | "prenom": "Ali", 13 | "Dept": "93" 14 | }, 15 | { 16 | "nom": "dupond", 17 | "prenom": "Bertrand", 18 | "Dept": "95" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /cours/04_fichier/cours_file.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "#
Fichiers texte
" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "slideshow": { 18 | "slide_type": "subslide" 19 | } 20 | }, 21 | "source": [ 22 | "# Lecture et écriture dans les fichiers\n", 23 | "\n", 24 | "Les outils informatiques ont été développés dans le but de travailler sur de gros volumes de données. Les données ne sont pas saisies par l'utilisateur lors de l'exécution du programme mais le plus souvent lues dans des fichiers, puis stockées dans des structures de données telles que les tableaux ou les dictionnaires. \n", 25 | "\n", 26 | "Les fichiers permettent en effet de stocker de façon stable de l'information dans un système informatique. Ces fichiers peuvent prendre différents formats. On n'utilise dans ce cours que trois types de fichiers, mais les règles présentées ici sont assez facilement généralisables à d'autres formats:\n" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "slideshow": { 33 | "slide_type": "subslide" 34 | } 35 | }, 36 | "source": [ 37 | "- les fichiers `texte` non formatés, c'est à dire des fichiers dont le contenu est directement lisible par un être humain qui ouvrirait le fichier avec un éditeur de texte simple ne respectant pas de format particulier,\n", 38 | "- les fichiers `CSV` qui sont des fichiers texte respectant un format particulier adapté aux données tabulaires,\n", 39 | "- les fichiers `JSON` qui sont aussi des fichiers texte respectant un format particulier adapté aux données de type association clé/valeur.\n" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "slideshow": { 46 | "slide_type": "subslide" 47 | } 48 | }, 49 | "source": [ 50 | "\n", 51 | "De nombreux autres types de fichiers existent dont certains sont dans un format binaire (pdf, png, gif). Afin de lire ces fichiers il faut le plus souvent disposer d'une librairie adaptée proposant des fonctions de lecture appropriées au format. Dans ce cas, la documentation de la librairie indique les fonctions d'intéraction existantes et les structures de données qui leur sont associées.\n", 52 | "\n" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": { 58 | "slideshow": { 59 | "slide_type": "subslide" 60 | } 61 | }, 62 | "source": [ 63 | "## Généralités\n", 64 | "Afin d'importer des données depuis un fichier vers la mémoire d'un programme, il faut:\n", 65 | "- un sous-programme:\n", 66 | " - interagissant avec le système de fichier pour localiser le fichier dans la mémoire - - sur un disque dur par exemple - et l'*ouvrir* afin de pouvoir lire/écrire son contenu,\n", 67 | " - permettant de naviguer dans le fichier *i.e.* de déplacer le curseur de lecture/écriture - pour passer d'un caractère à l'autre, d'un mot à l'autre ou d'une ligne à l'autre, ...\n", 68 | " - permettant de stocker dans une variable de la mémoire du programme une donnée lue dans le fichier pour pouvoir le cas échéant l'utiliser dans le programme ou de lire une donnée d'une variable de la mémoire du programme pour l'écrire dans le fichier.\n", 69 | "- dans le cas des fichiers formatés, il faut aussi un algorithme permettant de lire le contenu du fichier en suivant son format et ainsi structurer dans la mémoire du programmes les différentes informations encodées dans le format.\n", 70 | "\n", 71 | "**NB :** Les opérations de lecture/écriture sont exécutées à la position du curseur.\n", 72 | "\n" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": { 78 | "slideshow": { 79 | "slide_type": "slide" 80 | } 81 | }, 82 | "source": [ 83 | "## Interaction avec le système de fichiers\n", 84 | "\n", 85 | "Pour qu'un programme puisse utiliser les données inscrites dans un fichier, ce dernier doit pouvoir être *accessible* et *lu* par le programme. De façon symétrique, un programme souhaitant *sauvegarder* des données doit pouvoir accéder à l'emplacement du fichier les *écrire* des données dans celui-ci.\n", 86 | "\n", 87 | "Dans le cas de la *lecture* comme dans le cas de *l'écriture*, le fichier est identifié par un chemin (appelé `path`) qui est composé de son nom précédé de la séquence des répertoires de l'arborescence du système de fichiers qu'il faut traverser pour l'atteindre. Le chemin peut être donné comme un chemin absolu ou relatif. On n'utilise ici que des chemins relatifs au répertoire contenant le notebook (qui est supposé contenir un répertoire `files/`).\n", 88 | "\n", 89 | "La mécanique de la lecture et de l'écriture d'un fichier sont assez similaires et introduites ci-dessous:\n", 90 | "\n", 91 | "La première étape consiste à ouvrir le fichier. Ceci est réalisé par la fonction `open()`. Cette fonction admet 2 paramètres:\n", 92 | "- le premier paramètre est le nom du fichier. Il s'agit d'une chaîne de caractères qui indique le chemin du fichier (`path`).\n", 93 | "- le second paramètre indique le mode d'ouverture du fichier. Il y a 4 modes d'ouverture de fichier possibles:\n" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": { 99 | "slideshow": { 100 | "slide_type": "subslide" 101 | } 102 | }, 103 | "source": [ 104 | "\n", 105 | "| Mode | Description | Remarques |\n", 106 | "|--------|-------------------|---------------|\n", 107 | "|`r` | Read - Valeur par défaut. Ouvre le fichier en lecture et renvoie une erreur si le fichier n'existe pas.| |\n", 108 | "|`w` | Write - Ouvre le fichier en écriture et crée le fichier si il ne le trouve pas.| **Attention** Si le fichier prééxiste, le contenu intial du fichier est écrasé par le nouveau contenu.|\n", 109 | "|`a` | Append - Ouvre le fichier en écriture à la fin et crée le fichier si il ne le trouve pas.| **Attention** Si le fichier prééxiste, le contenu intial du fichier est préservé, le nouveau contenu est écrit à la suite du contenu prééxistant.|\n", 110 | "|`x` | Create - Crée le fichier ou retourne une erreur si il existe déjà.| |\n", 111 | "\n", 112 | "Cette fonction retourne un *objet fichier* qui doit être affecté à une variable. Cette variable représente le fichier durant l'exécution de votre programme.\n", 113 | "\n", 114 | "**NB:** Lors de l'ouverture d'un fichier, le curseur est automatiquement positionné au début du fichier *i.e.* devant le premier caratère.\n", 115 | "\n", 116 | "Voici un exemple de procédure d'ouverture d'un fichier en lecture" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": { 123 | "slideshow": { 124 | "slide_type": "subslide" 125 | } 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "# Définition du chemin vers le fichier\n", 130 | "path = \"files/lorem.txt\"\n", 131 | "# Définition du mode d'ouverture du fichier en lecture\n", 132 | "mode = 'r'\n", 133 | "# Ouverture du fichier et association du flux à une variable\n", 134 | "f_input = open(path, mode)\n", 135 | "f_input.close() #Il faut fermer le dossier pour exécuter la cellule" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": { 141 | "slideshow": { 142 | "slide_type": "subslide" 143 | } 144 | }, 145 | "source": [ 146 | "A ce moment de l'exécution du programme une variable `f_input` est définie dans la mémoire et permet d'accéder au contenu du fichier en lecture au moyen de différentes fonctions.\n", 147 | "\n", 148 | "**Bonne pratique** : Tout fichier ouvert par un programme (en écriture comme en lecture) **DOIT** être fermé par le programme. Cette fermeture doit avoir lieu au plus tôt, dès que le programme n'a plus à écrire ou lire dans le fichier et dans tout les cas avant la fin de l'exécution du programme. La fermeture du fichier s'opère au moyen de la fonction `close` et du nom de la variable fichier. Il est conseillé d'écrire l'instruction `close` au même moment que l'instruction `open`:" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "metadata": { 155 | "slideshow": { 156 | "slide_type": "fragment" 157 | } 158 | }, 159 | "outputs": [], 160 | "source": [ 161 | "f_input.close()" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": { 167 | "slideshow": { 168 | "slide_type": "subslide" 169 | } 170 | }, 171 | "source": [ 172 | "Entre l'ouverture et la fermeture du fichier, selon le mode d'ouverture choisie, le programme peut\n", 173 | "- lire des données dans le fichier au moyen de la fonction `readline()`,\n", 174 | "- écrire des données dans le fichier au moyen de la fonction `write()`.\n", 175 | "\n", 176 | "Il est à noter que la fonction `readline()` ne retourne que des chaînes de caractères (de type `str`). De façon analogue, la fonction `write()` ne sait écrire (prendre en paramètre) que des chaînes de caractères (de type `str`)." 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": { 182 | "slideshow": { 183 | "slide_type": "subslide" 184 | } 185 | }, 186 | "source": [ 187 | "**Remarque :** \n", 188 | "La méthode `strip()` permet supprimer tous les espaces notamment \" \" et le retour chariot `\\n` au début et à la fin d'une chaîne de caractères." 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 2, 194 | "metadata": { 195 | "slideshow": { 196 | "slide_type": "subslide" 197 | } 198 | }, 199 | "outputs": [ 200 | { 201 | "name": "stdout", 202 | "output_type": "stream", 203 | "text": [ 204 | " Bonjour \n", 205 | "\n", 206 | "Bonjour\n" 207 | ] 208 | } 209 | ], 210 | "source": [ 211 | "chaine = \" Bonjour \\n\"\n", 212 | "print(chaine)\n", 213 | "chaine=chaine.strip()\n", 214 | "print(chaine)" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": { 220 | "slideshow": { 221 | "slide_type": "subslide" 222 | } 223 | }, 224 | "source": [ 225 | "### Écriture dans un fichier\n", 226 | "\n", 227 | "L'écriture des données dans un fichier est une procédure qui suit le modèle suivant :\n", 228 | "- ouverture du fichier en écriture :" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 3, 234 | "metadata": { 235 | "slideshow": { 236 | "slide_type": "subslide" 237 | } 238 | }, 239 | "outputs": [], 240 | "source": [ 241 | "f_output = open( 'files/test_ecriture4' , 'w')" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": { 247 | "slideshow": { 248 | "slide_type": "subslide" 249 | } 250 | }, 251 | "source": [ 252 | "Dès que cette instruction est évaluée, un fichier vide est créé à l'emplacement indiqué dans le système de fichier de l'ordinateur. \n", 253 | "\n", 254 | "- Ecriture de texte dans le fichier :\n", 255 | "\n", 256 | "Il est alors possible d'écrire dans ce fichier au moyen de la fonction `write` et de la variable de flux `f_output`. L'instruction suivante écrit la chaîne de caractère `'bonjour'` dans le fichier `files/test_ecriture'`:" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": 4, 262 | "metadata": { 263 | "slideshow": { 264 | "slide_type": "subslide" 265 | } 266 | }, 267 | "outputs": [ 268 | { 269 | "data": { 270 | "text/plain": [ 271 | "9" 272 | ] 273 | }, 274 | "execution_count": 4, 275 | "metadata": {}, 276 | "output_type": "execute_result" 277 | } 278 | ], 279 | "source": [ 280 | "f_output.write('Bonjour \\n')" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": { 286 | "slideshow": { 287 | "slide_type": "subslide" 288 | } 289 | }, 290 | "source": [ 291 | "Il est possible que la chaîne `'Bonjour \\n'` ne soit pas écrite immédiatement dans le fichier. Certain langage ne procède à l'écriture effective dans le fichier que lorsqu'il y a suffisament de choses à écrire pour limiter les accès disque qui prennent du temps. Ces systèmes conservent les éléments à écrire dans un tampon et lorsque celui-ci est plein, il écrit dans le fichier le contenu du tampon et vide le tampon. Il est possible de forcer l'écriture du tampon dans le fichier en utilisant la fonction `flush` (par exemple avec une instruction de la forme: `f_output.flush()`)\n", 292 | "\n", 293 | "- Fermeture du fichier :\n", 294 | "\n", 295 | "Dans tout les cas, lorsque le flux du fichier est fermé, le contenu du tampon est écrit dans le fichier. Ainsi après l'exécution de l'instruction `close`, le fichier contient la chaîne de caractère `'Bonjour \\n'`." 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 5, 301 | "metadata": { 302 | "slideshow": { 303 | "slide_type": "fragment" 304 | } 305 | }, 306 | "outputs": [], 307 | "source": [ 308 | "f_output.close()" 309 | ] 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "metadata": { 314 | "slideshow": { 315 | "slide_type": "slide" 316 | } 317 | }, 318 | "source": [ 319 | "Il est possible d'écrire à la fin d'un fichier existant au moyen du mode d'ouverture `'a'`(pour append):" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 6, 325 | "metadata": { 326 | "slideshow": { 327 | "slide_type": "fragment" 328 | } 329 | }, 330 | "outputs": [], 331 | "source": [ 332 | "f_output = open( 'files/test_ecriture4' , 'a')\n", 333 | "i = 0\n", 334 | "while( i < 10 ) :\n", 335 | " f_output.write( str(2 * i + 1) + '\\n')\n", 336 | " i += 1\n", 337 | "f_output.close()" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": { 343 | "slideshow": { 344 | "slide_type": "fragment" 345 | } 346 | }, 347 | "source": [ 348 | "A l'issue de ces deux opérations d'écriture dans ce même fichier `'files/test_ecriture'`, le contenu de celui-ci est le suivant:\n", 349 | "```\n", 350 | "Bonjour \n", 351 | "1\n", 352 | "3\n", 353 | "5\n", 354 | "7\n", 355 | "9\n", 356 | "11\n", 357 | "13\n", 358 | "15\n", 359 | "17\n", 360 | "19\n", 361 | "```" 362 | ] 363 | }, 364 | { 365 | "cell_type": "markdown", 366 | "metadata": { 367 | "slideshow": { 368 | "slide_type": "slide" 369 | } 370 | }, 371 | "source": [ 372 | "### Lecture dans un fichier\n", 373 | "\n", 374 | "Afin de lire les données dans un fichier, on utlise la fonction `readline()`. Cette fonction lit le contenu du fichier *ligne à ligne*. A chaque appel, elle renvoie une ligne du fichier sous la forme d'une chaîne de caractères. Si l'on veut lire d'autre *types* de données il faut **caster** la valeur lue. Pour lire le contenu du fichier créé précédemment, on peut donc procèder de la façon suivante." 375 | ] 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "metadata": { 380 | "slideshow": { 381 | "slide_type": "subslide" 382 | } 383 | }, 384 | "source": [ 385 | "On ouvre d'abord le fichier en lecture avec le mode `'r'`" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": 8, 391 | "metadata": { 392 | "slideshow": { 393 | "slide_type": "fragment" 394 | } 395 | }, 396 | "outputs": [], 397 | "source": [ 398 | "# Ouverture du fichier en lecture\n", 399 | "f_input = open( 'files/test_ecriture4' , \"r\")" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "metadata": { 405 | "slideshow": { 406 | "slide_type": "fragment" 407 | } 408 | }, 409 | "source": [ 410 | "Puis on va lire séquentiellement son contenu. La première ligne est une chaîne de caractère:" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 9, 416 | "metadata": { 417 | "slideshow": { 418 | "slide_type": "subslide" 419 | } 420 | }, 421 | "outputs": [], 422 | "source": [ 423 | "ligne_1 = f_input.readline()" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": { 429 | "slideshow": { 430 | "slide_type": "fragment" 431 | } 432 | }, 433 | "source": [ 434 | "On peut vérifier que le contenu de la variable `ligne_1` est bien de type chaîne de caractère et que sa valeur, conformément au contenu du fichier est `'Bonjour \\n'`." 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": 10, 440 | "metadata": { 441 | "slideshow": { 442 | "slide_type": "fragment" 443 | } 444 | }, 445 | "outputs": [ 446 | { 447 | "name": "stdout", 448 | "output_type": "stream", 449 | "text": [ 450 | "\n", 451 | "Bonjour \n", 452 | "\n" 453 | ] 454 | } 455 | ], 456 | "source": [ 457 | "print( type(ligne_1))\n", 458 | "\n", 459 | "print( '' + ligne_1 + '')" 460 | ] 461 | }, 462 | { 463 | "cell_type": "markdown", 464 | "metadata": { 465 | "deletable": false, 466 | "run_control": { 467 | "frozen": true 468 | }, 469 | "slideshow": { 470 | "slide_type": "subslide" 471 | } 472 | }, 473 | "source": [ 474 | "Il est ensuite possible de lire le reste du contenu du fichier (constitués d'entiers) et par exemple de les stocker dans un tableau. Pour cela on utilise une boucle. On lit donc le contenu du fichier tant qu'il y a un contenu. Lorsque le curseur de lecture atteint à la fin du fichier, la fonction `readline` renvoie une chaîne vide `''`.\n", 475 | "\n", 476 | "Il faut donc répéter des appels à la fonction `readline` tant que celle-ci renvoie une chaîne de caractère différente de la chaîne vide.\n", 477 | "\n", 478 | "**NB** : Une ligne vide contient au minimum un caractère, le caractère non imprimé de retour à la ligne `'\\n'`." 479 | ] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": 11, 484 | "metadata": { 485 | "slideshow": { 486 | "slide_type": "subslide" 487 | } 488 | }, 489 | "outputs": [ 490 | { 491 | "name": "stdout", 492 | "output_type": "stream", 493 | "text": [ 494 | "1\n", 495 | "\n", 496 | "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]\n" 497 | ] 498 | } 499 | ], 500 | "source": [ 501 | "tab = []\n", 502 | "li = f_input.readline()\n", 503 | "print(li)\n", 504 | "while(li!='') :\n", 505 | " tab.append(int(li))\n", 506 | " li = f_input.readline()\n", 507 | "print(tab)\n", 508 | "f_input.close()" 509 | ] 510 | }, 511 | { 512 | "cell_type": "markdown", 513 | "metadata": { 514 | "slideshow": { 515 | "slide_type": "subslide" 516 | } 517 | }, 518 | "source": [ 519 | "On peut vérifier que le contenu du tableau est conforme au contenu du fichier:" 520 | ] 521 | }, 522 | { 523 | "cell_type": "code", 524 | "execution_count": 12, 525 | "metadata": { 526 | "slideshow": { 527 | "slide_type": "fragment" 528 | } 529 | }, 530 | "outputs": [ 531 | { 532 | "name": "stdout", 533 | "output_type": "stream", 534 | "text": [ 535 | "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]\n" 536 | ] 537 | } 538 | ], 539 | "source": [ 540 | "print(tab)" 541 | ] 542 | }, 543 | { 544 | "cell_type": "markdown", 545 | "metadata": { 546 | "slideshow": { 547 | "slide_type": "fragment" 548 | } 549 | }, 550 | "source": [ 551 | "Lors de l'ajout de la valeur lue dans le fichier au tableau, celle-ci est castée en entier (`int()`). Ceci est nécessaire pour que les valeurs du tableau soient des entiers. Si on ne le fait pas, la fonction `readline` renvoyant comme valeur de retour une chaîne de caractères, les valeurs du tableau seront des caractères.\n", 552 | "\n", 553 | "**NB** : Lors du cast de la chaîne de caractères `'1\\n'` en entier, le caractère de retour à la ligne est ignoré." 554 | ] 555 | }, 556 | { 557 | "cell_type": "markdown", 558 | "metadata": { 559 | "slideshow": { 560 | "slide_type": "slide" 561 | } 562 | }, 563 | "source": [ 564 | "### Lecture et ecriture formatée\n", 565 | "Quand on importe dans un programme des données depuis un fichier formaté, il faut définir un programme de lecture qui tient compte du format. dans le cas du fichier `'files/planetes.csv'` suivant:\n", 566 | "```\n", 567 | "Planete , Distance au soleil en millions de km , Nombre de satellites\n", 568 | "Mercure , 57.9 , 0\n", 569 | "Venus , 108.2 , 0\n", 570 | "Terre , 149.6 , 1\n", 571 | "Mars , 227.9 , 2\n", 572 | "Jupiter , 778.8 , 63\n", 573 | "Saturne , 1434 , 60\n", 574 | "Uranus , 2871 , 27\n", 575 | "Neptune , 4495 , 13\n", 576 | "```\n" 577 | ] 578 | }, 579 | { 580 | "cell_type": "markdown", 581 | "metadata": { 582 | "slideshow": { 583 | "slide_type": "subslide" 584 | } 585 | }, 586 | "source": [ 587 | "le format est `CSV` ce qui indique qu'il s'agit d'un tableau comportant potentiellement plusieurs lignes et que sur chaque ligne les valeurs de chaque colonne sont séparées par une virgule (`,`).\n", 588 | "\n", 589 | "Ici la première ligne ne contient pas de valeur, elle contient juste la description du type de données contenues dans chaque colonne. Le fichier contient donc 1 ligne de libellés et 8 lignes de données. Chaque ligne contient 3 colonnes. On se fixe pour objectif ici de créer 3 tableaux pour collecter le contenu de chaque colonne:\n", 590 | "- le tableau `planetes` contiendra le nom des planétes (1ère colonne) sous forme de chaîne de caractères,\n", 591 | "- le tableau `distances` contiendra la distance des planétes au soleil (2ème colonne) sous forme de flotants,\n", 592 | "- le tableau `satellites` contiendra le nombre de satellites des planétes (3ème colonne) sous forme d'entiers.\n", 593 | "Les informations de la première ligne ne seront pas stockées en mémoire.\n", 594 | "\n", 595 | "Pour lire le contenu de ce fichier il faut développer un programme de lecture adapté au format. Lorsque chaque ligne suit le même format, il est conseillé de définir une fonction de *parsing* qui prend en paramètre une chaîne de caractère correspondant à la lecture d'une ligne (ce qui est la valeur retournée par `read`), la decription du séprateur des colonnes `sep` et qui est capable d'extraire de façon individuelle la valeur d'une colonne indiqué par son numéro `num_colonne` et de la retourner avec un `type` `ty` paramétré." 596 | ] 597 | }, 598 | { 599 | "cell_type": "markdown", 600 | "metadata": { 601 | "slideshow": { 602 | "slide_type": "subslide" 603 | } 604 | }, 605 | "source": [ 606 | "| fonction utiles lors du parsing | Utilisation |\n", 607 | "|----------|-------------|\n", 608 | "| chaine.strip() | supprime les caractères espace en début et fin de ligne (aussi le caractère `'\\n'`) |\n", 609 | "| chaine.split( separateur ) | sépare la chaine là où il y a un caractère séparateur et retourne le tableau des chaines séparées. |\n" 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "execution_count": 13, 615 | "metadata": { 616 | "slideshow": { 617 | "slide_type": "fragment" 618 | } 619 | }, 620 | "outputs": [], 621 | "source": [ 622 | "def parse_line( ligne , sep, num_colonne, ty) :\n", 623 | " li = ligne.split(sep)\n", 624 | " if ty == \"int\" :\n", 625 | " return(int(li[num_colonne]))\n", 626 | " elif ty == \"float\" :\n", 627 | " return(float(li[num_colonne]))\n", 628 | " elif ty == \"str\" :\n", 629 | " return(li[num_colonne])\n", 630 | " elif ty == \"bool\" :\n", 631 | " return(bool(li[num_colonne]))\n", 632 | " else:\n", 633 | " print(\"Erreur type non reconnu.\")" 634 | ] 635 | }, 636 | { 637 | "cell_type": "markdown", 638 | "metadata": { 639 | "slideshow": { 640 | "slide_type": "slide" 641 | } 642 | }, 643 | "source": [ 644 | "Ensuite il faut écrire un programme de parsing du fichier complet. Ce programme doit prendre en charge l'ouverture et la fermeture du fichier, lire les données et les mémoriser dans des variables.\n", 645 | "\n", 646 | "Voici un exemple de fonction de parsing du contenu du fichier `CSV`." 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": 14, 652 | "metadata": { 653 | "slideshow": { 654 | "slide_type": "fragment" 655 | } 656 | }, 657 | "outputs": [], 658 | "source": [ 659 | "f_input = open( 'files/planetes.csv' , 'r')\n", 660 | "planetes = []\n", 661 | "distances = []\n", 662 | "satellites = []\n", 663 | "f_input.readline() # saut de la 1ère ligne de libellés\n", 664 | "li = f_input.readline() # lecture de la 1ère ligne de données\n", 665 | "while( '' != li ) : # tant que ce n'est pas la fin du fichier \n", 666 | " planetes.append(parse_line(li, ',', 0, \"str\")) # mémorisation des données lues\n", 667 | " distances.append(parse_line(li, ',', 1, \"float\"))\n", 668 | " satellites.append(parse_line(li, ',', 2, \"int\"))\n", 669 | " li = f_input.readline() # lecture de la ligne suivante\n", 670 | "f_input.close()" 671 | ] 672 | }, 673 | { 674 | "cell_type": "markdown", 675 | "metadata": { 676 | "slideshow": { 677 | "slide_type": "subslide" 678 | } 679 | }, 680 | "source": [ 681 | "On peut vérifier que le programme s'est déroulé comme attendu en consultant le contenu des variables de stockages des données du fichier:" 682 | ] 683 | }, 684 | { 685 | "cell_type": "code", 686 | "execution_count": 15, 687 | "metadata": { 688 | "slideshow": { 689 | "slide_type": "fragment" 690 | } 691 | }, 692 | "outputs": [ 693 | { 694 | "name": "stdout", 695 | "output_type": "stream", 696 | "text": [ 697 | "['Mercure ', 'Venus ', 'Terre ', 'Mars ', 'Jupiter ', 'Saturne ', 'Uranus ', 'Neptune ']\n", 698 | "[57.9, 108.2, 149.6, 227.9, 778.8, 1434.0, 2871.0, 4495.0]\n", 699 | "[0, 0, 1, 2, 63, 60, 27, 13]\n" 700 | ] 701 | } 702 | ], 703 | "source": [ 704 | "print(planetes)\n", 705 | "print(distances)\n", 706 | "print(satellites)" 707 | ] 708 | }, 709 | { 710 | "cell_type": "code", 711 | "execution_count": null, 712 | "metadata": {}, 713 | "outputs": [], 714 | "source": [] 715 | } 716 | ], 717 | "metadata": { 718 | "celltoolbar": "Diaporama", 719 | "kernelspec": { 720 | "display_name": "Python 3", 721 | "language": "python", 722 | "name": "python3" 723 | }, 724 | "language_info": { 725 | "codemirror_mode": { 726 | "name": "ipython", 727 | "version": 3 728 | }, 729 | "file_extension": ".py", 730 | "mimetype": "text/x-python", 731 | "name": "python", 732 | "nbconvert_exporter": "python", 733 | "pygments_lexer": "ipython3", 734 | "version": "3.8.5" 735 | }, 736 | "latex_envs": { 737 | "LaTeX_envs_menu_present": true, 738 | "autoclose": false, 739 | "autocomplete": true, 740 | "bibliofile": "biblio.bib", 741 | "cite_by": "apalike", 742 | "current_citInitial": 1, 743 | "eqLabelWithNumbers": true, 744 | "eqNumInitial": 1, 745 | "hotkeys": { 746 | "equation": "Ctrl-E", 747 | "itemize": "Ctrl-I" 748 | }, 749 | "labels_anchors": false, 750 | "latex_user_defs": false, 751 | "report_style_numbering": false, 752 | "user_envs_cfg": false 753 | }, 754 | "toc": { 755 | "base_numbering": 1, 756 | "nav_menu": {}, 757 | "number_sections": true, 758 | "sideBar": true, 759 | "skip_h1_title": false, 760 | "title_cell": "Table of Contents", 761 | "title_sidebar": "Contents", 762 | "toc_cell": false, 763 | "toc_position": {}, 764 | "toc_section_display": true, 765 | "toc_window_display": false 766 | } 767 | }, 768 | "nbformat": 4, 769 | "nbformat_minor": 2 770 | } 771 | -------------------------------------------------------------------------------- /cours/05_hachage/cours_table_hachage.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "deletable": false, 7 | "editable": false, 8 | "run_control": { 9 | "frozen": true 10 | } 11 | }, 12 | "source": [ 13 | "# Cours : Tables de hachage" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "run_control": { 20 | "frozen": true 21 | } 22 | }, 23 | "source": [ 24 | "Dans ce cours, on présente une nouvelle structure de données : *les tables de hachage*. Les tables de hachage servent en particulier à stocker un ensemble de valeurs (sans qu'elles soient ordonnées) en permettant de : \n", 25 | "- savoir rapidement si une valeur est ou non dans la table, \n", 26 | "- ajouter/supprimer rapidement des valeurs dans la table." 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "deletable": false, 33 | "editable": false, 34 | "run_control": { 35 | "frozen": true 36 | } 37 | }, 38 | "source": [ 39 | "Une structure de données permettant de déterminer rapidement si une valeur appartient à un ensemble est la liste triée (recherche dichotomique). En revanche, ajouter/supprimer des valeurs n'est pas efficace car il faut maintenir la liste triée.\n", 40 | "\n", 41 | "Une liste non triée (ne prenant pas en compte un ordre sur les éléments) permet d'ajouter/supprimer rapidement des éléments mais la recherche d'un élément dans la liste n'est pas rapide (complexité linéaire).\n", 42 | "\n", 43 | "Les tables de hachage permettent (sous certaines conditions) d'avoir les deux propriétés simultanément.\n", 44 | "\n", 45 | "**Remarque :** Les dictionnaires en python sont des tables de hachage (une version plus complexe que les tables de hachage présentées dans ce chapitre)." 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": { 51 | "deletable": false, 52 | "editable": false, 53 | "run_control": { 54 | "frozen": true 55 | } 56 | }, 57 | "source": [ 58 | "## Principe" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": { 64 | "deletable": false, 65 | "editable": false, 66 | "run_control": { 67 | "frozen": true 68 | } 69 | }, 70 | "source": [ 71 | "On souhaite stocker l'ensemble de nombres suivant : \n", 72 | "\n", 73 | "12, 45, 34, 67, 78, 345, 7069, 59482, 4, 2, 34534, 57, 3321, 23, 543, -12, 847, -342, 897, 0, -1\n", 74 | "\n", 75 | "Si l'on stocke cet ensemble sous la forme d'un tableau :" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "tab = [12, 45, 34, 67, 78, 345, 7069, 59482, 4, 2, 34534, 57, 3321, 23, 543, 18, 847, 342, 897, 0, 1]" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": { 90 | "deletable": false, 91 | "editable": false, 92 | "run_control": { 93 | "frozen": true 94 | } 95 | }, 96 | "source": [ 97 | "alors tester si un nombre est dans mon tableau nécessite de tester 21 valeurs dans le pire des cas.\n", 98 | "\n", 99 | "Si l'on sépare les nombres pairs et impairs en deux tableaux distincts : " 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "pairs = [12, 34, 78, 59482, 4, 2, 34534, 18, 342, 0]\n", 109 | "impairs = [ 45, 67, 345, 7069, 57, 3321, 23, 543, 847, 897, 1]" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": { 115 | "deletable": false, 116 | "editable": false, 117 | "run_control": { 118 | "frozen": true 119 | } 120 | }, 121 | "source": [ 122 | "tester si une valeur est l'ensemble nécessitera alors au plus 10 tests si la valeur est paire, et 11 tests si la valeur est impaire.\n", 123 | "\n", 124 | "On peut même faire mieux en séparant les nombres qui se terminent par 0, ceux qui se terminent par 1, etc." 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [ 133 | "fini_par_0 = [0]\n", 134 | "fini_par_1 = [3321, 1]\n", 135 | "fini_par_2 = [12, 59482, 2, 342]\n", 136 | "fini_par_3 = [23, 543]\n", 137 | "fini_par_4 = [34, 4, 34534]\n", 138 | "fini_par_5 = [45, 345]\n", 139 | "fini_par_6 = []\n", 140 | "fini_par_7 = [67, 57, 847, 897]\n", 141 | "fini_par_8 = [78, 18]\n", 142 | "fini_par_9 = [7069]" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": { 148 | "deletable": false, 149 | "editable": false, 150 | "run_control": { 151 | "frozen": true 152 | } 153 | }, 154 | "source": [ 155 | "Dans ce cas, pour déterminer si 97047 appartient à l'ensemble, il suffit de chercher si ce nombre est dans la liste des nombres se terminant par 7. Il faut donc chercher parmi 4 valeurs (et non plus 21).\n", 156 | "Dans cet exemple, la recherche d'un nombre nécessite au plus 4 tests." 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": { 162 | "deletable": false, 163 | "editable": false, 164 | "run_control": { 165 | "frozen": true 166 | } 167 | }, 168 | "source": [ 169 | "La recherche est plus rapide mais requiert 10 tableaux. Pour implanter efficacement cette stratégie, on utilise une structure de données imbriquée : on crée une variable `table` qui correspond à un tableau de 10 cases. Pour tout indice `i` (entre 0 et 9), `table[i]` est un tableau contenant l'ensemble des nombres se terminant par le chiffre `i`.\n", 170 | "\n", 171 | "De cette manière, les 10 tableaux précédents sont stockés sous la forme : " 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "table = [\n", 181 | " [0],\n", 182 | " [3321, 1],\n", 183 | " [12, 59482, 2, 342],\n", 184 | " [23, 543],\n", 185 | " [34, 4, 34534],\n", 186 | " [45, 345],\n", 187 | " [],\n", 188 | " [67, 57, 847, 897],\n", 189 | " [78, 18],\n", 190 | " [7069]\n", 191 | "]" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": { 197 | "deletable": false, 198 | "editable": false, 199 | "run_control": { 200 | "frozen": true 201 | } 202 | }, 203 | "source": [ 204 | "On peut alors coder des fonctions pour chercher si un entier apparaît dans la table, ajouter des entiers dans la table ou en supprimer.\n", 205 | "\n", 206 | "**Remarque :** Quand l'entier est positif, on peut utiliser l'opérateur `entier % 10` pour déterminer le dernier chiffre et donc l'indice dans la table. Si l'entier est négatif, on obtient le dernier chiffre avec l'instruction `-entier % 10`." 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": { 212 | "deletable": false, 213 | "editable": false, 214 | "run_control": { 215 | "frozen": true 216 | } 217 | }, 218 | "source": [ 219 | "## Fonctions de hachage" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": { 225 | "deletable": false, 226 | "editable": false, 227 | "run_control": { 228 | "frozen": true 229 | } 230 | }, 231 | "source": [ 232 | "Si l'exemple précédent est efficace quand on a une petite liste des nombres, il pose cependant quelques problèmes :\n", 233 | "- si le nombre de valeurs à stocker est très grand (par exemple 100 000), alors chaque case de la table va contenir en moyenne 10 000 entiers. La recherche d'une valeur nécessitera jusqu'à 10 000 comparaisons ce qui n'est pas efficace. Pour améliorer la recherche, il faudrait pouvoir faire la même chose avec une table ne contenant plus 10 cases mais 10 000 voir 100 000 cases, et faire en sorte que chacune des cases ne contienne que très peu d'entiers ;\n", 234 | "- si l'on doit stocker uniquement des multiples de 10, alors tous les nombres seront dans `table[0]`, les autres cases ne contenant alors que des tableaux vides. La table est aussi peu performante pour la recherche qu'un tableau non trié ; \n", 235 | "- si l'on veut stocker des valeurs non entières, il faut procéder autrement pour séparer les valeurs." 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "metadata": { 241 | "deletable": false, 242 | "editable": false, 243 | "run_control": { 244 | "frozen": true 245 | } 246 | }, 247 | "source": [ 248 | "L'utilisation des fonctions de hachage permet de pallier ces différents problèmes." 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": { 254 | "deletable": false, 255 | "editable": false, 256 | "run_control": { 257 | "frozen": true 258 | } 259 | }, 260 | "source": [ 261 | "### Principe d'une fonction de hachage\n", 262 | "\n", 263 | "Une *fonction de hachage* est une fonction prenant en paramètre une valeur et lui associant un entier. Elle doit respecter les conditions suivantes :\n", 264 | "- être rapide,\n", 265 | "- produire le même résultat lorsqu'elle est appelée avec la même valeur.\n", 266 | "\n", 267 | "Pour n'importe quelle valeur, l'entier retourné par la fonction de hachage **modulo la taille de la table** correspond alors à l'indice de la case du tableau dans laquelle la valeur doit être stockée.\n", 268 | "\n", 269 | "Par exemple, pour créer une table de hachage contenant des chaînes de caractères, il faut concevoir une fonction de hachage qui associe à chaque chaîne de caractères un entier. On peut par exemple choisir d'additionner les codes ASCII des caractères formant la chaîne : " 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": 1, 275 | "metadata": {}, 276 | "outputs": [ 277 | { 278 | "name": "stdout", 279 | "output_type": "stream", 280 | "text": [ 281 | "hachage de a : 97\n", 282 | "hachage de b : 98\n", 283 | "hachage de bonjour : 767\n", 284 | "hachage de ab : 195\n", 285 | "hachage de ba : 195\n" 286 | ] 287 | } 288 | ], 289 | "source": [ 290 | "def hachage(str):\n", 291 | " nombre = 0\n", 292 | " i = 0\n", 293 | " while i < len(str):\n", 294 | " nombre += ord(str[i])\n", 295 | " i += 1\n", 296 | " return nombre\n", 297 | "\n", 298 | "\n", 299 | "print(\"hachage de a : \", hachage(\"a\"))\n", 300 | "print(\"hachage de b : \", hachage(\"b\"))\n", 301 | "print(\"hachage de bonjour : \", hachage(\"bonjour\"))\n", 302 | "print(\"hachage de ab : \", hachage(\"ab\"))\n", 303 | "print(\"hachage de ba : \", hachage(\"ba\"))" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": { 309 | "deletable": false, 310 | "editable": false, 311 | "run_control": { 312 | "frozen": true 313 | } 314 | }, 315 | "source": [ 316 | "Grâce à la fonction de hachage, on peut déterminer dans quelle case de la table chercher : l'indice de la chaîne `str` sera donné par `hachage(str)%len(table)`." 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": { 322 | "deletable": false, 323 | "editable": false, 324 | "run_control": { 325 | "frozen": true 326 | } 327 | }, 328 | "source": [ 329 | "## Notions de performances" 330 | ] 331 | }, 332 | { 333 | "cell_type": "markdown", 334 | "metadata": { 335 | "deletable": false, 336 | "editable": false, 337 | "run_control": { 338 | "frozen": true 339 | } 340 | }, 341 | "source": [ 342 | "L'efficacité de la recherche, de l'ajout et de la suppression dépend grandement du nombre de valeurs contenues dans une même case de la table. Si l'on note $c$ le nombre maximal de valeurs dans une même case de la table, alors la recherche, l'ajout et la suppression se font en $O(c)$.\n", 343 | "\n", 344 | "Idéalement, on cherche à avoir une table de hachage très grande avec des valeurs bien réparties dans les différentes cases de manière à avoir une valeur petite pour $c$.\n", 345 | "\n", 346 | "**Remarques :**\n", 347 | "\n", 348 | "* La valeur $c$ dépend directement de la fonction de hachage. Le choix de la fonction de hachage a donc une grande influence sur l'efficacité de la table de hachage. \n", 349 | "\n", 350 | " Une fonction de hachage *parfaite* répartit uniformément les différentes valeurs dans les cases de la table (même nombre de valeurs dans chaque case de la table).\n", 351 | "\n", 352 | "* La valeur de $c$ varie au cours des ajouts/suppressions. Au départ, quand la table est vide, elle vaut 0. Dans le pire des cas, elle est égale au nombre de valeurs dans la table (si toutes les valeurs sont rangées dans la même case).\n", 353 | "\n", 354 | "* La dimension de la table est importante pour l'efficacité. Même si la fonction de hachage est *parfaite*, $c \\geq \\frac{n}{k}$ où $n$ est le nombre de valeurs dans la table et $k$ le nombre de cases de la table.\n", 355 | "\n", 356 | " Il faut donc avoir une table avec suffisamment de cases par rapport au nombre de valeurs à stocker, quitte à recopier une table de hachage dans une autre plus grande." 357 | ] 358 | } 359 | ], 360 | "metadata": { 361 | "celltoolbar": "Éditer les Méta-Données", 362 | "kernelspec": { 363 | "display_name": "Python 3", 364 | "language": "python", 365 | "name": "python3" 366 | }, 367 | "language_info": { 368 | "codemirror_mode": { 369 | "name": "ipython", 370 | "version": 3 371 | }, 372 | "file_extension": ".py", 373 | "mimetype": "text/x-python", 374 | "name": "python", 375 | "nbconvert_exporter": "python", 376 | "pygments_lexer": "ipython3", 377 | "version": "3.8.5" 378 | }, 379 | "toc": { 380 | "base_numbering": 1, 381 | "nav_menu": {}, 382 | "number_sections": false, 383 | "sideBar": false, 384 | "skip_h1_title": false, 385 | "title_cell": "Table of Contents", 386 | "title_sidebar": "Contents", 387 | "toc_cell": false, 388 | "toc_position": {}, 389 | "toc_section_display": false, 390 | "toc_window_display": false 391 | } 392 | }, 393 | "nbformat": 4, 394 | "nbformat_minor": 5 395 | } 396 | -------------------------------------------------------------------------------- /cours/06_modularité/cours_modularite.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "deletable": false, 7 | "run_control": { 8 | "frozen": true 9 | }, 10 | "slideshow": { 11 | "slide_type": "slide" 12 | } 13 | }, 14 | "source": [ 15 | "# Cours : Modularité en Python" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "deletable": false, 22 | "run_control": { 23 | "frozen": true 24 | }, 25 | "slideshow": { 26 | "slide_type": "subslide" 27 | } 28 | }, 29 | "source": [ 30 | "Les modules et packages permettent de découper un programme sur plusieurs fichiers et de regrouper ceux-ci de manière logique. C'est indispensable \n", 31 | "lorsque l'on travaille sur des projets longs et à plusieurs. " 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": { 37 | "deletable": false, 38 | "run_control": { 39 | "frozen": true 40 | }, 41 | "slideshow": { 42 | "slide_type": "slide" 43 | } 44 | }, 45 | "source": [ 46 | "## Python en dehors des notebooks" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": { 52 | "deletable": false, 53 | "run_control": { 54 | "frozen": true 55 | }, 56 | "slideshow": { 57 | "slide_type": "subslide" 58 | } 59 | }, 60 | "source": [ 61 | "Il est possible d'exécuter du code Python en dehors des notebooks." 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": { 67 | "deletable": false, 68 | "run_control": { 69 | "frozen": true 70 | }, 71 | "slideshow": { 72 | "slide_type": "subslide" 73 | } 74 | }, 75 | "source": [ 76 | "### Python interactif" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": { 82 | "deletable": false, 83 | "run_control": { 84 | "frozen": true 85 | }, 86 | "slideshow": { 87 | "slide_type": "subslide" 88 | } 89 | }, 90 | "source": [ 91 | "Lancer dans un terminal la commande `python` transforme le terminal en une console python interactive. Il est possible de saisir des instructions Python. À chaque instruction saisie, celle-ci est exécutée." 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": { 97 | "deletable": false, 98 | "run_control": { 99 | "frozen": true 100 | }, 101 | "slideshow": { 102 | "slide_type": "slide" 103 | } 104 | }, 105 | "source": [ 106 | "### Fichiers de code Python" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "deletable": false, 113 | "run_control": { 114 | "frozen": true 115 | }, 116 | "slideshow": { 117 | "slide_type": "subslide" 118 | } 119 | }, 120 | "source": [ 121 | "Il est possible d'écrire du code Python dans des fichiers que l'on peut exécuter ensuite dans un terminal. \n", 122 | "Pour écrire du code Python dans un fichier, il faut utiliser un éditeur de texte tel que `gedit`, `atom` ou `vscode` (**pas open office**).\n", 123 | "\n", 124 | "Pour exécuter le fichier contenant le code Python, il faut taper la commande dans le terminal : \n", 125 | "```bash\n", 126 | "python nom_du_fichier_python\n", 127 | "```\n" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "slideshow": { 134 | "slide_type": "subslide" 135 | } 136 | }, 137 | "source": [ 138 | "**Remarques :**\n", 139 | "* les fichiers de code Python ont généralement l'extension .py\n", 140 | "* Pour qu'il n'y ait pas de problème d'accents, il faut que le fichier soit encodé en utf-8.\n", 141 | "* Si le fichier de code Python commence par la ligne\n", 142 | "```python\n", 143 | "#!/usr/bin/env python\n", 144 | "```\n", 145 | "et qu'il est exécutable (dans le terminal, taper `chmod +x nom_du_fichier_python` pour le rendre exécutable), il est possible de lancer le script python en tapant :\n", 146 | "```bash\n", 147 | "./nom_du_fichier_python\n", 148 | "```" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": { 154 | "deletable": false, 155 | "run_control": { 156 | "frozen": true 157 | }, 158 | "slideshow": { 159 | "slide_type": "slide" 160 | } 161 | }, 162 | "source": [ 163 | "## Modules" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": { 169 | "deletable": false, 170 | "run_control": { 171 | "frozen": true 172 | }, 173 | "slideshow": { 174 | "slide_type": "subslide" 175 | } 176 | }, 177 | "source": [ 178 | "Un module est un fichier contenant du code Python, généralement des définitions de fonctions, qui peut par la suite être inclus dans un autre fichier Python. Ce dernier peut alors appeler les fonctions définies dans le module.\n", 179 | "\n", 180 | "Le nom de fichier d'un module est le nom du module suffixé de .py. Par exemple, le module `hello` est défini dans le fichier `hello.py`.\n", 181 | "\n", 182 | "**Remarque :** on suppose pour l'instant que le module est dans le même répertoire que le fichier Python qui appelle les fonctions du module.\n", 183 | "\n", 184 | "**Remarque :** un module peut bien sûr être importé dans un notebook. Un notebook ne peut en revanche pas être utilisé comme module. Il est toutefois possible de sauvegarder un notebook au format python (fichier .py) en cliquant sur Fichier -> Télécharger au format -> Python. Les cellules de texte (markdown) deviennent alors des commentaires." 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": { 190 | "deletable": false, 191 | "run_control": { 192 | "frozen": true 193 | }, 194 | "slideshow": { 195 | "slide_type": "slide" 196 | } 197 | }, 198 | "source": [ 199 | "### Importer un module" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": { 205 | "deletable": false, 206 | "run_control": { 207 | "frozen": true 208 | }, 209 | "slideshow": { 210 | "slide_type": "subslide" 211 | } 212 | }, 213 | "source": [ 214 | "Pour utiliser les fonctions d'un module, il faut auparavant importer ce module. Il existe deux manières d'importer un module." 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": { 220 | "deletable": false, 221 | "run_control": { 222 | "frozen": true 223 | }, 224 | "slideshow": { 225 | "slide_type": "subslide" 226 | } 227 | }, 228 | "source": [ 229 | "#### Première méthode\n", 230 | "\n", 231 | "On inclut le module avec l'instruction :\n", 232 | "```python\n", 233 | "import module\n", 234 | "```\n", 235 | "On appelle une fonction `fonction` définie dans le module avec l'instruction :\n", 236 | "```python\n", 237 | "module.fonction(val1, val2, ..., valk) \n", 238 | "# val1, val2, ..., valk sont les valeurs des paramètres lors de l'appel\n", 239 | "```\n", 240 | "\n" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": { 246 | "slideshow": { 247 | "slide_type": "subslide" 248 | } 249 | }, 250 | "source": [ 251 | "**Remarque :** on peut donner un autre nom au module à l'intérieur du script grâce au mot clé `as`. Par exemple : \n", 252 | "```python\n", 253 | "import module as nom_module\n", 254 | "\n", 255 | "nom_module.fonction(val1, val2, ..., valk) \n", 256 | "# val1, val2, ..., valk sont les valeurs des paramètres lors de l'appel\n", 257 | "```\n" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": { 263 | "deletable": false, 264 | "run_control": { 265 | "frozen": true 266 | }, 267 | "slideshow": { 268 | "slide_type": "subslide" 269 | } 270 | }, 271 | "source": [ 272 | "#### Deuxième méthode\n", 273 | "\n", 274 | "On inclut le module avec l'instruction : \n", 275 | "```python\n", 276 | "from module import fonction, autre_fonction # etc\n", 277 | "```\n", 278 | "Dans ce cas, on peut appeler les fonctions dont les noms sont écrits après le mot `import` directement dans le code :\n", 279 | "```python\n", 280 | "fonction(val1, val2, ..., valk)\n", 281 | "```\n" 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": { 287 | "slideshow": { 288 | "slide_type": "subslide" 289 | } 290 | }, 291 | "source": [ 292 | "**Remarque :** seules les fonctions qui sont après le mot clé `import` peuvent être utilisées dans le script.\n", 293 | "\n", 294 | "Pour importer toutes les fonctions du module, on peut écrire directement :\n", 295 | "```python\n", 296 | "from module import * # importe toutes les fonctions du module\n", 297 | "```\n", 298 | "\n", 299 | "**Attention :** les fonctions importées de cette manière écrasent les fonctions ayant le même nom dans le script. Par exemple, l'instruction \n", 300 | "```python\n", 301 | "from os import *\n", 302 | "``` \n", 303 | "importe la fonction `open` définie dans le module `os`. On ne peut alors plus utiliser la fonction `open` pour ouvrir des fichiers !" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": { 309 | "deletable": false, 310 | "run_control": { 311 | "frozen": true 312 | }, 313 | "slideshow": { 314 | "slide_type": "slide" 315 | } 316 | }, 317 | "source": [ 318 | "#### Exemple\n", 319 | "\n", 320 | "Considérons le code suivant : " 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 1, 326 | "metadata": { 327 | "slideshow": { 328 | "slide_type": "fragment" 329 | } 330 | }, 331 | "outputs": [], 332 | "source": [ 333 | "def occurence(s, c):\n", 334 | " \"\"\"\n", 335 | " Retourne le nombre de fois où le caractère c apparaît dans la chaîne s.\n", 336 | " \"\"\"\n", 337 | " compteur = 0\n", 338 | " i = 0\n", 339 | " while i < len(s):\n", 340 | " if s[i] == c:\n", 341 | " compteur += 1\n", 342 | " i += 1\n", 343 | " return compteur\n", 344 | "\n" 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 2, 350 | "metadata": { 351 | "slideshow": { 352 | "slide_type": "subslide" 353 | } 354 | }, 355 | "outputs": [ 356 | { 357 | "name": "stdout", 358 | "output_type": "stream", 359 | "text": [ 360 | "Saisir un texte\n", 361 | "RTFeRe\n", 362 | "Le texte contient 2 fois la lettre e.\n" 363 | ] 364 | } 365 | ], 366 | "source": [ 367 | "\n", 368 | "print(\"Saisir un texte\")\n", 369 | "texte = input()\n", 370 | "texte = texte.lower() # transforme le texte en minuscules\n", 371 | "\n", 372 | "nbE = occurence(texte, \"e\")\n", 373 | "print(\"Le texte contient\", nbE, \"fois la lettre e.\")" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": { 379 | "deletable": false, 380 | "run_control": { 381 | "frozen": true 382 | }, 383 | "slideshow": { 384 | "slide_type": "subslide" 385 | } 386 | }, 387 | "source": [ 388 | "Même si ce code est simple, on souhaite découper ce code en deux fichiers : \n", 389 | "\n", 390 | "* un module `fonctionChaines.py` qui contiendra la définition de la fonction `occurence` (ce module pourrait également contenir d'autres fonctions relatives aux chaînes de caractères).\n", 391 | "\n", 392 | "* un fichier `occurencesTexte.py` qui contiendra la saisie du texte, et l'affichage du nombre d'occurences de la lettre e dans le texte.\n", 393 | "\n", 394 | "On crée alors les deux fichiers de la manière suivante." 395 | ] 396 | }, 397 | { 398 | "cell_type": "markdown", 399 | "metadata": { 400 | "deletable": false, 401 | "run_control": { 402 | "frozen": true 403 | }, 404 | "slideshow": { 405 | "slide_type": "subslide" 406 | } 407 | }, 408 | "source": [ 409 | "##### Contenu du fichier `fonctionsChaines.py`" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": null, 415 | "metadata": { 416 | "deletable": false, 417 | "run_control": { 418 | "frozen": true 419 | }, 420 | "slideshow": { 421 | "slide_type": "fragment" 422 | } 423 | }, 424 | "outputs": [], 425 | "source": [ 426 | "def occurence(s, c):\n", 427 | " \"\"\"\n", 428 | " Retourne le nombre de fois où le caractère c apparaît dans la chaîne s.\n", 429 | " \"\"\"\n", 430 | " compteur = 0\n", 431 | " i = 0\n", 432 | " while i < len(s):\n", 433 | " if s[i] == c:\n", 434 | " compteur += 1\n", 435 | " i += 1\n", 436 | " return compteur" 437 | ] 438 | }, 439 | { 440 | "cell_type": "markdown", 441 | "metadata": { 442 | "deletable": false, 443 | "run_control": { 444 | "frozen": true 445 | }, 446 | "slideshow": { 447 | "slide_type": "subslide" 448 | } 449 | }, 450 | "source": [ 451 | "##### Contenu du fichier `occurenceTexte.py`\n" 452 | ] 453 | }, 454 | { 455 | "cell_type": "code", 456 | "execution_count": null, 457 | "metadata": { 458 | "deletable": false, 459 | "run_control": { 460 | "frozen": true 461 | }, 462 | "slideshow": { 463 | "slide_type": "fragment" 464 | } 465 | }, 466 | "outputs": [], 467 | "source": [ 468 | "import fonctionsChaines as fch\n", 469 | "\n", 470 | "print(\"Saisir un texte\")\n", 471 | "texte = input()\n", 472 | "texte = texte.lower() # transforme le texte en minuscules\n", 473 | "\n", 474 | "nbE = fch.occurence(\n", 475 | " texte, \"e\") # fonction occurence du module fonctionsChaines renommé fch\n", 476 | "print(\"Le texte contient\", nbE, \"fois la lettre e.\")" 477 | ] 478 | }, 479 | { 480 | "cell_type": "markdown", 481 | "metadata": { 482 | "deletable": false, 483 | "run_control": { 484 | "frozen": true 485 | }, 486 | "slideshow": { 487 | "slide_type": "subslide" 488 | } 489 | }, 490 | "source": [ 491 | "##### Exécution du programme\n", 492 | "\n", 493 | "On exécute le code Python en tapant dans le terminal la commande \n", 494 | "```\n", 495 | "python occurenceTexte.py \n", 496 | "```" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": { 502 | "deletable": false, 503 | "run_control": { 504 | "frozen": true 505 | }, 506 | "slideshow": { 507 | "slide_type": "subslide" 508 | } 509 | }, 510 | "source": [ 511 | "## Utiliser des modules comme des scripts\n", 512 | "\n", 513 | "Un module est utilisé dans d'autres scripts python. Il est néanmoins possible d'y inclure du code qui ne sera exécuté que si le module est le fichier exécuté (autrement dit, si l'instruction `python nom_du_module` est exécutée).\n", 514 | "Ceci se fait en utilisant : " 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": null, 520 | "metadata": { 521 | "slideshow": { 522 | "slide_type": "fragment" 523 | } 524 | }, 525 | "outputs": [], 526 | "source": [ 527 | "if __name__ == '__main__':\n", 528 | " # Code qui sera exécuté uniquement si le module est exécuté \n", 529 | " # directement (pas inclus dans un autre script)" 530 | ] 531 | }, 532 | { 533 | "cell_type": "markdown", 534 | "metadata": { 535 | "deletable": false, 536 | "run_control": { 537 | "frozen": true 538 | }, 539 | "slideshow": { 540 | "slide_type": "subslide" 541 | } 542 | }, 543 | "source": [ 544 | "Ceci permet notamment d'insérer des tests pour des fonctions définies au sein du module. Ces tests ne seront exécutés que lorsque le script sera exécuté (et pas quand il est utilisé dans d'autres scripts)." 545 | ] 546 | }, 547 | { 548 | "cell_type": "markdown", 549 | "metadata": { 550 | "deletable": false, 551 | "run_control": { 552 | "frozen": true 553 | }, 554 | "slideshow": { 555 | "slide_type": "slide" 556 | } 557 | }, 558 | "source": [ 559 | "## Packages en Python" 560 | ] 561 | }, 562 | { 563 | "cell_type": "markdown", 564 | "metadata": { 565 | "deletable": false, 566 | "run_control": { 567 | "frozen": true 568 | }, 569 | "slideshow": { 570 | "slide_type": "subslide" 571 | } 572 | }, 573 | "source": [ 574 | "Les packages en Python permettent de regrouper logiquement des modules ensemble. La création de packages est simple puisqu'un package correspond à un répertoire : les fichiers (et répertoires) à l'intérieur correspondent aux modules (et sous-packages) contenus dans le package.\n", 575 | "\n", 576 | "**Remarque :** on suppose pour l'instant que le package est dans le même répertoire que le fichier Python ou notebook qui importe le package.\n", 577 | "\n", 578 | "\n", 579 | "Dans un script, pour utiliser un module du package, il faut importer le module grâce à l'instruction :\n", 580 | "```python\n", 581 | "import package.module\n", 582 | "```\n", 583 | "ou\n", 584 | "```python\n", 585 | "from package.module import fonction1, fonction2 # etc\n", 586 | "```\n" 587 | ] 588 | }, 589 | { 590 | "cell_type": "markdown", 591 | "metadata": { 592 | "deletable": false, 593 | "run_control": { 594 | "frozen": true 595 | }, 596 | "slideshow": { 597 | "slide_type": "subslide" 598 | } 599 | }, 600 | "source": [ 601 | "**Remarque :** on peut créer un fichier `__init__.py` à l'intérieur d'un package pour exécuter du code au moment de l'import du package (cela permet également d'indiquer que le répertoire est un package, ce qui est nécessaire si le nom du répertoire correspond à un package de base de Python tel que `string` par exemple). Un tel fichier, même vide, est nécessaire pour les tests unitaires par exemple. **Il est donc recommandé de créer un tel fichier dans chaque package créé**." 602 | ] 603 | }, 604 | { 605 | "cell_type": "markdown", 606 | "metadata": { 607 | "deletable": false, 608 | "run_control": { 609 | "frozen": true 610 | }, 611 | "slideshow": { 612 | "slide_type": "subslide" 613 | } 614 | }, 615 | "source": [ 616 | "Par exemple, supposons que le package package `Utils` contient un seul module `words`. \n", 617 | "Ce module contient une seule fonction `compteMots` :" 618 | ] 619 | }, 620 | { 621 | "cell_type": "code", 622 | "execution_count": null, 623 | "metadata": { 624 | "slideshow": { 625 | "slide_type": "subslide" 626 | } 627 | }, 628 | "outputs": [], 629 | "source": [ 630 | "def compteMots(s):\n", 631 | " \"\"\"\n", 632 | " Retourne le nombre de mots dans une phrase.\n", 633 | " (un mot est une séquence non vide de caractères comprise entre deux espaces)\n", 634 | " \"\"\"\n", 635 | " # split découpe la chaîne selon les espaces et retourne un tableau contenant les différentes parties\n", 636 | " return len(s.split())" 637 | ] 638 | }, 639 | { 640 | "cell_type": "markdown", 641 | "metadata": { 642 | "deletable": false, 643 | "run_control": { 644 | "frozen": true 645 | }, 646 | "slideshow": { 647 | "slide_type": "fragment" 648 | } 649 | }, 650 | "source": [ 651 | "On a donc un répertoire `Utils` contenant un unique fichier `words.py`. Pour utiliser ce module à travers le package `Utils`, on utilise dans le fichier l'import : `import Utils.words as uw`." 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": { 657 | "deletable": false, 658 | "run_control": { 659 | "frozen": true 660 | }, 661 | "slideshow": { 662 | "slide_type": "subslide" 663 | } 664 | }, 665 | "source": [ 666 | "Voici un exemple de fichier appelant le module `fonctionsChaines` et le module `words` du package `Utils` :\n" 667 | ] 668 | }, 669 | { 670 | "cell_type": "code", 671 | "execution_count": 1, 672 | "metadata": { 673 | "slideshow": { 674 | "slide_type": "fragment" 675 | } 676 | }, 677 | "outputs": [ 678 | { 679 | "name": "stdout", 680 | "output_type": "stream", 681 | "text": [ 682 | "saisir un texte \n", 683 | "jjbjhkjhjkhkjheee jkgjk \n", 684 | "Le texte saisi contient 3 fois la lettre e et contient 2 mots.\n" 685 | ] 686 | } 687 | ], 688 | "source": [ 689 | "import fonctionsChaines as fch\n", 690 | "import Utils.words as uw\n", 691 | "\n", 692 | "\n", 693 | "print(\"saisir un texte \")\n", 694 | "texte = input()\n", 695 | "nbE = fch.occurence(texte, \"e\")\n", 696 | "nbMots = uw.compteMots(texte)\n", 697 | "print(\"Le texte saisi contient\", nbE, \"fois la lettre e et contient\", nbMots, \"mots.\") \n" 698 | ] 699 | }, 700 | { 701 | "cell_type": "markdown", 702 | "metadata": { 703 | "deletable": false, 704 | "run_control": { 705 | "frozen": true 706 | }, 707 | "slideshow": { 708 | "slide_type": "subslide" 709 | } 710 | }, 711 | "source": [ 712 | "## Utiliser des modules et packages qui ne sont pas dans le répertoire courant\n", 713 | "\n", 714 | "Si le module ou le package n'est pas dans le même répertoire que le script (ou notebook) qui les utilise, alors Python ne le trouve pas et cela engendre une erreur. Pour remédier à ce problème, il faut ajouter le répertoire contenant le module (ou package) dans le chemin de Python. Pour cela on utilise le package `sys` qui permet d'ajouter des nouveaux chemins :\n", 715 | "\n", 716 | "```python\n", 717 | "#chemin doit être une chaîne de caractères correspondant au chemin (relatif ou absolu) du répertoire \n", 718 | "#contenant le module ou package que l'on souhaite utiliser \n", 719 | "import sys\n", 720 | "sys.path.append(chemin)\n", 721 | "```\n", 722 | "\n", 723 | "Par exemple, si l'on a un répertoire contenant un fichier (module) `mod.py` et un répertoire `Programme` contenant le fichier `programme.py` et si l'on souhaite utiliser le module `mod` dans `programme.py`, alors le début de ce fichier sera : \n", 724 | "\n", 725 | "```python\n", 726 | "import sys\n", 727 | "sys.path.append(\"../\")\n", 728 | "from mod import *\n", 729 | "```" 730 | ] 731 | }, 732 | { 733 | "cell_type": "markdown", 734 | "metadata": { 735 | "deletable": false, 736 | "run_control": { 737 | "frozen": true 738 | }, 739 | "slideshow": { 740 | "slide_type": "slide" 741 | } 742 | }, 743 | "source": [ 744 | "## Tests unitaires avec pytest" 745 | ] 746 | }, 747 | { 748 | "cell_type": "markdown", 749 | "metadata": { 750 | "deletable": false, 751 | "run_control": { 752 | "frozen": true 753 | }, 754 | "slideshow": { 755 | "slide_type": "subslide" 756 | } 757 | }, 758 | "source": [ 759 | "Il est possible d'exécuter tous les tests unitaires dans un package ou un module à l'aide du programme `pytest`.\n", 760 | "\n", 761 | "La commande\n", 762 | "```\n", 763 | "pytest fichier.py\n", 764 | "```\n", 765 | "exécute toutes les fonctions commençant par `test_` qui sont définies à l'intérieur du fichier `fichier.py`. Ces fonctions doivent être des fonctions de tests unitaires utilisant la fonction `assert` (selon le modèle vu en cours).\n", 766 | "\n", 767 | "\n", 768 | "La commande\n", 769 | "```\n", 770 | "pytest\n", 771 | "```\n", 772 | "considère tous les fichiers à l'intérieur du répertoire courant (et des sous-répertoires) commençant par `test_`. Pour chacun de ces fichiers, le programme exécute toutes les fonctions commençant par `test_`. \n", 773 | "\n" 774 | ] 775 | } 776 | ], 777 | "metadata": { 778 | "celltoolbar": "Diaporama", 779 | "kernelspec": { 780 | "display_name": "Python 3", 781 | "language": "python", 782 | "name": "python3" 783 | }, 784 | "language_info": { 785 | "codemirror_mode": { 786 | "name": "ipython", 787 | "version": 3 788 | }, 789 | "file_extension": ".py", 790 | "mimetype": "text/x-python", 791 | "name": "python", 792 | "nbconvert_exporter": "python", 793 | "pygments_lexer": "ipython3", 794 | "version": "3.8.5" 795 | }, 796 | "toc": { 797 | "base_numbering": 1, 798 | "nav_menu": {}, 799 | "number_sections": false, 800 | "sideBar": false, 801 | "skip_h1_title": false, 802 | "title_cell": "Table of Contents", 803 | "title_sidebar": "Contents", 804 | "toc_cell": false, 805 | "toc_position": {}, 806 | "toc_section_display": false, 807 | "toc_window_display": false 808 | } 809 | }, 810 | "nbformat": 4, 811 | "nbformat_minor": 5 812 | } 813 | -------------------------------------------------------------------------------- /cours/0_cours_git/aideCoursGit.txt: -------------------------------------------------------------------------------- 1 | Fichier d'aide pour le cours sur Git, à destination des enseignants: 2 | 3 | Slide 3-4: Git est certes décentralisé et peut s'utiliser sans serveur dédié. Par simplicité, le serveur (GitHub) sert de point de rencontre, d'où le slide 4 où le dessin semble être le dessin d'un système P2P. 4 | 5 | 6 | Slide 7: décrire les fichiers /dossiers dans un ordi, avec le chemin complet, répertoire courant,... 7 | 8 | Slide 8: pour ceux qui veulent, parler de SSH (dire que c'est juste un autre protocole de communication que HTTP,...). Le .git est un dossier caché, qu'on peut voir avec ls -a. 9 | C'est dans le .git qu'il y a l'hitorique. C'est dans les fichiers qu'il y a la version la plus à jour. 10 | 11 | Slide 11: Le format d'un log: 12 | On remarque: un code hexa -> unique par commit (utile pour reverse) 13 | l'auteur du commit 14 | l'heure et date du commit 15 | le message dudit commit 16 | quel(s) fichiers ont été modifiés par le commit, et comment nombre d'insertions/ suppressions. 17 | 18 | Slide 12: le HEAD^, ou bien HEAD^^ permet de supprimer les deux derniers commit et de revenir à l'avant avant dernier (on peut en parler, mais ca risque de les perturber d'apprendre la syntaxe complexe, je me suis donc restreint à "j'annule le dernier commit et je reviens à l'avant dernier") 19 | 20 | Slide 13: s'il y a des conflits, Git indique dans les fichiers où ca pose problème, et seulement où ca pose problème. Ca donne des info précises. Dire que ca va être le coeur du TD. 21 | 22 | Slide 17: oui checkout sert pour deux choses: revenir au dernier commit, ou changer de branche. 23 | 24 | Slide 19: On n'aura probablement pas ce problème en python, mais on peut parler du fait que si on aura un langage compilé (C), on ne met pas les .o (idem quand on fait du latex), et on ne met que le code source. 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /cours/0_cours_git/fichier_free_of_rights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/0_cours_git/fichier_free_of_rights.png -------------------------------------------------------------------------------- /cours/0_cours_git/folder_free_of_rights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/0_cours_git/folder_free_of_rights.png -------------------------------------------------------------------------------- /cours/0_cours_git/logo_uvsq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/0_cours_git/logo_uvsq.jpg -------------------------------------------------------------------------------- /cours/0_cours_git/pc_free_of_rights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/0_cours_git/pc_free_of_rights.png -------------------------------------------------------------------------------- /cours/0_cours_git/server_free_of_rights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/0_cours_git/server_free_of_rights.png -------------------------------------------------------------------------------- /cours/0_cours_git/slides_cours_git.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/cours/0_cours_git/slides_cours_git.pdf -------------------------------------------------------------------------------- /projets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/.gitkeep -------------------------------------------------------------------------------- /projets/Blackjack.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/Blackjack.pdf -------------------------------------------------------------------------------- /projets/Projet-2048.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/Projet-2048.pdf -------------------------------------------------------------------------------- /projets/ProjetStatsRegLin_Enonce/ProjetStatsRegLin.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/ProjetStatsRegLin_Enonce/ProjetStatsRegLin.pdf -------------------------------------------------------------------------------- /projets/ProjetStatsRegLin_Enonce/exemple.txt: -------------------------------------------------------------------------------- 1 | 0.028582366491472014 16.121352030427623 2 | 1.0058097990142743 12.518604953326912 3 | 1.930860659831006 15.574231635639801 4 | 3.0173162097197133 12.885360849037244 5 | 3.976878767316248 14.434343569222815 6 | 5.027994481700637 12.777337333548434 7 | 6.062032539494441 12.455147020643079 8 | 7.0170529494742135 13.231116595475758 9 | 8.057030706899427 10.766391881351902 10 | 9.08774032942603 10.960827733090023 11 | 10.082348349095652 10.114111763598512 12 | 11.011008990512366 9.858769295532783 13 | 12.055707124657062 8.97705770272745 14 | 13.04565409233255 10.829151894385603 15 | 14.07699643882204 8.894838696745962 16 | 15.010825148652696 9.63696634187271 17 | 15.93983322123828 9.843701134403279 18 | 16.962793328016776 9.96978936785124 19 | 17.95439372181549 6.2502095281965655 20 | 19.061552621491803 5.419398366335248 21 | 19.942712041118067 6.019260533198029 22 | 21.030187069180442 6.11905288754703 23 | 21.905459876069756 4.403969125763834 24 | 22.920882600489495 4.882003820447199 25 | 23.9070044488916 6.854207439905958 26 | 25.027029850948125 4.252236664959612 27 | 25.949093063782975 4.560356886008935 28 | 27.064764046599443 5.16549538271287 29 | 28.054609337136213 3.9921608243630997 30 | 28.956759346794176 3.009830965561207 31 | 29.944915351345323 4.757256979437489 32 | 31.097454218384783 0.8636780321394291 33 | 32.041901956415565 1.2145533438474096 34 | 33.05140619014308 1.0715497725030159 35 | 33.960450072671094 2.595466318456443 36 | 35.024043848611186 0.1401679119387862 37 | 35.99328080492316 0.003459326902546689 38 | 36.994600363814 0.5768547614653818 39 | 38.049270773715335 0.6101946017950333 40 | 38.92496434766183 1.136283421348828 41 | 40.09807343781136 0.08758516157921514 42 | 41.06738661472447 2.84014520960755 43 | 41.99360734123315 0.8820371586881999 44 | 43.084922677781286 1.9816015688169526 45 | 44.02942842942223 3.974338484758669 46 | 44.939530426863065 1.285219330100452 47 | 45.90543903056139 2.439468389773039 48 | 46.961941780141764 3.2118131919042527 49 | 48.080944371697 2.093146685447932 50 | 49.00466853807157 2.9951409541212404 51 | 50.09154508275954 4.833898832621797 52 | 50.92364995287684 6.434939777782436 53 | 51.98470560238701 5.583326271598189 54 | 53.009106618557794 6.106526013085947 55 | 54.0144804002217 7.491129591850341 56 | 54.93677269730896 5.909107794722691 57 | 56.0692906903528 7.33499042843299 58 | 56.94242453874252 7.83499546304021 59 | 58.00110665599922 6.347930552992279 60 | 59.083885265680124 8.16560655770838 61 | 59.951253108963165 8.965248780145785 62 | 61.053741060152 9.266212629851108 63 | 62.071886778495916 7.502605018098023 64 | 63.078460109559806 9.84612213957933 65 | 63.9625083095217 8.914987429610818 66 | 65.04293723183608 11.282235546684579 67 | 65.92591167611818 9.5856229026395 68 | 67.08206481438829 12.285166802831652 69 | 67.91808137130396 12.283158875409296 70 | 68.92410869097849 12.868691832474973 71 | 69.9543774220974 14.08625010448195 72 | 70.97406653953965 10.93248962906739 73 | 72.07494735936736 13.525594781465132 74 | 72.9827846696111 11.40519820144645 75 | 74.09165930624212 12.185176496239952 76 | 74.95627465499638 13.417550902104827 77 | 76.0497756455759 15.245767862645998 78 | 76.9394682732031 12.951988188751342 79 | 78.05874745032284 14.234106484814102 80 | 79.04566278308018 15.549154307131564 81 | 79.95408057777107 14.77793522655484 82 | 81.01987042187451 14.911832582045694 83 | 81.90547669978231 15.595421906031586 84 | 83.0013707541652 17.285388047196665 85 | 84.09705020279402 17.406611159931636 86 | 85.01404056633736 19.161055089487537 87 | 85.95568882848085 16.687876164334785 88 | 86.94711665241178 17.340299642384352 89 | 88.09994487363171 18.659394272861956 90 | 88.99481094823776 19.698636328393032 91 | 89.98884534320004 20.41755179320272 92 | 90.9727019783031 19.411932401137463 93 | 92.00604616738008 21.191592306077016 94 | 93.00417267287787 20.75953958901371 95 | 94.08755854762845 21.35236369422937 96 | 95.02374584904892 21.21396720408499 97 | 96.03528311158918 22.534987611561263 98 | 97.03471257193912 23.26438387886279 99 | 97.99791804135741 22.209922193164115 100 | 99.00138764817859 21.216249950783215 101 | 100.07935129434819 23.608740326000483 102 | 100.97920261909478 23.79195275771685 103 | 102.05682599969936 23.566019681109914 104 | 103.02867616910497 24.42028322613105 105 | 104.09496042200071 23.18586292061876 106 | 104.96277236534644 26.179505712262763 107 | 105.92454817305955 23.91587961331213 108 | 107.04837765660555 28.051895799664138 109 | 108.01759615629094 26.696238111965332 110 | 109.00852681713121 28.649288940385706 111 | 110.01949202732513 27.125025249102855 112 | 110.90889389557094 28.448751599303133 113 | 111.96573683484128 28.490073156719525 114 | 112.90641240618845 27.968647120243983 115 | 114.0070683044039 27.079181185536232 116 | 114.9718543182121 29.20296958177592 117 | 115.97513359305015 30.828216162113517 118 | 116.94707774347421 29.018142087860568 119 | 117.91581457022521 28.770723512110536 120 | 118.98261136357068 32.44609929799042 121 | 119.9685670832801 29.169604053360136 122 | 120.95229145855097 32.207673085572445 123 | 121.98747938370657 30.503217149608446 124 | 123.06896301099515 31.145422990996604 125 | 124.00371844992063 31.46875152699871 126 | 125.09721841819015 34.649448607199275 127 | 126.07558036846709 34.0725728789028 128 | 126.96525485891401 35.27666121352143 129 | 127.91097267448744 33.75832971665891 130 | 129.03185847750055 35.120949834342056 131 | 130.07627869844862 36.5040190251055 132 | 130.922011000263 36.92450100093571 133 | 131.9960274578057 34.53073560623382 134 | 132.9121721146044 36.39518742603871 135 | 133.93922790065199 34.530978771432174 136 | 135.0544252164004 38.39820069340861 137 | 136.0059174899528 36.58879906706079 138 | 136.99951595220816 36.27048900417556 139 | 137.9830646842101 36.32824856677292 140 | 139.08741891530127 36.999340340660375 141 | 140.022241801518 38.14254123323003 142 | 140.97436289846775 37.93910979501035 143 | 141.94775062321636 40.292847679149816 144 | 143.0747684913998 38.36058546669445 145 | 144.09316025617196 38.529389053992745 146 | 145.06444481167082 41.4147982164616 147 | 146.0915177602295 42.575191601166566 148 | 146.9409772095296 41.71763775412221 149 | 148.0628539434433 43.29268265932674 150 | 149.01623709700954 40.54609247718494 151 | 149.9662300963629 40.78223212190505 152 | 150.99604482768646 44.04935568441194 153 | 151.91129313113487 42.96569421206482 154 | 153.05573747280772 42.106913576835026 155 | 154.03570181647706 45.39912329065374 156 | 155.07210331048375 43.00426827572751 157 | 156.0985259125062 44.041313181909146 158 | 157.0295214470537 46.48447441253694 159 | 158.06296475118853 45.01450796183651 160 | 159.08975254886386 47.51333382559624 161 | 160.02302813056673 47.93102432050834 162 | 160.94035643997856 47.554871666942475 163 | 162.07327542373415 48.20152718720988 164 | 163.0766378399331 49.35364964283481 165 | 163.99987165156182 46.62098753264065 166 | 164.95623102118034 48.053699426477166 167 | 166.0085143572452 48.91291125429977 168 | 167.0135735468605 49.596934631063554 169 | 167.9425175665552 48.5706125585571 170 | 169.09214115503292 51.82385748318622 171 | 169.9454848082965 50.65689083975627 172 | 170.9701907047028 51.12431987622819 173 | 171.94072481654982 51.6483530215191 174 | 172.99341096885695 51.113295814965895 175 | 174.05306375062796 50.46468445005788 176 | 174.99392787302648 51.04193809269779 177 | 175.98378958226576 52.913273128666916 178 | 177.00963509935386 53.99568103776048 179 | 178.08997207635767 53.523966042866334 180 | 179.09182138306264 54.512204018992875 181 | 179.9614222638013 52.91210235121535 182 | 180.9663198708729 53.138930869037324 183 | 182.05960125157347 54.26044575674992 184 | 183.06477850984493 53.4860910859418 185 | 183.99480027746208 55.733956835132915 186 | 184.96944955935646 57.44253867734047 187 | 186.009417698067 57.05048580564546 188 | 186.9824517131747 57.29819115231292 189 | 188.02437409199473 58.16505490638719 190 | 189.07509769443777 57.39342971825489 191 | 189.93947438268265 58.77442135017456 192 | 190.9617214176768 59.45224961284534 193 | 191.9961973790402 58.67341434423699 194 | 192.94715093693483 59.43763338545094 195 | 193.9497628973279 60.64086816767332 196 | 195.03995001951577 57.88258288004471 197 | 196.05422355715882 59.55059333945941 198 | 196.98674449678018 61.348540486576844 199 | 197.9419589128684 59.23051846517965 200 | 199.07059591849344 62.84547562526118 201 | 199.91229147919324 62.4002668724676 202 | 201.01953221454983 62.28245982308679 203 | 201.97882862300065 61.69609714970238 204 | 203.04726687193553 61.023257439876666 205 | 204.03592511899038 63.71358159290559 206 | 205.03870212190267 64.5536253799685 207 | 206.00866014689612 64.11550472041573 208 | 206.96930756024415 65.24985500091755 209 | 208.05725564026716 66.4929113229928 210 | 208.99903341208469 63.426847580880306 211 | 209.94081749258154 65.61769075723221 212 | 210.94244686689916 66.13884749655261 213 | 212.09833183234667 65.51669303546768 214 | 213.08116666535244 65.29682725365778 215 | 214.05258476026867 68.35368170174826 216 | 214.98502997059433 65.81341733099389 217 | 215.9684917244394 68.4701282251574 218 | 217.06445147796322 68.9282221216381 219 | 217.98066353917577 68.92410238674692 220 | 219.07168908604507 68.9932770228207 221 | 220.06682357209704 70.44053947650129 222 | 220.9465604767078 70.01088885589573 223 | 221.94610365650342 71.59454907782658 224 | 222.93022640972035 69.4074719364749 225 | 224.0735177956187 69.46429926281047 226 | 225.01307354000332 69.82154627063511 227 | 225.98835474947109 70.40024078911415 228 | 227.04274169050373 70.08774796830996 229 | 228.0928316726454 72.6946150139552 230 | 228.93285233969087 72.5853796243917 231 | 229.9346864803631 71.21986084739186 232 | 231.0224368805157 74.01538428635436 233 | 231.94926573308936 72.96372037366979 234 | 232.9671454945031 72.88580898799665 235 | 234.06844558654964 73.23410949354253 236 | 235.00207817325966 75.2138086746073 237 | 236.06357049799794 76.05044984988395 238 | 237.0519207325804 75.91337259212598 239 | 237.94727625847133 75.56242131978402 240 | 239.05458027240394 77.89272672408708 241 | 239.98603518609306 77.44204050278584 242 | 241.03804678621523 76.2250455273926 243 | 241.9275620845617 78.0394404334672 244 | 243.0835679307132 77.25985656073858 245 | 243.97354285484192 76.37248813514486 246 | 244.9630418936697 76.95670053583748 247 | 245.93148584945138 79.8586373976273 248 | 246.95659499824237 77.64893083027766 249 | 247.96256167647815 78.75758931418399 250 | 248.99319213939225 80.23320417610057 251 | 249.91151820159234 80.73134560992521 252 | 251.037402011523 79.99425143745164 253 | 251.95444132333807 82.99711348137149 254 | 252.97556727460034 83.29945864481704 255 | 253.93560028963674 81.37375472543916 256 | 254.90011505488334 81.32349381844388 257 | 256.08409947454055 84.14615580415837 258 | 256.9548158619332 81.34023980626313 259 | 258.0091132034872 85.19572966881557 260 | 258.9990492715306 84.20422372894451 261 | 259.975149080538 83.98907321549537 262 | 261.03559996213306 85.5588615913093 263 | 262.0921560751274 83.36385534923114 264 | 262.9163961119433 84.89237721503251 265 | 264.05381471519485 86.17952097352322 266 | 264.91788228781616 87.69184175948855 267 | 266.02120662275104 86.82895908968543 268 | 266.9352890694876 86.87053408603524 269 | 267.975086076101 85.8547117281631 270 | 268.9180948979542 87.03087747679443 271 | 270.03934667008383 88.68747245842248 272 | 270.9552781998154 86.83311808604405 273 | 271.9762861158458 89.7524887841983 274 | 273.0066241008085 88.30092364165796 275 | 274.0392238524803 89.72285370270188 276 | 275.0603692268273 89.24282485827767 277 | 275.9792124190684 91.50616602945799 278 | 276.9983269381378 89.44927887847827 279 | 277.9637057514408 91.40953846929888 280 | 278.96771978768794 90.57462446397395 281 | 280.0573113603883 90.30065635126181 282 | 280.99645787629333 94.32163407317248 283 | 282.01008104202884 91.88747626103633 284 | 282.9220536818113 93.73465481316059 285 | 284.04866723436527 92.48146427502434 286 | 285.05517222312466 95.33804970069512 287 | 285.9567596654058 96.02162112330959 288 | 287.0673379407803 93.93566070721276 289 | 287.916966854514 94.56480654855231 290 | 289.04437358142394 96.58952589249255 291 | 290.08723354060817 95.4837406021777 292 | 291.04863303055254 97.6599574064715 293 | 291.93439118381013 94.74225825072965 294 | 293.0397063376789 95.46707482338059 295 | 294.03280129608504 98.26834511318317 296 | 295.0258799366637 97.44130996761731 297 | 295.96931574428703 99.77834218986267 298 | 296.9347977629642 98.29355249349913 299 | 298.04720691877003 99.25482089991247 300 | 298.965772776821 99.15298129053079 301 | 300.05379021043314 99.86733514815487 302 | 301.09832120247705 98.19587814893785 303 | 302.0657398768082 98.67081449125698 304 | 302.990366095186 100.54798344930133 305 | 303.99356691957 100.28208813935595 306 | 305.0865861544543 101.17616527596162 307 | 306.0249054346736 101.03373311982078 308 | 307.00681350826096 103.03533722818862 309 | 307.92673539379786 101.45020556417911 310 | 308.9083760007497 103.09248153313116 311 | 309.9095428169091 102.16631235823941 312 | 311.0714117527982 104.02727273962316 313 | 311.9084412983961 103.48317098375792 314 | 313.014059655321 104.27488060440157 315 | 313.9420015377551 105.84773146633465 316 | 315.0224314545133 106.0368022138312 317 | 316.0864100498962 106.99952814676665 318 | 316.92208748902834 105.92255413389105 319 | 317.944496066947 105.57347071470777 320 | 319.075802370605 107.29857216609679 321 | 320.04380153876207 107.91077427504 322 | 320.94452866469805 108.96929324920417 323 | 321.95092777021136 106.67097655306524 324 | 322.98792566390574 109.70461165570794 325 | 323.9496905840276 109.77975599856417 326 | 325.0882219787976 109.91543187358981 327 | 326.07751553060274 110.6186168769971 328 | 327.06206653308936 110.89737558495817 329 | 328.005248599805 111.06152919359138 330 | 328.93963087940676 108.93309264117786 331 | 330.04186252773394 109.86256090544549 332 | 330.9261167306301 112.61861400232245 333 | 332.00219365392746 111.80774814285155 334 | 333.0582459229526 113.07800741133141 335 | 334.0807131056572 111.70534671973306 336 | 335.01229410749494 114.97191572658093 337 | 335.9142104702981 115.1731700593113 338 | 336.976508013443 114.5006188138486 339 | 338.04079265784094 115.76434066481639 340 | 338.91841323938115 112.95091142992412 341 | 339.9963660913915 114.12890759862348 342 | 341.0405274654101 113.55627356472617 343 | 341.9985345505804 115.61133568186885 344 | 342.9551207349663 117.67624645661597 345 | 343.9279648350443 118.29849757700993 346 | 344.9357655441083 117.466617049779 347 | 345.91514781779017 115.69595840733086 348 | 346.9418186038195 117.36088523031668 349 | 347.9537429423832 119.7153534928627 350 | 349.02652730764606 117.77075183084425 351 | 349.93242590970686 116.87036713359433 352 | 351.0874149498066 118.92345561367145 353 | 351.93422584463156 120.24651168092781 354 | 352.9673396679113 119.220157904507 355 | 353.90301027244857 119.70744052402266 356 | 355.0656513315951 120.3399480963645 357 | 356.0670359934459 121.35865534553973 358 | 356.99103053057917 121.12674498687109 359 | 357.92276288929776 120.27595808653113 360 | 358.9386989282876 122.8401325532923 361 | 360.0033350013452 121.96674299110093 362 | 361.01457862123897 121.44576100755917 363 | 362.018166925553 122.08181757904272 364 | 363.01100713598953 122.68679776801675 365 | 364.0770680008455 122.12302340836767 366 | 364.92688708573587 126.17553379454203 367 | 366.03927081262907 125.15318505259904 368 | 367.043615268343 125.98689956990263 369 | 368.0016007617881 125.4232499899747 370 | 368.9289007648482 126.29071587355479 371 | 370.0301580564072 124.6441695130247 372 | 371.0197517822554 126.10971467565153 373 | 372.0402214392374 127.59015836945049 374 | 373.02326776682236 127.27998552187503 375 | 374.0257043949152 129.0511791443 376 | 374.9142539577165 127.71220027128214 377 | 375.96272934184884 127.92690085724611 378 | 377.04830940168614 128.67033918153754 379 | 377.98485190974844 129.86709228102063 380 | 379.03549582379316 130.3137704655709 381 | 379.9888713039293 131.1520749388649 382 | 380.9534552652357 130.92050733724963 383 | 382.0613622735635 130.4416503972174 384 | 382.90288007937795 133.0555542222257 385 | 384.0351472958668 132.10260525768746 386 | 385.0151961470456 132.87708471421647 387 | 386.07089210234284 131.35111112318918 388 | 386.972102506543 133.05669044020786 389 | 387.9283877791727 132.7063768060162 390 | 388.9471341665909 133.73964113512466 391 | 389.9563975860736 133.3533224730396 392 | 391.0111725432327 135.56390991326475 393 | 392.0414105117676 133.7830127491164 394 | 393.0616459567042 135.9467263814582 395 | 394.0870557187866 134.18231984069834 396 | 394.97458167898253 134.0568098855622 397 | 395.9492153701326 135.89828143257617 398 | 397.017766474225 135.98190623464313 399 | 397.9686718235749 135.44322460163517 400 | 398.9783166024957 135.93363150075294 401 | 399.98211891512716 136.71545746749825 402 | 401.0133857997851 138.76617904664022 403 | 401.993093461492 137.7036909892317 404 | 402.9530486763773 138.19202963659737 405 | 404.07530352780776 140.61673493358992 406 | 405.09818495296935 139.7883293600233 407 | 406.0918885483916 138.5450557671842 408 | 406.9030379317955 139.87127061991944 409 | 407.9281152280325 139.1723455639089 410 | 408.9965029949017 141.63593375508242 411 | 409.99244237460914 142.05664769891348 412 | 411.01800091175903 140.47492279340617 413 | 412.0816024103387 140.35278853286187 414 | 412.93460263466454 144.4754650661885 415 | 413.941960904107 142.2621173705563 416 | 414.93590721817037 145.28976211247698 417 | 416.0224925301432 143.0219413514444 418 | 416.97019111771556 145.35492343586907 419 | 418.0044902025456 146.42298329726148 420 | 418.9305383130717 144.17817980417723 421 | 420.00581819706287 145.62891155930302 422 | 421.06617472554433 145.3596436030227 423 | 422.0114650742008 147.41917372405692 424 | 422.9936759419808 146.29117615487823 425 | 424.08518180866787 148.4597541031419 426 | 425.0773310020393 148.42619300289977 427 | 425.98616131076614 146.54930572176275 428 | 427.06254929258364 149.8587960269601 429 | 428.08482978926696 147.51539524338503 430 | 429.0289390898905 149.88981151232957 431 | 430.0318587123066 147.57666981585274 432 | 431.02501510602593 149.7129786359793 433 | 431.9012277040595 149.4438327016681 434 | 432.9076819472134 148.5756863763203 435 | 433.9597037306008 151.6944069990971 436 | 435.0761787107622 151.30628624374137 437 | 435.9201294228523 152.4159042551084 438 | 436.99408431500495 153.7140252532312 439 | 438.08364858376297 154.09571995715376 440 | 438.94636092479254 150.65399380558372 441 | 440.0665290378312 153.74002033450734 442 | 440.9999180892223 151.75142021067322 443 | 442.09319803992173 153.64911035380925 444 | 443.01338345658496 155.8710975890074 445 | 444.0331168786891 154.25688529944202 446 | 445.00096164730115 155.07602794518138 447 | 446.0029915776413 153.31598204227694 448 | 446.98230256150754 154.01275286214806 449 | 448.08577273736086 156.3215158679143 450 | 448.98046598624177 156.2343272009277 451 | 450.09457285849953 158.22457447386688 452 | 451.07615648612955 158.45400256293573 453 | 452.0144706602523 156.15533853777447 454 | 452.91669356464 156.45550670035485 455 | 454.0605557678532 158.94965208673597 456 | 455.0891128204066 157.77296173559256 457 | 455.9931309096686 157.9920381292601 458 | 456.96391374903817 157.93540682769418 459 | 457.95497875760856 158.46967250422608 460 | 458.94666331856666 158.3619558925705 461 | 459.90607936563526 161.33049196996706 462 | 460.9803262855388 159.1386475574288 463 | 461.9283679469766 162.8400757880862 464 | 462.93675001522024 162.22464391026725 465 | 463.99012582674345 161.88348385879564 466 | 465.0953338610015 161.568934296486 467 | 465.95277921276806 164.4750737546734 468 | 467.01776476844935 162.66511896687902 469 | 467.9284991981137 165.10495018612116 470 | 468.9520964168565 163.78535308450535 471 | 470.0612978794956 163.6904471009592 472 | 471.01673042281453 166.4633487400688 473 | 472.0265457638861 164.36537913472617 474 | 473.03659805593037 166.275818891934 475 | 474.0312578758044 166.13089237948913 476 | 475.09261740647014 165.60187763728922 477 | 475.9409374382181 167.38005700180412 478 | 477.02482960222784 165.9666112806419 479 | 478.08535266583607 169.04295655584687 480 | 478.9023770371612 168.98418664710863 481 | 479.9775268233559 167.34364382862148 482 | 481.0623669619108 167.13022222575898 483 | 481.9597616869193 170.05155639022328 484 | 482.9025004205786 168.8238734873252 485 | 483.95064928610634 169.67708706085276 486 | 484.99544517414085 171.14123458559888 487 | 486.0351971290793 170.31678114167138 488 | 486.9639646799805 170.94891695904485 489 | 487.93859917642783 170.60207598331786 490 | 489.09908061396254 170.45848855886769 491 | 489.94600138450284 173.0274065779464 492 | 490.92395649917273 174.197505125604 493 | 491.9681318947462 173.80274458045756 494 | 492.9724827410563 171.29086875671038 495 | 494.05740358364795 173.11279786208698 496 | 494.9778714817623 174.83536509646345 497 | 496.088071920588 174.2148452555999 498 | 497.0124084971283 174.29273382729633 499 | 497.9940546402784 175.98491057607237 500 | 498.92375407390983 174.92934905609187 501 | -------------------------------------------------------------------------------- /projets/Projet_Puissance 4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/Projet_Puissance 4.pdf -------------------------------------------------------------------------------- /projets/Sujet_fourmi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/Sujet_fourmi.pdf -------------------------------------------------------------------------------- /projets/mastermind.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/mastermind.pdf -------------------------------------------------------------------------------- /projets/pendu.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/pendu.pdf -------------------------------------------------------------------------------- /projets/projetCryptoIN200.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/projetCryptoIN200.pdf -------------------------------------------------------------------------------- /projets/sudoku.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/sudoku.pdf -------------------------------------------------------------------------------- /projets/sujet de projet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/sujet de projet.pdf -------------------------------------------------------------------------------- /projets/taquin.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IN200/S2-python/142e3ae2c2e8849ceba92ca7f455ca26e34c7a01/projets/taquin.pdf --------------------------------------------------------------------------------