{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Différent types de données en python\n",
    "\n",
    "Les types en Python sont dynamiques. Une même variable peut changer de type."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Manipulation des nombres"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = int(2010) \n",
    "print(type(s))\n",
    "\n",
    "s = 3.14\n",
    "print(type(s))\n",
    "\n",
    "s = True\n",
    "print(type(s))\n",
    "\n",
    "s = 1.0j\n",
    "print(type(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 44            # Ceci est un commentaire\n",
    "x += 2            # équivalent à x = x + 2 pour des nombres\n",
    "\n",
    "print(x)\n",
    "print(x > 45)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = 2.5\n",
    "print(\"x+y =\", x+y)  # Ici, on ajoute un entier avec un réel, le résultat est un réel.\n",
    "print(type(x+y))     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x += 10   # !! L'ordre d'exécution des cellules est important !!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(10/3)   # division réelle\n",
    "print(10//3)  # division entière"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(10 % 3) # l'opérateur % retourne le reste de la division entière"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Assignations multiples\n",
    "a = b = c = 1\n",
    "print(a, b, c) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Les chaînes de caractères\n",
    "\n",
    "### Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Les chaînes de caractères sont définies en les entourant de simple 'quotes' ou de \"guillemets\". Il est possible d'utiliser un backslash (`\\`) pour afficher certains caractères spéciaux."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "print('spam eggs')          # simple quotes\n",
    "print('doesn\\'t')           # on utilise \\' pour écrire une simple quote\n",
    "print(\"doesn't\")            # ou on peut utiliser des guillemets pour définir la chaîne de caractère à la place\n",
    "print('\"Yes,\" he said.')    \n",
    "print(\"\\\"Yes,\\\" he said.\")\n",
    "print('\"Isn\\'t,\" she said.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Quelques caractères spéciaux"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "s = '\\tFirst line.\\nSecond line.'      # \\n fait une nouvelle ligne, \\t ajoute une tabulation\n",
    "print(s)                               # avec print(), \\n ajoute une nouvelle ligne\n",
    "print(r'\\tFirst line.\\nSecond line.')  # avec un \"r\" devant la chaîne de caractère, elle est affichée sans formatage (raw string)\n",
    "\n",
    "a = 3\n",
    "print(f\"the value of a^2 is {a**2}\")   # avec un \"f\" devant la chaîne de caractère, tout ce qui est mis entre accolade est évalué"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Chaîne de caractères sur plusieurs lignes avec des triple guillemets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "print(\"\"\"\n",
    "Usage: thingy [OPTIONS]\n",
    "     -h                        Display this usage message\n",
    "     -H hostname               Hostname to connect to\n",
    "\"\"\") "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Quelques opérations sur les chaînes de caractères"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Plusieurs chaînes de caractères peuvent être concaténer (coller les unes à la suite des autres) avec l'opération d'addition. Elles peuvent être répétée avec l'opération de multiplication par un entier."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# 3 fois 'un', suivi de 'ium'\n",
    "print(3 * 'un' + 'ium')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Les chaînes de caractères peuvent être indexée pour récupérer un caractère de la chaîne en particulier ou bien des sous chaînes de caractères. L'indice du premier caractère est 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "word = 'Python'\n",
    "print(word[0]) # caractère en position 0 (le premier donc)\n",
    "print(word[5]) # caractère en position 5 (le sixième)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Les indices peuvent aussi être négatif pour commencer à compter de la fin."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "print(word[-1])  # le dernier caractère\n",
    "print(word[-2])  # l'avant dernier caractère"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Les chaînes de caractères ne peuvent pas être modifiées en Python. On dit qu'elles sont **immutable**. Si vous devez en modifier une, il faut lui réassigner la nouvelle valeur complète."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "word[0] = 'J'    # Ne marche pas, on essaye de modifier la chaîne de caractère contenue dans la variable word"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word = 'Jython'  # On redéfinit complètement word avec la nouvelle valeur. On verra comment faire plus simplement plus tard."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Les chaînes de caractères contiennent beaucoup de fonctions qui peuvent leur être appliquées directement. Ce sont des objets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word = \"bonjour\"\n",
    "word  # Le résultat de la dernière commande d'une cellule est toujours affiché"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "word.startswith('P')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word.capitalize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word.upper()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Pour afficher tous ce que contient une variable, on peut utiliser la fonction python `dir`\n",
    "print(dir(word))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "help(word.replace)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word.replace('o','O', 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word.isalpha?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "word.isalpha()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut demander à un utilisateur d'entrée des données avec la fonction `input`. Elle retourne une chaîne de caractère avec la valeur entrée par l'utilisateur dedans."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "name = input(\"Enter votre nom : \")\n",
    "name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = input(\"Entrer un entier : \")\n",
    "print(x, type(x))                  # x est une chaîne de caractère\n",
    "\n",
    "x = int(x)                         # que l'on convertie en entier\n",
    "print(x, type(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Les listes Python\n",
    "\n",
    "- Une liste permet de grouper des plusieurs valeurs, potentiellement de types différents, entres elles\n",
    "- On définit une liste en écrivant entre des crochets ([ ]) ses éléments séparés par des virgules\n",
    "- Les listes, tout comme les chaînes de caractères, peuvent être indexées pour récupérer ses éléments ou concaténées"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a_list = [1, \"texte\", 2.3, max]\n",
    "print(a_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Indexation des listes\n",
    "\n",
    "Cela marche comme pour les chaînes de caractères"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares = [1, 4, 9, 16, 25, 36]\n",
    "print(squares)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[0]  # premier élément de la liste"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[-1]  # dernier élément de la liste"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut récupérer une sous liste avec du \"slicing\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[0:4]  # slicing basique. Noter que l'indice \"4\" n'est pas retourné, on s'arrête juste avant"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(squares[0], squares[1], squares[2], squares[3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[:4] # ne rien mettre pour le premier indice signifie que l'on commence du début de la liste"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[2:]  # ne rien mettre pour le dernier indice signifie que l'on va jusqu'à la fin de la liste"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(squares)\n",
    "squares[-3:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[1:5:2]  # il existe un troisième argument qui est le pas avec lequel on se déplace. Il vaut 1 par défaut."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[5:1:-2]  # ce pas peut être négatif"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[::2]  # un élément sur deux"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares[::-1]  # inversion de la liste"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Concaténation des listes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "squares += [49, 64, 81, 100] # Équivalent à  `squares.extend([49, 64, 81, 100])` \n",
    "                             # mais pas exactement à `squares = squares + [49, 64, 81, 100]`\n",
    "print(squares)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(10*[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(10*[0])   # len est une fonction qui retourne le nombre d'élément dans la liste"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Mutabilité des listes\n",
    "\n",
    "Contrairement aux chaînes de caractères qui sont immutables, les listes sont mutables. Elles peuvent être modifées."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cubes = [1, 8, 27, 65, 125]   # Oups, une valeur est fausse\n",
    "cubes[3] = 64                 # On corrige tout ça\n",
    "print(cubes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cubes.append(216)  # On ajoute 216 à la fin de la liste\n",
    "print(cubes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cubes.remove(64)  # On enlève la valeur 64 de la liste. Si 64 n'est pas dans la liste, on obtient une erreur.\n",
    "print(cubes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cubes.insert(3, 64)   # On insère la valeur 64 à l'indice 3 de la liste\n",
    "print(cubes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Assignations, copies, et références des listes Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']\n",
    "letters[2:5] = ['C', 'D', 'E']   # on change toute une sous liste\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "letters[2:5] = [] # On enlève tout une sous liste\n",
    "print(letters)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = ['a', 'b', 'c']\n",
    "n = [1, 2, 3]\n",
    "x = [a, n]      # x est une liste de liste. x contient deux éléments qui sont des listes.\n",
    "print(len(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x  # la liste x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x[0]  # le premier élément de x, une liste"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x[1]   # le deuxième élément de x, une liste aussi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x[0][1]  # le deuxième élément du premier élément de x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Attention aux copies et aux références des listes. Si vous voulez copier une liste, il vaut mieux le faire explicitement !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [0, 1, 2, 3, 4]\n",
    "b = a\n",
    "print(\"b = \", b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b[1] = 20        # On change un élément de b\n",
    "print(\"b = \", b)\n",
    "print(\"a = \", a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**b est une référence à a, elles occupent le même espace mémoire**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a[:]          # En assignant un slice de a (ici tout a), on obtient une nouvelle liste, qui n'est pas une référence !\n",
    "b[2] = 10\n",
    "print(\"b = \", b)\n",
    "print(\"a = \", a)   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a.copy()      # avec la fonction `copy`, plus explicite.\n",
    "b[2] = 10\n",
    "print(\"b = \", b)\n",
    "print(\"a = \", a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**a\\[:\\] et .copy() sont des copies peu profondes**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = ['a', 'b', 'c']\n",
    "n = [1, 2, 3]\n",
    "x = [a, n]           # x est une liste à deux éléments qui sont aussi des listes\n",
    "print(x)\n",
    "\n",
    "y = x.copy()         # y est une copie de x\n",
    "y[0][1] = 'd'\n",
    "\n",
    "print(x)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Copies profondes**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "a = ['a', 'b', 'c']\n",
    "n = [1, 2, 3]\n",
    "x = [a, n]\n",
    "\n",
    "y = copy.deepcopy(x)\n",
    "y[0][1] = 'd'\n",
    "\n",
    "print(x)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Quelques méthodes sur les listes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = list(\"python-2024\")\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(dir(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"La liste a\")\n",
    "print(a)\n",
    "\n",
    "print(\"Fonction sorted appliquée à a\")\n",
    "print(sorted(a))\n",
    "\n",
    "print(\"La liste a n'est pas modifiée\")\n",
    "print(a)\n",
    "\n",
    "print(\"La fonction .sort de a (appliquée à a donc). La liste a est modifiée dans ce cas\")\n",
    "a.sort()\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.reverse()\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(a.pop())   # retourne le dernier élément de a et l'enlève de la liste\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Les tuples Python\n",
    "\n",
    "Les tuples sont des objets très similaires aux listes sauf qu'ils sont **immutables**.\n",
    "On utilises des parenthèses ( ) pour les définir au lieu des crochets pour les listes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = (12, -3.2, 'hello')  # un tuple avec trois éléments\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = 12, -3.2, 'hello'  # Les parenthèses ne sont en réalité pas utiles\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t[0]    # l'indexation marche comme pour les listes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# on peut faire des tuples contenant des tuples\n",
    "u = t, 1, 2, 3, 4, 5\n",
    "print(u)\n",
    "\n",
    "u = t, (1, 2, 3, 4, 5)\n",
    "print(u)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Erreur, ils sont immutables ! On ne peut pas les modifier\n",
    "t[0] = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Mais ils peuvent contenir des objets mutables, comme des listes\n",
    "v = ([1, 2, 3], [4, 5, 6])\n",
    "print(v)\n",
    "\n",
    "v[0].append(3.5)   # On peut modifier le premier élément car c'est une liste, donc mutable\n",
    "v[0][1] = 20       # Même chose\n",
    "print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "u = ()          # Le tuple vide\n",
    "print(len(u))\n",
    "print(u)\n",
    "\n",
    "v = ('hello',)  # Un tuple à un seul élément. Il ne faut pas oublier la virgule, sinon ce n'est pas un tuple !\n",
    "print(len(v))\n",
    "print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "coords = -1.2, 23, 4.3   # tuple packing\n",
    "print(coords)\n",
    "\n",
    "x, y, z = coords         # tuple unpacking\n",
    "print(\"x =\", x)\n",
    "print(\"y =\", y)\n",
    "print(\"z =\", z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b, c = 1, 2, 3       # Le tuple (1, 2, 3) est créé, puis le tuple unpacking est réalisé\n",
    "print(a, b, c)\n",
    "\n",
    "a, b, c = 10, 4*a, b    # Idem, Le tuple de droite est d'abord créé, puis les assignations sont faites\n",
    "print(a, b, c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a, c = c, a     # Permutation de deux valeurs\n",
    "print(a, b, c) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Les dictionnaires\n",
    "\n",
    "Ce sont des objets qui ressemblent aux listes mais que l'on peut indexer avec autre chose que des entiers. C'est un ensemble de paire de (clé / valeur). Les clés, qui servent d'indices, sont des objets immutables. On utilisera souvent des chaînes de caractères par exemple."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# On peut créer un dictionnaire en utilisant des accolades et en spécifiant les paires clé / valeur\n",
    "person = {\"name\": \"John Smith\", \"email\": \"john.doe@domain.fr\"}\n",
    "print(person)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# On peut aussi utiliser la fonction `dict()`\n",
    "person = dict(name=\"John Smith\", email=\"john.doe@domain.fr\")   # Si les clés sont des chaînes de caractères, il est inutile de mettre les guillemets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "person"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Et il est possible d'ajouter de nouvelles entrées de la façon suivante\n",
    "person['size'] = 1.80\n",
    "person['weight'] = 70\n",
    "print(person)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "person['size']   # Indexation, on veut la valeur correspondant à la clé \"size\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "person['phone']  # On obtient une erreur si la clé n'existe pas dans le dictionnaire"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# On liste toutes les clés d'un dictionnaire\n",
    "person.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# la méthode `items` liste toutes les paires clé / valeur\n",
    "print(person.items())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Pour tester si un clé existe dans un dictionnaire\n",
    "print(\"size\" in person)\n",
    "print(\"weight\" not in person)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Les Set Python\n",
    "\n",
    "Ils sont moins utilisés que les autres types. C'est une collection non ordonnée unique d'éléments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "l = [4, 1, 2, 3, 4, 2, -1]  # une liste\n",
    "s = set(l)                  # transformée en set\n",
    "\n",
    "print(l)\n",
    "print(s)                    # les éléments en double ou plus on été enlevé"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# On peut tester si un élément est dans le set (marche aussi avec les listes et les tuples)\n",
    "if 2 in s: \n",
    "    print(\"2 est dans s\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(sorted(s))  # tri, retourne une liste"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Opération sur les ensembles <, <=, >, >=, |, &, -, ^\n",
    "s2 = set([3, 1])\n",
    "print(s - s2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercices"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercice 1\n",
    "\n",
    "- Découper la chaîne \"python L1 2024\" en une liste [\"python\",\"L1\", 2024] (voir la fonction split() pour les chaînes).\n",
    "- Insérer \"Mai\" et la valeur 21 avant 2024 dans la liste obtenue.\n",
    "- Créer un dictionnaire depuis la liste avec les clés \"niveau\", \"cours\", \"mois\", \"jours\", et \"annee\".\n",
    "- Afficher le dictionnaire.\n",
    "- Ajouter la paire clé / valeur suivante dans le dictionnaire : \"lieu\" / \"Lyon\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load solutions/types/dict.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercice 2\n",
    "\n",
    "- Créer une liste avec quelques éléments.\n",
    "- Déplacer tous ses éléments d'une place vers la gauche (le premier élément devient le dernier).\n",
    "- Refaire la même chose mais en déplaçant tous les éléments d'un cran vers la droite cette fois ci."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load solutions/types/shifting.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.10.13"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
