{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# 1A.1 - Dictionnaires, fonctions, code de Vigen\u00e8re\n", "\n", "Le dictionnaire est une structure de donn\u00e9es tr\u00e8s utilis\u00e9e. Elle est illustr\u00e9e pour un probl\u00e8me de d\u00e9cryptage."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Fonctions"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Les fonctions sont des portions de programmes qui reproduisent les m\u00eames instructions. La fonction suivante calcule un polyn\u00f4me de second degr\u00e9 $x^2+x-5$. A chaque fois qu'on appellera la fonction ``polynome``, elle fera le m\u00eame calcul sur des ``x`` diff\u00e9rents. Cela \u00e9vite principalement d'avoir \u00e0 recopier les m\u00eames lignes \u00e0 chaque fois qu'on en a besoin."]}, {"cell_type": "code", "execution_count": 2, "metadata": {"collapsed": true}, "outputs": [], "source": ["def polynome ( x ) :\n", " x2 = x*x\n", " return x2 + x - 5"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Une fonction commence toujours par ``def``. Entre parenth\u00e8ses, ce sont les param\u00e8tres (ou entr\u00e9es de la fonction). Ce qui suit le mot-cl\u00e9 ``return`` est le r\u00e9sultat de la fonction (ou sa sortie). Parmi les fonctions, il y a celles qui existent d\u00e9j\u00e0 et celles que vous \u00e9crivez. La fonction ``cos`` existe d\u00e9j\u00e0 : elle fait un calcul qu'il n'est pas besoin de r\u00e9\u00e9crire. La fonction ``polynome`` d\u00e9crite plus haut n'existait pas avant de l'avoir d\u00e9finie. On distingue la d\u00e9finition d'une fonction :"]}, {"cell_type": "code", "execution_count": 3, "metadata": {"collapsed": true}, "outputs": [], "source": ["def polynome ( x, coefficient ) :\n", " return sum ( [ x**i * c for i,c in enumerate(coefficient) ] )"]}, {"cell_type": "markdown", "metadata": {}, "source": ["De son utilisation ou appel :"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": ["1.96"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["y = polynome ( 1.2, [ 1, 2, -1] ) # calcul de -x^2 + 2x + 1 pour x = 1.2\n", "y"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On peut appeler une fonction depuis une autre fonction. Une fonction peut prendre autant de param\u00e8tres que l'on veut \u00e0 condition qu'ils aient des noms diff\u00e9rents. On peut aussi leur associer une **valeur par d\u00e9faut** :"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": ["(2.9999999999999996, 9.965784284662087)"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["from math import log # on importe une fonction existante\n", "def log_base ( x, base = 10 ) :\n", " return log (x) / log(base)\n", "\n", "y = log_base (1000) # identique \u00e0 y = log_base (1000, 10)\n", "z = log_base (1000, 2) # logarithme en base deux\n", "y,z"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Les fonctions doivent porter des noms diff\u00e9rents. Dans le cas contraire, seule la derni\u00e8re existe."]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "polynome() missing 1 required positional argument: 'coefficient'", "output_type": "error", "traceback": ["\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mpolynome\u001b[0m \u001b[1;33m(\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcoefficient\u001b[0m \u001b[1;33m)\u001b[0m \u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0msum\u001b[0m \u001b[1;33m(\u001b[0m \u001b[1;33m[\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m**\u001b[0m\u001b[0mi\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mc\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mc\u001b[0m \u001b[1;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcoefficient\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m]\u001b[0m \u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpolynome\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# d\u00e9clenche une exception\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: polynome() missing 1 required positional argument: 'coefficient'"]}], "source": ["def polynome ( x ) : # remplac\u00e9e par la seconde fonction\n", " return x*x + x - 5\n", "def polynome ( x, coefficient ) :\n", " return sum ( [ x**i * c for i,c in enumerate(coefficient) ] )\n", "y = polynome(4) # d\u00e9clenche une exception"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 1\n", "\n", "Les fonctions [chr](https://docs.python.org/3.4/library/functions.html#chr) et [ord](https://docs.python.org/3.4/library/functions.html#ord) sont sym\u00e9triques l'une de l'autre : elles convertissent un nombre en lettre et r\u00e9ciproquement."]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["A a\n", "66 98\n"]}], "source": ["print ( chr( 65 ), chr (97) )\n", "print ( ord(\"B\"), ord (\"b\") )"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Le symbol ``%`` permet d'obtenir le reste d'une division enti\u00e8re. L'exercice consiste \u00e0 \u00e9crire une fonction qui retourne la lettre suivante dans l'ordre alphab\u00e9tique. La lettre qui suit ``z`` est ``a``."]}, {"cell_type": "code", "execution_count": 8, "metadata": {"collapsed": true}, "outputs": [], "source": ["def lettre_suivante(lettre) :\n", " # ......\n", " return ...."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Fonctions dans le d\u00e9tail"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Variable locale\n", "\n", "**Une variable cr\u00e9\u00e9e \u00e0 l'int\u00e9rieur d'une fonction n'existe pas \u00e0 l'ext\u00e9rieur : c'est une variable locale.** C'est pourquoi le code suivant provoque une erreur car la variable ``z`` n'existe pas en dehors de la fonction ``calcul``. Les variables ``y`` ou ``z`` ne servent que d'interm\u00e9diaire de calcul. Le seul r\u00e9sultat qui sort de la fonction suit le mot-cl\u00e9 ``return``."]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"ename": "NameError", "evalue": "name 'z' is not defined", "output_type": "error", "traceback": ["\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mz\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mz\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mNameError\u001b[0m: name 'z' is not defined"]}], "source": ["def calcul(x) :\n", " y = x**2\n", " z = x + y\n", " return z\n", "\n", "print(z) # d\u00e9clenche une exception"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Mot-cl\u00e9 ``return``\n", "\n", "**Sans mot-cl\u00e9 ``return``, le r\u00e9sultat est ``None``.**"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["None\n"]}], "source": ["def calcul(x) :\n", " y = x**2\n", " z = x + y\n", "\n", "a = calcul(3)\n", "print(a)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["La fonction se termine apr\u00e8s le premier ``return`` rencontr\u00e9 lors de l'ex\u00e9cution."]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["je passe par ici\n"]}, {"data": {"text/plain": ["5"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["def valeur_absolue(x) :\n", " print(\"je passe par ici\")\n", " if x < 0 : \n", " y = -x\n", " return y\n", " else :\n", " y = x\n", " return y\n", " print(\"je ne passe jamais par ici\")\n", " \n", "valeur_absolue(-5)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Fonction r\u00e9cursive\n", "\n", "**Une fonction peut \u00eatre r\u00e9cursive : elle s'appelle elle-m\u00eame.** Mais il est important de savoir qu'il existe un cas dans lequel elle ne s'appelle pas pour arr\u00eater la r\u00e9cursion."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["je m'appelle pour x= 10\n", "je m'appelle pour x= 5.0\n", "je m'appelle pour x= 2.5\n", "je ne m'appelle pas pour x= 1.25\n"]}, {"data": {"text/plain": ["4"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["def recursive(x) :\n", " if x / 2 < 1 :\n", " print(\"je ne m'appelle pas pour x=\",x)\n", " return 1\n", " else :\n", " print(\"je m'appelle pour x=\",x)\n", " return recursive (x/2) + 1\n", "\n", "recursive( 10 )"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Dictionnaires"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### cl\u00e9 - valeur"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Une **liste** est un ensemble d'autres objets index\u00e9s par des entiers. Un **dictionnaire** est un ensemble d'autres objets index\u00e9s par presque n'importe quoi."]}, {"cell_type": "code", "execution_count": 13, "metadata": {"collapsed": true}, "outputs": [], "source": ["d = { } # un dictionnaire vide\n", "d = { 'a' : 'acronym', 'b': 'bizarre' } # un dictionnaire qui associe 'acroym' \u00e0 'a' et 'bizarre' \u00e0 'b'.\n", "z = d ['a'] # z re\u00e7oit la valeur associ\u00e9e \u00e0 'a' et stock\u00e9e dans le dictionnaire d"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Quelques fonctions utiles :"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["('d=', {'a': 'acronym', 'b': 'bizarre'}, 'l=', 2, 'b=', True, 'x=', 'acronym')"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["d = { 'a' : 'acronym', 'b': 'bizarre' } \n", "l = len(d) # retourne le nombre d'\u00e9l\u00e9ment de d\n", "b = 'a' in d # b vaut True si une valeur est associ\u00e9e \u00e0 'a', on dit aussi que la cl\u00e9 'a' est pr\u00e9sente \n", "x = d.get ('a', '') # x vaut d['a'] si la cl\u00e9 'a' existe, il vaut '' sinon \n", "\n", "\"d=\",d,\"l=\",l,\"b=\",b,\"x=\",x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On utilise souvent un dictionnaire pour compter les lettres d'un texte :"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'t': 2, 'l': 1, 'e': 6, ' ': 2, 'x': 2, 'm': 1, 'd': 1, 'p': 1}"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["texte = \"exemple de texte\"\n", "d = { }\n", "for c in texte :\n", " d[c] = d.get(c,0) + 1\n", "\n", "d"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Les valeurs peuvent \u00eatre n'importe quoi, y compris des listes ou des dictionnaires. Les cl\u00e9s doivent \u00eatre des types [immuables](http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/all_FAQ.html#tabulations-ou-espace) (nombre, cha\u00eenes de caract\u00e8res, ``tuple`` incluant des types immuables). Si vous utilisez un autre type, cela d\u00e9clenche une erreur : "]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "unhashable type: 'list'", "output_type": "error", "traceback": ["\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0md\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'"]}], "source": ["f = [3,4]\n", "d[f] = 0 # d\u00e9clenche une exception"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Lorsqu'on affecte une valeur \u00e0 une cl\u00e9, le dictionnaire cr\u00e9e la cl\u00e9 ou remplace la valeur pr\u00e9c\u00e9dente par la nouvelle :"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'a': 1}"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["d = { }\n", "d['a'] = 0 # cr\u00e9ation d'une cl\u00e9\n", "d['a'] = 1 # remplacement d'une valeur\n", "\n", "d"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On peut aussi cr\u00e9er un dictionnaire de fa\u00e7on compacte :"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'un': 2, 'trois': 5, 'deux': 4}"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["d = { s:len(s) for s in ['un', 'deux', 'trois'] }\n", "d"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### notions de co\u00fbt\n", "\n", "Il est aussi rapide d'acc\u00e9der \u00e0 un \u00e9l\u00e9ment d'un dictionnaire que d'acc\u00e9der \u00e0 un \u00e9l\u00e9ment d'une liste : [TimeComplexity](https://wiki.python.org/moin/TimeComplexity). C'est une [table de hashage](https://en.wikipedia.org/wiki/Hash_table) qui permet d'obtenir ce r\u00e9sultat."]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### ordonner les \u00e9l\u00e9ments d'un dictionnaire\n", "\n", "Les \u00e9l\u00e9ments d'un dictionnaire ne sont pas ordonn\u00e9es ou tout du moins ne le sont pas d'une fa\u00e7on pr\u00e9dictible. Pour les parcourir dans un ordre pr\u00e9cis, il faut utiliser une liste puis les ordonner. L'exemple suivant montre comment ordonner les \u00e9l\u00e9ments par ordre croissant de valeur, puis par ordre alphab\u00e9tique en cas d'ex aeco."]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'cinq': 4, 'deux': 4, 'quatre': 6, 'trois': 5, 'un': 2}"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["d = { s:len(s) for s in ['un', 'deux', 'trois', 'quatre', 'cinq'] }\n", "d"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"data": {"text/plain": ["[(4, 'cinq'), (5, 'trois'), (4, 'deux'), (6, 'quatre'), (2, 'un')]"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["ordonne = [ (v,k) for k,v in d.items()]\n", "ordonne"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/plain": ["[(2, 'un'), (4, 'cinq'), (4, 'deux'), (5, 'trois'), (6, 'quatre')]"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["ordonne.sort()\n", "ordonne"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**A quoi \u00e7a sert ?** on se sert beaucoup des dictionnaires pour compter la fr\u00e9quences des caract\u00e8res, des mots ou de couples de mots dans un texte. On les ordonne ensuite par fr\u00e9quences d\u00e9croissantes pour obtenir les mots ou caract\u00e8res les plus fr\u00e9quents."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 2 : recherche dans une liste\n", "\n", "On consid\u00e8re une liste de mots :"]}, {"cell_type": "code", "execution_count": 22, "metadata": {"collapsed": true}, "outputs": [], "source": ["mots = ['eddard', 'catelyn', 'robb', 'sansa', 'arya', 'brandon',\n", " 'rickon', 'theon', 'rorbert', 'cersei', 'tywin', 'jaime',\n", " 'tyrion', 'shae', 'bronn', 'lancel', 'joffrey', 'sandor',\n", " 'varys', 'renly', 'a' ]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Il faut \u00e9crire une fonction qui retourne tous les mots de la liste qui ont un 'y' en seconde position."]}, {"cell_type": "code", "execution_count": 23, "metadata": {"collapsed": true}, "outputs": [], "source": ["def mots_lettre_position (liste, lettre, position) :\n", " # ......\n", " return [ .... ]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 3 : utilisation d'un dictionnaire\n", "\n", "On modifie la fonction pr\u00e9c\u00e9dente ``mots_lettre_position`` de telle sorte qu'elle s'\u00e9crive comme suit :"]}, {"cell_type": "code", "execution_count": 24, "metadata": {"collapsed": true}, "outputs": [], "source": ["def mots_lettre_position (dictionnaire_bien_choisi, lettre, position) :\n", " return dictionnaire_bien_choisi. get ( (position, lettre) , [] )"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Construisez le dictionnaire ``dictionnaire_bien_choisi`` pour que cela fonctionne.\n", "Combien de mots sont stock\u00e9s dans ``dictionnaire_bien_choisi`` ?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Reformulation** Lorsqu'on cherche un mot dans un dictionnaire (un vrai), on tourne peu de pages pour le trouver puisqu'ils sont tri\u00e9s par ordre alphab\u00e9tique. Maintenant, si on souhaite trouver tous les mots dans la seconde lettre est ``e``, c'est impossible \u00e0 moins de trier les mots par leur seconde lettre : il faudrait un dictionnaire diff\u00e9rent pour chaque position de lettre. L'objectif de cet exercice est de concevoir une sorte de dictionnaire qui permette de retrouver tous les mots ayant telle lettre \u00e0 telle position."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Exercice 4 : crypter de d\u00e9crypter selon Vigen\u00e8re\n", "\n", "Le [code de C\u00e9sar](http://fr.wikipedia.org/wiki/Chiffrement_par_d%C3%A9calage) est une permutation de lettre ou un d\u00e9calage. Toutes les lettres du message sont d\u00e9cal\u00e9es d'un nombre fixe :\n", "\n", "- ``JENESUISPASCODE``\n", "- ``MHQHVXLVSDVFRGH``\n", "\n", "Le [code de Vigen\u00e8re](http://fr.wikipedia.org/wiki/Chiffre_de_Vigen%C3%A8re) introduit un d\u00e9calage qui d\u00e9pend de la position de la lettre dans le message \u00e0 coder. On choisit d'abord un mot qui servira de code (par exemple ``DOP``) puis on le traduit en d\u00e9calages : ``[3, 14, 15]`` en servant de la position des lettres dans l'alphabet. \n", "\n", "Pour coder, on d\u00e9cale la premi\u00e8re lettre de 3, la seconde de 14, la troisi\u00e8me 15, la quatri\u00e8me de 3 \u00e0 nouveau... L'objectif de cette partie est d'\u00e9crire une fonction qui crypte le message pr\u00e9c\u00e9dent et une autre qui d\u00e9crypte."]}, {"cell_type": "code", "execution_count": 25, "metadata": {"collapsed": true}, "outputs": [], "source": ["def code_vigenere ( message, cle) :\n", " # ...... \u00e0 remplir\n", " return message_code"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A quelle condition le code de Vigen\u00e8re est un simple code de C\u00e9sar ?\n", "\n", "Pensez-vous qu'il soit possible de casser le code de Vigen\u00e8re (de le d\u00e9crypter sans la cl\u00e9) ?"]}, {"cell_type": "code", "execution_count": 26, "metadata": {"collapsed": true}, "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", "version": "3.6.1"}}, "nbformat": 4, "nbformat_minor": 2}