Utilisation de Python pour la modélisation et les calculs

TleMathematiquesStructures de contrôle et listesUtilisation de Python pour la modélisation et les calculs~9 min de lecture

Utiliser Python pour modéliser et calculer

Avec quelques briques (tests, boucles for et while, fonctions, listes), Python calcule à notre place les termes d'une suite, trouve un seuil, approche la solution d'une équation par dichotomie et simule le hasard.

Objectifs

  • Utiliser les instructions conditionnelles et les boucles for et while, et choisir la bonne boucle.
  • Écrire des fonctions qui renvoient un résultat.
  • Construire et exploiter des listes pour tabuler une suite ou une fonction.
  • Programmer un algorithme de seuil et un algorithme de dichotomie.
  • Simuler une expérience aléatoire et observer la fréquence d'un événement.

1. Les briques de base

Notions clés

  • Test : if / elif / else exécute un bloc seulement si une condition est vraie.
  • Boucle bornée for k in range(n) : on connaît à l'avance le nombre de répétitions (\(n\)).
  • Boucle non bornée while condition: : on répète tant que la condition est vraie, sans savoir à l'avance combien de fois.
  • Fonction : def nom(paramètres): … return résultat regroupe un calcul réutilisable.
  • Liste : L = [], L.append(x), L[i], len(L) pour stocker une série de valeurs.
def tarif(age):
    if age < 5:
        return 0          # gratuit
    elif age < 18:
        return 1000       # tarif réduit en F CFA
    else:
        return 2000

Que renvoie tarif(12) ?

  1. 0
  2. 1000
  3. 2000
12 n'est pas inférieur à 5, mais il est inférieur à 18 : la branche elif s'exécute et renvoie 1000.

Pour chercher le premier mois où une épargne dépasse 500 000 F CFA, quelle boucle choisir ?

  1. Une boucle while
  2. Une boucle for
  3. Aucune boucle
On ne sait pas d'avance combien de mois il faudra : on répète tant que le seuil n'est pas atteint, c'est une boucle while.

2. Suites et algorithme de seuil

Le capital au bout de \(n\) années est \(u_n = 100\,000 \times 1{,}05^{\,n}\), soit \(u_0 = 100\,000\) et \(u_{n+1} = 1{,}05\,u_n\). La suite est croissante : on cherche le plus petit \(n\) tel que \(u_n > 150\,000\).

flowchart TD
A[n vaut 0 et u vaut 100000] --> B{u inferieur ou egal a 150000}
B -- oui --> C[u devient 1.05 fois u et n augmente de 1]
C --> B
B -- non --> D[Renvoyer n]
def seuil(S):
    n = 0
    u = 100000
    while u <= S:
        u = 1.05 * u
        n = n + 1
    return n

print(seuil(150000))

Exemple résolu : que renvoie seuil(150000) ?

La boucle tourne tant que \(u_n \le 150\,000\). On calcule les termes : \(u_7 \approx 140\,710\), \(u_8 \approx 147\,746\).
\(u_8 \le 150\,000\), donc la boucle continue : \(u_9 = 1{,}05 \times 147\,746 \approx 155\,133\).
\(u_9 > 150\,000\) : la boucle s'arrête et la fonction renvoie \(n = 9\). Aïcha dépasse 150 000 F CFA au bout de 9 ans.

Dans la fonction seuil, que se passe-t-il si l'on écrit n = 1 au départ au lieu de n = 0 ?

  1. Le résultat ne change pas
  2. Le programme ne s'arrête plus
  3. Le résultat est trop grand de 1
Le nombre de tours de boucle est le même, mais le compteur part de 1 : la fonction renverrait 10 au lieu de 9.

3. Tabuler une fonction avec une liste

Pour étudier \(f(x) = x^2 - 2\) sur \([0\,;2]\) avec un pas de \(0{,}5\), on range les abscisses et les images dans deux listes :

def f(x):
    return x**2 - 2

X = [0.5 * k for k in range(5)]    # [0, 0.5, 1, 1.5, 2]
Y = [f(x) for x in X]              # [-2, -1.75, -1, 0.25, 2]

Les images passent d'une valeur négative (\(f(1) = -1\)) à une valeur positive (\(f(1{,}5) = 0{,}25\)). La fonction étant continue et strictement croissante sur \([0\,;2]\), le théorème des valeurs intermédiaires assure que l'équation \(f(x) = 0\) a une unique solution \(\alpha\) dans \([1\,;1{,}5]\). Ici \(\alpha = \sqrt{2}\).

Manipule

Le graphique trace \(y = x^2 - c\). Fais varier \(c\) : la courbe coupe l'axe des abscisses en \(\sqrt{c}\), la valeur que la dichotomie va approcher.

4. La dichotomie : couper en deux pour trouver une solution

Si \(f\) est continue sur \([a\,;b]\) et que \(f(a)\) et \(f(b)\) sont de signes contraires, on prend le milieu \(m = \dfrac{a+b}{2}\) et on garde la moitié où le signe change. On recommence jusqu'à ce que l'intervalle soit plus petit que la précision voulue.

def dichotomie(a, b, precision):
    while b - a > precision:
        m = (a + b) / 2
        if f(a) * f(m) <= 0:    # changement de signe entre a et m
            b = m
        else:
            a = m
    return a, b

print(dichotomie(1, 2, 0.1))

Exemple résolu : encadrer \(\sqrt{2}\)

Avec \(f(x) = x^2 - 2\), \(a = 1\), \(b = 2\) et une précision de \(0{,}1\), déroule l'algorithme à la main avant de regarder.

\(m = 1{,}5\) et \(f(1{,}5) = 0{,}25 > 0\) : le signe change entre 1 et 1,5, donc \(b = 1{,}5\).
\(m = 1{,}25\) et \(f(1{,}25) = -0{,}4375 < 0\) : on pose \(a = 1{,}25\).
\(m = 1{,}375\) et \(f(1{,}375) \approx -0{,}109 < 0\) : on pose \(a = 1{,}375\).
\(m = 1{,}4375\) et \(f(1{,}4375) \approx 0{,}066 > 0\) : on pose \(b = 1{,}4375\).
La largeur vaut \(0{,}0625 \le 0{,}1\) : la boucle s'arrête. On obtient \(1{,}375 \le \sqrt{2} \le 1{,}4375\).

En partant de l'intervalle [1 ; 2], combien d'étapes faut-il au minimum pour obtenir un intervalle de largeur inférieure à 0,01 ?

  1. 6
  2. 7
  3. 100
Il faut 1 / 2^k inférieur à 0,01, soit 2^k supérieur à 100. Or 2^6 = 64 et 2^7 = 128 : il faut 7 étapes.

5. Simuler le hasard

from random import randint

def frequence_six(n):
    compteur = 0
    for k in range(n):
        if randint(1, 6) == 6:    # entier au hasard entre 1 et 6
            compteur = compteur + 1
    return compteur / n

randint(1, 6) renvoie un entier entre 1 et 6 inclus, chacun avec la même probabilité. Quand \(n\) devient grand, la fréquence renvoyée se rapproche de la probabilité \(\dfrac{1}{6} \approx 0{,}167\) : c'est la loi des grands nombres. Avec peu de lancers, la fréquence peut s'en écarter nettement.

Exemple : une fréquence observée

Sur 600 lancers simulés, le 6 est sorti 112 fois. Quelle fréquence la fonction renvoie-t-elle, et est-ce cohérent ?

Voir la solution

\(f = \dfrac{112}{600} \approx 0{,}187\). Elle est proche de \(\dfrac{1}{6} \approx 0{,}167\) : l'écart est normal pour 600 lancers. Au seuil de 95 %, l'intervalle de fluctuation asymptotique \(\left[p - 1{,}96\sqrt{\dfrac{p(1-p)}{n}}\,;\, p + 1{,}96\sqrt{\dfrac{p(1-p)}{n}}\right]\) avec \(p = \dfrac{1}{6}\) et \(n = 600\) vaut environ \([0{,}137\,;\,0{,}196]\) : il contient bien 0,187.

Pourquoi utilise-t-on ici une boucle for et non une boucle while ?

  1. Le nombre de lancers n est connu d'avance
  2. La boucle for est plus rapide à écrire
  3. Une boucle while ne peut pas contenir de if
On répète exactement n fois : c'est une boucle bornée, la boucle for est faite pour cela.

Erreurs fréquentes

  • Oublier l'indentation : en Python, c'est elle qui indique ce qui est dans la boucle ou dans le test.
  • Écrire = (affectation) au lieu de == (comparaison) dans une condition.
  • Utiliser print au lieu de return dans une fonction dont on veut réutiliser le résultat.
  • Écrire une boucle while dont la condition ne devient jamais fausse.
  • Se tromper de borne : range(n) va de 0 à \(n-1\).

Récapitulatif

  • for quand le nombre de répétitions est connu, while quand on attend qu'une condition change.
  • Algorithme de seuil : un compteur et une boucle while qui calcule les termes tant que le seuil n'est pas franchi.
  • Les listes servent à tabuler une suite ou une fonction et à repérer un changement de signe.
  • Dichotomie : on coupe l'intervalle en deux et on garde la moitié où \(f\) change de signe ; après \(k\) étapes, la largeur est divisée par \(2^k\).
  • Simulation : randint et un compteur donnent une fréquence proche de la probabilité quand \(n\) est grand.
Boucle for ou while ?
for : nombre de tours connu. while : on répète tant qu'une condition est vraie.
Algorithme de seuil
Renvoie le premier rang n pour lequel la suite franchit une valeur donnée.
Dichotomie
Couper l'intervalle en deux et garder la moitié où f change de signe.
return
Renvoie le résultat d'une fonction pour pouvoir le réutiliser.
randint(a, b)
Entier au hasard entre a et b inclus, du module random.

Teste tes connaissances sur ce cours

Crée ton compte gratuitement pour accéder aux quiz associés et suivre ta progression.