# Permet de tout executer au lancement du notebook + conserver le notebook actif pendant 2h
from IPython.display import Javascript
from masquer import *
Javascript("""
function repeter(){
IPython.notebook.kernel.execute("a=1");
}
// execute a = 1 en python toutes les 8 minutes pendant 2h
let timerId = setInterval(() => repeter(), 4800);
setTimeout(() => { clearInterval(timerId); alert('fin de cession'); }, 7200000);
// Supprimer la taille limite pour la sortie d'une cellule
IPython.OutputArea.prototype._should_scroll = function(lines) {
return false;
};
IPython.notebook.kernel.execute("url = '" + window.location + "'");
// Exécuter toutes les cellule du notebook
require(
['base/js/namespace', 'jquery'],
function(jupyter, $) {
jupyter.actions.call('jupyter-notebook:run-all-cells-below');
jupyter.actions.call('jupyter-notebook:save-notebook');
Jupyter.actions.call('jupyter-notebook:hide-header')
}
);""")
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
HTML("""<style>
h1 {
font-family: 'Permanent Marker', cursive;
text-align: center;
color: red;
}
ol {
list-style-position: inside;
margin-left: 1em;
list-style-position: outside;
}
h2 {
font-family: 'Permanent Marker', cursive;
color: blue;
}
h3 {
font-family: 'Permanent Marker', cursive;
}
</style>""")
def: Une fonction récursive est une fonction qui s'appelle elle-même. C'est la version informatique de la récurrence mathématique.
Exemple: Si on définit une suite $u_n$ telle que
On peut la programmer comme ci-dessous:
def u(n):
if n == 0:
return 2
else:
return 0.5*(u(n-1) + 3 / u(n-1))
u(0)
u(1)
u(2)
2
1.75
1.7321428571428572
Ainsi $u_0$ renvoie directement 2, c'est la condition d'arrêt. Si n est supérieur à 0, la fonction s'appelle elle même avec un argument inférieur, qui s'appelle elle même avec un argument inférieur, etc.. jusqu'à atteindre la condition d'arrêt. Il ne faudra jamais oublier cette condition d'arrêt sans quoi le programme ne s'arrêterait plus.
# 2.
# 4.
cacher_code("Solution de la 4.")
def u(n):
r"""
Renvoie la valeur de la suite $u_n$ définie par
u_0 = 2
u_n = 0.5 * (u_(n-1) + 3 / u_(n-1)) pour tout entier positif
"""
assert n >= 0, "n doit être positif ou nul"
assert type(n)==int, "n doit être un entier"
if n == 0:
return 2
else:
return 0.5*(u(n-1) + 3 / u(n-1))
On peut souvent programmer une même chose en utilisant une fonction itérative (avec une boucle) ou une fonction récursive.
Nous allons l'expérimenter avec la fonction factorielle qui s'y prête bien. C'est une fonction définie sur les entiers naturels telle que: $$n! = \prod_{k = 1}^{n} k = n\times \prod_{k = 1}^{n-1}k = n \times (n - 1)!$$
On peut donc calculer $n!$ en faisant une boucle. Une variable est initialisée à 1 puis est multipliée par un entier plus grand à chaque tout de boucle. On utilise en fait la définition $n! = \prod_{k = 1}^{n} k$.
On peut aussi calculer $n!$ en utilisant la définition $n! = n \times (n - 1)!$ et la condition d'arrêt $1! = 1$.
# question 1
# question 2
# question 3
Lorsque la définition de la fonction est récursive, il sera très facile de la programmer de cette manière. Idem lorsque la définition est itérative. Mais cela n'est pas une obligation.
# question 1
cacher_code("solution",output=True)
def u_iter(n):
rep = 2
for i in range(1,n+1):
rep = 0.5*(rep + 3 / rep)
return rep
# Comparaison des valeurs obtenues en iteratif et en récursif
u(0), u_iter(0)
u(1), u_iter(1)
u(2), u_iter(2)
(2, 2)
(1.75, 1.75)
(1.7321428571428572, 1.7321428571428572)
# question 1
# question 2
cacher_code("Coup de pouce",for_markdown=True)
Pour la version itérative, il faut utiliser $x^n = \prod_{k=1}^{n} x$
Pour la version recursive, on utilise $x^n = x \times x^{n-1}$ avec $x^0 = 1$