7784 lines
500 KiB
Plaintext
7784 lines
500 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Récursivité et Programmation Dynamique\n",
|
|
"\n",
|
|
"# La reproduction des lapins\n",
|
|
"\n",
|
|
"Nous allons utiliser 2 grandes méthodes de programmation que nous allons appliquer à un problème célèbre et récurrent dans le milieu de la programmation.\n",
|
|
"\n",
|
|
"En 1202, Leonardo Fibonacci publie un ouvrage dans lequel il traite d'un problème simple et concret : la croissance d'une population de lapins. Il s'agit de savoir comment contrôler la population des clapiers et quand vendre ses lapins, etc.\n",
|
|
"\n",
|
|
"Voici le fonctionnement simplifié de cette reproduction :\n",
|
|
"\n",
|
|
"1. On compte les lapins par **couple**\n",
|
|
"2. **Chaque mois** chaque couple de lapins matures donne naissance à 1 couple de jeunes lapins immatures\n",
|
|
"3. Après 2 mois les jeunes couples devienent matures et engendrent à leur tour un jeune couple immature\n",
|
|
"4. On étudie la croissance de la population tous les mois : n est le nombre de mois\n",
|
|
"\n",
|
|
"| n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |\n",
|
|
"|:------------------------------:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:--:|:--:|:--:|:--:|\n",
|
|
"| nb couples matures | 0 | 0 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 |\n",
|
|
"| nb couples immatures 1er mois | 0 | 1 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 |\n",
|
|
"| nb couples immatures 2ème mois | 0 | 0 | 1 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 |\n",
|
|
"| nb couples | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 |\n",
|
|
"\n",
|
|
"- Complétez les mois manquants en respectant les règles de reproduction.\n",
|
|
"\n",
|
|
"- En vous inspirant de la méthode que vous avez employée pour compléter le tableau ci-dessus, écrivez une fonction `lapinoux(n)` qui retourne le nombre de couples de lapin obtenus au mois n.\n",
|
|
"- Testez votre fonction pour des valeurs de n entre 0 et 10."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Pour n=0 le nombre de couples vaut:0\n",
|
|
"Pour n=1 le nombre de couples vaut:1\n",
|
|
"Pour n=2 le nombre de couples vaut:1\n",
|
|
"Pour n=3 le nombre de couples vaut:2\n",
|
|
"Pour n=4 le nombre de couples vaut:3\n",
|
|
"Pour n=5 le nombre de couples vaut:5\n",
|
|
"Pour n=6 le nombre de couples vaut:8\n",
|
|
"Pour n=7 le nombre de couples vaut:13\n",
|
|
"Pour n=8 le nombre de couples vaut:21\n",
|
|
"Pour n=9 le nombre de couples vaut:34\n",
|
|
"Pour n=10 le nombre de couples vaut:55\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def lapinoux(n: int) -> int:\n",
|
|
" \"\"\" Calcule le nombre de couples de lapins au bout de n mois (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" \n",
|
|
" nb_couples_matures = 0\n",
|
|
" nb_couples_immatures1 = 1\n",
|
|
" nb_couples_immatures2 = 0\n",
|
|
" \n",
|
|
" for i in range(n+1):\n",
|
|
" nb_couples_matures += nb_couples_immatures2\n",
|
|
" nb_couples_immatures2 = nb_couples_immatures1\n",
|
|
" nb_couples_immatures1 = nb_couples_matures\n",
|
|
" \n",
|
|
" return nb_couples_matures\n",
|
|
"\n",
|
|
"def lapinoux_base(n: int) -> int:\n",
|
|
" \"\"\" Calcule le nombre de couples de lapins au bout de n mois (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" \n",
|
|
" if n <= 0 : return 0\n",
|
|
" nb_couples_matures = 0\n",
|
|
" nb_couples_immatures1 = 1\n",
|
|
" nb_couples_immatures2 = 0\n",
|
|
" \n",
|
|
" for i in range(2,n+1):\n",
|
|
" nb_couples_matures += nb_couples_immatures2\n",
|
|
" nb_couples_immatures2 = nb_couples_immatures1\n",
|
|
" nb_couples_immatures1 = nb_couples_matures\n",
|
|
"\n",
|
|
" return nb_couples_matures + nb_couples_immatures1 + nb_couples_immatures2\n",
|
|
"\n",
|
|
"for i in range(11):\n",
|
|
" print(f\"Pour n={i} le nombre de couples vaut:{lapinoux(i)}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"🏁 **Terminaison** : la fonction termine toujours car elle est constituée d'un boucle finie `for ... range`.\n",
|
|
"\n",
|
|
"🐌 **Complexité** : $O(n)$ car à chaque fois qu'on augmente n de 1 on ajoute un tour de boucle avec 3 affectations et 1 addition."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Suite de Fibonacci\n",
|
|
"\n",
|
|
"Comme vous êtes de bons élèves en mathématiques, il ne vous a pas échappé que ce fonctionnement pouvait se formaliser sous forme de suite mathématique qu'on nomme la **Suite de Fibonacci**.\n",
|
|
"\n",
|
|
"En effet, vous avez pu constater que pour obtenir un terme pour un mois donné, il suffisait de faire la somme des termes des 2 mois précédents : `fibo(0) = 0 ; fibo(1) = 1 ; fibo(n) = fibo(n-1) + fibo(n-2)`.\n",
|
|
"\n",
|
|
"- Reprogrammez la fonction précédente en la nommant `fibo(n)` mais cette fois en utilisant la définition de la suite ci-dessus.\n",
|
|
"\n",
|
|
"- Testez votre fonction pour des valeurs de n entre 0 et 10."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Pour n=0 le nombre de couples vaut:0\n",
|
|
"Pour n=1 le nombre de couples vaut:1\n",
|
|
"Pour n=2 le nombre de couples vaut:1\n",
|
|
"Pour n=3 le nombre de couples vaut:2\n",
|
|
"Pour n=4 le nombre de couples vaut:3\n",
|
|
"Pour n=5 le nombre de couples vaut:5\n",
|
|
"Pour n=6 le nombre de couples vaut:8\n",
|
|
"Pour n=7 le nombre de couples vaut:13\n",
|
|
"Pour n=8 le nombre de couples vaut:21\n",
|
|
"Pour n=9 le nombre de couples vaut:34\n",
|
|
"Pour n=10 le nombre de couples vaut:55\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def fibo(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" \n",
|
|
" if n <= 0: return 0\n",
|
|
" elif n <= 1: return 1\n",
|
|
" \n",
|
|
" un_moins_2 = 0\n",
|
|
" un_moins_1 = 1\n",
|
|
" \n",
|
|
" for i in range(2,n+1):\n",
|
|
" un = un_moins_1 + un_moins_2\n",
|
|
" un_moins_2 = un_moins_1\n",
|
|
" un_moins_1 = un\n",
|
|
" return un\n",
|
|
"\n",
|
|
"for i in range(11):\n",
|
|
" print(f\"Pour n={i} le nombre de couples vaut:{fibo(i)}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"🏁 **Terminaison** : la fonction termine toujours car elle est constituée d'un boucle finie `for ... range`.\n",
|
|
"\n",
|
|
"🐌 **Complexité** : $O(n)$ car à chaque fois qu'on augmente n de 1 on ajoute un tour de boucle avec 3 affectations et 1 addition."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Récursivité\n",
|
|
"\n",
|
|
"⚠️ En informatique une fonction peut **s'appeler elle-même**, c'est ce qu'on nomme une **fonction récursive**. Faisons un exemple pour voir :"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n",
|
|
"Lancement de la fonction recursive_infinie()\n"
|
|
]
|
|
},
|
|
{
|
|
"ename": "RecursionError",
|
|
"evalue": "maximum recursion depth exceeded while calling a Python object",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mRecursionError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[0;32m<ipython-input-10-2d19be49f426>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[0;32m<ipython-input-10-2d19be49f426>\u001b[0m in \u001b[0;36mrecursive_infinie\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Lancement de la fonction recursive_infinie()\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
"... last 1 frames repeated, from the frame below ...\n",
|
|
"\u001b[0;32m<ipython-input-10-2d19be49f426>\u001b[0m in \u001b[0;36mrecursive_infinie\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Lancement de la fonction recursive_infinie()\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mrecursive_infinie\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
"\u001b[0;31mRecursionError\u001b[0m: maximum recursion depth exceeded while calling a Python object"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def recursive_infinie():\n",
|
|
" print(\"Lancement de la fonction recursive_infinie()\")\n",
|
|
" recursive_infinie()\n",
|
|
" \n",
|
|
"recursive_infinie()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Vous constatez que la fonction **s'appelle elle-même** sans s'arrêter jusqu'à provoquer l'erreur : *RecursionError: maximum recursion depth exceeded while calling a Python object*. Qui se traduit littéralement par : *Ta function ne s'arrête pas gros noob !*\n",
|
|
"\n",
|
|
"⚠️ Quand nous écrivons une **fonction récursive**, il faut s'assurer que la **fonction s'arrête à coup sûr** ! Il faut donc bien écrire le ou les **cas d'arrêt**.\n",
|
|
"\n",
|
|
"Essayons cet autre exemple :"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"On est dans la fonction recursive(10)\n",
|
|
"On est dans la fonction recursive(9)\n",
|
|
"On est dans la fonction recursive(8)\n",
|
|
"On est dans la fonction recursive(7)\n",
|
|
"On est dans la fonction recursive(6)\n",
|
|
"On est dans la fonction recursive(5)\n",
|
|
"On est dans la fonction recursive(4)\n",
|
|
"On est dans la fonction recursive(3)\n",
|
|
"On est dans la fonction recursive(2)\n",
|
|
"On est dans la fonction recursive(1)\n",
|
|
"On est dans la fonction recursive(0)\n",
|
|
"C'est fini !\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def recursive(n: int):\n",
|
|
" print(f\"On est dans la fonction recursive({n})\")\n",
|
|
" if n <= 0 :\n",
|
|
" print(\"C'est fini !\")\n",
|
|
" else :\n",
|
|
" recursive(n-1)\n",
|
|
" \n",
|
|
"recursive(10)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"- Écrivez la fonction `fibor(n)` pour calculer les termes de la Suite de Fibonacci en utilisant une **fonction récursive**. Pour cela vous devez utiliser le fait que `fibor(n)` doit **retourner** `fibor(n-1) + fibor(n-2)` ! Et pensez aux cas d'arrêt !\n",
|
|
"- Testez votre fonction pour des valeurs de n entre 0 et 10."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Pour n=0 le nombre de couples vaut:0\n",
|
|
"Pour n=1 le nombre de couples vaut:1\n",
|
|
"Pour n=2 le nombre de couples vaut:1\n",
|
|
"Pour n=3 le nombre de couples vaut:2\n",
|
|
"Pour n=4 le nombre de couples vaut:3\n",
|
|
"Pour n=5 le nombre de couples vaut:5\n",
|
|
"Pour n=6 le nombre de couples vaut:8\n",
|
|
"Pour n=7 le nombre de couples vaut:13\n",
|
|
"Pour n=8 le nombre de couples vaut:21\n",
|
|
"Pour n=9 le nombre de couples vaut:34\n",
|
|
"Pour n=10 le nombre de couples vaut:55\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def fibor(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" \n",
|
|
" if n < 2: return n\n",
|
|
" else: return fibor(n-1) + fibor(n-2)\n",
|
|
" \n",
|
|
"for i in range(11):\n",
|
|
" print(f\"Pour n={i} le nombre de couples vaut:{fibor(i)}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"🏁 **Terminaison** : la fonction termine toujours car elle est appelée récursivement avec des paramètres entiers positifs **décroissants** donc ils arriveront forcément à 0 et 1 ce qui **arrêtera les appels récursifs**.\n",
|
|
"\n",
|
|
"🐌 **Complexité** : $O(A^n)$, chaque appel de la fonction avec un nombre n plus grand déploie un arbre d'appel qui croît exponentiellement.\n",
|
|
"\n",
|
|
"Cette méthode de programmation **récursive** est séduisante car elle permet de **programmer simplement** des problèmes **difficiles** (parcours de structures, etc.). Mais elle a un gros défaut, c'est qu'elle est souvent **peu performante** en terme de **temps de calcul** et **d'efficacité mémoire**. Voyons pourquoi.\n",
|
|
"\n",
|
|
"- Ajouter à votre fonction un `print` qui permet de voir toutes les fonctions appelées. Ensuite testez `fibor(10)`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"On calcule fibor(10)\n",
|
|
"On calcule fibor(9)\n",
|
|
"On calcule fibor(8)\n",
|
|
"On calcule fibor(7)\n",
|
|
"On calcule fibor(6)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(6)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(7)\n",
|
|
"On calcule fibor(6)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(8)\n",
|
|
"On calcule fibor(7)\n",
|
|
"On calcule fibor(6)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(6)\n",
|
|
"On calcule fibor(5)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(4)\n",
|
|
"On calcule fibor(3)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(2)\n",
|
|
"On calcule fibor(1)\n",
|
|
"On calcule fibor(0)\n",
|
|
"55\n",
|
|
"fibor lancée 177 fois\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"compteur = 0\n",
|
|
"\n",
|
|
"def fibor(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" global compteur\n",
|
|
" compteur += 1\n",
|
|
" print(f\"On calcule fibor({n})\")\n",
|
|
" if n < 2: return n\n",
|
|
" else: return fibor(n-1) + fibor(n-2)\n",
|
|
" \n",
|
|
"print(fibor(10))\n",
|
|
"print(\"fibor lancée\", compteur, \"fois\")"
|
|
]
|
|
},
|
|
{
|
|
"attachments": {
|
|
"out.svg": {
|
|
"image/svg+xml": [
|
|
"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8IS0tIEdlbmVyYXRlZCBieSBncmFwaHZpeiB2ZXJzaW9uIDIuNDQuMCAoMCkKIC0tPgo8IS0tIFRpdGxlOiBGaWJvbm5hY2NpIFBhZ2VzOiAxIC0tPgo8c3ZnIHdpZHRoPSI2ODNwdCIgaGVpZ2h0PSIzNTZwdCIKIHZpZXdCb3g9IjAuMDAgMC4wMCA2ODMuMDAgMzU2LjAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KPGcgaWQ9ImdyYXBoMCIgY2xhc3M9ImdyYXBoIiB0cmFuc2Zvcm09InNjYWxlKDEgMSkgcm90YXRlKDApIHRyYW5zbGF0ZSg0IDM1MikiPgo8dGl0bGU+Rmlib25uYWNjaTwvdGl0bGU+Cjxwb2x5Z29uIGZpbGw9IndoaXRlIiBzdHJva2U9InRyYW5zcGFyZW50IiBwb2ludHM9Ii00LDQgLTQsLTM1MiA2NzksLTM1MiA2NzksNCAtNCw0Ii8+CjxnIGlkPSJjbHVzdDIiIGNsYXNzPSJjbHVzdGVyIj4KPHRpdGxlPmNsdXN0ZXIxPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLWRhc2hhcnJheT0iNSwyIiBkPSJNMjAsLTgwQzIwLC04MCAyMzksLTgwIDIzOSwtODAgMjQ1LC04MCAyNTEsLTg2IDI1MSwtOTIgMjUxLC05MiAyNTEsLTI3MiAyNTEsLTI3MiAyNTEsLTI3OCAyNDUsLTI4NCAyMzksLTI4NCAyMzksLTI4NCAyMCwtMjg0IDIwLC0yODQgMTQsLTI4NCA4LC0yNzggOCwtMjcyIDgsLTI3MiA4LC05MiA4LC05MiA4LC04NiAxNCwtODAgMjAsLTgwIi8+CjwvZz4KPGcgaWQ9ImNsdXN0NCIgY2xhc3M9ImNsdXN0ZXIiPgo8dGl0bGU+Y2x1c3RlcjE8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBzdHJva2UtZGFzaGFycmF5PSIxLDUiIGQ9Ik05OCwtODhDOTgsLTg4IDIzMSwtODggMjMxLC04OCAyMzcsLTg4IDI0MywtOTQgMjQzLC0xMDAgMjQzLC0xMDAgMjQzLC0yMDAgMjQzLC0yMDAgMjQzLC0yMDYgMjM3LC0yMTIgMjMxLC0yMTIgMjMxLC0yMTIgOTgsLTIxMiA5OCwtMjEyIDkyLC0yMTIgODYsLTIwNiA4NiwtMjAwIDg2LC0yMDAgODYsLTEwMCA4NiwtMTAwIDg2LC05NCA5MiwtODggOTgsLTg4Ii8+CjwvZz4KPGcgaWQ9ImNsdXN0NyIgY2xhc3M9ImNsdXN0ZXIiPgo8dGl0bGU+Y2x1c3RlcjI8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBzdHJva2UtZGFzaGFycmF5PSIxLDUiIGQ9Ik0yNzEsLTg4QzI3MSwtODggNDA0LC04OCA0MDQsLTg4IDQxMCwtODggNDE2LC05NCA0MTYsLTEwMCA0MTYsLTEwMCA0MTYsLTIwMCA0MTYsLTIwMCA0MTYsLTIwNiA0MTAsLTIxMiA0MDQsLTIxMiA0MDQsLTIxMiAyNzEsLTIxMiAyNzEsLTIxMiAyNjUsLTIxMiAyNTksLTIwNiAyNTksLTIwMCAyNTksLTIwMCAyNTksLTEwMCAyNTksLTEwMCAyNTksLTk0IDI2NSwtODggMjcxLC04OCIvPgo8L2c+CjxnIGlkPSJjbHVzdDkiIGNsYXNzPSJjbHVzdGVyIj4KPHRpdGxlPmNsdXN0ZXIzPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLWRhc2hhcnJheT0iNSwyIiBkPSJNNDM2LC04QzQzNiwtOCA2NTUsLTggNjU1LC04IDY2MSwtOCA2NjcsLTE0IDY2NywtMjAgNjY3LC0yMCA2NjcsLTIwMCA2NjcsLTIwMCA2NjcsLTIwNiA2NjEsLTIxMiA2NTUsLTIxMiA2NTUsLTIxMiA0MzYsLTIxMiA0MzYsLTIxMiA0MzAsLTIxMiA0MjQsLTIwNiA0MjQsLTIwMCA0MjQsLTIwMCA0MjQsLTIwIDQyNCwtMjAgNDI0LC0xNCA0MzAsLTggNDM2LC04Ii8+CjwvZz4KPGcgaWQ9ImNsdXN0MTEiIGNsYXNzPSJjbHVzdGVyIj4KPHRpdGxlPmNsdXN0ZXI0PC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLWRhc2hhcnJheT0iMSw1IiBkPSJNNTE0LC0xNkM1MTQsLTE2IDY0NywtMTYgNjQ3LC0xNiA2NTMsLTE2IDY1OSwtMjIgNjU5LC0yOCA2NTksLTI4IDY1OSwtMTI4IDY1OSwtMTI4IDY1OSwtMTM0IDY1MywtMTQwIDY0NywtMTQwIDY0NywtMTQwIDUxNCwtMTQwIDUxNCwtMTQwIDUwOCwtMTQwIDUwMiwtMTM0IDUwMiwtMTI4IDUwMiwtMTI4IDUwMiwtMjggNTAyLC0yOCA1MDIsLTIyIDUwOCwtMTYgNTE0LC0xNiIvPgo8L2c+CjwhLS0gZmliKDYpIC0tPgo8ZyBpZD0ibm9kZTEiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmZpYig2KTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIyMzEiIGN5PSItMzMwIiByeD0iMzAuNTkiIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIyMzEiIHk9Ii0zMjYuMyIgZm9udC1mYW1pbHk9IlRpbWVzLHNlcmlmIiBmb250LXNpemU9IjE0LjAwIj5maWIoNik8L3RleHQ+CjwvZz4KPCEtLSBmaWI0IC0tPgo8ZyBpZD0ibm9kZTIiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmZpYjQ8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMTY1IiBjeT0iLTI1OCIgcng9IjMwLjU5IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMTY1IiB5PSItMjU0LjMiIGZvbnQtZmFtaWx5PSJUaW1lcyxzZXJpZiIgZm9udC1zaXplPSIxNC4wMCI+ZmliKDQpPC90ZXh0Pgo8L2c+CjwhLS0gZmliKDYpJiM0NTsmZ3Q7ZmliNCAtLT4KPGcgaWQ9ImVkZ2UxIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWIoNikmIzQ1OyZndDtmaWI0PC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTIxNi42OCwtMzEzLjgxQzIwNy43NywtMzA0LjM2IDE5Ni4xNSwtMjkyLjA0IDE4Ni4xOSwtMjgxLjQ4Ii8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE4OC43LC0yNzkuMDMgMTc5LjI5LC0yNzQuMTYgMTgzLjYxLC0yODMuODQgMTg4LjcsLTI3OS4wMyIvPgo8L2c+CjwhLS0gZmliNSAtLT4KPGcgaWQ9Im5vZGUzIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5maWI1PC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjMzNyIgY3k9Ii0yNTgiIHJ4PSIzMC41OSIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjMzNyIgeT0iLTI1NC4zIiBmb250LWZhbWlseT0iVGltZXMsc2VyaWYiIGZvbnQtc2l6ZT0iMTQuMDAiPmZpYig1KTwvdGV4dD4KPC9nPgo8IS0tIGZpYig2KSYjNDU7Jmd0O2ZpYjUgLS0+CjxnIGlkPSJlZGdlMiIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZmliKDYpJiM0NTsmZ3Q7ZmliNTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0yNTAuOTQsLTMxNS44M0MyNjcuMzMsLTMwNS4wMSAyOTAuNzQsLTI4OS41NSAzMDkuMDEsLTI3Ny40OSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIzMTEuMDksLTI4MC4zIDMxNy41MSwtMjcxLjg3IDMwNy4yNCwtMjc0LjQ2IDMxMS4wOSwtMjgwLjMiLz4KPC9nPgo8IS0tIGZpYjIgLS0+CjxnIGlkPSJub2RlNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI0NyIgY3k9Ii0xODYiIHJ4PSIzMC41OSIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjQ3IiB5PSItMTgyLjMiIGZvbnQtZmFtaWx5PSJUaW1lcyxzZXJpZiIgZm9udC1zaXplPSIxNC4wMCI+ZmliKDIpPC90ZXh0Pgo8L2c+CjwhLS0gZmliNCYjNDU7Jmd0O2ZpYjIgLS0+CjxnIGlkPSJlZGdlMyIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZmliNCYjNDU7Jmd0O2ZpYjI8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTQyLjM4LC0yNDUuN0MxMjUuNDUsLTIzNy4wMSAxMDEuODgsLTIyNC40MiA4MiwtMjEyIDc5LjIxLC0yMTAuMjYgNzYuMzUsLTIwOC4zOCA3My41MiwtMjA2LjQ2Ii8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9Ijc1LjQ0LC0yMDMuNTMgNjUuMjQsLTIwMC42NyA3MS40MywtMjA5LjI3IDc1LjQ0LC0yMDMuNTMiLz4KPC9nPgo8IS0tIGZpYjMgLS0+CjxnIGlkPSJub2RlNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMzwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxNjUiIGN5PSItMTg2IiByeD0iMzAuNTkiIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxNjUiIHk9Ii0xODIuMyIgZm9udC1mYW1pbHk9IlRpbWVzLHNlcmlmIiBmb250LXNpemU9IjE0LjAwIj5maWIoMyk8L3RleHQ+CjwvZz4KPCEtLSBmaWI0JiM0NTsmZ3Q7ZmliMyAtLT4KPGcgaWQ9ImVkZ2U0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWI0JiM0NTsmZ3Q7ZmliMzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNjUsLTIzOS43QzE2NSwtMjMxLjk4IDE2NSwtMjIyLjcxIDE2NSwtMjE0LjExIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE2OC41LC0yMTQuMSAxNjUsLTIwNC4xIDE2MS41LC0yMTQuMSAxNjguNSwtMjE0LjEiLz4KPC9nPgo8IS0tIGZpYjMzIC0tPgo8ZyBpZD0ibm9kZTgiIGNsYXNzPSJub2RlIj4KPHRpdGxlPmZpYjMzPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjMzNyIgY3k9Ii0xODYiIHJ4PSIzMC41OSIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjMzNyIgeT0iLTE4Mi4zIiBmb250LWZhbWlseT0iVGltZXMsc2VyaWYiIGZvbnQtc2l6ZT0iMTQuMDAiPmZpYigzKTwvdGV4dD4KPC9nPgo8IS0tIGZpYjUmIzQ1OyZndDtmaWIzMyAtLT4KPGcgaWQ9ImVkZ2U3IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWI1JiM0NTsmZ3Q7ZmliMzM8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMzM3LC0yMzkuN0MzMzcsLTIzMS45OCAzMzcsLTIyMi43MSAzMzcsLTIxNC4xMSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIzNDAuNSwtMjE0LjEgMzM3LC0yMDQuMSAzMzMuNSwtMjE0LjEgMzQwLjUsLTIxNC4xIi8+CjwvZz4KPCEtLSBmaWI0NCAtLT4KPGcgaWQ9Im5vZGU5IiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5maWI0NDwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI0NjMiIGN5PSItMTg2IiByeD0iMzAuNTkiIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI0NjMiIHk9Ii0xODIuMyIgZm9udC1mYW1pbHk9IlRpbWVzLHNlcmlmIiBmb250LXNpemU9IjE0LjAwIj5maWIoNCk8L3RleHQ+CjwvZz4KPCEtLSBmaWI1JiM0NTsmZ3Q7ZmliNDQgLS0+CjxnIGlkPSJlZGdlOCIgY2xhc3M9ImVkZ2UiPgo8dGl0bGU+ZmliNSYjNDU7Jmd0O2ZpYjQ0PC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTM1OC45NCwtMjQ1LjMzQzM3NS43MywtMjM2LjM1IDM5OS40MiwtMjIzLjU2IDQyMCwtMjEyIDQyNC4yOSwtMjA5LjU5IDQyOC44LC0yMDcuMDEgNDMzLjIzLC0yMDQuNDYiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNDM1LjE4LC0yMDcuMzggNDQyLjA4LC0xOTkuMzMgNDMxLjY3LC0yMDEuMzIgNDM1LjE4LC0yMDcuMzgiLz4KPC9nPgo8IS0tIGZpYjEgLS0+CjxnIGlkPSJub2RlNiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMTwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSIxMjUiIGN5PSItMTE0IiByeD0iMzAuNTkiIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSIxMjUiIHk9Ii0xMTAuMyIgZm9udC1mYW1pbHk9IlRpbWVzLHNlcmlmIiBmb250LXNpemU9IjE0LjAwIj5maWIoMSk8L3RleHQ+CjwvZz4KPCEtLSBmaWIzJiM0NTsmZ3Q7ZmliMSAtLT4KPGcgaWQ9ImVkZ2U1IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWIzJiM0NTsmZ3Q7ZmliMTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik0xNTUuNzIsLTE2OC43NkMxNTAuOTUsLTE2MC40IDE0NS4wMSwtMTUwLjAyIDEzOS42MywtMTQwLjYxIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE0Mi41MSwtMTM4LjU4IDEzNC41LC0xMzEuNjMgMTM2LjQzLC0xNDIuMDUgMTQyLjUxLC0xMzguNTgiLz4KPC9nPgo8IS0tIGZpYjIyIC0tPgo8ZyBpZD0ibm9kZTciIGNsYXNzPSJub2RlIj4KPHRpdGxlPmZpYjIyPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjIwNCIgY3k9Ii0xMTQiIHJ4PSIzMC41OSIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjIwNCIgeT0iLTExMC4zIiBmb250LWZhbWlseT0iVGltZXMsc2VyaWYiIGZvbnQtc2l6ZT0iMTQuMDAiPmZpYigyKTwvdGV4dD4KPC9nPgo8IS0tIGZpYjMmIzQ1OyZndDtmaWIyMiAtLT4KPGcgaWQ9ImVkZ2U2IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWIzJiM0NTsmZ3Q7ZmliMjI8L3RpdGxlPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBkPSJNMTc0LjA1LC0xNjguNzZDMTc4LjcsLTE2MC40IDE4NC40OSwtMTUwLjAyIDE4OS43MywtMTQwLjYxIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjE5Mi45MiwtMTQyLjA3IDE5NC43MywtMTMxLjYzIDE4Ni44MSwtMTM4LjY3IDE5Mi45MiwtMTQyLjA3Ii8+CjwvZz4KPCEtLSBmaWIxMSAtLT4KPGcgaWQ9Im5vZGUxMCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMTE8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMjk4IiBjeT0iLTExNCIgcng9IjMwLjU5IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMjk4IiB5PSItMTEwLjMiIGZvbnQtZmFtaWx5PSJUaW1lcyxzZXJpZiIgZm9udC1zaXplPSIxNC4wMCI+ZmliKDEpPC90ZXh0Pgo8L2c+CjwhLS0gZmliMzMmIzQ1OyZndDtmaWIxMSAtLT4KPGcgaWQ9ImVkZ2U5IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWIzMyYjNDU7Jmd0O2ZpYjExPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTMyNy45NSwtMTY4Ljc2QzMyMy4zLC0xNjAuNCAzMTcuNTEsLTE1MC4wMiAzMTIuMjcsLTE0MC42MSIvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgcG9pbnRzPSIzMTUuMTksLTEzOC42NyAzMDcuMjcsLTEzMS42MyAzMDkuMDgsLTE0Mi4wNyAzMTUuMTksLTEzOC42NyIvPgo8L2c+CjwhLS0gZmliMjIyIC0tPgo8ZyBpZD0ibm9kZTExIiBjbGFzcz0ibm9kZSI+Cjx0aXRsZT5maWIyMjI8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iMzc3IiBjeT0iLTExNCIgcng9IjMwLjU5IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iMzc3IiB5PSItMTEwLjMiIGZvbnQtZmFtaWx5PSJUaW1lcyxzZXJpZiIgZm9udC1zaXplPSIxNC4wMCI+ZmliKDIpPC90ZXh0Pgo8L2c+CjwhLS0gZmliMzMmIzQ1OyZndDtmaWIyMjIgLS0+CjxnIGlkPSJlZGdlMTAiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmZpYjMzJiM0NTsmZ3Q7ZmliMjIyPC90aXRsZT4KPHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgZD0iTTM0Ni4yOCwtMTY4Ljc2QzM1MS4wNSwtMTYwLjQgMzU2Ljk5LC0xNTAuMDIgMzYyLjM3LC0xNDAuNjEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iMzY1LjU3LC0xNDIuMDUgMzY3LjUsLTEzMS42MyAzNTkuNDksLTEzOC41OCAzNjUuNTcsLTE0Mi4wNSIvPgo8L2c+CjwhLS0gZmliMjIyMiAtLT4KPGcgaWQ9Im5vZGUxMiIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMjIyMjwvdGl0bGU+CjxlbGxpcHNlIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGN4PSI0NjMiIGN5PSItMTE0IiByeD0iMzAuNTkiIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI0NjMiIHk9Ii0xMTAuMyIgZm9udC1mYW1pbHk9IlRpbWVzLHNlcmlmIiBmb250LXNpemU9IjE0LjAwIj5maWIoMik8L3RleHQ+CjwvZz4KPCEtLSBmaWI0NCYjNDU7Jmd0O2ZpYjIyMjIgLS0+CjxnIGlkPSJlZGdlMTEiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmZpYjQ0JiM0NTsmZ3Q7ZmliMjIyMjwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00NjMsLTE2Ny43QzQ2MywtMTU5Ljk4IDQ2MywtMTUwLjcxIDQ2MywtMTQyLjExIi8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjQ2Ni41LC0xNDIuMSA0NjMsLTEzMi4xIDQ1OS41LC0xNDIuMSA0NjYuNSwtMTQyLjEiLz4KPC9nPgo8IS0tIGZpYjMzMyAtLT4KPGcgaWQ9Im5vZGUxMyIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMzMzPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjU0MiIgY3k9Ii0xMTQiIHJ4PSIzMC41OSIgcnk9IjE4Ii8+Cjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjU0MiIgeT0iLTExMC4zIiBmb250LWZhbWlseT0iVGltZXMsc2VyaWYiIGZvbnQtc2l6ZT0iMTQuMDAiPmZpYigzKTwvdGV4dD4KPC9nPgo8IS0tIGZpYjQ0JiM0NTsmZ3Q7ZmliMzMzIC0tPgo8ZyBpZD0iZWRnZTEyIiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWI0NCYjNDU7Jmd0O2ZpYjMzMzwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik00NzkuMzcsLTE3MC41QzQ5MC40OSwtMTYwLjY0IDUwNS4zOSwtMTQ3LjQ0IDUxNy44NywtMTM2LjM4Ii8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiBwb2ludHM9IjUyMC40OSwtMTM4Ljc0IDUyNS42NSwtMTI5LjQ5IDUxNS44NSwtMTMzLjUgNTIwLjQ5LC0xMzguNzQiLz4KPC9nPgo8IS0tIGZpYjExMSAtLT4KPGcgaWQ9Im5vZGUxNCIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMTExPC90aXRsZT4KPGVsbGlwc2UgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgY3g9IjU0MSIgY3k9Ii00MiIgcng9IjMwLjU5IiByeT0iMTgiLz4KPHRleHQgdGV4dC1hbmNob3I9Im1pZGRsZSIgeD0iNTQxIiB5PSItMzguMyIgZm9udC1mYW1pbHk9IlRpbWVzLHNlcmlmIiBmb250LXNpemU9IjE0LjAwIj5maWIoMSk8L3RleHQ+CjwvZz4KPCEtLSBmaWIzMzMmIzQ1OyZndDtmaWIxMTEgLS0+CjxnIGlkPSJlZGdlMTMiIGNsYXNzPSJlZGdlIj4KPHRpdGxlPmZpYjMzMyYjNDU7Jmd0O2ZpYjExMTwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik01NDEuNzUsLTk1LjdDNTQxLjY0LC04Ny45OCA1NDEuNTEsLTc4LjcxIDU0MS4zOSwtNzAuMTEiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNTQ0Ljg5LC03MC4wNSA1NDEuMjQsLTYwLjEgNTM3Ljg5LC03MC4xNSA1NDQuODksLTcwLjA1Ii8+CjwvZz4KPCEtLSBmaWIyMjIyMiAtLT4KPGcgaWQ9Im5vZGUxNSIgY2xhc3M9Im5vZGUiPgo8dGl0bGU+ZmliMjIyMjI8L3RpdGxlPgo8ZWxsaXBzZSBmaWxsPSJub25lIiBzdHJva2U9ImJsYWNrIiBjeD0iNjIwIiBjeT0iLTQyIiByeD0iMzAuNTkiIHJ5PSIxOCIvPgo8dGV4dCB0ZXh0LWFuY2hvcj0ibWlkZGxlIiB4PSI2MjAiIHk9Ii0zOC4zIiBmb250LWZhbWlseT0iVGltZXMsc2VyaWYiIGZvbnQtc2l6ZT0iMTQuMDAiPmZpYigyKTwvdGV4dD4KPC9nPgo8IS0tIGZpYjMzMyYjNDU7Jmd0O2ZpYjIyMjIyIC0tPgo8ZyBpZD0iZWRnZTE0IiBjbGFzcz0iZWRnZSI+Cjx0aXRsZT5maWIzMzMmIzQ1OyZndDtmaWIyMjIyMjwvdGl0bGU+CjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik01NTguMTYsLTk4LjVDNTY5LjE0LC04OC42NCA1ODMuODUsLTc1LjQ0IDU5Ni4xNywtNjQuMzgiLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHBvaW50cz0iNTk4Ljc1LC02Ni43NyA2MDMuODYsLTU3LjQ5IDU5NC4wOCwtNjEuNTYgNTk4Ljc1LC02Ni43NyIvPgo8L2c+CjwvZz4KPC9zdmc+Cg=="
|
|
]
|
|
}
|
|
},
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Vous constatez que la fonction `fibor` est lancée **177 fois** ! Et surtout, on calcule les mêmes valeurs plusieurs fois, par exemple on calcule **8 fois** `fibor(5)` !\n",
|
|
"\n",
|
|
"Cette image montre bien le problème pour `fibor(6)` :\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"On voit dans l'arbre des appels successifs que `fibor(4)` est calculé 2 fois et `fibor(3)` 3 fois. Ce qui est évidemment **inefficace**.\n",
|
|
"\n",
|
|
"On peut, en général, améliorer la **récursivité** en faisant de la **récursivité terminale**, mais nous approfondirons ce problème plus tard...\n",
|
|
"\n",
|
|
"⚠️ Retenons pour l'instant que la **récursivité** permet de programmer avec **simplicité et élégance** des problème **difficiles** mais souvent au **détriment de la performance**.\n",
|
|
"\n",
|
|
"# Programmation dynamique\n",
|
|
"\n",
|
|
"Le gros défaut de l'algorithme précédent est qu'il **recalcule** sans cesse les **mêmes termes** inutilement. Il existe une méthode de programmation qui répond justement à ce problème :\n",
|
|
"\n",
|
|
"⚠️ La **programmation dynamique** est une méthode de programmation qui consiste à **enregistrer des résultats de calculs intermédiaires** pour les **réutiliser plus tard afin d'éviter de les recalculer**.\n",
|
|
"\n",
|
|
"- Écrivez la fonction `fibordyn` qui calcule les termes de la suite de Fibonacci **récursivement** mais avec une **liste pour enregistrer les résultats intermédiaires** que vous consulterez avant de recommencer un calcul.\n",
|
|
"\n",
|
|
"- Testez votre fonction avec n = 10."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"On appelle fibor(10)\n",
|
|
"On appelle fibor(9)\n",
|
|
"On appelle fibor(8)\n",
|
|
"On appelle fibor(7)\n",
|
|
"On appelle fibor(6)\n",
|
|
"On appelle fibor(5)\n",
|
|
"On appelle fibor(4)\n",
|
|
"On appelle fibor(3)\n",
|
|
"On appelle fibor(2)\n",
|
|
"On appelle fibor(1)\n",
|
|
"On appelle fibor(0)\n",
|
|
"On appelle fibor(1)\n",
|
|
"On appelle fibor(2)\n",
|
|
"On appelle fibor(3)\n",
|
|
"On appelle fibor(4)\n",
|
|
"On appelle fibor(5)\n",
|
|
"On appelle fibor(6)\n",
|
|
"On appelle fibor(7)\n",
|
|
"On appelle fibor(8)\n",
|
|
"55\n",
|
|
"On appelle fibor(10)\n",
|
|
"On appelle fibor(9)\n",
|
|
"On appelle fibor(8)\n",
|
|
"On appelle fibor(7)\n",
|
|
"On appelle fibor(6)\n",
|
|
"On appelle fibor(5)\n",
|
|
"On appelle fibor(4)\n",
|
|
"On appelle fibor(3)\n",
|
|
"On appelle fibor(2)\n",
|
|
"55\n",
|
|
"On appelle fibor(10)\n",
|
|
"On appelle fibor(9)\n",
|
|
"On appelle fibor(8)\n",
|
|
"On appelle fibor(7)\n",
|
|
"On appelle fibor(6)\n",
|
|
"On appelle fibor(5)\n",
|
|
"On appelle fibor(4)\n",
|
|
"On appelle fibor(3)\n",
|
|
"On appelle fibor(2)\n",
|
|
"55\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def fibordyn1(n: int) -> int:\n",
|
|
" \"\"\" Lanceur de la fonction fibor (n>=0) : initialisation du tableau de résultats \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" resultats = [None for i in range(n+2)]\n",
|
|
" resultats[0] = 0\n",
|
|
" resultats[1] = 1\n",
|
|
" return fibor1(n, resultats)\n",
|
|
"\n",
|
|
"def fibor1(n: int, resultats: list) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement avec programmation dynamique (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" print(f\"On appelle fibor({n})\")\n",
|
|
"\n",
|
|
" if resultats[n] == None:\n",
|
|
" resultats[n] = fibor1(n-1, resultats) + fibor1(n-2, resultats)\n",
|
|
" \n",
|
|
" return resultats[n]\n",
|
|
"\n",
|
|
"def fibordyn2(n: int) -> int:\n",
|
|
" \"\"\" Lanceur de la fonction fibor (n>=0) : initialisation du tableau de résultats \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" resultats = [None for i in range(n+2)]\n",
|
|
" resultats[0] = 0\n",
|
|
" resultats[1] = 1\n",
|
|
" return fibor2(n, resultats)\n",
|
|
"\n",
|
|
"def fibor2(n: int, resultats: list) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement avec programmation dynamique (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" print(f\"On appelle fibor({n})\")\n",
|
|
" if resultats[n] != None: return resultats[n]\n",
|
|
" if resultats[n-1] == None: resultats[n-1] = fibor2(n-1, resultats)\n",
|
|
" if resultats[n-2] == None: resultats[n-2] = fibor2(n-2, resultats)\n",
|
|
" return resultats[n-1] + resultats[n-2]\n",
|
|
"\n",
|
|
"def fibordyn3(n: int) -> int:\n",
|
|
" \"\"\" Lanceur de la fonction fibor (n>=0) : initialisation du tableau de résultats \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" resultats = [None for i in range(n+2)]\n",
|
|
" resultats[0] = 0\n",
|
|
" resultats[1] = 1\n",
|
|
" \n",
|
|
" # === Nested function ===\n",
|
|
" def fibor3(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement avec programmation dynamique (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" print(f\"On appelle fibor({n})\")\n",
|
|
" \n",
|
|
" if resultats[n] != None: return resultats[n]\n",
|
|
" if resultats[n-1] == None: resultats[n-1] = fibor3(n-1)\n",
|
|
" if resultats[n-2] == None: resultats[n-2] = fibor3(n-2)\n",
|
|
" return resultats[n-1] + resultats[n-2]\n",
|
|
" # === End of nested function ===\n",
|
|
" \n",
|
|
" return fibor3(n)\n",
|
|
"\n",
|
|
"print(fibordyn1(10))\n",
|
|
"print(fibordyn2(10))\n",
|
|
"print(fibordyn3(10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"🏁 **Terminaison** : la fonction termine toujours car elle est appelée récursivement avec des paramètres entiers positifs **décroissants** donc ils arriveront forcément à 0 et 1 ce qui **arrêtera les appels récursifs**.\n",
|
|
"\n",
|
|
"🐌 **Complexité** : $O(n)$, on appelle n+1 fois la fonction `fibor()` qui contient des tests, des affectations, des additions mais aussi des **accès à des listes qui se font en temps constant en Python**.\n",
|
|
"\n",
|
|
"⚠️ Je vous conseille de faire un arbre d'appel avec `n = 5` pour comprendre exactement comment marche ce programme car c'est plus subtil qu'il n'y parait ! C'est l'occasion d'utiliser [Python Tutor](http://www.pythontutor.com/visualize.html#mode=edit) !\n",
|
|
"\n",
|
|
"# Performances\n",
|
|
"\n",
|
|
"Nous avons donc 4 algorithmes différents pour calculer la croissance de la population de nos couples de lapins. Testons leurs performances.\n",
|
|
"\n",
|
|
"- **Copier-coller** la définition de votre fonction `lapinoux` au début de la cellule ci-dessous et exécutez la cellule pour analyser les performances."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Test avec n=10 - Test avec n=1010 - Test avec n=2010 - Test avec n=3010 - Test avec n=4010 - Test avec n=5010 - Test avec n=6010 - Test avec n=7010 - Test avec n=8010 - Test avec n=9010 - Test avec n=10010 - Test avec n=11010 - Test avec n=12010 - Test avec n=13010 - Test avec n=14010 - Test avec n=15010 - Test avec n=16010 - Test avec n=17010 - Test avec n=18010 - Test avec n=19010 - Test avec n=20010 - Test avec n=21010 - Test avec n=22010 - Test avec n=23010 - Test avec n=24010 - Test avec n=25010 - Test avec n=26010 - Test avec n=27010 - Test avec n=28010 - Test avec n=29010 - Test avec n=30010 - Test avec n=31010 - Test avec n=32010 - Test avec n=33010 - Test avec n=34010 - Test avec n=35010 - Test avec n=36010 - Test avec n=37010 - Test avec n=38010 - Test avec n=39010 - Test avec n=40010 - Test avec n=41010 - Test avec n=42010 - Test avec n=43010 - Test avec n=44010 - Test avec n=45010 - Test avec n=46010 - Test avec n=47010 - Test avec n=48010 - Test avec n=49010 - Test avec n=50010 - Test avec n=51010 - Test avec n=52010 - Test avec n=53010 - Test avec n=54010 - Test avec n=55010 - Test avec n=56010 - Test avec n=57010 - Test avec n=58010 - Test avec n=59010 - Test avec n=60010 - Test avec n=61010 - Test avec n=62010 - Test avec n=63010 - Test avec n=64010 - Test avec n=65010 - Test avec n=66010 - Test avec n=67010 - Test avec n=68010 - Test avec n=69010 - Test avec n=70010 - Test avec n=71010 - Test avec n=72010 - Test avec n=73010 - Test avec n=74010 - Test avec n=75010 - Test avec n=76010 - Test avec n=77010 - Test avec n=78010 - Test avec n=79010 - Test avec n=80010 - Test avec n=81010 - Test avec n=82010 - Test avec n=83010 - Test avec n=84010 - Test avec n=85010 - Test avec n=86010 - Test avec n=87010 - Test avec n=88010 - Test avec n=89010 - Test avec n=90010 - Test avec n=91010 - Test avec n=92010 - Test avec n=93010 - Test avec n=94010 - Test avec n=95010 - Test avec n=96010 - Test avec n=97010 - Test avec n=98010 - Test avec n=99010 - "
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"/* global mpl */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function () {\n",
|
|
" if (typeof WebSocket !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof MozWebSocket !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert(\n",
|
|
" 'Your browser does not have WebSocket support. ' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.'\n",
|
|
" );\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = this.ws.binaryType !== undefined;\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById('mpl-warnings');\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent =\n",
|
|
" 'This browser does not support binary websocket messages. ' +\n",
|
|
" 'Performance may be slow.';\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = document.createElement('div');\n",
|
|
" this.root.setAttribute('style', 'display: inline-block');\n",
|
|
" this._root_extra_style(this.root);\n",
|
|
"\n",
|
|
" parent_element.appendChild(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message('supports_binary', { value: fig.supports_binary });\n",
|
|
" fig.send_message('send_image_mode', {});\n",
|
|
" if (fig.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
|
|
" }\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onload = function () {\n",
|
|
" if (fig.image_mode === 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function () {\n",
|
|
" fig.ws.close();\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function () {\n",
|
|
" var titlebar = document.createElement('div');\n",
|
|
" titlebar.classList =\n",
|
|
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
|
|
" var titletext = document.createElement('div');\n",
|
|
" titletext.classList = 'ui-dialog-title';\n",
|
|
" titletext.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: 100%; text-align: center; padding: 3px;'\n",
|
|
" );\n",
|
|
" titlebar.appendChild(titletext);\n",
|
|
" this.root.appendChild(titlebar);\n",
|
|
" this.header = titletext;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
|
|
" canvas_div.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'border: 1px solid #ddd;' +\n",
|
|
" 'box-sizing: content-box;' +\n",
|
|
" 'clear: both;' +\n",
|
|
" 'min-height: 1px;' +\n",
|
|
" 'min-width: 1px;' +\n",
|
|
" 'outline: 0;' +\n",
|
|
" 'overflow: hidden;' +\n",
|
|
" 'position: relative;' +\n",
|
|
" 'resize: both;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" function on_keyboard_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.key_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keydown',\n",
|
|
" on_keyboard_event_closure('key_press')\n",
|
|
" );\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keyup',\n",
|
|
" on_keyboard_event_closure('key_release')\n",
|
|
" );\n",
|
|
"\n",
|
|
" this._canvas_extra_style(canvas_div);\n",
|
|
" this.root.appendChild(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = (this.canvas = document.createElement('canvas'));\n",
|
|
" canvas.classList.add('mpl-canvas');\n",
|
|
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
|
|
"\n",
|
|
" this.context = canvas.getContext('2d');\n",
|
|
"\n",
|
|
" var backingStore =\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" this.context.webkitBackingStorePixelRatio ||\n",
|
|
" this.context.mozBackingStorePixelRatio ||\n",
|
|
" this.context.msBackingStorePixelRatio ||\n",
|
|
" this.context.oBackingStorePixelRatio ||\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" 1;\n",
|
|
"\n",
|
|
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
|
" if (this.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: this.ratio });\n",
|
|
" }\n",
|
|
"\n",
|
|
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
|
|
" 'canvas'\n",
|
|
" ));\n",
|
|
" rubberband_canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" var resizeObserver = new ResizeObserver(function (entries) {\n",
|
|
" var nentries = entries.length;\n",
|
|
" for (var i = 0; i < nentries; i++) {\n",
|
|
" var entry = entries[i];\n",
|
|
" var width, height;\n",
|
|
" if (entry.contentBoxSize) {\n",
|
|
" if (entry.contentBoxSize instanceof Array) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" width = entry.contentBoxSize[0].inlineSize;\n",
|
|
" height = entry.contentBoxSize[0].blockSize;\n",
|
|
" } else {\n",
|
|
" // Firefox implements old version of spec.\n",
|
|
" width = entry.contentBoxSize.inlineSize;\n",
|
|
" height = entry.contentBoxSize.blockSize;\n",
|
|
" }\n",
|
|
" } else {\n",
|
|
" // Chrome <84 implements even older version of spec.\n",
|
|
" width = entry.contentRect.width;\n",
|
|
" height = entry.contentRect.height;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Keep the size of the canvas and rubber band canvas in sync with\n",
|
|
" // the canvas container.\n",
|
|
" if (entry.devicePixelContentBoxSize) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'width',\n",
|
|
" entry.devicePixelContentBoxSize[0].inlineSize\n",
|
|
" );\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'height',\n",
|
|
" entry.devicePixelContentBoxSize[0].blockSize\n",
|
|
" );\n",
|
|
" } else {\n",
|
|
" canvas.setAttribute('width', width * fig.ratio);\n",
|
|
" canvas.setAttribute('height', height * fig.ratio);\n",
|
|
" }\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.setAttribute('width', width);\n",
|
|
" rubberband_canvas.setAttribute('height', height);\n",
|
|
"\n",
|
|
" // And update the size in Python. We ignore the initial 0/0 size\n",
|
|
" // that occurs as the element is placed into the DOM, which should\n",
|
|
" // otherwise not happen due to the minimum size styling.\n",
|
|
" if (width != 0 && height != 0) {\n",
|
|
" fig.request_resize(width, height);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" });\n",
|
|
" resizeObserver.observe(canvas_div);\n",
|
|
"\n",
|
|
" function on_mouse_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.mouse_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousedown',\n",
|
|
" on_mouse_event_closure('button_press')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseup',\n",
|
|
" on_mouse_event_closure('button_release')\n",
|
|
" );\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousemove',\n",
|
|
" on_mouse_event_closure('motion_notify')\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseenter',\n",
|
|
" on_mouse_event_closure('figure_enter')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseleave',\n",
|
|
" on_mouse_event_closure('figure_leave')\n",
|
|
" );\n",
|
|
"\n",
|
|
" canvas_div.addEventListener('wheel', function (event) {\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" on_mouse_event_closure('scroll')(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.appendChild(canvas);\n",
|
|
" canvas_div.appendChild(rubberband_canvas);\n",
|
|
"\n",
|
|
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
|
|
" this.rubberband_context.strokeStyle = '#000000';\n",
|
|
"\n",
|
|
" this._resize_canvas = function (width, height, forward) {\n",
|
|
" if (forward) {\n",
|
|
" canvas_div.style.width = width + 'px';\n",
|
|
" canvas_div.style.height = height + 'px';\n",
|
|
" }\n",
|
|
" };\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus() {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'mpl-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var button = (fig.buttons[name] = document.createElement('button'));\n",
|
|
" button.classList = 'mpl-widget';\n",
|
|
" button.setAttribute('role', 'button');\n",
|
|
" button.setAttribute('aria-disabled', 'false');\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
"\n",
|
|
" var icon_img = document.createElement('img');\n",
|
|
" icon_img.src = '_images/' + image + '.png';\n",
|
|
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
|
|
" icon_img.alt = tooltip;\n",
|
|
" button.appendChild(icon_img);\n",
|
|
"\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker = document.createElement('select');\n",
|
|
" fmt_picker.classList = 'mpl-widget';\n",
|
|
" toolbar.appendChild(fmt_picker);\n",
|
|
" this.format_dropdown = fmt_picker;\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = document.createElement('option');\n",
|
|
" option.selected = fmt === mpl.default_extension;\n",
|
|
" option.innerHTML = fmt;\n",
|
|
" fmt_picker.appendChild(option);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function (type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function () {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1], msg['forward']);\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
|
|
" var x0 = msg['x0'] / fig.ratio;\n",
|
|
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
|
|
" var x1 = msg['x1'] / fig.ratio;\n",
|
|
" var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0,\n",
|
|
" 0,\n",
|
|
" fig.canvas.width / fig.ratio,\n",
|
|
" fig.canvas.height / fig.ratio\n",
|
|
" );\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch (cursor) {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function (fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
|
|
" for (var key in msg) {\n",
|
|
" if (!(key in fig.buttons)) {\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" fig.buttons[key].disabled = !msg[key];\n",
|
|
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
|
|
" if (msg['mode'] === 'PAN') {\n",
|
|
" fig.buttons['Pan'].classList.add('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" } else if (msg['mode'] === 'ZOOM') {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.add('active');\n",
|
|
" } else {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message('ack', {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function (fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = 'image/png';\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src\n",
|
|
" );\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data\n",
|
|
" );\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" } else if (\n",
|
|
" typeof evt.data === 'string' &&\n",
|
|
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
|
|
" ) {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig['handle_' + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
|
|
" e,\n",
|
|
" e.stack,\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"};\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function (e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e) {\n",
|
|
" e = window.event;\n",
|
|
" }\n",
|
|
" if (e.target) {\n",
|
|
" targ = e.target;\n",
|
|
" } else if (e.srcElement) {\n",
|
|
" targ = e.srcElement;\n",
|
|
" }\n",
|
|
" if (targ.nodeType === 3) {\n",
|
|
" // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" var boundingRect = targ.getBoundingClientRect();\n",
|
|
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
|
|
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
|
|
"\n",
|
|
" return { x: x, y: y };\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys(original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object') {\n",
|
|
" obj[key] = original[key];\n",
|
|
" }\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function (event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event);\n",
|
|
"\n",
|
|
" if (name === 'button_press') {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x * this.ratio;\n",
|
|
" var y = canvas_pos.y * this.ratio;\n",
|
|
"\n",
|
|
" this.send_message(name, {\n",
|
|
" x: x,\n",
|
|
" y: y,\n",
|
|
" button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event),\n",
|
|
" });\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function (event, name) {\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name === 'key_press') {\n",
|
|
" if (event.which === this._key) {\n",
|
|
" return;\n",
|
|
" } else {\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" }\n",
|
|
" if (name === 'key_release') {\n",
|
|
" this._key = null;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which !== 17) {\n",
|
|
" value += 'ctrl+';\n",
|
|
" }\n",
|
|
" if (event.altKey && event.which !== 18) {\n",
|
|
" value += 'alt+';\n",
|
|
" }\n",
|
|
" if (event.shiftKey && event.which !== 16) {\n",
|
|
" value += 'shift+';\n",
|
|
" }\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
|
|
" if (name === 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message('toolbar_button', { name: name });\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";/* global mpl */\n",
|
|
"\n",
|
|
"var comm_websocket_adapter = function (comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function () {\n",
|
|
" comm.close();\n",
|
|
" };\n",
|
|
" ws.send = function (m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function (msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data']);\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function (comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = document.getElementById(id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm);\n",
|
|
"\n",
|
|
" function ondownload(figure, _format) {\n",
|
|
" window.open(figure.canvas.toDataURL());\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element;\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error('Failed to find cell for figure', id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" fig.cell_info[0].output_area.element.one(\n",
|
|
" 'cleared',\n",
|
|
" { fig: fig },\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
|
|
" var width = fig.canvas.width / fig.ratio;\n",
|
|
" fig.cell_info[0].output_area.element.off(\n",
|
|
" 'cleared',\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable();\n",
|
|
" fig.parent_element.innerHTML =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function (fig, msg) {\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var width = this.canvas.width / this.ratio;\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message('ack', {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () {\n",
|
|
" fig.push_to_output();\n",
|
|
" }, 1000);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'btn-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" var button;\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" button = fig.buttons[name] = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-default';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = name;\n",
|
|
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message pull-right';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = document.createElement('div');\n",
|
|
" buttongrp.classList = 'btn-group inline pull-right';\n",
|
|
" button = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-mini btn-primary';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = 'Stop Interaction';\n",
|
|
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
|
|
" button.addEventListener('click', function (_evt) {\n",
|
|
" fig.handle_close(fig, {});\n",
|
|
" });\n",
|
|
" button.addEventListener(\n",
|
|
" 'mouseover',\n",
|
|
" on_mouseover_closure('Stop Interaction')\n",
|
|
" );\n",
|
|
" buttongrp.appendChild(button);\n",
|
|
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
|
|
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
|
|
" var fig = event.data.fig;\n",
|
|
" fig.close_ws(fig, {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (el) {\n",
|
|
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.setAttribute('tabindex', 0);\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" } else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager) {\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which === 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" // select the cell after this one\n",
|
|
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
|
" IPython.notebook.select(index + 1);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function (html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i = 0; i < ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code') {\n",
|
|
" for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] === html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel !== null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target(\n",
|
|
" 'matplotlib',\n",
|
|
" mpl.mpl_figure_comm\n",
|
|
" );\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"\n",
|
|
"Temps d'execution de lapinoux avec n=99010 : 0.08579590969999984\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def lapinoux(n: int) -> int:\n",
|
|
" \"\"\" Calcule le nombre de couples de lapins au bout de n mois (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" nb_couples_immatures1 = 1\n",
|
|
" nb_couples_immatures2 = 0\n",
|
|
" nb_couples_matures = 0\n",
|
|
" \n",
|
|
" for i in range(n+1):\n",
|
|
" nb_couples_matures += nb_couples_immatures2\n",
|
|
" nb_couples_immatures2 = nb_couples_immatures1\n",
|
|
" nb_couples_immatures1 = nb_couples_matures\n",
|
|
" \n",
|
|
" return nb_couples_matures\n",
|
|
"\n",
|
|
"# Mesure du temps et tracés\n",
|
|
"import time\n",
|
|
"%matplotlib notebook\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"n = [i for i in range(10, 100000, 1000)]\n",
|
|
"liste_temps = []\n",
|
|
"\n",
|
|
"for i in n:\n",
|
|
" print(f\"Test avec n={i}\", end = \" - \")\n",
|
|
" temps = 0.0\n",
|
|
" nb_loops = 10\n",
|
|
" for test in range(nb_loops):\n",
|
|
" start = time.process_time()\n",
|
|
" lapinoux(i)\n",
|
|
" temps += time.process_time() - start\n",
|
|
" temps /= nb_loops\n",
|
|
" liste_temps.append(temps)\n",
|
|
"\n",
|
|
"plt.plot(n, liste_temps, label=\"lapinoux\")\n",
|
|
"plt.xlabel(\"n\")\n",
|
|
"plt.grid(True)\n",
|
|
"print(f\"\\n\\nTemps d'execution de lapinoux avec n={n[-1]} : {liste_temps[-1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"On constate que le temps d'exécution en fonction de `n` n'est **pas linéaire** comme la complexité le laissait supposer... ???\n",
|
|
"\n",
|
|
"- **Copier-coller** la définition de votre fonction `fibo` au début de la cellule suivante et exécutez la cellule pour analyser les performances."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Test avec n=10 - Test avec n=1010 - Test avec n=2010 - Test avec n=3010 - Test avec n=4010 - Test avec n=5010 - Test avec n=6010 - Test avec n=7010 - Test avec n=8010 - Test avec n=9010 - Test avec n=10010 - Test avec n=11010 - Test avec n=12010 - Test avec n=13010 - Test avec n=14010 - Test avec n=15010 - Test avec n=16010 - Test avec n=17010 - Test avec n=18010 - Test avec n=19010 - Test avec n=20010 - Test avec n=21010 - Test avec n=22010 - Test avec n=23010 - Test avec n=24010 - Test avec n=25010 - Test avec n=26010 - Test avec n=27010 - Test avec n=28010 - Test avec n=29010 - Test avec n=30010 - Test avec n=31010 - Test avec n=32010 - Test avec n=33010 - Test avec n=34010 - Test avec n=35010 - Test avec n=36010 - Test avec n=37010 - Test avec n=38010 - Test avec n=39010 - Test avec n=40010 - Test avec n=41010 - Test avec n=42010 - Test avec n=43010 - Test avec n=44010 - Test avec n=45010 - Test avec n=46010 - Test avec n=47010 - Test avec n=48010 - Test avec n=49010 - Test avec n=50010 - Test avec n=51010 - Test avec n=52010 - Test avec n=53010 - Test avec n=54010 - Test avec n=55010 - Test avec n=56010 - Test avec n=57010 - Test avec n=58010 - Test avec n=59010 - Test avec n=60010 - Test avec n=61010 - Test avec n=62010 - Test avec n=63010 - Test avec n=64010 - Test avec n=65010 - Test avec n=66010 - Test avec n=67010 - Test avec n=68010 - Test avec n=69010 - Test avec n=70010 - Test avec n=71010 - Test avec n=72010 - Test avec n=73010 - Test avec n=74010 - Test avec n=75010 - Test avec n=76010 - Test avec n=77010 - Test avec n=78010 - Test avec n=79010 - Test avec n=80010 - Test avec n=81010 - Test avec n=82010 - Test avec n=83010 - Test avec n=84010 - Test avec n=85010 - Test avec n=86010 - Test avec n=87010 - Test avec n=88010 - Test avec n=89010 - Test avec n=90010 - Test avec n=91010 - Test avec n=92010 - Test avec n=93010 - Test avec n=94010 - Test avec n=95010 - Test avec n=96010 - Test avec n=97010 - Test avec n=98010 - Test avec n=99010 - "
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"/* global mpl */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function () {\n",
|
|
" if (typeof WebSocket !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof MozWebSocket !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert(\n",
|
|
" 'Your browser does not have WebSocket support. ' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.'\n",
|
|
" );\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = this.ws.binaryType !== undefined;\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById('mpl-warnings');\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent =\n",
|
|
" 'This browser does not support binary websocket messages. ' +\n",
|
|
" 'Performance may be slow.';\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = document.createElement('div');\n",
|
|
" this.root.setAttribute('style', 'display: inline-block');\n",
|
|
" this._root_extra_style(this.root);\n",
|
|
"\n",
|
|
" parent_element.appendChild(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message('supports_binary', { value: fig.supports_binary });\n",
|
|
" fig.send_message('send_image_mode', {});\n",
|
|
" if (fig.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
|
|
" }\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onload = function () {\n",
|
|
" if (fig.image_mode === 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function () {\n",
|
|
" fig.ws.close();\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function () {\n",
|
|
" var titlebar = document.createElement('div');\n",
|
|
" titlebar.classList =\n",
|
|
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
|
|
" var titletext = document.createElement('div');\n",
|
|
" titletext.classList = 'ui-dialog-title';\n",
|
|
" titletext.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: 100%; text-align: center; padding: 3px;'\n",
|
|
" );\n",
|
|
" titlebar.appendChild(titletext);\n",
|
|
" this.root.appendChild(titlebar);\n",
|
|
" this.header = titletext;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
|
|
" canvas_div.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'border: 1px solid #ddd;' +\n",
|
|
" 'box-sizing: content-box;' +\n",
|
|
" 'clear: both;' +\n",
|
|
" 'min-height: 1px;' +\n",
|
|
" 'min-width: 1px;' +\n",
|
|
" 'outline: 0;' +\n",
|
|
" 'overflow: hidden;' +\n",
|
|
" 'position: relative;' +\n",
|
|
" 'resize: both;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" function on_keyboard_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.key_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keydown',\n",
|
|
" on_keyboard_event_closure('key_press')\n",
|
|
" );\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keyup',\n",
|
|
" on_keyboard_event_closure('key_release')\n",
|
|
" );\n",
|
|
"\n",
|
|
" this._canvas_extra_style(canvas_div);\n",
|
|
" this.root.appendChild(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = (this.canvas = document.createElement('canvas'));\n",
|
|
" canvas.classList.add('mpl-canvas');\n",
|
|
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
|
|
"\n",
|
|
" this.context = canvas.getContext('2d');\n",
|
|
"\n",
|
|
" var backingStore =\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" this.context.webkitBackingStorePixelRatio ||\n",
|
|
" this.context.mozBackingStorePixelRatio ||\n",
|
|
" this.context.msBackingStorePixelRatio ||\n",
|
|
" this.context.oBackingStorePixelRatio ||\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" 1;\n",
|
|
"\n",
|
|
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
|
" if (this.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: this.ratio });\n",
|
|
" }\n",
|
|
"\n",
|
|
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
|
|
" 'canvas'\n",
|
|
" ));\n",
|
|
" rubberband_canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" var resizeObserver = new ResizeObserver(function (entries) {\n",
|
|
" var nentries = entries.length;\n",
|
|
" for (var i = 0; i < nentries; i++) {\n",
|
|
" var entry = entries[i];\n",
|
|
" var width, height;\n",
|
|
" if (entry.contentBoxSize) {\n",
|
|
" if (entry.contentBoxSize instanceof Array) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" width = entry.contentBoxSize[0].inlineSize;\n",
|
|
" height = entry.contentBoxSize[0].blockSize;\n",
|
|
" } else {\n",
|
|
" // Firefox implements old version of spec.\n",
|
|
" width = entry.contentBoxSize.inlineSize;\n",
|
|
" height = entry.contentBoxSize.blockSize;\n",
|
|
" }\n",
|
|
" } else {\n",
|
|
" // Chrome <84 implements even older version of spec.\n",
|
|
" width = entry.contentRect.width;\n",
|
|
" height = entry.contentRect.height;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Keep the size of the canvas and rubber band canvas in sync with\n",
|
|
" // the canvas container.\n",
|
|
" if (entry.devicePixelContentBoxSize) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'width',\n",
|
|
" entry.devicePixelContentBoxSize[0].inlineSize\n",
|
|
" );\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'height',\n",
|
|
" entry.devicePixelContentBoxSize[0].blockSize\n",
|
|
" );\n",
|
|
" } else {\n",
|
|
" canvas.setAttribute('width', width * fig.ratio);\n",
|
|
" canvas.setAttribute('height', height * fig.ratio);\n",
|
|
" }\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.setAttribute('width', width);\n",
|
|
" rubberband_canvas.setAttribute('height', height);\n",
|
|
"\n",
|
|
" // And update the size in Python. We ignore the initial 0/0 size\n",
|
|
" // that occurs as the element is placed into the DOM, which should\n",
|
|
" // otherwise not happen due to the minimum size styling.\n",
|
|
" if (width != 0 && height != 0) {\n",
|
|
" fig.request_resize(width, height);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" });\n",
|
|
" resizeObserver.observe(canvas_div);\n",
|
|
"\n",
|
|
" function on_mouse_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.mouse_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousedown',\n",
|
|
" on_mouse_event_closure('button_press')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseup',\n",
|
|
" on_mouse_event_closure('button_release')\n",
|
|
" );\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousemove',\n",
|
|
" on_mouse_event_closure('motion_notify')\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseenter',\n",
|
|
" on_mouse_event_closure('figure_enter')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseleave',\n",
|
|
" on_mouse_event_closure('figure_leave')\n",
|
|
" );\n",
|
|
"\n",
|
|
" canvas_div.addEventListener('wheel', function (event) {\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" on_mouse_event_closure('scroll')(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.appendChild(canvas);\n",
|
|
" canvas_div.appendChild(rubberband_canvas);\n",
|
|
"\n",
|
|
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
|
|
" this.rubberband_context.strokeStyle = '#000000';\n",
|
|
"\n",
|
|
" this._resize_canvas = function (width, height, forward) {\n",
|
|
" if (forward) {\n",
|
|
" canvas_div.style.width = width + 'px';\n",
|
|
" canvas_div.style.height = height + 'px';\n",
|
|
" }\n",
|
|
" };\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus() {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'mpl-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var button = (fig.buttons[name] = document.createElement('button'));\n",
|
|
" button.classList = 'mpl-widget';\n",
|
|
" button.setAttribute('role', 'button');\n",
|
|
" button.setAttribute('aria-disabled', 'false');\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
"\n",
|
|
" var icon_img = document.createElement('img');\n",
|
|
" icon_img.src = '_images/' + image + '.png';\n",
|
|
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
|
|
" icon_img.alt = tooltip;\n",
|
|
" button.appendChild(icon_img);\n",
|
|
"\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker = document.createElement('select');\n",
|
|
" fmt_picker.classList = 'mpl-widget';\n",
|
|
" toolbar.appendChild(fmt_picker);\n",
|
|
" this.format_dropdown = fmt_picker;\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = document.createElement('option');\n",
|
|
" option.selected = fmt === mpl.default_extension;\n",
|
|
" option.innerHTML = fmt;\n",
|
|
" fmt_picker.appendChild(option);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function (type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function () {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1], msg['forward']);\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
|
|
" var x0 = msg['x0'] / fig.ratio;\n",
|
|
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
|
|
" var x1 = msg['x1'] / fig.ratio;\n",
|
|
" var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0,\n",
|
|
" 0,\n",
|
|
" fig.canvas.width / fig.ratio,\n",
|
|
" fig.canvas.height / fig.ratio\n",
|
|
" );\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch (cursor) {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function (fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
|
|
" for (var key in msg) {\n",
|
|
" if (!(key in fig.buttons)) {\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" fig.buttons[key].disabled = !msg[key];\n",
|
|
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
|
|
" if (msg['mode'] === 'PAN') {\n",
|
|
" fig.buttons['Pan'].classList.add('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" } else if (msg['mode'] === 'ZOOM') {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.add('active');\n",
|
|
" } else {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message('ack', {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function (fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = 'image/png';\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src\n",
|
|
" );\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data\n",
|
|
" );\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" } else if (\n",
|
|
" typeof evt.data === 'string' &&\n",
|
|
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
|
|
" ) {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig['handle_' + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
|
|
" e,\n",
|
|
" e.stack,\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"};\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function (e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e) {\n",
|
|
" e = window.event;\n",
|
|
" }\n",
|
|
" if (e.target) {\n",
|
|
" targ = e.target;\n",
|
|
" } else if (e.srcElement) {\n",
|
|
" targ = e.srcElement;\n",
|
|
" }\n",
|
|
" if (targ.nodeType === 3) {\n",
|
|
" // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" var boundingRect = targ.getBoundingClientRect();\n",
|
|
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
|
|
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
|
|
"\n",
|
|
" return { x: x, y: y };\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys(original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object') {\n",
|
|
" obj[key] = original[key];\n",
|
|
" }\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function (event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event);\n",
|
|
"\n",
|
|
" if (name === 'button_press') {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x * this.ratio;\n",
|
|
" var y = canvas_pos.y * this.ratio;\n",
|
|
"\n",
|
|
" this.send_message(name, {\n",
|
|
" x: x,\n",
|
|
" y: y,\n",
|
|
" button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event),\n",
|
|
" });\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function (event, name) {\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name === 'key_press') {\n",
|
|
" if (event.which === this._key) {\n",
|
|
" return;\n",
|
|
" } else {\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" }\n",
|
|
" if (name === 'key_release') {\n",
|
|
" this._key = null;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which !== 17) {\n",
|
|
" value += 'ctrl+';\n",
|
|
" }\n",
|
|
" if (event.altKey && event.which !== 18) {\n",
|
|
" value += 'alt+';\n",
|
|
" }\n",
|
|
" if (event.shiftKey && event.which !== 16) {\n",
|
|
" value += 'shift+';\n",
|
|
" }\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
|
|
" if (name === 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message('toolbar_button', { name: name });\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";/* global mpl */\n",
|
|
"\n",
|
|
"var comm_websocket_adapter = function (comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function () {\n",
|
|
" comm.close();\n",
|
|
" };\n",
|
|
" ws.send = function (m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function (msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data']);\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function (comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = document.getElementById(id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm);\n",
|
|
"\n",
|
|
" function ondownload(figure, _format) {\n",
|
|
" window.open(figure.canvas.toDataURL());\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element;\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error('Failed to find cell for figure', id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" fig.cell_info[0].output_area.element.one(\n",
|
|
" 'cleared',\n",
|
|
" { fig: fig },\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
|
|
" var width = fig.canvas.width / fig.ratio;\n",
|
|
" fig.cell_info[0].output_area.element.off(\n",
|
|
" 'cleared',\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable();\n",
|
|
" fig.parent_element.innerHTML =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function (fig, msg) {\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var width = this.canvas.width / this.ratio;\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message('ack', {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () {\n",
|
|
" fig.push_to_output();\n",
|
|
" }, 1000);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'btn-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" var button;\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" button = fig.buttons[name] = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-default';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = name;\n",
|
|
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message pull-right';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = document.createElement('div');\n",
|
|
" buttongrp.classList = 'btn-group inline pull-right';\n",
|
|
" button = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-mini btn-primary';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = 'Stop Interaction';\n",
|
|
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
|
|
" button.addEventListener('click', function (_evt) {\n",
|
|
" fig.handle_close(fig, {});\n",
|
|
" });\n",
|
|
" button.addEventListener(\n",
|
|
" 'mouseover',\n",
|
|
" on_mouseover_closure('Stop Interaction')\n",
|
|
" );\n",
|
|
" buttongrp.appendChild(button);\n",
|
|
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
|
|
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
|
|
" var fig = event.data.fig;\n",
|
|
" fig.close_ws(fig, {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (el) {\n",
|
|
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.setAttribute('tabindex', 0);\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" } else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager) {\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which === 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" // select the cell after this one\n",
|
|
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
|
" IPython.notebook.select(index + 1);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function (html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i = 0; i < ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code') {\n",
|
|
" for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] === html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel !== null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target(\n",
|
|
" 'matplotlib',\n",
|
|
" mpl.mpl_figure_comm\n",
|
|
" );\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOzda3hU5b3+8bGQhEot3faqVatdQQwkLbUSlW1bgW2roq2Hvbvb2qpoW+smoAL2vzcTziIh4gmtCqgxHiGgYIiyEo5CAkkgEDkFhjMkhBAOAZJASCaZmfv/IjI6JkDI8+Q3M8/cn+taLzqZJItv14U3k8yMA0REREQUURzBPgEiIiIiksUBSERERBRhOACJiIiIIgwHIBEREVGE4QAkIiIiijAcgEREREQRhgOQiIiIKMJwABIRERFFGA5AIiIiogjDAUhEREQUYTgAiYiIiCIMByARERFRhOEAJCIiIoowHIBEREREEYYDkIiIiCjCcAASERERRRgOQCIiIqIIwwFIREREFGE4AImIiIgiDAcgERERUYThACQiIiKKMByARERERBGGA5CIiIgownAAEhEREUUYDkAiIiKiCMMBSERERBRhOACJiIiIIgwHIBEREVGE4QAkIiIiijAcgEREREQRhgOQiIiIKMJwABIRERFFGA5AIiIiogjDAUhEREQUYTgAiYiIiCIMByARERFRhOEAJCIiIoowHIBEREREEYYDkIiIiCjCcAASERERRRgOQCIiIqIIwwFIREREFGE4AImIiIgiDAcgERERUYThACQiIiKKMByARERERBGGA5CIiIgownAAEhEREUUYDkAiIiKiCMMBSERERBRhOACJiIiIIgwHIBEREVGE4QAkIiIiijAcgEREREQRhgOQiIiIKMJwABIRERFFGA5ABV6vF+Xl5aiurkZNTQ0PHjx48ODBIwyO6upqlJeXw+v1BntKBA0HoILy8nI4HA4ePHjw4MGDRxge5eXlwZ4SQcMBqKC6utp/Aen8l0lVVRUyMjJQVVUV9H8lRcLB3mxt4sHWbG3ioav1mQdwqqurgz0lgoYDUEFNTQ0cDgdqamq0ft3GxkZkZWWhsbFR69el1rG3HLaWw9Zy2FqOrtYd9d/vcMIBqIAD0AzsLYet5bC1HLaWwwGoDwegAg5AM7C3HLaWw9Zy2FoOB6A+HIAKOADNwN5y2FoOW8thazkcgPpwACrgADQDe8thazlsLYet5XAA6sMBqIAD0AzsLYet5bC1HLaWwwGoDwegAg5AM7C3HLaWw9Zy2FoOB6A+HIAKOADNwN5y2FoOW8thazkc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Lr30Unz729/Gz3/+cxQXF/s/zt56NDU1YcyYMYiNjUWXLl3QvXt3TJw4MeBdIdi6ffLy8nD33XfjiiuugMPhwPz58wM+HmpdN2/ejP79+6NLly648sorMXHiRPh8Po1FQhcHYIiZM2cOoqKikJaWBpfLheHDh6Nr164oKysL9qmFhIEDB+Ldd9/Fli1bsHHjRvzud7/Dj3/8Y5w6dcp/nylTpuCSSy7BJ598gpKSEtx///244oorUFtb679PUlISfvSjH2Hp0qVYv349br31Vvz85z+Hx+Px3+fOO+9E7969UVhYiMLCQvTu3Rt33323/+Mejwe9e/fGrbfeivXr12Pp0qW48sor8cQTT8jEELR27VrExsbiuuuuCxiAbK3P8ePHYVkW/vrXv6KoqAj79u3DsmXLsHv3bv992FuPlJQUfP/734dt29i3bx/mzp2L73znO3jllVf892Hr9snJycGYMWPwySeftDoAQ6lrTU0NfvjDH+LPf/4zSkpK8Mknn+CSSy7Biy++2IGFQgcHYIjp27cvkpKSAm6Lj49HcnJykM4otB05cgQOhwN5eXkAmv91efnll2PKlCn++zQ0NKBbt2544403AADV1dWIiorCnDlz/PepqKjAt771LSxatAgA4HK54HA4sGbNGv99Vq9eDYfD4X/EMScnB9/61rdQUVHhv8/s2bMRExNj1IuUnjx5EnFxcVi6dCkGDBjgH4BsrZfT6cQtt9xy1o+ztz6/+93v8Pe//z3gtt///vd46KGHALC1Lt8cgKHWdfr06ejWrVvAawo+++yzuPLKKyPiUUAOwBDidrvRqVMnZGZmBtw+bNgw9O/fP0hnFdp27doFh8OBkpISAMCePXvgcDiwfv36gPvde++9ePjhhwEAn3/+ORwOB44fPx5wn+uuuw7jx48HAKSnp6Nbt24tvl+3bt3wzjvvAADGjRuH6667LuDjx48fh8PhwPLly/X8AUPAww8/jBEjRgBAwABka70SEhIwYsQI/OEPf8APfvADXH/99Xjrrbf8H2dvfZ599llYloUdO3YAADZu3IjLLrsMGRkZANhal28OwFDrOmjQINx7770B91m/fj0cDgf27t3bnj9yWOEADCEVFRVwOBwoKCgIuH3y5Mno2bNnkM4qdPl8Ptxzzz0Bj5oUFBTA4XAE/KsPAB577DHccccdAIBZs2YhOjq6xde7/fbb8T//8z8AmpvHxcW1uE9cXBxSU1P9X/P2229vcZ/o6Gj/f0jC3ezZs9G7d2/U19cDCByAbK1XTEwMYmJiMGrUKKxfvx5vvPEGunTpgvfffx8Ae+vk8/mQnJyMiy66CJ07d8ZFF13k/7MDbK3LNwdgqHW9/fbb8dhjjwV8/Mx/hwsLCy/kjxqWOABDyNkuvJSUFPTq1StIZxW6hg4dCsuyAn45+MxfMAcPHgy47z/+8Q8MHDgQwNn/grntttswePBgAGcf3ddeey2effZZAIF/aX1dVFQUZs+e3f4/WIjYv38/LrvsMmzcuNF/W2sDkK31iIqKwi9+8YuA25588kncfPPNANhbp9mzZ+Oqq67C7NmzsXnzZnzwwQe49NJL8d577wFga13ONgBDpevXR+UZBw4cgMPhwOrVqy/kjxqWOABDCH8E3HZPPPEErrrqqhYP04fajxjC2fz58+FwONCpUyf/4XA4cNFFF6FTp07YvXs3W2v04x//GI8++mjAbdOnT8eVV14JgNe2TldddRVef/31gNsmTZrk/4c2W+vBHwGHNg7AENO3b18MGTIk4LaEhAQ+CeRLPp8Pjz/+OK688krs3Lmz1Y9ffvnleO655/y3ud3uVn/J+KOPPvLf5+DBg63+knFRUZH/PmvWrGn1l4y//q/ZOXPmGPHL2wBQW1uLkpKSgOPGG2/EQw89hJKSErbW7C9/+UuLJ4GMGDHC/6gge+tz6aWXYvr06QG3paam+n+syNZ6nO1JIKHSdfr06fje974X8NIwU6ZM4ZNAKDjOvAxMeno6XC4XRowYga5du6K0tDTYpxYShgwZgm7duiE3NxeVlZX+4/Tp0/77TJkyBd26dUNmZiZKSkrwl7/8pdWXGbjqqquwbNmy/9/OHYK0uoYBHFc4OBU2UIQNFAWTQQ2CTf1Ao6JZDMMqikkNBlesNrMIWldsIhgHhg20abMLosH4nHA5Y7sYLodddu59fz9Y+fjCyxPGf9/4nqjX67G8vPztmoHZ2dmo1WpRq9ViZmbm2zUDKysrUa/X4+7uLsbGxv6z6xv+ida/gCPMupMeHh7ix48fcXp6Gi8vL3F9fR2Dg4NxdXXVvMe8O6NcLsfo6GhzDUy1Wo2RkZE4PDxs3mPWv+fz8zMajUY0Go3o6emJs7OzaDQazVVmf9Jc39/fo1gsxubmZjw9PUW1Wo1CoWANDN1zfn4eExMT0dfXF3Nzc80VJ/z1i/K7z8XFRfOeX4tGS6VS5HK5WFpaar4l/MvX11fs7u42F+6ura3F6+tr2z1vb2+xtbUV+Xw+8vl8bG1tfbtodHV1NQYGBmJ4eDh2d3fbVgr83/w9AM26s25ubmJ6ejpyuVxMTU21vQUcYd6d8vHxEfv7+zE+Ph79/f0xOTkZx8fHbU+CzPr33N/ff/sdXS6XI+LPm+vj42MsLi5GLpeLUqkUlUoliad/EQIQACA5AhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEKBFlmWxt7cXBwcHMTQ0FMViMU5OTrp9LICOEoAALbIsi0KhEJVKJZ6fn+Py8jJ6e3vj9va220cD6BgBCNAiy7JYWFhouzY/Px9HR0ddOhFA5wlAgBZZlsXOzk7btfX19dje3u7SiQA6TwACtMiyLPb399uubWxsRLlc7s6BAP4FAhCghQAEUiAAAVoIQCAFAhCghQAEUiAAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQAS8xPDgnMIVrX4xAAAAABJRU5ErkJggg==\" width=\"640\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"\n",
|
|
"Temps d'execution de fibo avec n=99010 : 0.08708674800000082\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def fibo(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" \n",
|
|
" if n <= 1: return 1\n",
|
|
" elif n <= 0: return 0\n",
|
|
"\n",
|
|
" un_moins_2 = 0\n",
|
|
" un_moins_1 = 1\n",
|
|
" \n",
|
|
" for i in range(2,n+1):\n",
|
|
" un = un_moins_1 + un_moins_2\n",
|
|
" un_moins_2 = un_moins_1\n",
|
|
" un_moins_1 = un\n",
|
|
" return un\n",
|
|
"\n",
|
|
"# Mesure du temps et tracés\n",
|
|
"import time\n",
|
|
"%matplotlib notebook\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"n = [i for i in range(10, 100000, 1000)]\n",
|
|
"liste_temps = []\n",
|
|
"\n",
|
|
"for i in n:\n",
|
|
" print(f\"Test avec n={i}\", end = \" - \")\n",
|
|
" temps = 0.0\n",
|
|
" nb_loops = 10\n",
|
|
" for test in range(nb_loops):\n",
|
|
" start = time.process_time()\n",
|
|
" fibo(i)\n",
|
|
" temps += time.process_time() - start\n",
|
|
" temps /= nb_loops\n",
|
|
" liste_temps.append(temps)\n",
|
|
"\n",
|
|
"plt.plot(n, liste_temps, label=\"fibo\")\n",
|
|
"plt.xlabel(\"n\")\n",
|
|
"plt.grid(True)\n",
|
|
"print(f\"\\n\\nTemps d'execution de fibo avec n={n[-1]} : {liste_temps[-1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Nous obtenons des résultats identiques à la fonction précédente, ce qui est normal puisque ces fonctions sont presques identiques.\n",
|
|
"\n",
|
|
"- **Copier-coller** la définition de votre fonction `fibor` au début de la cellule suivante et exécutez la cellule pour analyser les performances."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Test avec n=5 - Test avec n=7 - Test avec n=9 - Test avec n=11 - Test avec n=13 - Test avec n=15 - Test avec n=17 - Test avec n=19 - Test avec n=21 - Test avec n=23 - Test avec n=25 - Test avec n=27 - Test avec n=29 - Test avec n=31 - Test avec n=33 - Test avec n=35 - Test avec n=37 - Test avec n=39 - "
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"/* global mpl */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function () {\n",
|
|
" if (typeof WebSocket !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof MozWebSocket !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert(\n",
|
|
" 'Your browser does not have WebSocket support. ' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.'\n",
|
|
" );\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = this.ws.binaryType !== undefined;\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById('mpl-warnings');\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent =\n",
|
|
" 'This browser does not support binary websocket messages. ' +\n",
|
|
" 'Performance may be slow.';\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = document.createElement('div');\n",
|
|
" this.root.setAttribute('style', 'display: inline-block');\n",
|
|
" this._root_extra_style(this.root);\n",
|
|
"\n",
|
|
" parent_element.appendChild(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message('supports_binary', { value: fig.supports_binary });\n",
|
|
" fig.send_message('send_image_mode', {});\n",
|
|
" if (fig.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
|
|
" }\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onload = function () {\n",
|
|
" if (fig.image_mode === 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function () {\n",
|
|
" fig.ws.close();\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function () {\n",
|
|
" var titlebar = document.createElement('div');\n",
|
|
" titlebar.classList =\n",
|
|
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
|
|
" var titletext = document.createElement('div');\n",
|
|
" titletext.classList = 'ui-dialog-title';\n",
|
|
" titletext.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: 100%; text-align: center; padding: 3px;'\n",
|
|
" );\n",
|
|
" titlebar.appendChild(titletext);\n",
|
|
" this.root.appendChild(titlebar);\n",
|
|
" this.header = titletext;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
|
|
" canvas_div.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'border: 1px solid #ddd;' +\n",
|
|
" 'box-sizing: content-box;' +\n",
|
|
" 'clear: both;' +\n",
|
|
" 'min-height: 1px;' +\n",
|
|
" 'min-width: 1px;' +\n",
|
|
" 'outline: 0;' +\n",
|
|
" 'overflow: hidden;' +\n",
|
|
" 'position: relative;' +\n",
|
|
" 'resize: both;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" function on_keyboard_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.key_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keydown',\n",
|
|
" on_keyboard_event_closure('key_press')\n",
|
|
" );\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keyup',\n",
|
|
" on_keyboard_event_closure('key_release')\n",
|
|
" );\n",
|
|
"\n",
|
|
" this._canvas_extra_style(canvas_div);\n",
|
|
" this.root.appendChild(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = (this.canvas = document.createElement('canvas'));\n",
|
|
" canvas.classList.add('mpl-canvas');\n",
|
|
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
|
|
"\n",
|
|
" this.context = canvas.getContext('2d');\n",
|
|
"\n",
|
|
" var backingStore =\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" this.context.webkitBackingStorePixelRatio ||\n",
|
|
" this.context.mozBackingStorePixelRatio ||\n",
|
|
" this.context.msBackingStorePixelRatio ||\n",
|
|
" this.context.oBackingStorePixelRatio ||\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" 1;\n",
|
|
"\n",
|
|
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
|
" if (this.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: this.ratio });\n",
|
|
" }\n",
|
|
"\n",
|
|
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
|
|
" 'canvas'\n",
|
|
" ));\n",
|
|
" rubberband_canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" var resizeObserver = new ResizeObserver(function (entries) {\n",
|
|
" var nentries = entries.length;\n",
|
|
" for (var i = 0; i < nentries; i++) {\n",
|
|
" var entry = entries[i];\n",
|
|
" var width, height;\n",
|
|
" if (entry.contentBoxSize) {\n",
|
|
" if (entry.contentBoxSize instanceof Array) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" width = entry.contentBoxSize[0].inlineSize;\n",
|
|
" height = entry.contentBoxSize[0].blockSize;\n",
|
|
" } else {\n",
|
|
" // Firefox implements old version of spec.\n",
|
|
" width = entry.contentBoxSize.inlineSize;\n",
|
|
" height = entry.contentBoxSize.blockSize;\n",
|
|
" }\n",
|
|
" } else {\n",
|
|
" // Chrome <84 implements even older version of spec.\n",
|
|
" width = entry.contentRect.width;\n",
|
|
" height = entry.contentRect.height;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Keep the size of the canvas and rubber band canvas in sync with\n",
|
|
" // the canvas container.\n",
|
|
" if (entry.devicePixelContentBoxSize) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'width',\n",
|
|
" entry.devicePixelContentBoxSize[0].inlineSize\n",
|
|
" );\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'height',\n",
|
|
" entry.devicePixelContentBoxSize[0].blockSize\n",
|
|
" );\n",
|
|
" } else {\n",
|
|
" canvas.setAttribute('width', width * fig.ratio);\n",
|
|
" canvas.setAttribute('height', height * fig.ratio);\n",
|
|
" }\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.setAttribute('width', width);\n",
|
|
" rubberband_canvas.setAttribute('height', height);\n",
|
|
"\n",
|
|
" // And update the size in Python. We ignore the initial 0/0 size\n",
|
|
" // that occurs as the element is placed into the DOM, which should\n",
|
|
" // otherwise not happen due to the minimum size styling.\n",
|
|
" if (width != 0 && height != 0) {\n",
|
|
" fig.request_resize(width, height);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" });\n",
|
|
" resizeObserver.observe(canvas_div);\n",
|
|
"\n",
|
|
" function on_mouse_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.mouse_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousedown',\n",
|
|
" on_mouse_event_closure('button_press')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseup',\n",
|
|
" on_mouse_event_closure('button_release')\n",
|
|
" );\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousemove',\n",
|
|
" on_mouse_event_closure('motion_notify')\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseenter',\n",
|
|
" on_mouse_event_closure('figure_enter')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseleave',\n",
|
|
" on_mouse_event_closure('figure_leave')\n",
|
|
" );\n",
|
|
"\n",
|
|
" canvas_div.addEventListener('wheel', function (event) {\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" on_mouse_event_closure('scroll')(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.appendChild(canvas);\n",
|
|
" canvas_div.appendChild(rubberband_canvas);\n",
|
|
"\n",
|
|
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
|
|
" this.rubberband_context.strokeStyle = '#000000';\n",
|
|
"\n",
|
|
" this._resize_canvas = function (width, height, forward) {\n",
|
|
" if (forward) {\n",
|
|
" canvas_div.style.width = width + 'px';\n",
|
|
" canvas_div.style.height = height + 'px';\n",
|
|
" }\n",
|
|
" };\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus() {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'mpl-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var button = (fig.buttons[name] = document.createElement('button'));\n",
|
|
" button.classList = 'mpl-widget';\n",
|
|
" button.setAttribute('role', 'button');\n",
|
|
" button.setAttribute('aria-disabled', 'false');\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
"\n",
|
|
" var icon_img = document.createElement('img');\n",
|
|
" icon_img.src = '_images/' + image + '.png';\n",
|
|
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
|
|
" icon_img.alt = tooltip;\n",
|
|
" button.appendChild(icon_img);\n",
|
|
"\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker = document.createElement('select');\n",
|
|
" fmt_picker.classList = 'mpl-widget';\n",
|
|
" toolbar.appendChild(fmt_picker);\n",
|
|
" this.format_dropdown = fmt_picker;\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = document.createElement('option');\n",
|
|
" option.selected = fmt === mpl.default_extension;\n",
|
|
" option.innerHTML = fmt;\n",
|
|
" fmt_picker.appendChild(option);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function (type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function () {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1], msg['forward']);\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
|
|
" var x0 = msg['x0'] / fig.ratio;\n",
|
|
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
|
|
" var x1 = msg['x1'] / fig.ratio;\n",
|
|
" var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0,\n",
|
|
" 0,\n",
|
|
" fig.canvas.width / fig.ratio,\n",
|
|
" fig.canvas.height / fig.ratio\n",
|
|
" );\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch (cursor) {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function (fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
|
|
" for (var key in msg) {\n",
|
|
" if (!(key in fig.buttons)) {\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" fig.buttons[key].disabled = !msg[key];\n",
|
|
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
|
|
" if (msg['mode'] === 'PAN') {\n",
|
|
" fig.buttons['Pan'].classList.add('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" } else if (msg['mode'] === 'ZOOM') {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.add('active');\n",
|
|
" } else {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message('ack', {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function (fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = 'image/png';\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src\n",
|
|
" );\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data\n",
|
|
" );\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" } else if (\n",
|
|
" typeof evt.data === 'string' &&\n",
|
|
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
|
|
" ) {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig['handle_' + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
|
|
" e,\n",
|
|
" e.stack,\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"};\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function (e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e) {\n",
|
|
" e = window.event;\n",
|
|
" }\n",
|
|
" if (e.target) {\n",
|
|
" targ = e.target;\n",
|
|
" } else if (e.srcElement) {\n",
|
|
" targ = e.srcElement;\n",
|
|
" }\n",
|
|
" if (targ.nodeType === 3) {\n",
|
|
" // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" var boundingRect = targ.getBoundingClientRect();\n",
|
|
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
|
|
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
|
|
"\n",
|
|
" return { x: x, y: y };\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys(original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object') {\n",
|
|
" obj[key] = original[key];\n",
|
|
" }\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function (event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event);\n",
|
|
"\n",
|
|
" if (name === 'button_press') {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x * this.ratio;\n",
|
|
" var y = canvas_pos.y * this.ratio;\n",
|
|
"\n",
|
|
" this.send_message(name, {\n",
|
|
" x: x,\n",
|
|
" y: y,\n",
|
|
" button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event),\n",
|
|
" });\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function (event, name) {\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name === 'key_press') {\n",
|
|
" if (event.which === this._key) {\n",
|
|
" return;\n",
|
|
" } else {\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" }\n",
|
|
" if (name === 'key_release') {\n",
|
|
" this._key = null;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which !== 17) {\n",
|
|
" value += 'ctrl+';\n",
|
|
" }\n",
|
|
" if (event.altKey && event.which !== 18) {\n",
|
|
" value += 'alt+';\n",
|
|
" }\n",
|
|
" if (event.shiftKey && event.which !== 16) {\n",
|
|
" value += 'shift+';\n",
|
|
" }\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
|
|
" if (name === 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message('toolbar_button', { name: name });\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";/* global mpl */\n",
|
|
"\n",
|
|
"var comm_websocket_adapter = function (comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function () {\n",
|
|
" comm.close();\n",
|
|
" };\n",
|
|
" ws.send = function (m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function (msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data']);\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function (comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = document.getElementById(id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm);\n",
|
|
"\n",
|
|
" function ondownload(figure, _format) {\n",
|
|
" window.open(figure.canvas.toDataURL());\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element;\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error('Failed to find cell for figure', id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" fig.cell_info[0].output_area.element.one(\n",
|
|
" 'cleared',\n",
|
|
" { fig: fig },\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
|
|
" var width = fig.canvas.width / fig.ratio;\n",
|
|
" fig.cell_info[0].output_area.element.off(\n",
|
|
" 'cleared',\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable();\n",
|
|
" fig.parent_element.innerHTML =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function (fig, msg) {\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var width = this.canvas.width / this.ratio;\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message('ack', {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () {\n",
|
|
" fig.push_to_output();\n",
|
|
" }, 1000);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'btn-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" var button;\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" button = fig.buttons[name] = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-default';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = name;\n",
|
|
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message pull-right';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = document.createElement('div');\n",
|
|
" buttongrp.classList = 'btn-group inline pull-right';\n",
|
|
" button = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-mini btn-primary';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = 'Stop Interaction';\n",
|
|
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
|
|
" button.addEventListener('click', function (_evt) {\n",
|
|
" fig.handle_close(fig, {});\n",
|
|
" });\n",
|
|
" button.addEventListener(\n",
|
|
" 'mouseover',\n",
|
|
" on_mouseover_closure('Stop Interaction')\n",
|
|
" );\n",
|
|
" buttongrp.appendChild(button);\n",
|
|
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
|
|
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
|
|
" var fig = event.data.fig;\n",
|
|
" fig.close_ws(fig, {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (el) {\n",
|
|
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.setAttribute('tabindex', 0);\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" } else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager) {\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which === 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" // select the cell after this one\n",
|
|
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
|
" IPython.notebook.select(index + 1);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function (html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i = 0; i < ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code') {\n",
|
|
" for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] === html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel !== null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target(\n",
|
|
" 'matplotlib',\n",
|
|
" mpl.mpl_figure_comm\n",
|
|
" );\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"\n",
|
|
"Temps d'execution de fibor avec n=39 : 25.778192887666663\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def fibor(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" if n <= 0: return 0\n",
|
|
" elif n <= 1: return 1\n",
|
|
" else: return fibor(n-1) + fibor(n-2)\n",
|
|
"\n",
|
|
"# Mesure du temps et tracés\n",
|
|
"import time\n",
|
|
"%matplotlib notebook\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"n = [i for i in range(5, 40, 2)]\n",
|
|
"liste_temps = []\n",
|
|
"\n",
|
|
"for i in n:\n",
|
|
" print(f\"Test avec n={i}\", end = \" - \")\n",
|
|
" temps = 0.0\n",
|
|
" nb_loops = 3\n",
|
|
" for test in range(nb_loops):\n",
|
|
" start = time.process_time()\n",
|
|
" fibor(i)\n",
|
|
" temps += time.process_time() - start\n",
|
|
" temps /= nb_loops\n",
|
|
" liste_temps.append(temps)\n",
|
|
"\n",
|
|
"plt.plot(n, liste_temps, label=\"fibor\")\n",
|
|
"plt.xlabel(\"n\")\n",
|
|
"plt.grid(True)\n",
|
|
"print(f\"\\n\\nTemps d'execution de fibor avec n={n[-1]} : {liste_temps[-1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Comme prévu, le temps d'exécution est bien **exponentiel** en fonction du nombre n. Cet algorithme **récursif** est très **esthétique** dans son écriture mais c'est une **catastrophe en terme de performance** : 25 sec pour n = 39 seulement !\n",
|
|
"\n",
|
|
"- **Copier-coller** la définition de votre fonction `fibordyn` au début de la cellule suivante et exécutez la cellule pour analyser les performances."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Test avec n=10 - Test avec n=35 - Test avec n=60 - Test avec n=85 - Test avec n=110 - Test avec n=135 - Test avec n=160 - Test avec n=185 - Test avec n=210 - Test avec n=235 - Test avec n=260 - Test avec n=285 - Test avec n=310 - Test avec n=335 - Test avec n=360 - Test avec n=385 - Test avec n=410 - Test avec n=435 - Test avec n=460 - Test avec n=485 - Test avec n=510 - Test avec n=535 - Test avec n=560 - Test avec n=585 - Test avec n=610 - Test avec n=635 - Test avec n=660 - Test avec n=685 - Test avec n=710 - Test avec n=735 - Test avec n=760 - Test avec n=785 - Test avec n=810 - Test avec n=835 - Test avec n=860 - Test avec n=885 - Test avec n=910 - Test avec n=935 - Test avec n=960 - Test avec n=985 - Test avec n=1010 - Test avec n=1035 - Test avec n=1060 - Test avec n=1085 - Test avec n=1110 - Test avec n=1135 - Test avec n=1160 - Test avec n=1185 - Test avec n=1210 - Test avec n=1235 - Test avec n=1260 - Test avec n=1285 - Test avec n=1310 - Test avec n=1335 - Test avec n=1360 - Test avec n=1385 - Test avec n=1410 - Test avec n=1435 - Test avec n=1460 - Test avec n=1485 - Test avec n=1510 - Test avec n=1535 - Test avec n=1560 - Test avec n=1585 - Test avec n=1610 - Test avec n=1635 - Test avec n=1660 - Test avec n=1685 - Test avec n=1710 - Test avec n=1735 - Test avec n=1760 - Test avec n=1785 - Test avec n=1810 - Test avec n=1835 - Test avec n=1860 - Test avec n=1885 - Test avec n=1910 - Test avec n=1935 - Test avec n=1960 - Test avec n=1985 - Test avec n=2010 - Test avec n=2035 - Test avec n=2060 - Test avec n=2085 - Test avec n=2110 - Test avec n=2135 - Test avec n=2160 - Test avec n=2185 - Test avec n=2210 - Test avec n=2235 - Test avec n=2260 - Test avec n=2285 - Test avec n=2310 - Test avec n=2335 - Test avec n=2360 - Test avec n=2385 - Test avec n=2410 - Test avec n=2435 - Test avec n=2460 - Test avec n=2485 - Test avec n=2510 - Test avec n=2535 - Test avec n=2560 - Test avec n=2585 - Test avec n=2610 - Test avec n=2635 - Test avec n=2660 - Test avec n=2685 - Test avec n=2710 - Test avec n=2735 - Test avec n=2760 - Test avec n=2785 - Test avec n=2810 - Test avec n=2835 - Test avec n=2860 - Test avec n=2885 - Test avec n=2910 - Test avec n=2935 - Test avec n=2960 - "
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"/* global mpl */\n",
|
|
"window.mpl = {};\n",
|
|
"\n",
|
|
"mpl.get_websocket_type = function () {\n",
|
|
" if (typeof WebSocket !== 'undefined') {\n",
|
|
" return WebSocket;\n",
|
|
" } else if (typeof MozWebSocket !== 'undefined') {\n",
|
|
" return MozWebSocket;\n",
|
|
" } else {\n",
|
|
" alert(\n",
|
|
" 'Your browser does not have WebSocket support. ' +\n",
|
|
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
|
|
" 'Firefox 4 and 5 are also supported but you ' +\n",
|
|
" 'have to enable WebSockets in about:config.'\n",
|
|
" );\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n",
|
|
" this.id = figure_id;\n",
|
|
"\n",
|
|
" this.ws = websocket;\n",
|
|
"\n",
|
|
" this.supports_binary = this.ws.binaryType !== undefined;\n",
|
|
"\n",
|
|
" if (!this.supports_binary) {\n",
|
|
" var warnings = document.getElementById('mpl-warnings');\n",
|
|
" if (warnings) {\n",
|
|
" warnings.style.display = 'block';\n",
|
|
" warnings.textContent =\n",
|
|
" 'This browser does not support binary websocket messages. ' +\n",
|
|
" 'Performance may be slow.';\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj = new Image();\n",
|
|
"\n",
|
|
" this.context = undefined;\n",
|
|
" this.message = undefined;\n",
|
|
" this.canvas = undefined;\n",
|
|
" this.rubberband_canvas = undefined;\n",
|
|
" this.rubberband_context = undefined;\n",
|
|
" this.format_dropdown = undefined;\n",
|
|
"\n",
|
|
" this.image_mode = 'full';\n",
|
|
"\n",
|
|
" this.root = document.createElement('div');\n",
|
|
" this.root.setAttribute('style', 'display: inline-block');\n",
|
|
" this._root_extra_style(this.root);\n",
|
|
"\n",
|
|
" parent_element.appendChild(this.root);\n",
|
|
"\n",
|
|
" this._init_header(this);\n",
|
|
" this._init_canvas(this);\n",
|
|
" this._init_toolbar(this);\n",
|
|
"\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" this.waiting = false;\n",
|
|
"\n",
|
|
" this.ws.onopen = function () {\n",
|
|
" fig.send_message('supports_binary', { value: fig.supports_binary });\n",
|
|
" fig.send_message('send_image_mode', {});\n",
|
|
" if (fig.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n",
|
|
" }\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onload = function () {\n",
|
|
" if (fig.image_mode === 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function () {\n",
|
|
" fig.ws.close();\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function () {\n",
|
|
" var titlebar = document.createElement('div');\n",
|
|
" titlebar.classList =\n",
|
|
" 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n",
|
|
" var titletext = document.createElement('div');\n",
|
|
" titletext.classList = 'ui-dialog-title';\n",
|
|
" titletext.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: 100%; text-align: center; padding: 3px;'\n",
|
|
" );\n",
|
|
" titlebar.appendChild(titletext);\n",
|
|
" this.root.appendChild(titlebar);\n",
|
|
" this.header = titletext;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = (this.canvas_div = document.createElement('div'));\n",
|
|
" canvas_div.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'border: 1px solid #ddd;' +\n",
|
|
" 'box-sizing: content-box;' +\n",
|
|
" 'clear: both;' +\n",
|
|
" 'min-height: 1px;' +\n",
|
|
" 'min-width: 1px;' +\n",
|
|
" 'outline: 0;' +\n",
|
|
" 'overflow: hidden;' +\n",
|
|
" 'position: relative;' +\n",
|
|
" 'resize: both;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" function on_keyboard_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.key_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keydown',\n",
|
|
" on_keyboard_event_closure('key_press')\n",
|
|
" );\n",
|
|
" canvas_div.addEventListener(\n",
|
|
" 'keyup',\n",
|
|
" on_keyboard_event_closure('key_release')\n",
|
|
" );\n",
|
|
"\n",
|
|
" this._canvas_extra_style(canvas_div);\n",
|
|
" this.root.appendChild(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = (this.canvas = document.createElement('canvas'));\n",
|
|
" canvas.classList.add('mpl-canvas');\n",
|
|
" canvas.setAttribute('style', 'box-sizing: content-box;');\n",
|
|
"\n",
|
|
" this.context = canvas.getContext('2d');\n",
|
|
"\n",
|
|
" var backingStore =\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" this.context.webkitBackingStorePixelRatio ||\n",
|
|
" this.context.mozBackingStorePixelRatio ||\n",
|
|
" this.context.msBackingStorePixelRatio ||\n",
|
|
" this.context.oBackingStorePixelRatio ||\n",
|
|
" this.context.backingStorePixelRatio ||\n",
|
|
" 1;\n",
|
|
"\n",
|
|
" this.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
|
|
" if (this.ratio !== 1) {\n",
|
|
" fig.send_message('set_dpi_ratio', { dpi_ratio: this.ratio });\n",
|
|
" }\n",
|
|
"\n",
|
|
" var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n",
|
|
" 'canvas'\n",
|
|
" ));\n",
|
|
" rubberband_canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" var resizeObserver = new ResizeObserver(function (entries) {\n",
|
|
" var nentries = entries.length;\n",
|
|
" for (var i = 0; i < nentries; i++) {\n",
|
|
" var entry = entries[i];\n",
|
|
" var width, height;\n",
|
|
" if (entry.contentBoxSize) {\n",
|
|
" if (entry.contentBoxSize instanceof Array) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" width = entry.contentBoxSize[0].inlineSize;\n",
|
|
" height = entry.contentBoxSize[0].blockSize;\n",
|
|
" } else {\n",
|
|
" // Firefox implements old version of spec.\n",
|
|
" width = entry.contentBoxSize.inlineSize;\n",
|
|
" height = entry.contentBoxSize.blockSize;\n",
|
|
" }\n",
|
|
" } else {\n",
|
|
" // Chrome <84 implements even older version of spec.\n",
|
|
" width = entry.contentRect.width;\n",
|
|
" height = entry.contentRect.height;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Keep the size of the canvas and rubber band canvas in sync with\n",
|
|
" // the canvas container.\n",
|
|
" if (entry.devicePixelContentBoxSize) {\n",
|
|
" // Chrome 84 implements new version of spec.\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'width',\n",
|
|
" entry.devicePixelContentBoxSize[0].inlineSize\n",
|
|
" );\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'height',\n",
|
|
" entry.devicePixelContentBoxSize[0].blockSize\n",
|
|
" );\n",
|
|
" } else {\n",
|
|
" canvas.setAttribute('width', width * fig.ratio);\n",
|
|
" canvas.setAttribute('height', height * fig.ratio);\n",
|
|
" }\n",
|
|
" canvas.setAttribute(\n",
|
|
" 'style',\n",
|
|
" 'width: ' + width + 'px; height: ' + height + 'px;'\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.setAttribute('width', width);\n",
|
|
" rubberband_canvas.setAttribute('height', height);\n",
|
|
"\n",
|
|
" // And update the size in Python. We ignore the initial 0/0 size\n",
|
|
" // that occurs as the element is placed into the DOM, which should\n",
|
|
" // otherwise not happen due to the minimum size styling.\n",
|
|
" if (width != 0 && height != 0) {\n",
|
|
" fig.request_resize(width, height);\n",
|
|
" }\n",
|
|
" }\n",
|
|
" });\n",
|
|
" resizeObserver.observe(canvas_div);\n",
|
|
"\n",
|
|
" function on_mouse_event_closure(name) {\n",
|
|
" return function (event) {\n",
|
|
" return fig.mouse_event(event, name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousedown',\n",
|
|
" on_mouse_event_closure('button_press')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseup',\n",
|
|
" on_mouse_event_closure('button_release')\n",
|
|
" );\n",
|
|
" // Throttle sequential mouse events to 1 every 20ms.\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mousemove',\n",
|
|
" on_mouse_event_closure('motion_notify')\n",
|
|
" );\n",
|
|
"\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseenter',\n",
|
|
" on_mouse_event_closure('figure_enter')\n",
|
|
" );\n",
|
|
" rubberband_canvas.addEventListener(\n",
|
|
" 'mouseleave',\n",
|
|
" on_mouse_event_closure('figure_leave')\n",
|
|
" );\n",
|
|
"\n",
|
|
" canvas_div.addEventListener('wheel', function (event) {\n",
|
|
" if (event.deltaY < 0) {\n",
|
|
" event.step = 1;\n",
|
|
" } else {\n",
|
|
" event.step = -1;\n",
|
|
" }\n",
|
|
" on_mouse_event_closure('scroll')(event);\n",
|
|
" });\n",
|
|
"\n",
|
|
" canvas_div.appendChild(canvas);\n",
|
|
" canvas_div.appendChild(rubberband_canvas);\n",
|
|
"\n",
|
|
" this.rubberband_context = rubberband_canvas.getContext('2d');\n",
|
|
" this.rubberband_context.strokeStyle = '#000000';\n",
|
|
"\n",
|
|
" this._resize_canvas = function (width, height, forward) {\n",
|
|
" if (forward) {\n",
|
|
" canvas_div.style.width = width + 'px';\n",
|
|
" canvas_div.style.height = height + 'px';\n",
|
|
" }\n",
|
|
" };\n",
|
|
"\n",
|
|
" // Disable right mouse context menu.\n",
|
|
" this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
" });\n",
|
|
"\n",
|
|
" function set_focus() {\n",
|
|
" canvas.focus();\n",
|
|
" canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" window.setTimeout(set_focus, 100);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'mpl-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'mpl-button-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var button = (fig.buttons[name] = document.createElement('button'));\n",
|
|
" button.classList = 'mpl-widget';\n",
|
|
" button.setAttribute('role', 'button');\n",
|
|
" button.setAttribute('aria-disabled', 'false');\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
"\n",
|
|
" var icon_img = document.createElement('img');\n",
|
|
" icon_img.src = '_images/' + image + '.png';\n",
|
|
" icon_img.srcset = '_images/' + image + '_large.png 2x';\n",
|
|
" icon_img.alt = tooltip;\n",
|
|
" button.appendChild(icon_img);\n",
|
|
"\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fmt_picker = document.createElement('select');\n",
|
|
" fmt_picker.classList = 'mpl-widget';\n",
|
|
" toolbar.appendChild(fmt_picker);\n",
|
|
" this.format_dropdown = fmt_picker;\n",
|
|
"\n",
|
|
" for (var ind in mpl.extensions) {\n",
|
|
" var fmt = mpl.extensions[ind];\n",
|
|
" var option = document.createElement('option');\n",
|
|
" option.selected = fmt === mpl.default_extension;\n",
|
|
" option.innerHTML = fmt;\n",
|
|
" fmt_picker.appendChild(option);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n",
|
|
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
|
|
" // which will in turn request a refresh of the image.\n",
|
|
" this.send_message('resize', { width: x_pixels, height: y_pixels });\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_message = function (type, properties) {\n",
|
|
" properties['type'] = type;\n",
|
|
" properties['figure_id'] = this.id;\n",
|
|
" this.ws.send(JSON.stringify(properties));\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.send_draw_message = function () {\n",
|
|
" if (!this.waiting) {\n",
|
|
" this.waiting = true;\n",
|
|
" this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" var format_dropdown = fig.format_dropdown;\n",
|
|
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
|
|
" fig.ondownload(fig, format);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_resize = function (fig, msg) {\n",
|
|
" var size = msg['size'];\n",
|
|
" if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n",
|
|
" fig._resize_canvas(size[0], size[1], msg['forward']);\n",
|
|
" fig.send_message('refresh', {});\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n",
|
|
" var x0 = msg['x0'] / fig.ratio;\n",
|
|
" var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n",
|
|
" var x1 = msg['x1'] / fig.ratio;\n",
|
|
" var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n",
|
|
" x0 = Math.floor(x0) + 0.5;\n",
|
|
" y0 = Math.floor(y0) + 0.5;\n",
|
|
" x1 = Math.floor(x1) + 0.5;\n",
|
|
" y1 = Math.floor(y1) + 0.5;\n",
|
|
" var min_x = Math.min(x0, x1);\n",
|
|
" var min_y = Math.min(y0, y1);\n",
|
|
" var width = Math.abs(x1 - x0);\n",
|
|
" var height = Math.abs(y1 - y0);\n",
|
|
"\n",
|
|
" fig.rubberband_context.clearRect(\n",
|
|
" 0,\n",
|
|
" 0,\n",
|
|
" fig.canvas.width / fig.ratio,\n",
|
|
" fig.canvas.height / fig.ratio\n",
|
|
" );\n",
|
|
"\n",
|
|
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n",
|
|
" // Updates the figure title.\n",
|
|
" fig.header.textContent = msg['label'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_cursor = function (fig, msg) {\n",
|
|
" var cursor = msg['cursor'];\n",
|
|
" switch (cursor) {\n",
|
|
" case 0:\n",
|
|
" cursor = 'pointer';\n",
|
|
" break;\n",
|
|
" case 1:\n",
|
|
" cursor = 'default';\n",
|
|
" break;\n",
|
|
" case 2:\n",
|
|
" cursor = 'crosshair';\n",
|
|
" break;\n",
|
|
" case 3:\n",
|
|
" cursor = 'move';\n",
|
|
" break;\n",
|
|
" }\n",
|
|
" fig.rubberband_canvas.style.cursor = cursor;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_message = function (fig, msg) {\n",
|
|
" fig.message.textContent = msg['message'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_draw = function (fig, _msg) {\n",
|
|
" // Request the server to send over a new figure.\n",
|
|
" fig.send_draw_message();\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n",
|
|
" fig.image_mode = msg['mode'];\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n",
|
|
" for (var key in msg) {\n",
|
|
" if (!(key in fig.buttons)) {\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
" fig.buttons[key].disabled = !msg[key];\n",
|
|
" fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n",
|
|
" if (msg['mode'] === 'PAN') {\n",
|
|
" fig.buttons['Pan'].classList.add('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" } else if (msg['mode'] === 'ZOOM') {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.add('active');\n",
|
|
" } else {\n",
|
|
" fig.buttons['Pan'].classList.remove('active');\n",
|
|
" fig.buttons['Zoom'].classList.remove('active');\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Called whenever the canvas gets updated.\n",
|
|
" this.send_message('ack', {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"// A function to construct a web socket function for onmessage handling.\n",
|
|
"// Called in the figure constructor.\n",
|
|
"mpl.figure.prototype._make_on_message_function = function (fig) {\n",
|
|
" return function socket_on_message(evt) {\n",
|
|
" if (evt.data instanceof Blob) {\n",
|
|
" /* FIXME: We get \"Resource interpreted as Image but\n",
|
|
" * transferred with MIME type text/plain:\" errors on\n",
|
|
" * Chrome. But how to set the MIME type? It doesn't seem\n",
|
|
" * to be part of the websocket stream */\n",
|
|
" evt.data.type = 'image/png';\n",
|
|
"\n",
|
|
" /* Free the memory for the previous frames */\n",
|
|
" if (fig.imageObj.src) {\n",
|
|
" (window.URL || window.webkitURL).revokeObjectURL(\n",
|
|
" fig.imageObj.src\n",
|
|
" );\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
|
|
" evt.data\n",
|
|
" );\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" } else if (\n",
|
|
" typeof evt.data === 'string' &&\n",
|
|
" evt.data.slice(0, 21) === 'data:image/png;base64'\n",
|
|
" ) {\n",
|
|
" fig.imageObj.src = evt.data;\n",
|
|
" fig.updated_canvas_event();\n",
|
|
" fig.waiting = false;\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var msg = JSON.parse(evt.data);\n",
|
|
" var msg_type = msg['type'];\n",
|
|
"\n",
|
|
" // Call the \"handle_{type}\" callback, which takes\n",
|
|
" // the figure and JSON message as its only arguments.\n",
|
|
" try {\n",
|
|
" var callback = fig['handle_' + msg_type];\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"No handler for the '\" + msg_type + \"' message type: \",\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (callback) {\n",
|
|
" try {\n",
|
|
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
|
|
" callback(fig, msg);\n",
|
|
" } catch (e) {\n",
|
|
" console.log(\n",
|
|
" \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n",
|
|
" e,\n",
|
|
" e.stack,\n",
|
|
" msg\n",
|
|
" );\n",
|
|
" }\n",
|
|
" }\n",
|
|
" };\n",
|
|
"};\n",
|
|
"\n",
|
|
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
|
|
"mpl.findpos = function (e) {\n",
|
|
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
|
|
" var targ;\n",
|
|
" if (!e) {\n",
|
|
" e = window.event;\n",
|
|
" }\n",
|
|
" if (e.target) {\n",
|
|
" targ = e.target;\n",
|
|
" } else if (e.srcElement) {\n",
|
|
" targ = e.srcElement;\n",
|
|
" }\n",
|
|
" if (targ.nodeType === 3) {\n",
|
|
" // defeat Safari bug\n",
|
|
" targ = targ.parentNode;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // pageX,Y are the mouse positions relative to the document\n",
|
|
" var boundingRect = targ.getBoundingClientRect();\n",
|
|
" var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n",
|
|
" var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n",
|
|
"\n",
|
|
" return { x: x, y: y };\n",
|
|
"};\n",
|
|
"\n",
|
|
"/*\n",
|
|
" * return a copy of an object with only non-object keys\n",
|
|
" * we need this to avoid circular references\n",
|
|
" * http://stackoverflow.com/a/24161582/3208463\n",
|
|
" */\n",
|
|
"function simpleKeys(original) {\n",
|
|
" return Object.keys(original).reduce(function (obj, key) {\n",
|
|
" if (typeof original[key] !== 'object') {\n",
|
|
" obj[key] = original[key];\n",
|
|
" }\n",
|
|
" return obj;\n",
|
|
" }, {});\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype.mouse_event = function (event, name) {\n",
|
|
" var canvas_pos = mpl.findpos(event);\n",
|
|
"\n",
|
|
" if (name === 'button_press') {\n",
|
|
" this.canvas.focus();\n",
|
|
" this.canvas_div.focus();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var x = canvas_pos.x * this.ratio;\n",
|
|
" var y = canvas_pos.y * this.ratio;\n",
|
|
"\n",
|
|
" this.send_message(name, {\n",
|
|
" x: x,\n",
|
|
" y: y,\n",
|
|
" button: event.button,\n",
|
|
" step: event.step,\n",
|
|
" guiEvent: simpleKeys(event),\n",
|
|
" });\n",
|
|
"\n",
|
|
" /* This prevents the web browser from automatically changing to\n",
|
|
" * the text insertion cursor when the button is pressed. We want\n",
|
|
" * to control all of the cursor setting manually through the\n",
|
|
" * 'cursor' event from matplotlib */\n",
|
|
" event.preventDefault();\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (_event, _name) {\n",
|
|
" // Handle any extra behaviour associated with a key event\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.key_event = function (event, name) {\n",
|
|
" // Prevent repeat events\n",
|
|
" if (name === 'key_press') {\n",
|
|
" if (event.which === this._key) {\n",
|
|
" return;\n",
|
|
" } else {\n",
|
|
" this._key = event.which;\n",
|
|
" }\n",
|
|
" }\n",
|
|
" if (name === 'key_release') {\n",
|
|
" this._key = null;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var value = '';\n",
|
|
" if (event.ctrlKey && event.which !== 17) {\n",
|
|
" value += 'ctrl+';\n",
|
|
" }\n",
|
|
" if (event.altKey && event.which !== 18) {\n",
|
|
" value += 'alt+';\n",
|
|
" }\n",
|
|
" if (event.shiftKey && event.which !== 16) {\n",
|
|
" value += 'shift+';\n",
|
|
" }\n",
|
|
"\n",
|
|
" value += 'k';\n",
|
|
" value += event.which.toString();\n",
|
|
"\n",
|
|
" this._key_event_extra(event, name);\n",
|
|
"\n",
|
|
" this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n",
|
|
" return false;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onclick = function (name) {\n",
|
|
" if (name === 'download') {\n",
|
|
" this.handle_save(this, null);\n",
|
|
" } else {\n",
|
|
" this.send_message('toolbar_button', { name: name });\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n",
|
|
" this.message.textContent = tooltip;\n",
|
|
"};\n",
|
|
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
|
|
"\n",
|
|
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";/* global mpl */\n",
|
|
"\n",
|
|
"var comm_websocket_adapter = function (comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function () {\n",
|
|
" comm.close();\n",
|
|
" };\n",
|
|
" ws.send = function (m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function (msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data']);\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function (comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = document.getElementById(id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm);\n",
|
|
"\n",
|
|
" function ondownload(figure, _format) {\n",
|
|
" window.open(figure.canvas.toDataURL());\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element;\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error('Failed to find cell for figure', id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
" fig.cell_info[0].output_area.element.one(\n",
|
|
" 'cleared',\n",
|
|
" { fig: fig },\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function (fig, msg) {\n",
|
|
" var width = fig.canvas.width / fig.ratio;\n",
|
|
" fig.cell_info[0].output_area.element.off(\n",
|
|
" 'cleared',\n",
|
|
" fig._remove_fig_handler\n",
|
|
" );\n",
|
|
"\n",
|
|
" // Update the output cell to use the data from the current canvas.\n",
|
|
" fig.push_to_output();\n",
|
|
" var dataURL = fig.canvas.toDataURL();\n",
|
|
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
|
|
" // the notebook keyboard shortcuts fail.\n",
|
|
" IPython.keyboard_manager.enable();\n",
|
|
" fig.parent_element.innerHTML =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
" fig.close_ws(fig, msg);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.close_ws = function (fig, msg) {\n",
|
|
" fig.send_message('closing', msg);\n",
|
|
" // fig.ws.close()\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n",
|
|
" // Turn the data on the canvas into data in the output cell.\n",
|
|
" var width = this.canvas.width / this.ratio;\n",
|
|
" var dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] =\n",
|
|
" '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.updated_canvas_event = function () {\n",
|
|
" // Tell IPython that the notebook contents must change.\n",
|
|
" IPython.notebook.set_dirty(true);\n",
|
|
" this.send_message('ack', {});\n",
|
|
" var fig = this;\n",
|
|
" // Wait a second, then push the new image to the DOM so\n",
|
|
" // that it is saved nicely (might be nice to debounce this).\n",
|
|
" setTimeout(function () {\n",
|
|
" fig.push_to_output();\n",
|
|
" }, 1000);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_toolbar = function () {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var toolbar = document.createElement('div');\n",
|
|
" toolbar.classList = 'btn-toolbar';\n",
|
|
" this.root.appendChild(toolbar);\n",
|
|
"\n",
|
|
" function on_click_closure(name) {\n",
|
|
" return function (_event) {\n",
|
|
" return fig.toolbar_button_onclick(name);\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_mouseover_closure(tooltip) {\n",
|
|
" return function (event) {\n",
|
|
" if (!event.currentTarget.disabled) {\n",
|
|
" return fig.toolbar_button_onmouseover(tooltip);\n",
|
|
" }\n",
|
|
" };\n",
|
|
" }\n",
|
|
"\n",
|
|
" fig.buttons = {};\n",
|
|
" var buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" var button;\n",
|
|
" for (var toolbar_ind in mpl.toolbar_items) {\n",
|
|
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
|
|
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
|
|
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
|
|
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
|
|
"\n",
|
|
" if (!name) {\n",
|
|
" /* Instead of a spacer, we start a new button group. */\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
" buttonGroup = document.createElement('div');\n",
|
|
" buttonGroup.classList = 'btn-group';\n",
|
|
" continue;\n",
|
|
" }\n",
|
|
"\n",
|
|
" button = fig.buttons[name] = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-default';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = name;\n",
|
|
" button.innerHTML = '<i class=\"fa ' + image + ' fa-lg\"></i>';\n",
|
|
" button.addEventListener('click', on_click_closure(method_name));\n",
|
|
" button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n",
|
|
" buttonGroup.appendChild(button);\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (buttonGroup.hasChildNodes()) {\n",
|
|
" toolbar.appendChild(buttonGroup);\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Add the status bar.\n",
|
|
" var status_bar = document.createElement('span');\n",
|
|
" status_bar.classList = 'mpl-message pull-right';\n",
|
|
" toolbar.appendChild(status_bar);\n",
|
|
" this.message = status_bar;\n",
|
|
"\n",
|
|
" // Add the close button to the window.\n",
|
|
" var buttongrp = document.createElement('div');\n",
|
|
" buttongrp.classList = 'btn-group inline pull-right';\n",
|
|
" button = document.createElement('button');\n",
|
|
" button.classList = 'btn btn-mini btn-primary';\n",
|
|
" button.href = '#';\n",
|
|
" button.title = 'Stop Interaction';\n",
|
|
" button.innerHTML = '<i class=\"fa fa-power-off icon-remove icon-large\"></i>';\n",
|
|
" button.addEventListener('click', function (_evt) {\n",
|
|
" fig.handle_close(fig, {});\n",
|
|
" });\n",
|
|
" button.addEventListener(\n",
|
|
" 'mouseover',\n",
|
|
" on_mouseover_closure('Stop Interaction')\n",
|
|
" );\n",
|
|
" buttongrp.appendChild(button);\n",
|
|
" var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n",
|
|
" titlebar.insertBefore(buttongrp, titlebar.firstChild);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._remove_fig_handler = function (event) {\n",
|
|
" var fig = event.data.fig;\n",
|
|
" fig.close_ws(fig, {});\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function (el) {\n",
|
|
" el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function (el) {\n",
|
|
" // this is important to make the div 'focusable\n",
|
|
" el.setAttribute('tabindex', 0);\n",
|
|
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
|
|
" // off when our div gets focus\n",
|
|
"\n",
|
|
" // location in version 3\n",
|
|
" if (IPython.notebook.keyboard_manager) {\n",
|
|
" IPython.notebook.keyboard_manager.register_events(el);\n",
|
|
" } else {\n",
|
|
" // location in version 2\n",
|
|
" IPython.keyboard_manager.register_events(el);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype._key_event_extra = function (event, _name) {\n",
|
|
" var manager = IPython.notebook.keyboard_manager;\n",
|
|
" if (!manager) {\n",
|
|
" manager = IPython.keyboard_manager;\n",
|
|
" }\n",
|
|
"\n",
|
|
" // Check for shift+enter\n",
|
|
" if (event.shiftKey && event.which === 13) {\n",
|
|
" this.canvas_div.blur();\n",
|
|
" // select the cell after this one\n",
|
|
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
|
|
" IPython.notebook.select(index + 1);\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_save = function (fig, _msg) {\n",
|
|
" fig.ondownload(fig, null);\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.find_output_cell = function (html_output) {\n",
|
|
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
|
|
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
|
|
" // IPython event is triggered only after the cells have been serialised, which for\n",
|
|
" // our purposes (turning an active figure into a static one), is too late.\n",
|
|
" var cells = IPython.notebook.get_cells();\n",
|
|
" var ncells = cells.length;\n",
|
|
" for (var i = 0; i < ncells; i++) {\n",
|
|
" var cell = cells[i];\n",
|
|
" if (cell.cell_type === 'code') {\n",
|
|
" for (var j = 0; j < cell.output_area.outputs.length; j++) {\n",
|
|
" var data = cell.output_area.outputs[j];\n",
|
|
" if (data.data) {\n",
|
|
" // IPython >= 3 moved mimebundle to data attribute of output\n",
|
|
" data = data.data;\n",
|
|
" }\n",
|
|
" if (data['text/html'] === html_output) {\n",
|
|
" return [cell, data, j];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
"};\n",
|
|
"\n",
|
|
"// Register the function which deals with the matplotlib target/channel.\n",
|
|
"// The kernel may be null if the page has been refreshed.\n",
|
|
"if (IPython.notebook.kernel !== null) {\n",
|
|
" IPython.notebook.kernel.comm_manager.register_target(\n",
|
|
" 'matplotlib',\n",
|
|
" mpl.mpl_figure_comm\n",
|
|
" );\n",
|
|
"}\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Javascript object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<img src=\"data:image/png;base64,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\" width=\"640\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"\n",
|
|
"Temps d'execution de fibor avec n=2960 : 0.001542809620000014\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def fibordyn(n: int) -> int:\n",
|
|
" \"\"\" Lanceur de la fonction fibor (n>=0) : initialisation du tableau de résultats \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
" resultats = [None for i in range(n+2)]\n",
|
|
" resultats[0] = 0\n",
|
|
" resultats[1] = 1\n",
|
|
" \n",
|
|
" # === Nested function ===\n",
|
|
" def fibor(n: int) -> int:\n",
|
|
" \"\"\" Calcule les termes de la suite de Fibonacci récursivement avec programmation dynamique (n>=0) \"\"\"\n",
|
|
" assert isinstance(n, int) and n >= 0, \"n must be integer and positive\"\n",
|
|
"\n",
|
|
" if resultats[n] != None: return resultats[n]\n",
|
|
" if resultats[n-1] == None: resultats[n-1] = fibor(n-1)\n",
|
|
" if resultats[n-2] == None: resultats[n-2] = fibor(n-2)\n",
|
|
" return resultats[n-1] + resultats[n-2]\n",
|
|
" # === End of nested function ===\n",
|
|
" \n",
|
|
" return fibor(n)\n",
|
|
"\n",
|
|
"# Mesure du temps et tracés\n",
|
|
"import time\n",
|
|
"%matplotlib notebook\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"n = [i for i in range(10, 2985, 25)]\n",
|
|
"liste_temps = []\n",
|
|
"\n",
|
|
"for i in n:\n",
|
|
" print(f\"Test avec n={i}\", end = \" - \")\n",
|
|
" temps = 0.0\n",
|
|
" nb_loops = 100\n",
|
|
" for test in range(nb_loops):\n",
|
|
" start = time.process_time()\n",
|
|
" fibordyn(i)\n",
|
|
" temps += time.process_time() - start\n",
|
|
" temps /= nb_loops\n",
|
|
" liste_temps.append(temps)\n",
|
|
"\n",
|
|
"plt.plot(n, liste_temps, label=\"fibor\")\n",
|
|
"plt.xlabel(\"n\")\n",
|
|
"plt.grid(True)\n",
|
|
"print(f\"\\n\\nTemps d'execution de fibor avec n={n[-1]} : {liste_temps[-1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Ici le temps d'exécution est bien **linéaire** en fonction de n.\n",
|
|
"\n",
|
|
"⚠️ Mais il y a **trop d'appels de fonctions** imbriqués et Python ne peut pas calculer au delà de n=2900.\n",
|
|
"\n",
|
|
"Malgré tout, les performances sont bien en dessous de nos premiers algorithmes car ici il faut environ 1 ms pour calculer le terme avec n=2960 alors qu'il en fallait à peine 0.25 ms avec les premiers.\n",
|
|
"\n",
|
|
"# Conclusion\n",
|
|
"\n",
|
|
"⚠️ La **récursivité** permet de résoudre **facilement** des **problèmes complexes** mais elle s'accompagne souvent de **problèmes de performances**.\n",
|
|
"\n",
|
|
"⚠️ La **programmation dynamique** permet de gagner du temps dans les algorithmes car elle consiste à **enregistrer les résultats intermédiaires calculés** afin de les **ré-utiliser plus tard** dans l'algorithme.\n",
|
|
"\n",
|
|
"Cette technique est souvent utilisée dans les problèmes **d'optimisation** car dans ce domaine, les calculs utilisent souvent **plusieurs fois les mêmes valeurs**."
|
|
]
|
|
}
|
|
],
|
|
"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"
|
|
},
|
|
"widgets": {
|
|
"application/vnd.jupyter.widget-state+json": {
|
|
"state": {},
|
|
"version_major": 2,
|
|
"version_minor": 0
|
|
}
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|