{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapitre 5 : \"Fonctions et espaces de nommage\"\n",
    "\n",
    "### <span class=\"bg-info\">« *Le style est une façon très simple de dire des choses compliquées.* »</span>\n",
    "\n",
    "Jean Cocteau\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <span class=\"bg-success\">CE QU'IL FAUT RETENIR</span>\n",
    "\n",
    "- Syntaxe de définition de la fonction `f()` :\n",
    "```python\n",
    "def f(param1, param2...):\n",
    "    \"Docstring.\"\n",
    "    <corps de la fonction>\n",
    "```\n",
    "- Syntaxe de l'appel de la fonction `f()` :\n",
    "```python\n",
    "f(arg1, arg2...):\n",
    "```\n",
    "- Espace de noms : Python définit des noms par défaut disponibles dans l'espace de noms **I**nterne (exemples : `print`, `input`, `abs`...). Les noms définis au niveau d'un fichier (module) sont dans un espace de nom **G**lobal. Enfin les noms définis à l'intérieur d'une fonction (variables affectées dans la fonction et paramètres de celle-ci) sont dans un espace de noms **L**ocal. Quand Python recherche un nom, il le fait dans l'ordre **LGI**.\n",
    "\n",
    "\n",
    "- Portée des objets : Les variables dans l'espace de noms local ne sont visibles que dans la fonction où elles sont définies, et elles n'ont comme durée de vie que le temps d'exécution de la fonction (disparaissant quand on sort de la foncion par un `return`).\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_01 ✓✓\n",
    "\n",
    "Que pensez-vous que va afficher le programme ci-dessous ? :\n",
    "\n",
    "```python\n",
    "x = 2\n",
    "\n",
    "def f2(nbre):\n",
    "    global x\n",
    "    x = nbre\n",
    "    print(\"1.\", x)\n",
    "\n",
    "def f1(nbre):\n",
    "    global x\n",
    "    x = nbre\n",
    "    print(\"2.\", x)\n",
    "    return x\n",
    "\n",
    "f2(40)\n",
    "print(\"3.\", x)\n",
    "x = f1(5)\n",
    "print(\"4.\", x)\n",
    "```\n",
    "\n",
    "Que se passe-t-il si les lignes `global x` sont mise en commentaire ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_01\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_02 ✓\n",
    "\n",
    "Définir une fonction `maximum(n1, n2, n3)` qui renvoie le plus grand de ses trois arguments.\n",
    "\n",
    "Par exemple, l'exécution de l'instruction :\n",
    "\n",
    "```python\n",
    "print(maximum (2, 5, 4))\n",
    "```\n",
    "\n",
    "doit renvoyer `5`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_02"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_03 ✓\n",
    "\n",
    "Définir une fonction `minimum(liste)` qui reçoit une liste non vide d'entiers et retourne deux valeurs, le plus petit et le plus grand élément, sans modifier la liste originale."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_03"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_04 ✓\n",
    "\n",
    "Définir une fonction `indexMax(liste)` qui renvoie l'**indice** du plus grand élément de la liste transmise en argument.\n",
    "\n",
    "Exemple d'utilisation :\n",
    "\n",
    "```python\n",
    "seq = [5, 8, 2, 1, 9, 3, 6, 7]\n",
    "print(indexMax(seq))\n",
    "```    \n",
    "\n",
    "doit afficher : `4`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_04"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_05 ✓\n",
    "\n",
    "Définir une fonction `indexMinMax(liste)` qui renvoie les **indices** du plus petit et du plus grand élément de la liste transmise en argument.\n",
    "\n",
    "```python\n",
    "seq = [5, 8, 2, 1, 9, 3, 6, 7]\n",
    "print(indexMinMax(seq))\n",
    "```    \n",
    "\n",
    "doit afficher : `(3,4)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_05"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_06 ✓\n",
    "\n",
    "Écrire une fonction `filtrage(un_tuple)` qui prend un tuple de chaînes en argument et renvoie une liste de tous les éléments du tuple dont les quatre premiers caractères sont `\"anti\"`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_06"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_07 ✓✓\n",
    "\n",
    "Corriger les cinq erreurs de la fonction `cinqErreurs()` ci-dessous, qui permet de dire si les 40 premiers nombres entiers naturels sont des multiples de 7 et/ou de 4 :\n",
    "\n",
    "```python\n",
    "def cinqErreurs()\n",
    "    x == range(41)\n",
    "\n",
    "    for i in x:\n",
    "        if (i % 7) = 0:           # si modulo par 7 donne 0\n",
    "            if (i % 4) != 0         si modulo par 4 donne différent de 0 #\n",
    "                print(f\"{i} est un multiple de 7\")\n",
    "            elif:\n",
    "                print(f\"{i} est un multiple de 7 et de 4\")\n",
    "\n",
    "        elif (i % 4) == 0:        # si modulo par 4 donne 0\n",
    "            print(f\"{i} est un multiple de 4\")\n",
    "```  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_07"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_08 ✓✓\n",
    "\n",
    "Créer deux fonctions `PGCD(x, y)` et `PPCM(x, y)` qui prennent deux entiers comme argument et renvoient respectivement leur PGCD et leur PPCM (cf. l'algorithme d'Euclide pour le [PGCD](https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide) et pour le [PPCM](https://fr.wikipedia.org/wiki/Plus_petit_commun_multiple#.C3.80_l.27aide_du_PGCD))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_08"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_09 ✓✓\n",
    "\n",
    "La fonction `indexMax(tt)` renvoie l'index du plus grand élément de la liste transmise en argument :\n",
    "\n",
    "```python\n",
    "def indexMax(tt)\n",
    "\"\"\"Renvoie l'indice du plus grand élément de la liste tt.\"\"\"\n",
    "    i, max = 0, 0\n",
    "    while i < len(tt) ;\n",
    "        if tt[i] > max :\n",
    "            max, imax = tt[i], i\n",
    "            i = i + 1\n",
    "        return imax\n",
    "```        \n",
    "\n",
    "Maheureusement, elle comporte un certain nombre d'erreurs de syntaxe et/ou de logique !\n",
    "\n",
    "Corriger et tester cette fonction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_09"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_10 ✓\n",
    "\n",
    "Écrire et tester trois fonctions qui reçoivent une chaîne de caractères `ch` et qui retournent un booléen :\n",
    "\n",
    "- la fonction `padi(ch)` renvoie **`True`** si la chaîne `ch` ne contient pas la lettre `\"i\"`, **`False`** sinon ;\n",
    "- la fonction `pado(ch)` renvoie **`True`** si la chaîne `ch` ne contient pas la lettre `\"o\"`, **`False`** sinon ;\n",
    "- la fonction `padiPado(ch)` renvoie **`True`** si la chaîne `ch` ne contient pas les lettres `\"i\"` et `\"o\"`, **`False`** sinon."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_11 ✓\n",
    "\n",
    "Écrire et tester une fonction `dansRectangle(rectangle, point)` qui reçoit deux tuples `rectangle` et `point` et qui retourne **`True`** si le point est dans le rectangle, **`False`** sinon.\n",
    "\n",
    "**Conseils :**\n",
    "\n",
    "+ Le tuple `point` est formé de deux flottants qui représentent les coordonnées d'un point du plan.\n",
    "+ Le tuple `rectangle` est formé de deux tuples `point` qui représentent les sommets inférieur gauche et supérieur droit du rectangle.\n",
    "\n",
    "Pourquoi avoir choisi des tuples et non des listes comme paramètres de la fonction ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_11"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_12  ✓✓✓\n",
    "\n",
    "À partir d'un entier *N* de 4 chiffres non nuls pas tous égaux (on peut avoir plusieurs chiffres égaux, mais pas tous les 4 en même temps), on génère par permutation des chiffres le plus grand (*PG*) et le plus petit (*PP*) entier et on calcule le nouvel entier *N = PG* $-$ *PP*.\n",
    "\t\t\n",
    "On itère le processus jusqu'à obtenir la constante : 6174 (appelé [\"constante de Kaprekar\"](https://fr.wikipedia.org/wiki/Dattatreya_Ramachandra_Kaprekar))\n",
    "\t\t\n",
    "Par exemple : \n",
    "- 7068 => (8760 $-$ 678) = 8082 => (8820 $-$ 288) = 8532 => (8532 $-$ 2358) = **6174**\n",
    "- 5379 => (9753 $-$ 3579) = ** 6174 **\n",
    "\n",
    "**Conseil :** Pour le calcul des permutations d'une chaîne, on peut utiliser la fonction standard [permutations](https://docs.python.org/3/library/itertools.html#itertools.permutations) du module `itertools`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_12"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_13 ✓✓✓\n",
    "\n",
    "À partir d'un entier *N* de 3 chiffres non nuls pas tous égaux, on génère par permutation des chiffres le plus grand (*PG*) et le plus petit (*PP*) entier et on calcule le nouvel entier *N = PG* $-$ *PP*.\n",
    "\t\t\n",
    "On itère le processus jusqu'à obtenir la constante : 495 (autre nombre de Kaprekar)\n",
    "\t\t\n",
    "Par exemple : \n",
    "- 674 => (764 $-$ 467) = 297 => (972 $-$ 279) = 693 => (963 $-$ 369) = 594 => (954 $-$ 459) = ** 495 **\n",
    "- 438 => (843 $-$ 348) => **495**\n",
    "\n",
    "**Indication :** Pour le calcul des permutations d'une chaîne, on peut utiliser la fonction standard [permutations](https://docs.python.org/3/library/itertools.html#itertools.permutations) du module `itertools`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_13"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_14 ✓✓\n",
    "\n",
    "Un jeu de carte est formé de *n* cartes numérotées de *1* à *n*.\n",
    "\n",
    "On crée le jeu, dans l'ordre naturel.  \n",
    "On retire la première carte, on met la 2<sup>e</sup> sous le paquet et on itère.\n",
    "Quelle est la carte restante ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# exo05_14"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_15 ✓\n",
    "\n",
    "Les acides aminés d'une séquence protéique sont au nombre de 20 :\n",
    "```python\n",
    "aa = 'arndceqghilkmfpstwyv'\n",
    "```\n",
    "\n",
    "Écrire une fonction booléenne `dans(seq_prot, aa)` qui reçoit une séquence et la chaîne `aa` des 20 acides aminés et qui retourne **`True`** si `seq_prot` est bien une séquence protéique, **`False`** sinon.\n",
    "\n",
    "Dans le programme principal, on saisira une séquence (une chaîne de caractères) et on appellera la fonction `dans()` pour vérifier (et afficher) si c'est une séquence protéique."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo05_15"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### exo05_16 ✓\n",
    "\n",
    "Trouvez le **nombre mystère** qui répond aux conditions suivantes :\n",
    "\n",
    "- il est composé de 3 chiffres ;\n",
    "- il est strictement supérieur à 500 ;\n",
    "- il est impair ;\n",
    "- deux de ses chiffres sont identiques;\n",
    "- la somme de ses chiffres est égale à 7.\n",
    "\n",
    "On demande d'écrire une fonction `cdu()` qui retourne le tuple `(centaine, dizaine, unité)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# exo05_16"
   ]
  }
 ],
 "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.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
