{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cpython\n", "pypy\n", "jython\n", "ironpython\n" ] } ], "source": [ "implementations = ['cpython', 'pypy', 'jython', 'ironpython']\n", "\n", "for implementation in implementations:\n", " print(implementation)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "\n", "\n", "

La philosophie de l'itération

\n", "\n", "\n", "\n", "\n", "

\n", "\n", "



kevin@formationspython.com\n", "\n", "

\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Un design pattern : iterator" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Eviter de boucler à la main:\n", "\n", "```c\n", " const char *relatedTopics[] = { \n", " \"++\", \n", " \"jerome\", \n", " \"pas ma faute\", \n", " NULL \n", " };\n", "\n", " for (int i=0; relatedTopics[i]; ++i) {\n", " const char *ch = relatedTopics[i]; \n", " while(*ch) {\n", " putchar(*ch++);\n", " putchar('\\n');\n", " }\n", " putchar('\\n');\n", " }\n", " \n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Visitor\n", "\n", "Methode `forEach` des arrays en JS:\n", "\n", "```javascript\n", "var nope = [\"==\", \"with\", \"eval\"];\n", "nope.forEach((e) => {\n", " console.log(e)\n", "});\n", "```\n", "\n", "\"L'iterator\" `each` de Ruby:\n", "\n", "```Ruby\n", "popularProjects = [\"RoR\", \"rails\", \"Ruby on Rails\"];\n", "popularProjects.each do |i|\n", " puts i\n", "end\n", "});\n", "```\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Comment Python fait marcher tout ça" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " de cris :\n", "Cowabunga !\n", "Yippee ki-yay, mofo !\n", "Wololo !\n" ] } ], "source": [ "cris = ['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'] \n", "\n", "# cris = set(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])\n", "# cris = tuple(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])\n", "# cris = dict.fromkeys(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])\n", "\n", "print(f\"{type(cris)} de cris :\")\n", "\n", "for cri in cris:\n", " print(cri, '!')\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "cris = ['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'] \n", "\n", "#cris = set(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])\n", "#cris = tuple(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])\n", "#cris = dict.fromkeys(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo'])" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "sauce_magique = iter(cris)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "list_iterator" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(sauce_magique)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'Cowabunga'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(sauce_magique)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'Yippee ki-yay, mofo'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(sauce_magique)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'Wololo'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(sauce_magique)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msauce_magique\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m: " ] } ], "source": [ "next(sauce_magique)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Iterator, l'interface universelle" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n" ] } ], "source": [ "for i in range(1, 4):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n" ] } ], "source": [ "for lettre in \"abc\":\n", " print(lettre)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Chez moi ça marche\n", "\n", "T'as rebooté ?\n", "\n", "Réessaye pour voir\n", "\n" ] } ], "source": [ "for ligne in open('answers.txt'):\n", " print(ligne)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "['Chez moi ça marche\\n', \"T'as rebooté ?\\n\", 'Réessaye pour voir\\n']" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(open('answers.txt'))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tuple(range(1, 4))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "{'a', 'b', 'c'}" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "set('abc')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum([1, 2, 3])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(set([1, 2, 3]))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(range(1, 4))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(map(int, \"123\"))" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "['Cowabunga', 'Wololo', 'Yippee ki-yay, mofo']" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sorted(set(['Cowabunga', 'Yippee ki-yay, mofo', 'Wololo']))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "[True, 1]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(filter(bool, (True, False, None, 1, 0)))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "\"Chez moi ça marche\\n/////////////T'as rebooté ?\\n/////////////Réessaye pour voir\\n\"" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"/////////////\".join(open('answers.txt'))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 a\n", "2 b\n", "3 c\n" ] } ], "source": [ "for i, ligne in enumerate('abc', 1):\n", " print(i, ligne)" ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "Counter({'c': 1,\n", " 'd': 5,\n", " 'f': 4,\n", " 'h': 3,\n", " 'j': 3,\n", " 'k': 5,\n", " 'l': 3,\n", " 'q': 2,\n", " 's': 1,\n", " 'v': 1})" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import collections # amis des itérables\n", "\n", "collections.Counter('dkjflchldkfhjdlskqfvdkfdhqkj')\n", "\n", "# collections.deque\n", "# collections.defaultdict\n", "# collections.OrderedDict\n", "# collections.namedtuple" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n", "10\n" ] } ], "source": [ "# Prend n'importe quel itérable\n", "\n", "print(any([True, True, False, True, False]))\n", "print(all([True, True, False, True, False]))\n", "print(max([5, 10, 4, 1]))\n", "# min\n", "# reduce" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Retourne des itérables:\n", "\n", "- bytes\n", "- csv.reader\n", "- os.walk\n", "- multiprocessing.Pool.map\n", "- sqlite3.cursor\n", "- xml.etree.ElementTree\n", "\n", "\n", "Et même les libs externes:\n", "\n", "- Querysets des ORMs (Django, SQLAlchemy, Peewee...);\n", "- Body des réponses de WSGI " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Un module juste pour les itérables\n", "\n", "\n", "\n", "```python\n", "import itertools\n", "\n", "itertools.accumulate\n", "itertools.chain\n", "itertools.combinations\n", "itertools.combinations_with_replacement\n", "itertools.compress\n", "itertools.count\n", "itertools.cycle\n", "itertools.dropwhile\n", "itertools.filterfalse\n", "itertools.groupby\n", "itertools.islice\n", "itertools.permutations\n", "itertools.product\n", "itertools.repeat\n", "itertools.starmap\n", "itertools.takewhile\n", "itertools.tee\n", "itertools.zip_longest\n", "```" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n", "0\n", "1\n", "2\n" ] } ], "source": [ "import itertools\n", "for x in itertools.chain('abc', range(3)):\n", " print(x)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "scrolled": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "[('a', 0),\n", " ('a', 1),\n", " ('a', 2),\n", " ('b', 0),\n", " ('b', 1),\n", " ('b', 2),\n", " ('c', 0),\n", " ('c', 1),\n", " ('c', 2)]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(itertools.product('abc', range(3)))" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n", "b\n", "c\n", "a\n" ] } ], "source": [ "histoire_de_la_vie = iter(itertools.cycle('abc'))\n", "print(next(histoire_de_la_vie))\n", "print(next(histoire_de_la_vie))\n", "print(next(histoire_de_la_vie))\n", "print(next(histoire_de_la_vie))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## L'unpacking" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "x, y = (1, 2)\n", "print(x)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "def point():\n", " return 1, 2\n", "\n", "x, y = point()\n", "print(y)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = Aligator\n", "b = Behemot\n", "c = Claude\n" ] } ], "source": [ "a, b, c = [\"Aligator\", \"Behemot\", \"Claude\"]\n", "print(f'a = {a}')\n", "print(f'b = {b}')\n", "print(f'c = {c}') " ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = Chez moi ça marche\n", "\n", "b = T'as rebooté ?\n", "\n", "c = Réessaye pour voir\n", "\n" ] } ], "source": [ "a, b, c = open('answers.txt')\n", "print(f'a = {a}')\n", "print(f'b = {b}')\n", "print(f'c = {c}') " ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 0\n", "b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]\n", "d = 99\n" ] } ], "source": [ "a, *b, d = range(100)\n", "print(f'a = {a}')\n", "print(f'b = {b}')\n", "print(f'd = {d}')" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a#b#c\n" ] } ], "source": [ "print(*'abc', sep=\"#\") # équivaut à print(\"a\", \"b\", \"c\", sep=\"#\")" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "[0,\n", " 1,\n", " 2,\n", " 'Chez moi ça marche\\n',\n", " \"T'as rebooté ?\\n\",\n", " 'Réessaye pour voir\\n',\n", " 'Cowabunga',\n", " 'Yippee ki-yay, mofo',\n", " 'Wololo']" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[*range(3), *open('answers.txt'), *set(cris)] # marche aussi pour merger des dictionnaires avec ** :)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "pixels = [\"rouge\", \"vert\", \"bleu\", \"rouge\", \"vert\", \"bleu\", \"rouge\", \"vert\", \"bleu\"]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "pixels[::3], pixels[2::3] = pixels[2::3], pixels[::3]" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "['bleu', 'vert', 'rouge', 'bleu', 'vert', 'rouge', 'bleu', 'vert', 'rouge']" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pixels" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Le flux de données" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "docker0 Link encap:Ethernet HWaddr 02:42:70:a2:48:86 \n", " inet adr:172.17.0.1 Bcast:0.0.0.0 Masque:255.255.0.0\n", " UP BROADCAST MULTICAST MTU:1500 Metric:1\n", " Packets reçus:0 erreurs:0 :0 overruns:0 frame:0\n", " TX packets:0 errors:0 dropped:0 overruns:0 carrier:0\n", " collisions:0 lg file transmission:0 \n", " Octets reçus:0 (0.0 B) Octets transmis:0 (0.0 B)\n", "\n", "enx644bf0013110 Link encap:Ethernet HWaddr 64:4b:f0:01:31:10 \n", " inet adr:192.168.1.10 Bcast:192.168.1.255 Masque:255.255.255.0\n", " adr inet6: 2a01:cb1d:16:5b00:6a2c:d680:372e:a92a/64 Scope:Global\n", " adr inet6: fe80::1ff5:8827:4cd9:fdf2/64 Scope:Lien\n", " UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1\n", " Packets reçus:310258 erreurs:0 :0 overruns:0 frame:0\n", " TX packets:185186 errors:0 dropped:0 overruns:0 carrier:0\n", " collisions:0 lg file transmission:1000 \n", " Octets reçus:337432415 (337.4 MB) Octets transmis:20810130 (20.8 MB)\n", "\n", "lo Link encap:Boucle locale \n", " inet adr:127.0.0.1 Masque:255.0.0.0\n", " adr inet6: ::1/128 Scope:Hôte\n", " UP LOOPBACK RUNNING MTU:65536 Metric:1\n", " Packets reçus:30249 erreurs:0 :0 overruns:0 frame:0\n", " TX packets:30249 errors:0 dropped:0 overruns:0 carrier:0\n", " collisions:0 lg file transmission:1000 \n", " Octets reçus:18551108 (18.5 MB) Octets transmis:18551108 (18.5 MB)\n", "\n", "wlp2s0 Link encap:Ethernet HWaddr 44:1c:a8:e2:1a:df \n", " UP BROADCAST MULTICAST MTU:1500 Metric:1\n", " Packets reçus:10400 erreurs:0 :121 overruns:0 frame:0\n", " TX packets:5860 errors:0 dropped:0 overruns:0 carrier:0\n", " collisions:0 lg file transmission:1000 \n", " Octets reçus:11993856 (11.9 MB) Octets transmis:592176 (592.1 KB)\n", "\n", "\n" ] } ], "source": [ "import subprocess\n", "\n", "res = subprocess.check_output([\"ifconfig\"], encoding=\"utf8\") # devinez ce qu'attend \"call\" en paramètre ?\n", "\n", "print(res) " ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import re, subprocess\n", "\n", "res = subprocess.check_output([\"ifconfig\"], encoding=\"utf8\")\n", "reg = re.compile(r'(\\S+).*\\n.*adr:(\\S+)')" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'docker0': '172.17.0.1', 'enx644bf0013110': '192.168.1.10', 'lo': '127.0.0.1'}\n" ] } ], "source": [ "interfaces = {}\n", "for block in res.split('\\n\\n'): \n", " if 'adr' in block:\n", " interface, ip = reg.match(block).groups()\n", " interfaces[interface] = ip\n", "print(interfaces)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "{'docker0': '172.17.0.1', 'enx644bf0013110': '192.168.1.10', 'lo': '127.0.0.1'}" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "interfaces = [reg.match(block).groups() for block in res.split('\\n\\n') if 'adr' in block]\n", "dict(interfaces)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Les intensions" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[x * x for x in range(10)]" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{x: x * x for x in range(10)}" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "{0, 1, 4, 9, 16, 25, 36, 49, 64, 81}" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{x * x for x in range(10)}" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Les expressions génératrices" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# NOPE !\n", "# res = [x * x for x in range(10000000000000)] " ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "res = (x * x for x in range(10000000000000))" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ " at 0x7f0808755360>" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(res)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(res)" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n", "9\n", "16\n" ] } ], "source": [ "print(next(res))\n", "print(next(res))\n", "print(next(res))" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import sqlite3\n", "\n", "def get_results(n=10, profile=\"/home/pycon/.mozilla/firefox/l92ue2kx.default/places.sqlite\"):\n", " return sqlite3.connect(profile).execute(\"\"\"\n", " SELECT sites.rev_host as host, count(*) as visits FROM moz_historyvisits as visits, moz_places as sites\n", " WHERE visits.place_id == sites.id GROUP BY host ORDER BY visits DESC\n", " \"\"\")" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "sites = ((dom[-2::-1], vis) for dom, vis in get_results())" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "MOTEURS = set(['duckduckgo', 'google', 'bing', 'qwant'])\n", "sites = ((dom, vis) for dom, vis in sites if not any(m in dom for m in MOTEURS)) " ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import itertools\n", "sites = itertools.islice(sites, 0, 5) " ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sites" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "('localhost', 359)" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(sites)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "('nbviewer.jupyter.org', 41)" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(sites)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('github.com', 9)\n", "('lastpass.com', 9)\n", "('www.lastpass.com', 7)\n" ] } ], "source": [ "for s in sites:\n", " print(s)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Yield" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Avant le premier return\n", "1\n" ] } ], "source": [ "def fonction_normale():\n", " print('Avant le premier return')\n", " return 1\n", " print('Apres le premier return')\n", " return 2\n", " print(\"Apres le second return\")\n", " return 3\n", " print('Tout à la fin')\n", " \n", "res = fonction_normale()\n", "print(res)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "def fabriquer_un_generateur():\n", " print('Avant le premier yield')\n", " yield 1\n", " print('Apres le premier yield')\n", " yield 2\n", " print(\"Apres le second yield\")\n", " yield 3\n", " print('Tout à la fin')\n", " \n", "res = fabriquer_un_generateur()\n", "print(res)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Avant le premier yield\n" ] }, { "data": { "text/plain": [ "1" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(res)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Apres le premier yield\n" ] }, { "data": { "text/plain": [ "2" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(res)" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Apres le second yield\n", "3\n", "Tout à la fin\n" ] } ], "source": [ "for x in res:\n", " print(x)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import secrets\n", "\n", "def secret_key_generator(n):\n", " for i in range(n):\n", " yield secrets.token_hex() \n", "\n", "gen = secret_key_generator(10)" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'9c814af4bceb652403b32d908973ae10c9433e6031a51cb0221f7196c5420aea'" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(gen)" ] }, { "cell_type": "code", "execution_count": 70, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "'6acd1731134c0b8db62f42bab49652c4accf91731dd9e1c00d1fdf2f5ee28f5d'" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(gen)" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n", "Miaou !\n" ] } ], "source": [ "import itertools\n", "\n", "class MachineAtuer:\n", " def __iter__(self):\n", " while True:\n", " yield \"Miaou !\"\n", " \n", "for x in itertools.islice(MachineAtuer(), 10):\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Tous les tuyaux mis bouts à bouts" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import string\n", "from pathlib import Path\n", "\n", "\n", "def lister_mots_cles(dossier, ext):\n", " for chemin in Path(dossier).glob(f'./**/*.{ext}'): # iterable\n", " try:\n", " with open(chemin) as f:\n", " for ligne in f: # iterable\n", " for mot in ligne.split(): # iterable\n", " # expression generatrice sur un itérable passée à join... qui attend un itérable\n", " mot = \"\".join(l for l in mot if l not in string.punctuation).strip()\n", " if mot:\n", " # génération de données\n", " yield mot\n", " except Exception:\n", " pass\n" ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "- the: 2937\n", "- alias: 1504\n", "- to: 1477\n", "- for: 1100\n", "- if: 984\n" ] } ], "source": [ "from collections import Counter\n", "\n", "# Counter accepte un itérable en a paramètre\n", "for mot, score in Counter(lister_mots_cles('/etc', 'conf')).most_common(5): # itérable\n", " print(f'- {mot}: {score}')" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%HTML \n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "code", "execution_count": 74, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "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\nKdXH/wMx3clddjjO9wAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np # ou scipy, pandas, etc\n", "\n", "import matplotlib.pyplot as plt\n", "\n", "x = np.arange(0, 3 * np.pi, 0.1)\n", "y = np.sin(x)\n", "\n", "plt.plot(x, y)\n", "plt.show() " ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "23.4 µs ± 491 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n", "2.5 µs ± 36.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ] } ], "source": [ "import math\n", "\n", "x = np.arange(0, 3 * np.pi, 0.1)\n", "\n", "%timeit [math.sin(i) for i in x]\n", "%timeit np.sin(x)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Il y a un \"one more thing\" pour ça" ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def crieur():\n", " while True:\n", " res = yield\n", " print(res.upper(), '!')\n", " \n", "gen = crieur()\n", "next(gen)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "LES INTERDICTIONS !\n", "LES LISTES !\n", "LES INTERDICTIONS !\n", "LES REPETITIONS !\n", "LES METS !\n", "LES BLAGUES FACILES !\n" ] } ], "source": [ "interdits = [\n", " 'les interdictions', \n", " 'les listes', \n", " 'les interdictions', \n", " 'les repetitions', \n", " 'les mets',\n", " 'les blagues faciles'\n", "]\n", "\n", "for x in interdits:\n", " gen.send(x) " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "\n", "

Télécharger les slides

\n", "\n", "\n", "

\n", "https://huit.re/philo-iteration-fr\n", "

\n", "\n", "\n", "

\n", "\n", "

kevin@formationspython.com

\n" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 2 }