retrait des anciens fichiers TP récursivité
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
def recherche_dichotomique(t, v):
|
||||
debut = 0
|
||||
fin = len(t)-1
|
||||
while debut <= fin :
|
||||
milieu = (debut + fin) // 2
|
||||
print(milieu,debut,fin)
|
||||
if t[milieu] == v :
|
||||
return True
|
||||
else:
|
||||
if t[milieu] > v :
|
||||
fin = milieu - 1
|
||||
else :
|
||||
debut = milieu + 1
|
||||
return False
|
||||
|
||||
def recherche_recur(t,v):
|
||||
if len(t) == 1:
|
||||
return t[0] == v
|
||||
else :
|
||||
milieu = len(t)//2
|
||||
if t[milieu] > v :
|
||||
return recherche_recur(t[:milieu],v)
|
||||
else :
|
||||
return recherche_recur(t[milieu:],v)
|
||||
@@ -1,29 +0,0 @@
|
||||
## Activité : La récursivité dans les jeux vidéo
|
||||
|
||||
### Contexte :
|
||||
Imaginez un jeu vidéo populaire où le héros doit traverser différents niveaux pour sauver un personnage captif. Chaque niveau est plus difficile que le précédent, et chaque niveau contient des mini-boss qu'il faut vaincre avant de passer au suivant.
|
||||
|
||||
### Objectif de l'activité :
|
||||
Utiliser la récursivité pour simuler le parcours du héros à travers les niveaux du jeu.
|
||||
|
||||
### Instructions :
|
||||
|
||||
### Présentation du problème :
|
||||
- Le héros commence au niveau 1 et doit atteindre le niveau `n`.
|
||||
- À chaque niveau, il y a un certain nombre de mini-boss à vaincre avant de passer au niveau suivant.
|
||||
- Si le héros vainc tous les mini-boss d'un niveau, il passe au niveau suivant, sinon il recommence le même niveau.
|
||||
|
||||
### Modélisation en pseudo-code :
|
||||
Écrire une fonction récursive `traverse_levels` qui prend en entrée le niveau actuel et le nombre total de niveaux.
|
||||
|
||||
- Si le niveau actuel est supérieur au nombre total de niveaux, le héros a gagné.
|
||||
- Sinon, le héros combat les mini-boss et passe au niveau suivant.
|
||||
|
||||
### 3. Exemple de code en Python
|
||||
```python
|
||||
def combat_mini_bosses(level):
|
||||
pass
|
||||
|
||||
def traverse_levels(current_level, total_levels):
|
||||
pass
|
||||
```
|
||||
@@ -1,69 +0,0 @@
|
||||
# TP Récursivité :
|
||||
|
||||
------
|
||||
|
||||
## 1. Courbe de Koch :
|
||||
|
||||
> Prérequis : Module turtle
|
||||
|
||||
La courbe de koch est une figure récursive pouvant ressembler à cela :
|
||||
|
||||
> Inserer un exemple
|
||||
|
||||
Celle-ci possède un cas de base d'ordre 0, il est représenté par un segment. Le cas d'ordre 1 est ce même segment découpé en 3, la partie du milieu est quand à elle un triangle équilatéral sans sa base (ou un chapeau ^).
|
||||
|
||||
> Insérer les image ordre 0 et 1
|
||||
|
||||
Le cas d'ordre 2 reprend le cas d'ordre 1 est pour chaque segment, le redécoupe et dessine ce "triangle".
|
||||
|
||||
Le cas d'ordre n reprend le cas d'ordre n-1 puis refait la même chose... Ainsi de suite
|
||||
|
||||
1. Ecrire de manière récursive le code de la fonction courbe_koch(n, cote) permettant de dessiner cette courbe.
|
||||
|
||||
Nous voulons obtenir maintenant un flocon de koch. Celui-ci répète plusieurs fois la courbe de koch afin de revenir à son point initial.
|
||||
|
||||
2. Ecrire le code de la fonction flocon() qui dessine le flocon de la courbe de koch
|
||||
|
||||
> inserer flocon courbe koch
|
||||
|
||||
## 2. Triangle de Pascal :
|
||||
|
||||
Le triangle de pascal représente les coefficients binomiaux sous la forme d'un triangle :
|
||||
|
||||
coef(n,p) : *fonction permettant de calculer les coefficients*
|
||||
|
||||
coef(n,p) :
|
||||
|
||||
- 1 **si p = 0 ou n == p**
|
||||
- coef(n-1,p-1) + coef(n-1,p) **sinon**
|
||||
|
||||
1. Ecrire le code de la fonction coef(n,p)
|
||||
|
||||
Le sommet du triangle est le résultat de coef(0,0), la première ligne elle est représenté par coef(1,0) et coef(1,1), ainsi de suite pour les autres lignes
|
||||
|
||||
2. A l'aide de deux boucles écrire un code permettant d'afficher les 6 premières lignes du triangle.
|
||||
|
||||
## 3. Recherche dichotomique :
|
||||
|
||||
La recherche dichotomique fonctionne sur un tableau trié, et permet en fonction de la longueur du tableau n de trouver un élément de façon optimale.
|
||||
|
||||
Voici le code de la recherche dichotomique (programme 1ère) de manière itérative :
|
||||
|
||||
```python
|
||||
def recherche_dichotomique(t, v):
|
||||
debut = 0
|
||||
fin = len(t)-1
|
||||
while debut <= fin :
|
||||
milieu = (debut + fin) // 2
|
||||
print(milieu,debut,fin)
|
||||
if t[milieu] == v :
|
||||
return True
|
||||
else:
|
||||
if t[milieu] > v :
|
||||
fin = milieu - 1
|
||||
else :
|
||||
debut = milieu + 1
|
||||
return False
|
||||
```
|
||||
|
||||
1. Ecrire ce code en récursif
|
||||
@@ -1,27 +0,0 @@
|
||||
import turtle
|
||||
|
||||
def courbe_koch(n, l):
|
||||
if n == 0 :
|
||||
turtle.forward(l)
|
||||
else :
|
||||
courbe_koch(n-1, l/3)
|
||||
turtle.left(60)
|
||||
courbe_koch(n-1, l/3)
|
||||
turtle.left(-120)
|
||||
courbe_koch(n-1, l/3)
|
||||
turtle.left(60)
|
||||
courbe_koch(n-1, l/3)
|
||||
|
||||
def flocon(n,l,i=3):
|
||||
if i != 0:
|
||||
courbe_koch(n,l)
|
||||
turtle.left(-120)
|
||||
flocon(n,l,i-1)
|
||||
|
||||
turtle.setheading(0) # orientation intiale de la tête : vers la droite de l'écran
|
||||
turtle.hideturtle() # on cache la tortue
|
||||
turtle.speed(0) # on accélère la tortue
|
||||
turtle.color('green')
|
||||
#flocon(1,300)
|
||||
#courbe_koch(,400)
|
||||
print(8)
|
||||
@@ -1,10 +0,0 @@
|
||||
def coef(n,p):
|
||||
if p==0 or n == p :
|
||||
return 1
|
||||
else :
|
||||
return coef(n-1,p-1) + coef(n-1,p)
|
||||
|
||||
for i in range(19):
|
||||
for j in range(i+1):
|
||||
print(coef(i,j),' ',end='')
|
||||
print()
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,375 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Exercices sur la récursivité et la programmation dynamique\n",
|
||||
"\n",
|
||||
"## Évolution des abonnements\n",
|
||||
"\n",
|
||||
"Un youtuber constate chaque mois qu'il recrute 3000 nouveaux abonnés mais dans le même temps la lassitude pousse 2% de ses fidèles à se désabonner. Ce mois-ci (n=0) il compte 100000 abonnés et il souhaite pouvoir calculer les prédictions de ses abonnés pour démarcher des sponsors dans les mois à venir. Écrivez récursivement la fonction `prev_abo` qui calcule le nombre d'abonné au mois n.\n",
|
||||
"\n",
|
||||
"Utilisez votre fonction `prev_abo` pour calculer le nombre d'abonnés dans les mois à venir.\n",
|
||||
"\n",
|
||||
"D'après vous, le youtuber peut-il prétendre à ces sponsors qu'il va bientôt atteindre les 200000 abonnés ? Utilisez votre programme pour constater l'évolution des abonnés à long terme."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Sans maitrise la puissance n'est rien\n",
|
||||
"\n",
|
||||
"Écrivez par récurence une function `puissance(x: float, n: int) -> float` qui calcule $x^n$ pour n >= 0 en utilisant uniquement des multiplications et la valeur de $x^0$."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def puissance(x:float, n:int) -> float:\n",
|
||||
" \"\"\" n must be >= 0\n",
|
||||
" >>> puissance(0,0)\n",
|
||||
" 1\n",
|
||||
" >>> puissance(1,0)\n",
|
||||
" 1\n",
|
||||
" >>> puissance(1,1)\n",
|
||||
" 1\n",
|
||||
" >>> puissance(1,3)\n",
|
||||
" 1\n",
|
||||
" >>> puissance(2,3)\n",
|
||||
" 8\n",
|
||||
" >>> puissance(10,5)\n",
|
||||
" 100000\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"import doctest\n",
|
||||
"doctest.testmod(optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, verbose = False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Un PGCD pour l'examen ?\n",
|
||||
"\n",
|
||||
"Écrivez une fonction `pgcd` qui calcule le PGCD entre 2 nombres entiers avec l'algorithme d'Euclide qui dit ceci :\n",
|
||||
"- Le pgcd de a (a > 0) et b est le même que le pgcd de b et c avec c qui est le reste de la division entière (en python le modulo :**%**) de a par b. \n",
|
||||
"- Le pgcd de a par 0 est a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Réduction de fraction\n",
|
||||
"\n",
|
||||
"Utiliser le pgcd précédent pour écrire une fonction `reduc` qui réduit les fractions entières comme ceci : `reduc(12,8)` retourne `(3,2)` car $\\dfrac{12}{8} = \\dfrac{3}{2}$."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Suite de Syracuse\n",
|
||||
"\n",
|
||||
"Programmez par **récursivité** la fonction `syracuse(u0: int, n: int)` qui calcule la [suite de Syracuse](https://fr.wikipedia.org/wiki/Conjecture_de_Syracuse#Suite_de_Syracuse) définie **pour des entiers** comme ceci :\n",
|
||||
"\n",
|
||||
"$u_o = N$ avec N entier > 0\n",
|
||||
"\n",
|
||||
"$u_{n+1}={\\begin{cases}{\\dfrac {u_{n}}{2}} \\; {\\mbox{si }}u_{n}{\\mbox{ est pair,}}\\\\3u_{n}+1 \\; {\\mbox{si }}u_{n}{\\mbox{ est impair.}}\\end{cases}}$\n",
|
||||
"\n",
|
||||
"💡 **Si vous appelez récursivement plusieurs fois la fonction avec les mêmes paramètres, il vaut mieux faire 1 seul appel et mettre le résultat dans une variable. Vous limiterez ainsi considérablement le nombre d'appels.**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def syracuse(u0: int, n: int) -> int:\n",
|
||||
" \"\"\" Return Syracuse suite value\n",
|
||||
" u0 must be > 0 ; n must be >= 0\n",
|
||||
" >>> syracuse(1, 0)\n",
|
||||
" 1\n",
|
||||
" >>> syracuse(15, 7)\n",
|
||||
" 160\n",
|
||||
" >>> syracuse(15, 4)\n",
|
||||
" 35\n",
|
||||
" >>> syracuse(15, 17)\n",
|
||||
" 1\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"import doctest\n",
|
||||
"doctest.testmod(optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, verbose = False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Pour l'appel de la fonction `syracuse(15, 3)` comptez au brouillon combien de fois la fonction `syracuse` se lance en écrivant l'arbre des appels.\n",
|
||||
"\n",
|
||||
"Vérifiez cela en modifiant votre programme, puis trouvez le nombre d'appel pour calculer `syracuse(15, 5)`, `syracuse(15, 10)`, `syracuse(15, 15)` et `syracuse(15, 20)`. Que pensez vous de ces derniers résultats ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Une **conjecture encore non démontrée** en mathématique affirme que pour **tout N entier > 0 il existe toujours un terme de la suite pour lequel $u_n = 1$**.\n",
|
||||
"\n",
|
||||
"Écrivez un programme qui montre cette conjecture pour les valeurs de N allant jusqu'à 30."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"A ce stade, suivant le code de votre fonction `syracuse`, tout se passe bien (**1 seul appel récursif par fonction**), ou vous avez dû interrompre le programme car sa **compléxité** est telle qu'il ne peut pas répondre dans un temps raisonnable (**3 appels récursifs par fonction**) !\n",
|
||||
"\n",
|
||||
"Écrivez maintenant votre programme de recherche du rang pour lequel $u_n=1$ pour un N donné en utilisant un algorithme **itératif (avec une boucle)**. Testez votre code en trouvant les rangs recherchés pour N jusqu'à 100."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Recherche dichotomique récursive !\n",
|
||||
"\n",
|
||||
"Écrivez maintenant une fonction `find_dicho_recur` de recherche dichotomique dans une liste triée qui répond `True` ou `False` en fonction du résultat de la recherche. Vous pouvez utiliser les **slices** pour accéder à une sous-liste.\n",
|
||||
"\n",
|
||||
"💡 La technique qui consiste à résoudre un problème en résolvant plusieurs parties plus petite du problème s'appelle : **diviser pour régner**."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def find_dicho_recur(liste: list, value: int) -> bool:\n",
|
||||
" \"\"\" liste must be sorted\n",
|
||||
" >>> find_dicho_recur([], 0)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1], 0)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1], 1)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1, 2], 1)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1, 2], 2)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1, 2], 3)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1, 2], -1)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1,2,3], 0)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1,2,3], 5)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1,2,3], 1)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3], 2)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3], 3)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3,4], 1)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3,4], 2)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3,4], 3)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3,4], 4)\n",
|
||||
" True\n",
|
||||
" >>> find_dicho_recur([1,2,3,4], -1)\n",
|
||||
" False\n",
|
||||
" >>> find_dicho_recur([1,2,3,4], 10)\n",
|
||||
" False\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"import doctest\n",
|
||||
"doctest.testmod(optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, verbose = False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Rendu de monnaie optimal !\n",
|
||||
"\n",
|
||||
"Nous avons programmé le [rendu de monnaie](https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_rendu_de_monnaie) avec un **algorithme glouton** qui est optimal pour les **systèmes de monnaies cannoniques** (comme l'euro).\n",
|
||||
"\n",
|
||||
"Mais si nous disposons des pièces : **4, 3 et 1**, pour un rendu de 6, l'algorithme glouton rendra 3 pièces (4+1+1) alors qu'une solution en 2 pièces existe (3+3).\n",
|
||||
"\n",
|
||||
"Nous allons programmer une fonction `rendu_monnaie` **récursive** pour trouver la **solution optimale et explorant toutes les possibilités**.\n",
|
||||
"\n",
|
||||
"L'idée est de lancer une recherche récursive en choisissant 1 pièce et de garder seulement la solution qui demande le moins de pièces pour la somme restante. Voici un exemple avec [4,3,1] et 8 :\n",
|
||||
"- Je vais utiliser 1 pièce à tour de rôle : 4 puis je lance récursivement ma fonction avec [4,3,1] et 8-4 = 4. Puis je fais pareil avec les pièces 3 puis 1.\n",
|
||||
"- Je sais ainsi que le nombre de pièces total pour chaque possibilité est le résultat de l'appel récursif + 1. Il me suffit donc de choisir la branche qui retourne le moins de pièces.\n",
|
||||
"\n",
|
||||
"💡 Et comme le programme est **récursif toutes les possibilités seront automatiquement explorée** pour donner une solution optimale."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def rendu_monnaie(pieces: list, somme: int) -> list:\n",
|
||||
" \"\"\" Return optimal coin's count for money back\n",
|
||||
" Return None if no solution exists\n",
|
||||
" pieces : list of int\n",
|
||||
" >>> rendu_monnaie([], 5) is None\n",
|
||||
" True\n",
|
||||
" >>> rendu_monnaie([4,3], 1) is None\n",
|
||||
" True\n",
|
||||
" >>> rendu_monnaie([4,3], -1) is None\n",
|
||||
" True\n",
|
||||
" >>> rendu_monnaie([4,3], 5) is None\n",
|
||||
" True\n",
|
||||
" >>> rendu_monnaie([4,3], 6)\n",
|
||||
" [3, 3]\n",
|
||||
" >>> rendu_monnaie([4,3], 8)\n",
|
||||
" [4, 4]\n",
|
||||
" >>> rendu_monnaie([4,3,1], 6)\n",
|
||||
" [3, 3]\n",
|
||||
" >>> rendu_monnaie([4,3,1], 5)\n",
|
||||
" [4, 1] \n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"import doctest\n",
|
||||
"doctest.testmod(optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, verbose = False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Rendu de monnaie optimal et dynamique !\n",
|
||||
"\n",
|
||||
"La solution ci-dessus qui explore **toutes les possibilités** récursivement est séduisante mais si vous lancez `rendu_monnaie([4,3,1], 25)` avec l'affichage des appels vous allez constater que le nombre d'appels est considérable. Ce qui explique pourquoi `rendu_monnaie([4,3,1], 53)` a du mal à répondre dans un temps raisonnable...\n",
|
||||
"\n",
|
||||
"Nous allons donc améliorer notre algorithme en écrivant une fonction `rendu_dyn` avec la technique de la **programmation dynamique** en mémorisant les solutions déjà calculées pour les réutiliser au cours du calcul."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def rendu_dyn(pieces: list, somme: int) -> list:\n",
|
||||
" \"\"\" Return optimal coin's count for money back\n",
|
||||
" Return [] if no solution exists\n",
|
||||
" pieces : list of POSITIVE int \n",
|
||||
" >>> rendu_dyn([], 5)\n",
|
||||
" []\n",
|
||||
" >>> rendu_dyn([4,3], 1)\n",
|
||||
" []\n",
|
||||
" >>> rendu_dyn([4,3], 0)\n",
|
||||
" []\n",
|
||||
" >>> rendu_dyn([4,3], 5)\n",
|
||||
" []\n",
|
||||
" >>> rendu_dyn([4,3], 6)\n",
|
||||
" [3, 3]\n",
|
||||
" >>> rendu_dyn([4,3], 8)\n",
|
||||
" [4, 4]\n",
|
||||
" >>> rendu_dyn([4,3,1], 6)\n",
|
||||
" [3, 3]\n",
|
||||
" >>> rendu_dyn([4,3,1], 5)\n",
|
||||
" [4, 1]\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"import doctest\n",
|
||||
"doctest.testmod(optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, verbose = False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Diviser pour régner : rotation d'une image d'un quart de tour en temps constant\n",
|
||||
"\n",
|
||||
"🤯 Faites l'exercice `Objectif BAC` du livre de NSI page 52. Le corrigé est disponible page 63."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"👏👏👏 Bravo ! 👏👏👏"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Reference in New Issue
Block a user