00-python_de_base.ipynb 71.3 KB
Newer Older
vincentvigon's avatar
vincentvigon committed
1
2
3
4
5
6
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
7
8
9
10
11
    "#  Les bases de python\n",
    "\n",
    "Les basses de python sont exposées ici de façon sommaires. Le but est de passer le plus rapidement possibles aux programmes à vocation mathématiques; programmes que l'on veut le plus simple possible. Pour cela, vous commencerez toujours par observer du code, et quand ce sera à votre tour de coder, immitez au maximum ce que vous avez lu (en évitant cependant les copié-collé). \n",
    "\n",
    "Quand vous serez des vieux routier de la programmation, vous pourrez créer votre propre style (Ouaaa!)."
vincentvigon's avatar
vincentvigon committed
12
13
14
15
16
17
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
18
    "## Blocs de code via l'indentation\n",
vincentvigon's avatar
vincentvigon committed
19
    "\n",
vincentvigon's avatar
vincentvigon committed
20
    "Les blocs de codes sont définis par l'intentation. Les programmes sont ainsi très épurés. L'indentation se fait le plus souvent automatiquement lors des retours chariots, et sinon:\n",
vincentvigon's avatar
vincentvigon committed
21
22
23
24
25
26
27
    "\n",
    "* Pour indenter un bloc complet, sélectionner-le et appuyez sur la touche tabulation.  \n",
    "* Pour dé-sindenter :   shift+tabulation."
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
28
   "execution_count": 9,
vincentvigon's avatar
vincentvigon committed
29
30
31
32
33
34
35
36
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i= 3\n",
      "     j= 1\n",
vincentvigon's avatar
vincentvigon committed
37
      "     i**j= 3\n",
vincentvigon's avatar
vincentvigon committed
38
      "     j= 2\n",
vincentvigon's avatar
vincentvigon committed
39
      "     i**j= 9\n",
vincentvigon's avatar
vincentvigon committed
40
41
      "i= 4\n",
      "     j= 1\n",
vincentvigon's avatar
vincentvigon committed
42
      "     i**j= 4\n",
vincentvigon's avatar
vincentvigon committed
43
      "     j= 2\n",
vincentvigon's avatar
vincentvigon committed
44
      "     i**j= 16\n",
vincentvigon's avatar
vincentvigon committed
45
46
      "i= 5\n",
      "     j= 1\n",
vincentvigon's avatar
vincentvigon committed
47
      "     i**j= 5\n",
vincentvigon's avatar
vincentvigon committed
48
      "     j= 2\n",
vincentvigon's avatar
vincentvigon committed
49
      "     i**j= 25\n"
vincentvigon's avatar
vincentvigon committed
50
51
52
53
54
55
56
57
     ]
    }
   ],
   "source": [
    "for i in [3,4,5]:\n",
    "    print(\"i=\",i)\n",
    "    for j in [1,2]:\n",
    "        print(\"     j=\",j) \n",
vincentvigon's avatar
vincentvigon committed
58
    "        print(\"     i**j=\",i**j) # l'opérateur ** c'est la puissance"
vincentvigon's avatar
vincentvigon committed
59
60
61
62
63
64
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
65
66
67
68
    "## Fonctions\n",
    "\n",
    "* On utilise sans arrêt des fonctions crées par d'autres. Par exemple: `print(\"toto\")`. \n",
    "* On crée parfois nos propres fonctions: quand cela clarifie la présentation des programmes, ou quand cela évite de dupliquer du code (c'est très mal!). \n",
vincentvigon's avatar
vincentvigon committed
69
    "\n",
vincentvigon's avatar
vincentvigon committed
70
    "### Définition et appel d'une fonction"
vincentvigon's avatar
vincentvigon committed
71
72
73
74
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
75
   "execution_count": 10,
vincentvigon's avatar
vincentvigon committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n"
     ]
    }
   ],
   "source": [
    "def toto_add(a, b):\n",
    "    return a+b\n",
    "\n",
vincentvigon's avatar
vincentvigon committed
90
    "\"\"\" appel de la fonction précédemment définie:\"\"\"\n",
vincentvigon's avatar
vincentvigon committed
91
92
93
94
95
96
97
98
    "res=toto_add(3, 4)\n",
    "print(res)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
99
100
101
    "### Arguments facultatifs\n",
    "\n",
    "On peut ajouter des arguments avec des valeurs prédéfinies."
vincentvigon's avatar
vincentvigon committed
102
103
104
105
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
106
   "execution_count": 11,
vincentvigon's avatar
vincentvigon committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n",
      "14\n",
      "49\n",
      "196\n"
     ]
    }
   ],
   "source": [
    "def toto_do_computations(a,b,c=1,d=1):\n",
    "    return ((a+b)*c)**d\n",
    "\n",
    "print(toto_do_computations(3,4))\n",
    "\"\"\"conseille : toujours préciser le nom des arguments facultatifs \"\"\"\n",
    "print(toto_do_computations(3,4,c=2))\n",
    "print(toto_do_computations(3,4,d=2))\n",
    "print(toto_do_computations(3,4,c=2,d=2))\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    "### Conseil sur les arguments de fonctions\n",
    "\n",
    "Pour vos propres fonctions, je vous conseille de ne pas du tout utiliser d'argument facultatif; ce qui va bien avec notre devise \"programmer le plus simplement possible\". \n",
    "\n",
    "Mais vous allez devoir utiliser des fonctions crées par d'autres qui ont des arguments facultatifs. Par exemple, considérons une fonction de scipy qui généres des v.a gaussiennes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1.83439849 -0.97655303 -3.99448812]\n"
     ]
    }
   ],
   "source": [
    "import scipy.stats as stats\n",
    "\"\"\" 'loc':espérance, scale:'ecart type', 'size': nombre de v.a générées\"\"\"\n",
    "X=stats.norm.rvs(loc=-1,scale=3,size=3)\n",
    "print(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dans la fonction précédente, tous les arguments sont facultatifs. Les valeurs par défaut sont logiquement `loc=0,scale=1,size=1`. On peut écrire par exemple \n",
    "\n",
    "    simus=stat.norm.rvs(size=1000)\n",
    "\n",
    "pour\n",
    "\n",
    "     simus=stat.norm.rvs(loc=0,scale=1,size=1000)\n",
    "\n",
    "\n",
    "Mais attention : si on ne précise pas le nom des arguments, ils sont pris dans l'ordre `1:loc 2:scale 3:size`\n",
    "Par exemple: si, pour tirer 1000 gaussiennes, j'écris\n",
    "\n",
    "     simus=stat.norm.rvs(1000)\n",
    "\n",
    "mon programme bug car cela correspond à \n",
    "\n",
    "    simus=stat.norm.rvs(loc=1000)\n",
    "\n",
    "Je vous conseille d'écrire quasi tout le temps le nom des arguments pour éviter ce genre de confusion ; sauf quand il s'agit d'un argument obligatoire évident comme dans `plt.plot(x,y)`.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lambda expression\n",
    "C'est une façon courte d'écrire les fonctions sans leur donner de nom. On parle de fonction anomyme. On les rencontre fréquement comme argument d'autre fonction. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"une fonction qui prend comme argument une fonction\"\n",
    "def evaluate_a_function_on_integers(func,borne):\n",
    "    res=[]\n",
    "    for  i in range(borne):\n",
    "        res.append(func(i))\n",
    "    return res\n",
    "\n",
    "# lambda x:x**2  signifie   x->x**2\n",
    "evaluate_a_function_on_integers(lambda x:x**2,10)    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"sans utiliser de fonction anonyme:\"\"\"\n",
    "def square(x): \n",
    "    return x**2\n",
    "\n",
    "evaluate_a_function_on_integers(square,10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Listes, tuple, chaînes de caractères\n",
    "\n",
    "Notez bien que les indices commencent à 0! \n",
    "\n",
    "### Liste: `[...]`\n",
    "\n",
    "* Elles contiennent des éléments de n'importe quel type. \n",
    "* Leur taille peut varier en cours d'utilisation."
vincentvigon's avatar
vincentvigon committed
260
261
262
263
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
264
   "execution_count": 13,
vincentvigon's avatar
vincentvigon committed
265
266
267
268
269
270
271
272
273
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "la liste complète [1, 2, 3, 'quatre', 5]\n",
      "le premier élément (numéro 0) 1\n",
      "le dernier élément (numéro longueur-1) 5\n",
vincentvigon's avatar
vincentvigon committed
274
275
      "ou bien 5\n",
      "[1, 2, 3, 'quatre', 5, 'six']\n"
vincentvigon's avatar
vincentvigon committed
276
277
278
279
280
281
282
283
     ]
    }
   ],
   "source": [
    "list0= [1, 2, 3, \"quatre\", 5]\n",
    "print(\"la liste complète\", list0)\n",
    "print(\"le premier élément (numéro 0)\", list0[0])\n",
    "print(\"le dernier élément (numéro longueur-1)\", list0[len(list0) - 1])\n",
vincentvigon's avatar
vincentvigon committed
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    "print(\"ou bien\", list0[-1])\n",
    "\n",
    "\"\"\" On lui rajoute un élément à la fin \"\"\"\n",
    "list0.append(\"six\")\n",
    "print(list0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tuple: `(...)`\n",
    "\n",
    "* Ils contiennent des éléments de n'importe quel type\n",
    "* Leur taille ne peut pas varier\n",
    "* On ne peut pas les modifier (ils sont \"immutables\")"
vincentvigon's avatar
vincentvigon committed
300
301
302
303
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, 'trois')\n"
     ]
    }
   ],
   "source": [
    "a=(1,2,\"trois\")\n",
    "\"\"\" les lignes suivante produisent des messages erreurs. Lisez ces messages.\"\"\"\n",
    "print(a)\n",
    "#a[0]=2\n",
    "#a.append(\"quatre\")"
   ]
  },
  {
   "cell_type": "markdown",
vincentvigon's avatar
vincentvigon committed
325
326
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
327
    "Les tuples sont pratiques quand on veut qu'une fonction renvoie plusieurs éléments."
vincentvigon's avatar
vincentvigon committed
328
329
330
331
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
332
   "execution_count": 15,
vincentvigon's avatar
vincentvigon committed
333
334
335
336
337
338
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
vincentvigon's avatar
vincentvigon committed
339
340
      "poids: 3000\n",
      "prix: 7500.0\n"
vincentvigon's avatar
vincentvigon committed
341
342
343
344
     ]
    }
   ],
   "source": [
vincentvigon's avatar
vincentvigon committed
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
    "def beurreEtArgentDuBeure(nbPlaquette:float):\n",
    "    poids=nbPlaquette*250\n",
    "    prix=poids*2.5\n",
    "    return (poids,prix)\n",
    "    \n",
    "(po,pr)=beurreEtArgentDuBeure(12)\n",
    "print(\"poids:\",po)\n",
    "print(\"prix:\",pr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarque, les parenthèses autour des `tuples` sont souvent facultatives. Ci-dessus on aurait pu écrire: `return poids,prix` et: `po,pr=beurreEtArgentDuBeure(12)`"
vincentvigon's avatar
vincentvigon committed
360
361
362
363
364
365
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
366
    "### Chaîne de caractère: `\"...\"` ou `'...'`"
vincentvigon's avatar
vincentvigon committed
367
368
369
370
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
371
   "execution_count": 16,
vincentvigon's avatar
vincentvigon committed
372
373
374
   "metadata": {},
   "outputs": [
    {
vincentvigon's avatar
vincentvigon committed
375
376
377
378
379
380
381
382
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "toto\n",
      "toto dit \"bonjour\"\n",
      "\t 1 \n",
      "\t 2\n"
     ]
vincentvigon's avatar
vincentvigon committed
383
384
385
    }
   ],
   "source": [
vincentvigon's avatar
vincentvigon committed
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    "a=\"toto\"\n",
    "print(a)\n",
    "\"\"\" on peut mettre des doubles guillement dans les simples \"\"\"\n",
    "b='toto dit \"bonjour\"'\n",
    "print(b)\n",
    "\"\"\" on peut ajouter des retours chariots et des tabulations\"\"\"\n",
    "c='\\t 1 \\n\\t 2'\n",
    "print(c)\n",
    "\"\"\" chaîne sur plusieurs lignes. Je les utilise aussi pour les commentaires.\"\"\"\n",
    "d=\"\"\"\n",
    "$$$_____$$$$$$$$$$$$$$$_$$$_______$$$_$$$$$$$$$$\n",
    "$$$____$$$____$$$____$$$_$$$_____$$$__$$$_______\n",
    "$$$____$$$___________$$$_$$$_____$$$__$$$_______\n",
    "$$$_____$$$_________$$$___$$$___$$$___$$$$$$$$__\n",
    "$$$______$$$_______$$$_____$$$_$$$____$$$_______\n",
    "$$$_______$$$_____$$$______$$$_$$$____$$$_______\n",
    "$$$$$$$$$___$$$_$$$_________$$$$$_____$$$$$$$$$$\n",
    "\"\"\"\n",
    "#print(d)"
vincentvigon's avatar
vincentvigon committed
405
406
407
408
409
410
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
vincentvigon's avatar
vincentvigon committed
411
412
413
    "### Itérables (à lire rapidement)\n",
    "\n",
    "On utilise très fréquement la fonction `range()`. \n",
vincentvigon's avatar
vincentvigon committed
414
    "\n",
vincentvigon's avatar
vincentvigon committed
415
416
417
418
    "* `range(10)` c'est les entier de 0 à 9.\n",
    "* `range(1,10)` c'est les entiers de 1 à 9.\n",
    "\n",
    "Mais `range()` ne renvoie pas vraiment liste, mais un `iterable` c.à.d une liste potentielle, qui devient vraiment liste quand on l'itère dans une boucle: "
vincentvigon's avatar
vincentvigon committed
419
420
421
422
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
423
   "execution_count": 35,
vincentvigon's avatar
vincentvigon committed
424
425
426
   "metadata": {},
   "outputs": [
    {
vincentvigon's avatar
vincentvigon committed
427
428
429
430
431
432
433
434
435
436
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "10\n",
      "100\n",
      "1000\n",
      "10000\n",
      "100000\n"
     ]
vincentvigon's avatar
vincentvigon committed
437
438
439
    }
   ],
   "source": [
vincentvigon's avatar
vincentvigon committed
440
441
442
443
444
445
446
447
448
449
450
    "for i in range(4000000000000):\n",
    "    j=10**i\n",
    "    print(j)\n",
    "    if j>10000: break #j'arrète, c'est trop gros "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*** A vous:***  $(1\\heartsuit)$ Que se serait-il passé si dans le programme précédent si `range()` renvoyé une liste?  \n",
vincentvigon's avatar
vincentvigon committed
451
    "\n",
vincentvigon's avatar
vincentvigon committed
452
    "Pour comprendre l'intérêt des itérables: imaginez un programme de deeplearning qui doit s'entrainer en regardant des centaines de milliers d'images qu'il télécharge depuis le net. La strucutre principale du programme est:\n",
vincentvigon's avatar
vincentvigon committed
453
    "\n",
vincentvigon's avatar
vincentvigon committed
454
455
    "        for img in allImg(): \n",
    "            train_with(img)\n",
vincentvigon's avatar
vincentvigon committed
456
    "\n",
vincentvigon's avatar
vincentvigon committed
457
    "Si jamais `getAllImg()` renvoyait une liste, il faudrait attendre que toutes les images soient chargée en mémoire avant de commencer.  \n",
vincentvigon's avatar
vincentvigon committed
458
    "\n",
vincentvigon's avatar
vincentvigon committed
459
    "A notre niveau, on ne créera pas d'iterable.  Je vous en parle pour que vous ne soyez pas surpris si vous 'printer' un itérable:"
vincentvigon's avatar
vincentvigon committed
460
461
462
463
   ]
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
464
   "execution_count": 16,
vincentvigon's avatar
vincentvigon committed
465
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "range(0, 10)\n",
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
      "(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)\n"
     ]
    }
   ],
   "source": [
    "print(range(10)) # rien d'intéressant\n",
    "print(list(range(10))) #on convertit l'iterable en liste \n",
    "print(tuple(range(10)))# ou bien en tuple"
   ]
vincentvigon's avatar
vincentvigon committed
482
483
  },
  {
vincentvigon's avatar
vincentvigon committed
484
   "cell_type": "markdown",
vincentvigon's avatar
vincentvigon committed
485
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
486
487
488
489
490
491
492
   "source": [
    "### Point commun\n",
    "\n",
    "Les listes, les tuples, les chaines de caractère, les itérables (et les vecteurs numpy, cf plus loin) ont tous en commun de pouvoir être parcouru (=itérés). De nombreuses fonctions toute faites acceptent n'importe lesquels de ces types. Cette souplesse fait parti de la philosophie de python. \n",
    "\n",
    "Pour illustrer cela, écrivons nous-même une fonction qui accepte plein d'arguments différents:"
   ]
vincentvigon's avatar
vincentvigon committed
493
494
495
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
496
   "execution_count": 38,
vincentvigon's avatar
vincentvigon committed
497
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "liste\n",
      "l'élément: 0  est  1\n",
      "l'élément: 1  est  2\n",
      "tuple\n",
      "l'élément: 0  est  3\n",
      "l'élément: 1  est  4\n",
      "string\n",
      "l'élément: 0  est  t\n",
      "l'élément: 1  est  o\n",
      "l'élément: 2  est  t\n",
      "l'élément: 3  est  o\n",
      "iterable\n",
      "l'élément: 0  est  0\n",
      "l'élément: 1  est  1\n",
      "l'élément: 2  est  2\n",
      "tableau numpy\n",
      "l'élément: 0  est  0.0\n",
      "l'élément: 1  est  0.25\n",
      "l'élément: 2  est  0.5\n",
      "l'élément: 3  est  0.75\n",
      "l'élément: 4  est  1.0\n"
     ]
    }
   ],
   "source": [
    "def parcour(sequence):\n",
    "    for i in range(len(sequence)):\n",
    "        print(\"l'élément:\",i,\" est \",sequence[i])\n",
    "\n",
    "print(\"liste\")\n",
    "parcour([1,2])\n",
    "print(\"tuple\")\n",
    "parcour((3,4))\n",
    "print(\"string\")\n",
    "parcour(\"toto\")\n",
    "print(\"iterable\")\n",
    "parcour(range(3))\n",
    "print(\"tableau numpy\")\n",
    "parcour(np.linspace(0,1,5))\n"
   ]
vincentvigon's avatar
vincentvigon committed
543
544
  },
  {
vincentvigon's avatar
vincentvigon committed
545
   "cell_type": "markdown",
vincentvigon's avatar
vincentvigon committed
546
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
547
548
549
550
551
   "source": [
    "### Slicing\n",
    "\n",
    "Cela permet de sélectionner des bouts de liste/string/tuple"
   ]
vincentvigon's avatar
vincentvigon committed
552
553
554
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
555
   "execution_count": 19,
vincentvigon's avatar
vincentvigon committed
556
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2]\n",
      "[3, 4, 5, 6]\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "liste=[0,1,2,3,4,5,6]\n",
    "print(liste[:3])\n",
    "print(liste[3:])\n",
    "print(liste[-2])"
   ]
vincentvigon's avatar
vincentvigon committed
574
575
  },
  {
vincentvigon's avatar
vincentvigon committed
576
   "cell_type": "markdown",
vincentvigon's avatar
vincentvigon committed
577
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
578
579
580
   "source": [
    "***A vous:*** Refaites ceci avec le mot: \"abcdef\". "
   ]
vincentvigon's avatar
vincentvigon committed
581
582
  },
  {
vincentvigon's avatar
vincentvigon committed
583
   "cell_type": "markdown",
vincentvigon's avatar
vincentvigon committed
584
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
585
586
587
   "source": [
    "### Multiplier, additionner = concatenner"
   ]
vincentvigon's avatar
vincentvigon committed
588
589
590
  },
  {
   "cell_type": "code",
vincentvigon's avatar
vincentvigon committed
591
   "execution_count": 20,
vincentvigon's avatar
vincentvigon committed
592
   "metadata": {},
vincentvigon's avatar
vincentvigon committed
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 1, 2, 1, 2]\n",
      "(1, 2, 3, 4)\n",
      "totooooo\n"
     ]
    }
   ],
   "source": [
    "print([1,2]*3)\n",
    "print((1,2)+(3,4))\n",
    "print(\"tot\"+\"o\"*5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***A vous:*** Définissez $(1\\heartsuit)$ la chaine de caracère: `l'homme dit: \"envole toi!\"`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Trier\n",
    "\n",
    "C'est une opération qu'on utilise très souvent. Apprenez la syntaxe une bonne une bonne fois pour toute. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 2, 6, 8]\n",
      "[2, 5, 6, 8]\n"
     ]
    }
   ],
   "source": [
    "a=[5,2,6,8]\n",
    "b=sorted(a)\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 5, 6, 8]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"variante 'inplace', a utiliser uniquement quand les tableau sont très gros.\"\n",
    "a=[5,2,6,8]\n",
    "a.sort()\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "défaut:\n",
      " [('a', 2, 100), ('b', 0, 1000), ('c', 10, -20)]\n",
      "selon index 1:\n",
      " [('b', 0, 1000), ('a', 2, 100), ('c', 10, -20)]\n",
      "selon l'opposé de l'index 1:\n",
      " [('c', 10, -20), ('a', 2, 100), ('b', 0, 1000)]\n",
      "selon une fonction des index 1 et 2:\n",
      " [('c', 10, -20), ('a', 2, 100), ('b', 0, 1000)]\n"
     ]
    }
   ],
   "source": [
    "a=[('a',2,100),('c',10,-20),('b',0,1000)]\n",
    "print(\"défaut:\\n\",sorted(a))\n",
    "print(\"selon index 1:\\n\",sorted(a,key=lambda pair:pair[1] ))\n",
    "print(\"selon l'opposé de l'index 1:\\n\",sorted(a,key=lambda pair:-pair[1] ))\n",
    "print(\"selon une fonction des index 1 et 2:\\n\",sorted(a,key=lambda pair:pair[1]+pair[2] ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***A vous:*** Voici une liste de mot: `[\"bonjour\",\"les\",\"gars\",\"comment\",\"vous\",\"allez\"]`.\n",
    " Triez $(2\\heartsuit)$ ces mot dans l'ordre alphabétique de leur dernière lettre. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Graphiques\n",
    "\n",
    "On y reviendra beaucoup plus en détail par la suite. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"voici un import à connaître par coeur, il permet de faire des graphiques. \"\"\"\n",
    "import matplotlib.pyplot as plt  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Relier des points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x216 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"liste d'abscisses et liste d'ordonnées\"\"\"\n",
    "x= [1,1.5,2,2.5,3]\n",
    "y= [1,4,3,4,1]\n",
    "\"\"\" La figure, et les axes \"\"\"\n",
    "fig,ax=plt.subplots(1,3)\n",
    "\"\"\" on règle la taille de la figure \"\"\"\n",
    "fig.set_size_inches(12,3)\n",
    "\"\"\" on divise la figure en 1-ligne, 3-colonnes, et on affiche le premier graphique \"\"\"\n",
    "ax[0].plot(x,y)\n",
    "\"\"\"puis le second graphique\"\"\"\n",
    "ax[1].plot(x,y,'o') #essayez aussi avec '.' ou '*' \n",
    "\"\"\"puis le troisième\"\"\"\n",
    "ax[2].plot(x,y,'o-');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  Graphe de fonction\n",
    "\n",
    "En reliant finement des points, on peut tracer le graphe de fonctions lisses, avec un graphe... lisse! "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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zfQ+U7g5PI3wwo3G1lw1JcbrbPFUpY2kpMMICuOHsitqIIfdUY2BXNYYwMb9E03iAGPIWocYI4CTY20/up8Uc2wId4iNJE7WLxZC+JlSaoPW2qexzU22uLXWXymlera2qKbUux18/tsL6VV4kNenhfP3ksOML3wFgAKVwWY9lDXuvmyoP4kdjq7UV/yw22MPSkGCPZIOMZEkxRiTNvqlx5PkDeLGlnDDY28Qy4akQgir8Vsft1JqFjALoHv35o+tLj9yiI7ZB9g0QjOVZLbVTWBR/EAOJgzBFpdCh5hI0qIjueoHwZsYE0lStHE/ITpSJnAIIUKC34Jbaz0bmA1GV0lz39+hYw9i5zzH1L6nEJ3YgvHZQggRIoJqVMmg0VPMLkEIIYKerGEphBAW02RwK6XeAVYD/ZVS+5RSMwNflhBCiBPxZVTJtLYoRAghhG+kq0QIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISxGglsIISzGp+BWSp2rlMpVSu1QSv0p0EUJIYQ4sSaDWykVDrwInAcMAqYppQYFujAhhBDH50uLewywQ2udr7V2Ae8ClwS2LCGEECcS4cNrugJ7f/B4HzD2py9SSs0CZnkfVimlcltYUypQ3ML3WpV85vYv1D4vyGdurh6+vtCX4PaJ1no2MLu1x1FKrddaZ/qhJMuQz9z+hdrnBfnMgeRLV0kh0O0HjzO8zwkhhDCBL8H9LXCSUqqXUsoGXAV8EtiyhBBCnEiTXSVa6zql1C3AIiAceE1rnRPAmlrd3WJB8pnbv1D7vCCfOWCU1rotziOEEMJPZOakEEJYjAS3EEJYTNAEdyhOq1dKvaaUKlJKfWd2LW1BKdVNKbVcKbVVKZWjlLrd7JoCTSllV0qtU0pleT/zg2bX1FaUUuFKqU1Kqflm19IWlFK7lVLZSqnNSqn1AT1XMPRxe6fV5wFnY0zw+RaYprXeamphAaaUmgRUAW9orYeYXU+gKaU6A5211huVUvHABuDS9vz3rJRSQKzWukopFQmsBG7XWq8xubSAU0rdCWQCCVrrC82uJ9CUUruBTK11wCcdBUuLOySn1WutvwKOmF1HW9FaH9Bab/TerwS2YczMbbe0ocr7MNL7x/zWUoAppTKAC4A5ZtfSHgVLcB9vWn27/oEOdUqpnsBIYK25lQSet8tgM1AELNFat/vPDDwH3A3Um11IG9LAYqXUBu8SIAETLMEtQohSKg74ALhDa11hdj2BprX2aK1HYMw6HqOUatfdYkqpC4EirfUGs2tpYxO11qMwVlK92dsVGhDBEtwyrT5EePt5PwDe0lp/aHY9bUlrXQYsB841u5YAmwBc7O3zfRc4Qyn1X3NLCjytdaH3tgj4CKMLOCCCJbhlWn0I8F6oexXYprV+xux62oJSKk0pleS9H41xAf57c6sKLK31PVrrDK11T4yf5WVa62tMLiuglFKx3gvuKKVigXOAgI0WC4rg1lrXAQ3T6rcBcwM8rT4oKKXeAVYD/ZVS+5RSM82uKcAmANMxWmCbvX/ON7uoAOsMLFdKbcFooCzRWofE8LgQ0xFYqZTKAtYBn2mtFwbqZEExHFAIIYTvgqLFLYQQwncS3EIIYTES3EIIYTES3EIIYTES3EIIYTES3EIIYTES3EIIYTH/H/iF+vT9hH8JAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\" on anticipe sur les prochains TP. On va utiliser numpy, \n",
    "qui est une bibliothèque pour gérer les tableaux de nombres.\"\"\"\n",
    "import numpy as np\n",
    "\n",
    "x=np.linspace(0,5,100) # 100 points répartis entre 0 et 5\n",
    "fig,ax=plt.subplots()\n",
    "\n",
    "\"\"\"attention 'lambda' est un mot clef réservé de python. du coup j'utilise 'lamb' \"\"\"\n",
    "for lamb in [0.1,0.3,1,2]:\n",
    "    y=np.exp(lamb*x)\n",
    "    ax.plot(x,y,label=\"$lamb:$\"+str(lamb))\n",
    "\n",
    "\"\"\"on limite les ordonnées. Pourquoi est-ce important dans ce graphique ?\"\"\"\n",
    "ax.set_ylim([0,5])\n",
    "ax.legend();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Instructions conditionnelles\n",
    "\n",
    "### instructions `if`, `elif`, `else`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a est dans l'intervalle: ]4,7]\n"
     ]
    }
   ],
   "source": [
    "a=6\n",
    "if 4<a<=7:\n",
    "    print(\"a est dans l'intervalle: ]4,7]\")\n",
    "elif 7<a<=10:\n",
    "    print(\"a est dans l'intervalle: ]7,10]\")\n",
    "else :\n",
    "    print(\"a est dans le complémentaire\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### boucle while"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12368\n"
     ]
    }
   ],
   "source": [
    "def algo(x):\n",
    "    somme=0\n",
    "    n=1\n",
    "    while somme<x:\n",
    "        somme+=1/n #c'est comme: sum=sum+ 1/n\n",
    "        n+=1       #c'est comme: n=n+1\n",
    "    return n\n",
    "\n",
    "\"\"\"ne prenez pas ce paramètre 'x' trop grand -> cela devient très long. \n",
    "Au pire on peut toujours stopper un programme, avec le bouton carré stop\"\"\"\n",
    "print(algo(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***Exo:*** $(8\\diamondsuit)$  Voici enfin un problème où vous allez devoir sortir votre cerveau de mathématicien: trouvez un encadrement (majorant, minorant) pour l'entier `algo(x)`. Ces (majorant, minorant) doivent s'exprimer avec des fonctions usuelles. Vérifiez votre encadrement avec un petit programme graphique. \n",
    "\n",
    "Aide: pour coder les fonctions usuelles:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.1411200080598672\n",
      "1.6094379124341003\n",
      "148.4131591025766\n",
      "25\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "print(math.sin(3))\n",
    "print(math.log(5))\n",
    "print(math.exp(5))\n",
    "print(5**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### l'instruction break\n",
    "\n",
    "Elle permet de sortir d'une boucle. Très pratique, même si les puriste de la programmation la rejette. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "U: [0] V: [9.29209989]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "while True:\n",
    "    U=np.random.randint(0,7,size=1) #-> 0,1,2,3,4,5,6 with equal proba\n",
    "    V=np.random.uniform(4,10,size=1)#-> [4,10] uniformly\n",
    "    if U<V: break\n",
    "    \n",
    "print(\"U:\",U,\"V:\",V)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***A vous:*** Réécrivez $(3\\heartsuit)$ ce programme sans le `break`. En moyenne, combien  d'itération met ce programme pour s'arréter? Calculez-le théoriquement $(2\\heartsuit)$ puis vérifiez-le $(2\\heartsuit)$ informatiquement. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarquez que le programme avec break à deux avantages par rapport à celui sans break:\n",
    "\n",
    "* la condition d'arrête est plus naturelle que sa négation (la fonction dans le while).\n",
    "* Il n'est pas nécessaire d'initiliser `U` et `V`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dictionnaires\n",
    "\n",
    "Les dictionnaires (= tables de hashage) sont des outils indispensables pour programmer.\n",
    "Un dictionnaire est une collection contenant des VALEURS (=VALUES) qui sont indicées par des CLEFS (KEYS) uniques. Souvent les clefs sont des chaines de caractères.\n",
    "\n",
    "Les dictionnaires sont très efficaces car le temps d'accès aux valeurs (via une clef) ne dépend pas de la taille du dictionnaire. Imaginez que chaque clef est transformée, via un hashage, en adresse mémoire qui pointe vers une valeur.\n",
    "\n",
    "Il y a des dictionnaires partout :\n",
    "\n",
    "*  votre système d'exploitation crée des dictionnaires avec comme clef tous les mots présents dans tous les documents de votre ordinateur, et comme valeur l'adresse des documents en questions. \n",
    "*  les moteurs de recherche créent des dictionnaires pour indexer tous les mots clefs dans toutes les langues.\n",
    "*  les bases de données créent des indexes pour accéder plus rapidement aux données."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'unEntier': 3,\n",
       " 'unStr': 'aba',\n",
       " 'unDico': {'unEntier': 3, 'unStr': 'aba'},\n",
       " 'uneListe': [1, 2, 3, 4, 5]}"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\" création d'un dico par la notation 'JSON' (utilisées par de nombreux langages)\"\"\"\n",
    "dictionnaire = {'unEntier': 3, 'unStr': 'aba'}\n",
    "\"\"\"création d'un liste par la notation JSON\"\"\"\n",
    "maListe = [1, 2, 3, 4, 5]\n",
    "\n",
    "\"\"\"création d'un dico élément par élément \"\"\"\n",
    "dico = {}\n",
    "dico['unEntier'] = 3\n",
    "dico['unStr'] = 'aba'\n",
    "dico['unDico'] = dictionnaire\n",
    "dico['uneListe'] = maListe\n",
    "\n",
    "dico"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "\"\"\" il y a deux façons d'accéder aux valeurs : \"\"\"\n",
    "print(dico['unEntier'])  # quand on est sûr que la clef est présente. \n",
    "print(dico.get('toto'))  # quand on n'est pas sûr. Cela renvoie None quand la clef n'est pas présente"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1: True, 2: True, 4: True}\n",
      "0 est dans notre ensemble ?: None\n"
     ]
    }
   ],
   "source": [
    "\"\"\"  Chaque clef dans un dictionnaire est unique.\n",
    "Les dictionnaires peuvent être utilisés pour représenter des listes sans répétition:\"\"\"\n",
    "\n",
    "uneListe = [1, 2, 1, 4, 1, 4, 1, 1, 1, 1]\n",
    "laListeSansRepetition = {}\n",
    "for i in uneListe:\n",
    "    laListeSansRepetition[i] = True\n",
    "print(laListeSansRepetition)\n",
    "print(\"0 est dans notre ensemble ?:\", laListeSansRepetition.get(0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 4}\n",
      "{1, 2, 3, 4}\n"
     ]
    }
   ],
   "source": [
    "\"\"\" En fait, un dico avec que des \"True\" comme valeur est l'équivalent d'un ensemble (=set).  \"\"\"\n",
    "ensemble={1, 2, 1, 4, 1, 4, 1, 1, 1, 1} \n",
    "# c'est comme {1:True, 2:True, 1:True, 4:True, 1:True, 4:True, 1:True, 1:True, 1:True, 1:True}\n",
    "\n",
    "print(ensemble)\n",
    "ensemble.add(3)\n",
    "ensemble.add(1)\n",
    "print(ensemble)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['bonjour', 'bonjour', 'toi', 'toi', 'toi', 'comment', 'va', 'va']\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'bonjour': 2, 'toi': 3, 'comment': 1, 'va': 2}"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"les dictionnaires sont souvent utilisés pour compter des occurences\"\"\"\n",
    "unePhrase = \"bonjour bonjour toi toi toi comment va va\"\n",
    "lesMots = unePhrase.split(sep=\" \")\n",
    "print(lesMots)\n",
    "dico = {}\n",
    "for mot in lesMots:\n",
    "    if dico.get(mot) is None:\n",
    "        dico[mot] = 1\n",
    "    else:\n",
    "        dico[mot] += 1\n",
    "        \n",
    "dico"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'bonjour': 5, 'toi': 7, 'comment': 3, 'va': 5}"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"une astuce pour aller plus vite (éventuellement vous pouvez l'ignorer)\"\"\"\n",
    "dico2 = {}\n",
    "for mot in lesMots:\n",
    "    \"\"\"dico.get(key,0) renvoît 0 (au lieu de None) quand la clef n'est pas présente\"\"\"\n",
    "    dico2[mot]=dico.get(mot,0)+1\n",
    "dico2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{7: (5, 5), 'toto': 7, 5: 'bou', (9, 8): 7}\n",
      "[7, 'toto', 5, (9, 8)]\n",
      "[(5, 5), 7, 'bou', 7]\n",
      "7 (5, 5)\n",
      "toto 7\n",
      "5 bou\n",
      "(9, 8) 7\n",
      "{(5, 5): 7, 7: (9, 8), 'bou': 5}\n",
      "{(5, 5): 7, 7: (9, 8), 'bou': 5}\n"
     ]
    }
   ],
   "source": [
    "\"\"\"on voit que l'on peut indicer les dicos avec n'importe quoi comme clefs,\n",
    "     et l'on voit comment on inverse les clefs et valeurs dans un dico\"\"\"\n",
    "a=7\n",
    "b=(9,8)\n",
    "dico={a:5,\"toto\":7,5:\"bou\",b:7,7:(5,5)}\n",
    "print(dico)\n",
    "print(list(dico.keys()))\n",
    "print(list(dico.values()))\n",
    "\n",
    "\"inversons un dico\"\n",
    "dicoInv={}\n",
    "for key,val in dico.items():\n",
    "    print(key,val)\n",
    "    dicoInv[val]=key\n",
    "\n",
    "print(dicoInv)\n",
    "\n",
    "\"la même chose en une ligne\"\n",
    "dicoInv2={ val:key for key,val in dico.items() }\n",
    "print(dicoInv2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mais peut-on vraiment utiliser n'importe quoi comme clef  ? Dans le programme ci-dessus, essayer de remplacer `b=(9,8)` par  `b=[9,8]` pour voir. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***Exo:*** $(4\\heartsuit)$ Le but est de créer une fonction qui calcule *rapidement* les éléments communs à deux listes. Par exemple avec comme entrée:\n",
    "    \n",
    "        liste1=[1,3,5,7]\n",
    "        liste2=[8,6,5,3,2]\n",
    "        \n",
    "cette fonction renverra `[3,5]` ou `[5,3]`.  \n",
    "\n",
    "Naivement, on effectuerait une double boucle:\n",
    "```\n",
    "inter=[]\n",
    "for i in liste1:\n",
    "    for j in liste2:\n",
    "        if i==j: inter.append(j)\n",
    "```\n",
    "\n",
    "Mais la bonne technique  est de transformer la première listes en dico/ensemble puis de boucler sur la seconde liste. Cela va beaucoup plus vite.  \n",
    "\n",
    "Remarque: il existe une procédure toute faite (ci-dessous), ne l'utilisez pas! "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{3, 5}"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "liste1=[1,3,5,7]\n",
    "liste2=[8,6,5,3,2]\n",
    "\n",
    "ensemble1=set(liste1)\n",
    "ensemble2=set(liste2)\n",
    "inter=ensemble1.intersection(ensemble2)\n",
    "inter"
   ]
vincentvigon's avatar
vincentvigon committed
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
vincentvigon's avatar
vincentvigon committed
1268
   "version": "3.6.5"
vincentvigon's avatar
vincentvigon committed
1269
1270
1271
  }
 },
 "nbformat": 4,
vincentvigon's avatar
vincentvigon committed
1272
 "nbformat_minor": 2
vincentvigon's avatar
vincentvigon committed
1273
}