├── 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 | "\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 | "\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 | "\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 | "\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 | "\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 | "
\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 | "
\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
--------------------------------------------------------------------------------