{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table>\n",
    "    <td>\n",
    "        <h1>- TD2 -</h1>\n",
    "    </td>\n",
    "    <td style=\"text-align:left\">\n",
    "        <h2>UFR de sociologie et d'informatique pour les sciences humaines</h2>\n",
    "        <h2>Programmation en Python</h2> \n",
    "    </td>\n",
    "    <td style=\"text-align:left\"><img width=\"150\" src=\"http://lettres.sorbonne-universite.fr/sites/default/files/media/2019-10/sorbonne-lettre_1.svg\" /></td>\n",
    "    \n",
    "\n",
    "</table>\n",
    "\n",
    "-----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "<h2><font color = 'blue'>Les chaînes de caractères</font></h2>\n",
    "\n",
    "En *Sciences du Langage*, la manipulation de textes (au sens large, avec ponctuation, saut de ligne, etc.) est primordiale, d'où l'importance de ce TD.\n",
    "\n",
    "Dans la suite de ce notebook, le groupe de mot \"*chaîne de caractères*\" sera remplacé par \"*string*\". En effet les chaînes de caractères sont des suites de caractères quelconques. Elles sont du type __string__.\n",
    "\n",
    "Il y a plusieurs façons en  __*Python*__ d'écrire un *string*.\n",
    "\n",
    "```python\n",
    "    mot = 'lapin'         # guillemet simple\n",
    "    mot = \"lapin\"         # guillemet double\n",
    "    mot = \"\"\"lapin\"\"\"     # triple guillemet double\n",
    "    mot = '''lapin'''     # triple guillemet simple\n",
    "```\n",
    "Selon les circonstances, on utilise l'une ou l'autre.\n",
    "\n",
    "```python\n",
    "    phrase = \"j'arrive\"   # attention à l'apostrophe\n",
    "    phrase = 'Il dit : \"va-t-en !\" et partit'   # les guillemets 'double' sont utilisés dans la phrase\n",
    "    phrase = \"\"\"Il dit : \"J'arrive !\" et partit\"\"\"   # un peu de tout ici\n",
    "```\n",
    " Des délimitateurs de la chaîne doivent être les mêmes à gauche et à droite.\n",
    " \n",
    " \n",
    " <h2><font color = 'blue'>Slicing ou extraction de sous-chaînes</font></h2>\n",
    " \n",
    " **Rappel** : *les chaînes de caractères sont immutables, on ne peut pas les modifier sans en recréer une\n",
    "autre du même nom.*\n",
    "\n",
    "On peut par contre effectuer un découpage d'un *string* de façon simple, c'est ce qu'on appelle le **slicing**. Ceci se fait avec la notation crochet. Le 1e élément indique l'indice de début et le 2e l'indice avant lequel le découpage a lieu.\n",
    "\n",
    "\n",
    "Dans un string de longueur *n*, chaque élément qui le compose est indexé par un entier, ceci de deux façons :\n",
    "- en commençant à compter à partir de la gauche, de 0 à n-1\n",
    "- en commençant à compter à partir de la droite, de -1 à -n\n",
    "\n",
    "<h3><font color = 'orange'>Exemple</font></h3>\n",
    "\n",
    "```python\n",
    "    m = 'le beau lapin'\n",
    "```\n",
    "\n",
    "| l | e |   | b | e | a | u |   | l | a | p | i | n |\n",
    "|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n",
    "| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12|\n",
    "|-13|-12|-11|-10| -9| -8| -7| -6| -5| -4| -3| -2| -1|\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | complétez la cellule de code ci-dessous avec ce qui suit ligne après ligne (chaque ligne en remplacement de la précédente), en exécutant après chaque ligne.</font>\n",
    "\n",
    "\n",
    "```python\n",
    "    print(m[0])          # donne l\n",
    "    print(m[9])\n",
    "    print(m[-1])         # donne n\n",
    "    print(m[3 : 7])      # donne beau\n",
    "    print(m[2 : -5])     # aussi\n",
    "    print(m[5 :])\n",
    "    print(m[: 5])\n",
    "    print(m[-5 : -2])\n",
    "    print(m[:])\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    m = 'le beau lapin'\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarquez que l'indice de gauche, qu'il soit positif ou négatif, doit correspondre à un caractère plus à gauche dans le *string* que l'indice de droite, qu'il soit aussi positif ou négatif. Dans le cas contraire, on obtient une chaîne vide.\n",
    "\n",
    "Si vous regardez le tableau précédent\n",
    "\n",
    "```python\n",
    "    m[-9:-4] == m[4:-4] == m[-9:9] == m[4:9] == 'eau l'  # renvoi True\n",
    "```\n",
    "\n",
    "<h3><font color = 'blue'>Applications</font></h3>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | en découpant la chaîne *phrase* correctement, faites apparaître le mot \"covid\" en complétant la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "phrase = \"j'ai horreur du covid\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | en découpant la chaîne *phrase* correctement, faites apparaître le mot \"covid\" en complétant la cellule ci-dessous en utilisant des indices négatifs.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "phrase = \"Tuons le covid !\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | en découpant la chaîne *phrase* correctement, faites apparaître le texte du mot \"covid\" (compris) à la fin.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "phrase = \"Avec le covid, c'est pas super...\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | en découpant la chaîne *phrase* correctement, faites apparaître le texte du début au mot \"covid\" (compris).</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "phrase = \"On finira, avec le covid, par l'éradiquer !\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | écrivez un court programme qui demande d'une part un *prénom* et d'autre part, un *nom* et qui affiche le texte suivant : \"Tu t'appelles *prénom nom* et tes initiales sont *XX*\" avec bien sûr *prénom*, *nom* et *XX* correctement remplis.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | pour les mots suivants : 'certainement', 'sereinement' et 'correctement', on veut récupérer la racine. Par exemple pour \"rapidement\", on veut récupéré \"rapide\".\n",
    "Écrivez un programme qui demande d'entrer au clavier ces 3 mots un à un (vous lancerez 3 fois le programme) et qui écrit pour chacun d'eux, la phrase suivante : \"le mot XXXXXXX a pour racine XXX\"\n",
    ".</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2><font color = 'blue'>Opérations sur les strings</font></h2>\n",
    "\n",
    "Il y a principalement 4 opérations qui nous seront utiles sur les *strings*.\n",
    "\n",
    "- la concaténation avec +\n",
    "- la répétition avec *\n",
    "- l'appartenance avec *in*\n",
    "- la longueur d'un *string* avec *len()*\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "s1, s2 = 'un petit', 'coucou'\n",
    "print(\"Concaténation :\", s1 + s2)         # colle les 2 strings\n",
    "print(\"Répétition :\", s2 * 5)\n",
    "print(\"Appartenance :\", 'eti' in s1)      # la chaîne 'eti' est-elle dans s1 ?\n",
    "print(\"Longueur de s1 :\", len(s1))          # les espaces comptent !"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | Écrivez un court programme qui demande d'entrer une phrase au clavier, affiche la longueur de la phrase entrée, affiche si la lettre 'z' y figure ou pas, et affiche la concaténation de la phrase \"Vous avez entré :\" avec la phrase entrée au clavier, .</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2><font color = 'blue'>Méthodes sur les strings</font></h2>\n",
    "\n",
    "Beaucoup de méthodes sont disponibles pour traiter des *strings*. Vous allez vous en remémorer quelques unes mais n'hésitez pas à voir le cours et à recourrir à Internet, pour traiter facilement les exercices qui suivent.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 'Un Grand Pingouin'\n",
    "print(\"Majuscule :\", p.upper())\n",
    "print(\"Minuscule :\", p.lower())\n",
    "print(\"Centrage :\", p.center(30, '*'))        # centrage de p sur 30 caractères complétés avec des *\n",
    "print(\"Découpage selon l'espace\", p.split())\n",
    "print(\"Découpage selon le n :\", p.split('n'))\n",
    "print(\"Échange maj et min :\", p.swapcase())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il y en a bien d'autres, on trouve souvent ce qu'on cherche, voir par exemple :\n",
    "\n",
    "https://docs.python.org/fr/3.8/library/stdtypes.html?highlight=startswith#string-methods\n",
    "\n",
    "Voici d'autres méthodes qui retournent un **booléen**.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 'un petit pingouin'\n",
    "print(\"y a-t-il des chiffres ?\", p[:2].isdigit())\n",
    "print(\"p se finit par 'ouin' ?\", p.endswith('ouin'))\n",
    "print(\"p commence par 'le' ?\", p.startswith('le'))\n",
    "print(\"chaque mot de p est écrit en majuscule ?\", p.istitle())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Là aussi, il y a bien d'autres méthodes.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | complétez les XXX pour que chaque ligne renvoie *True*, et exécutez pour vérifier.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = 'covid19'\n",
    "print(p.endswith(XXX))\n",
    "print(p.XXX.isupper())       # isupper() teste si c'est en majuscule\n",
    "print(p.startswith(XXX))\n",
    "print(p.startswith(p[XXX]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | Écrivez un court programme qui demande d'entrer un mot au clavier et vérifie si ce mot commence par 'm', se finit par 'r' et contient la lettre 'e'. Testez votre programme avec 'menier', 'manger' et 'nager'.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2><font color = 'blue'>Recherche de sous-chaîne dans une chaîne</font></h2>\n",
    "\n",
    "On sait qu'avec l'opérateur *in* on peut tester si une sous-chaîne se trouve effectivement dans une chaîne, mais on ne sait pas où, ni en combien d'exemplaire...\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sc = 'lapin'\n",
    "p = 'la chasseur et le lapin deviennent amis, vive le lapin !'\n",
    "print(sc in p)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Deux méthodes sont disponibles pour trouver où se trouve une sous-chaîne d'une chaîne, c'est **find()** et **index()**. La seule différence réside dans le fait que si **find()** ne trouve rien, elle renvoie **-1**, alors qu'**index()** renvoie une erreur. Dans les 2 cas, elles renvoient l'indice de début de la sous-chaîne en cas de succès.\n",
    "\n",
    "La syntaxe est la suivante :\n",
    "\n",
    "*chaine.index(sous-chaine, debut, fin)*  ou  *chaine.find(sous-chaine, debut, fin)*\n",
    "\n",
    "où *debut* et *fin* désigne la plage d'indices où doit se faire la recherche. Si rien n'est précisé, la recherche s'effectue de l'indice 0 à l'indice de fin.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Exécutez et observez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sc = 'lapin'\n",
    "p = 'la chasseur et le lapin deviennent amis, vive le lapin !'\n",
    "indice = p.find(sc)\n",
    "print(\"le 1e mot 'lapin' se trouve à l'indice\", indice)\n",
    "print(\"le mot 'lapin' suivant se trouve à l'indice\", p.find(sc, indice + 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Enfin, la méthode **count()** permet de savoir combien il y a de fois une sous-chaîne dans une chaîne.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sc = 'lapin'\n",
    "p = 'la chasseur et le lapin deviennent amis, vive le lapin !'\n",
    "nb = p.count(sc)\n",
    "print(\"dans p, le mot\", sc, \"s'y trouve\", nb, \"fois\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | Écrivez un programme qui dans la phrase suivante \"le cygne et le canard\", cherche l'indice de la lettre \"g\" et ensuite affche le message suivant : \n",
    "\"la lettre g est entre les lettres X et Y\" (où bien sûr X et Y sont les vraies lettres de la phrase). Ces lettres doivent être obtenues avec la notation crochet et utiliser l'index récupéré précédemment.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | Sachant que dans la phrase suivante :\n",
    "    \"un mouton a tué un loup!\", il y a 3 lettres \"o\", écrivez un programme qui\n",
    "    trouve l'indice de ces 3 lettres.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2><font color = 'blue'>Formatage de chaînes</font></h2>\n",
    "\n",
    "De très nombreuses options existent pour formater une chaîne. Nous voyons juste quelques applications de l'opérateur **%** et de la méthode **format()**.\n",
    "\n",
    "L'opérateur **%s** replace les strings spécifiés à la fin dans l'ordre où ils sont écrits.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c1, nb, c2, c3 = 'le chasseur', 5, 'lapins', 'la prairie'\n",
    "print(\"%s et les %s %s courent dans %s\" %(c1, nb, c2, c3))\n",
    "# l'avantage est que le formatage ne change pas en changeant les variables\n",
    "c1, nb, c2, c3 = 'le lapin', 5, 'chasseurs', 'la ville'\n",
    "print(\"%s et les %s %s courent dans %s\" %(c1, nb, c2, c3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La méthode **format()** permet aussi de remplacer des accolades vides par les strings notés dans un certain ordre. Cette méthode permet aussi bien d'autres choses...\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez attentivement et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c1, c2, c3 = \"chasseur\", \"lapin\", \"cheval\"\n",
    "print(\"le {} à dos de {} court après le {}\".format(c1, c3, c2))\n",
    "print(\"le {} à dos de {} court après le {}\".format(c1, c2, c3))\n",
    "print(\"le produit 31 x 56 est {}\".format(31*56))  # un aperçu..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | En vous inspirant de ce qui précède et en utilisant l'un ou l'autre des utilitaires de formatage, affectez à des variables les entités suivantes :\n",
    "vaches, champ, veaux, poules, poussins, 5, 3, 2, 6 et affichez deux phrases construites de façon identiques mais utilisant l'une et l'autre l'ensemble des variables ci-dessus (inspirez-vous des exemples), ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> <font color=\"#7401ca\">**Exercice** | Les lignes suivantes renvoient True ou False. À vous de le deviner. Vérifiez-le ensuite en exécutant la cellule.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = \"la grenouille qui veux se faire aussi grosse que le boeuf\"\n",
    "print(\"il\" in a[5:10])                               # ligne 1\n",
    "print(a.find(\"g\",20) == False)                       # ligne 2\n",
    "print(a[:30].endswith(\"air\"))                        # ligne 3\n",
    "print(a.upper().islower() == a[3:].startswith(\"h\"))  # ligne 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2><font color = 'blue'>Compléments sur les types de données</font></h2>\n",
    "\n",
    "Les chaînes de caractères sont de type **string**. La concaténation n'est possible qu'entre deux chaînes de caractères. Par exemple, le code suivant renvoie une erreur.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a, n = \"lapins\", 3\n",
    "print(\"j'ai\" + n + a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*n* est de type **integer** et *a* est de type **string** ! Pour éviter ce genre de problème, on transforme un **integer** en un **string** (quand cela a du sens) avec la fonction **str()**.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a, n = \"lapins\", 3\n",
    "print(\"j'ai\" + str(n) + a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L'étape contraire, changer un **string** en un **integer**, a déjà été vue lors de l'emploi de **input()**.\n",
    "\n",
    "> <font color=\"#7401ca\">**Exercice** | Observez et exécutez la cellule ci-dessous.</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nb = input(\"Entre un nombre : \")\n",
    "print(\"Ici 'nb' est du type\", type(nb))\n",
    "nb = eval(nb)      # ou nb = int(nb)\n",
    "print(\"Ici 'nb' est du type\", type(nb))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img width=\"60\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/Gtk-dialog-info.svg/60px-Gtk-dialog-info.svg.png\"/>\n",
    "                      \n",
    "* Il est important de bien maîtriser l'ensemble des fonctionnalités liées aux chaînes de caractères compte tenu que le traitement de celles-ci est au coeur de vos études.\n",
    "\n",
    "<font color = 'red'>Bien connaître\n",
    "* les opérations sur les chaînes\n",
    "* les principales méthodes sur les chaînes\n",
    "* manipuler le formatage de chaîne</font>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# FIN DU TD2"
   ]
  }
 ],
 "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.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
