Spécialité maths, Première • Exercices corrigés à Montréal

Exercices corrigés : Python en spécialité maths et en sciences (Première)

Voici une série d'exercices corrigés de Python appliqué à la spécialité mathématiques, au niveau de la classe de Première du programme français, telle qu'elle est suivie au Lycée Marie de France et au Collège Stanislas à Montréal.

En Première, l'algorithmique n'est plus un chapitre à part : elle traverse les suites, la dérivation, le second degré et les probabilités. Chaque programme de cette série calcule un objet du cours, et chaque résultat affiché doit être retrouvé par un calcul exact. C'est ce va-et-vient qui est évalué au contrôle, jamais la syntaxe pour elle-même.

Série autocorrigée Tape tes réponses sous chaque question : la page te dit juste ou faux avant d'ouvrir la correction. Avec un compte, chaque bonne réponse du premier coup rapporte des points.

Ce chapitre fait partie de Spécialité mathématiques en Première
Avant de commencer Fiche de révision : les pièges et la méthode de ce chapitre

Avant ce chapitre

Ces notions sont supposées acquises ici. Si le premier exercice résiste, le blocage vient presque toujours de l'une d'elles, pas du chapitre lui-même.

Remonter plus loin : la chaîne complète (4 chapitres) ↓

Le chemin de remédiation, du plus ancien au plus proche. Un élève qui reprend ce chapitre de zéro le reprend dans cet ordre.

  1. 1Algorithmique et PythonSeconde
  2. 2Algorithmique et ScratchCinquième
  3. 3Algorithmique et ScratchQuatrième
  4. 4Algorithmique et ScratchTroisième

Rappel de cours

  • Une suite définie par récurrence se calcule terme après terme : on initialise, puis on répète la mise à jour dans une boucle.
  • Si un+1=aun+bu_{n+1}=a u_n + b avec a1a\ne 1, le point fixe LL vérifie L=aL+bL=aL+b, et la suite vn=unLv_n=u_n-L est géométrique de raison aa.
  • Un seuil se cherche avec une boucle `while` : on répète tant que la condition d'arrêt n'est pas atteinte, en comptant les tours.
  • Somme des termes d'une suite géométrique de raison q1q\ne 1 : u0×1qn+11qu_0\times\frac{1-q^{n+1}}{1-q}.
  • Le nombre dérivé est la limite du taux d'accroissement f(a+h)f(a)h\frac{f(a+h)-f(a)}{h} quand hh tend vers 00, et non sa valeur en h=0h=0.
  • Discriminant Δ=b24ac\Delta=b^2-4ac : deux racines si Δ>0\Delta>0, une racine double si Δ=0\Delta=0, aucune racine réelle si Δ<0\Delta<0.
  • Espérance E(X)=xipiE(X)=\sum x_i p_i, variance V(X)=E(X2)E(X)2V(X)=E(X^2)-E(X)^2 et écart-type σ=V(X)\sigma=\sqrt{V(X)}.
  • Les décimaux sont représentés de façon approchée en machine : une condition d'arrêt s'écrit avec une inégalité, jamais avec `==`.

Partie A : les bases (/50)

Exercice 1 : Suite récurrente et point fixe

La suite (un)(u_n) est définie par u0=2u_0=2 et un+1=0,8un+3u_{n+1}=0{,}8\,u_n+3 pour tout entier nn. On veut la calculer en Python.

def terme(n):
    u = 2
    for k in range(n):
        u = 0.8*u + 3
    return u
  • a) Calculez à la main u1u_1, u2u_2 et u3u_3, puis vérifiez que `terme(3)` renvoie la même valeur.
  • b) Un élève place l'instruction `return u` À L'INTÉRIEUR de la boucle. Que renvoie alors `terme(3)` ?
  • c) Que renvoie `terme(0)` ? Pourquoi ce cas est-il correct sans aucune ligne supplémentaire ?
  • d) Le programme affiche des valeurs qui se rapprochent d'un nombre. Déterminez-le par le calcul.

Tape tes réponses, la page te dit juste ou faux 0/6

a)
b)
c)
d)
Voir la correction

Réponses

  • a) u1=4,6u_1=4{,}6, u2=6,68u_2=6{,}68, u3=8,344u_3=8{,}344
  • b) 4,64{,}6 : return interrompt la boucle
  • c) 22 : la boucle ne tourne pas
  • d) 1515

a) On applique la relation trois fois : u1=0,8×2+3=4,6u_1=0{,}8\times 2+3=4{,}6, puis u2=0,8×4,6+3=3,68+3=6,68u_2=0{,}8\times 4{,}6+3=3{,}68+3=6{,}68, puis u3=0,8×6,68+3=5,344+3=8,344u_3=0{,}8\times 6{,}68+3=5{,}344+3=8{,}344. La boucle `for k in range(3)` effectue exactement trois mises à jour, donc `terme(3)` renvoie 8,3448{,}344. La variable de boucle `k` ne sert à rien d'autre qu'à compter : c'est normal, la relation de récurrence ne dépend pas de nn.

b) Elle renvoie 4,64{,}6, c'est-à-dire u1u_1. L'instruction `return` ne se contente pas de renvoyer une valeur, elle INTERROMPT immédiatement la fonction : dès la fin du premier tour, tout s'arrête. C'est l'erreur la plus fréquente sur ce type de programme, et elle est silencieuse, puisque 4,64{,}6 est une valeur parfaitement plausible. Le `return` d'une fonction de calcul itératif se place toujours APRÈS la boucle, au même niveau d'indentation que le `for`.

c) Il renvoie 22, c'est-à-dire u0u_0. La boucle `range(0)` est vide, donc aucune mise à jour n'a lieu et la fonction renvoie la valeur d'initialisation. Ce comportement est exactement celui que l'on veut, et il illustre un principe utile : une boucle qui tourne zéro fois n'est pas une erreur, c'est le cas de base traité gratuitement.

d) Si la suite converge vers un réel LL, alors en passant à la limite dans la relation on obtient L=0,8L+3L=0{,}8L+3, donc 0,2L=30{,}2L=3 et L=15L=15. On le démontre proprement en posant vn=un15v_n=u_n-15 : alors vn+1=un+115=0,8un+315=0,8(un15)=0,8vnv_{n+1}=u_{n+1}-15=0{,}8u_n+3-15=0{,}8(u_n-15)=0{,}8v_n. La suite (vn)(v_n) est donc GÉOMÉTRIQUE de raison 0,80{,}8 et de premier terme v0=215=13v_0=2-15=-13, d'où un=1513×0,8nu_n=15-13\times 0{,}8^{\,n}. Comme 0<0,8<10<0{,}8<1, le terme 0,8n0{,}8^{\,n} tend vers 00 et unu_n tend vers 1515 en croissant, sans jamais l'atteindre.

Le fil de la série commence ici : la boucle produit des NOMBRES, le calcul produit une FORMULE. On vérifie la formule sur les nombres, ici u3=1513×0,512=156,656=8,344u_3=15-13\times 0{,}512=15-6{,}656=8{,}344 ✓, et c'est ensuite la formule qui permet de répondre à toutes les questions de limite et de seuil.

def terme(n):
    u = 2
    for k in range(n):
        u = 0.8*u + 3
    return u

Exercice 2 : Recherche de seuil et preuve associée

On garde la suite u0=2u_0=2 et un+1=0,8un+3u_{n+1}=0{,}8\,u_n+3, dont on admet la forme explicite un=1513×0,8nu_n=15-13\times 0{,}8^{\,n}. On cherche le premier rang à partir duquel unu_n dépasse 14,914{,}9.

  • a) Écrivez un programme utilisant une boucle `while` qui affiche ce rang.
  • b) Donnez la valeur trouvée, en justifiant par les deux termes qui encadrent le seuil.
  • c) Retrouvez ce rang par le calcul, à l'aide de la forme explicite.
  • d) Pourquoi la boucle se termine-t-elle ? Que se passerait-il si le seuil valait 1515 ?

Tape tes réponses, la page te dit juste ou faux 0/2

b)
d)
Voir la correction

Réponses

  • a) Boucle while u <= 14.9, avec mise à jour et compteur
  • b) 2222 (u2114,880u_{21}\approx 14{,}880, u2214,904u_{22}\approx 14{,}904)
  • c) 0,8n<11300{,}8^{\,n}<\frac{1}{130} : n=22n=22
  • d) unu_n tend vers 1515 ; avec le seuil 1515, boucle infinie

a) `u = 2` puis `n = 0` puis `while u <= 14.9:` puis ` u = 0.8*u + 3` puis ` n = n + 1` puis `print(n)`. Les deux instructions du corps sont indissociables : la mise à jour du terme et le comptage du rang doivent avancer ENSEMBLE, sans quoi le rang affiché ne correspond pas au terme calculé.

b) Le programme affiche 2222. En effet u21=1513×0,8211513×0,00922314,8801u_{21}=15-13\times 0{,}8^{21}\approx 15-13\times 0{,}009223\approx 14{,}8801, encore sous le seuil, tandis que u22=1513×0,8221513×0,00737914,9041u_{22}=15-13\times 0{,}8^{22}\approx 15-13\times 0{,}007379\approx 14{,}9041, qui le dépasse. Donner ces deux valeurs est indispensable : un rang de seuil ne se justifie jamais par le seul affichage du programme.

c) On résout 1513×0,8n>14,915-13\times 0{,}8^{\,n}>14{,}9, soit 13×0,8n<0,113\times 0{,}8^{\,n}<0{,}1, soit 0,8n<11300,007690{,}8^{\,n}<\frac{1}{130}\approx 0{,}00769. La suite (0,8n)\left(0{,}8^{\,n}\right) est géométrique de raison comprise entre 00 et 11, donc strictement DÉCROISSANTE : dès qu'un rang convient, tous les suivants conviennent. La calculatrice donne 0,8210,009220{,}8^{21}\approx 0{,}00922, encore trop grand, et 0,8220,007380{,}8^{22}\approx 0{,}00738, qui convient. Le premier entier convenable est donc n=22n=22 ✓. C'est la décroissance qui fait de ce rang le SEUIL : sans elle, un rang convenable pourrait être suivi d'un rang qui ne convient plus.

d) Elle se termine parce que 0,8n0{,}8^{\,n} tend vers 00, donc unu_n tend vers 1515 : la suite finit par franchir n'importe quel seuil strictement inférieur à 1515. Avec un seuil égal à 1515, la boucle ne s'arrêterait JAMAIS, car un=1513×0,8nu_n=15-13\times 0{,}8^{\,n} reste strictement inférieur à 1515 pour tout nn. Une suite convergente ne dépasse pas sa limite : c'est le piège classique de la boucle `while` en analyse, et il ne se voit pas à la lecture du programme, seulement en connaissant la limite.

Le fil : le programme donne le rang, la forme explicite et la décroissance le démontrent, et les deux doivent coïncider. Quand ils diffèrent d'une unité, l'erreur est presque toujours un `<` écrit à la place d'un `<=` dans la condition d'arrêt.

u = 2
n = 0
while u <= 14.9:
    u = 0.8*u + 3
    n = n + 1
print(n)

Exercice 3 : Somme de termes et formule fermée

Une personne place 200200 dollars au début de chaque année sur un compte rémunéré à 5%5\% par an. Au bout de nn années, le capital vaut la somme Sn=200×1,05+200×1,052++200×1,05nS_n=200\times 1{,}05+200\times 1{,}05^2+\dots+200\times 1{,}05^{\,n}.

def capital(n):
    s = 0
    for k in range(1, n+1):
        s = s + 200*1.05**k
    return s
  • a) Que renvoie `capital(10)` ? Donnez la valeur au centime.
  • b) Établissez la formule fermée de SnS_n et vérifiez-la sur n=10n=10.
  • c) Un élève initialise `s = 200` au lieu de `s = 0`. De combien son résultat est-il faux ?
  • d) Écrivez un programme qui donne le nombre d'années nécessaires pour dépasser 50005000 dollars, et retrouvez-le par le calcul.

Tape tes réponses, la page te dit juste ou faux 0/4

a)
b)
c)
d)
Voir la correction

Réponses

  • a) 2641,36\approx 2\,641{,}36 dollars
  • b) Sn=4200(1,05n1)S_n=4200(1{,}05^{\,n}-1)
  • c) Trop grand de 200200 dollars
  • d) 1717 ans

a) La boucle ajoute dix termes, de k=1k=1 à k=10k=10, puisque `range(1, 11)` s'arrête à 1010 inclus. La fonction renvoie environ 2641,362641{,}36 dollars. La ligne `s = s + 200*1.05**k` est le motif de l'ACCUMULATEUR : une variable qui part de zéro et à laquelle on ajoute un terme par tour, la division ou la conclusion venant après la boucle.

b) C'est la somme des termes d'une suite géométrique de premier terme 210210 et de raison 1,051{,}05, comptant nn termes : Sn=210×1,05n11,051=4200(1,05n1)S_n=210\times\frac{1{,}05^{\,n}-1}{1{,}05-1}=4200\left(1{,}05^{\,n}-1\right). Pour n=10n=10 : 1,05101,628891{,}05^{10}\approx 1{,}62889, donc S104200×0,628892641,36S_{10}\approx 4200\times 0{,}62889\approx 2641{,}36 dollars, ce qui coïncide avec l'affichage ✓. Comparaison instructive : si les versements avaient lieu en FIN d'année, la somme partirait de k=0k=0 et vaudrait 200×1,051010,052515,58200\times\frac{1{,}05^{10}-1}{0{,}05}\approx 2515{,}58 dollars, soit 125,78125{,}78 dollars de moins. Un décalage d'un seul indice se paie donc en argent réel, et c'est exactement ce que la comparaison programme contre formule permet de détecter.

c) Il ajoute 200200 dollars qui ne correspondent à aucun versement rémunéré : son résultat est trop grand de exactement 200200 dollars, soit 2841,362841{,}36 au lieu de 2641,362641{,}36. L'initialisation d'un accumulateur de somme est toujours 00, comme celle d'un accumulateur de produit est toujours 11 : c'est l'élément neutre de l'opération que l'on répète.

d) `s = 0` puis `n = 0` puis `while s <= 5000:` puis ` n = n + 1` puis ` s = s + 200*1.05**n` puis `print(n)`. Le programme affiche 1717. Par le calcul : 4200(1,05n1)>50004200(1{,}05^{\,n}-1)>5000 équivaut à 1,05n>1+500042002,19051{,}05^{\,n}>1+\frac{5000}{4200}\approx 2{,}1905, et la suite (1,05n)\left(1{,}05^{\,n}\right) est croissante : 1,05162,18291{,}05^{16}\approx 2{,}1829 ne suffit pas, 1,05172,29201{,}05^{17}\approx 2{,}2920 convient, d'où n=17n=17 ✓. On vérifie : S164968,07S_{16}\approx 4968{,}07 dollars et S175426,48S_{17}\approx 5426{,}48 dollars.

Le fil : dès qu'une somme apparaît, deux écritures coexistent, la boucle et la formule. La formule est indispensable pour les seuils, la boucle sert de contrôle, et le seul vrai danger est l'indice de départ.

s = 0
n = 0
while s <= 5000:
    n = n + 1
    s = s + 200*1.05**n
print(n)

Exercice 4 : Nombre dérivé approché et limites de la machine

Soit ff définie sur R\mathbb{R} par f(x)=x32xf(x)=x^3-2x. On veut estimer le nombre dérivé de ff en a=1a=1 à l'aide du taux d'accroissement T(h)=f(1+h)f(1)hT(h)=\frac{f(1+h)-f(1)}{h}.

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

for k in range(1, 7):
    h = 10**(-k)
    print(h, (f(1+h) - f(1))/h)
  • a) Donnez les valeurs affichées pour k=1k=1, k=2k=2 et k=3k=3, au millième.
  • b) Développez T(h)T(h) en fonction de hh et déduisez-en la limite quand hh tend vers 00.
  • c) Retrouvez le résultat en dérivant ff, puis donnez l'équation de la tangente en 11.
  • d) Un élève prend h=1017h=10^{-17} et obtient 00. Expliquez pourquoi, et dites quel ordre de grandeur de hh il faut choisir.

Tape tes réponses, la page te dit juste ou faux 0/7

a)
b)
c)
d)
Voir la correction

Réponses

  • a) 1,3101{,}310 ; 1,0301{,}030 ; 1,0031{,}003
  • b) T(h)=1+3h+h2T(h)=1+3h+h^{2}, limite 11
  • c) f(1)=1f'(1)=1 ; tangente y=x2y=x-2
  • d) 1+10171+10^{-17} vaut 11 en machine ; choisir hh vers 10610^{-6} à 10810^{-8}

a) On a f(1)=12=1f(1)=1-2=-1. Pour h=0,1h=0{,}1 : f(1,1)=1,3312,2=0,869f(1{,}1)=1{,}331-2{,}2=-0{,}869, donc T=0,869+10,1=1,310T=\frac{-0{,}869+1}{0{,}1}=1{,}310. Pour h=0,01h=0{,}01 : f(1,01)=1,0303012,02=0,989699f(1{,}01)=1{,}030301-2{,}02=-0{,}989699, donc T=1,030T=1{,}030. Pour h=0,001h=0{,}001 : T=1,003T=1{,}003. Les valeurs se rapprochent visiblement de 11.

b) On développe : f(1+h)=(1+h)32(1+h)=1+3h+3h2+h322h=1+h+3h2+h3f(1+h)=(1+h)^3-2(1+h)=1+3h+3h^2+h^3-2-2h=-1+h+3h^2+h^3. En retranchant f(1)=1f(1)=-1 il reste h+3h2+h3h+3h^2+h^3, et en divisant par hh, qui est non nul, on obtient T(h)=1+3h+h2T(h)=1+3h+h^2. La limite quand hh tend vers 00 vaut donc 11. Cette écriture explique les chiffres observés : pour h=0,1h=0{,}1 on lit 1+0,3+0,01=1,311+0{,}3+0{,}01=1{,}31 ✓, et l'erreur est de l'ordre de 3h3h, ce qui se voit à l'oeil sur la colonne des résultats.

c) f(x)=3x22f'(x)=3x^2-2, donc f(1)=32=1f'(1)=3-2=1, ce qui confirme la limite. La tangente en 11 a pour équation y=f(1)(x1)+f(1)y=f'(1)(x-1)+f(1), soit y=(x1)1y=(x-1)-1, c'est-à-dire y=x2y=x-2. Le taux d'accroissement est le coefficient directeur de la SÉCANTE passant par les points d'abscisses 11 et 1+h1+h ; quand hh diminue, cette sécante bascule vers la tangente, et le nombre dérivé est la position limite de sa pente.

d) Parce qu'en machine 1+10171+10^{-17} est arrondi à 11 exactement : les nombres flottants ne retiennent qu'une quinzaine de chiffres significatifs, et un 11 suivi de dix-sept zéros puis d'un 11 ne tient pas. Le numérateur f(1+h)f(1)f(1+h)-f(1) devient donc 00, et le quotient vaut 00 au lieu de 11. Il y a deux erreurs qui se combattent : si hh est trop GRAND, l'approximation mathématique est mauvaise, de l'ordre de 3h3h ; si hh est trop PETIT, la soustraction de deux nombres presque égaux détruit les chiffres significatifs. Le compromis se situe vers h=106h=10^{-6} à 10810^{-8}. C'est un fait important : contrairement à l'intuition, diminuer indéfiniment le pas ne rend pas le résultat plus juste.

Le fil : la limite mathématique et le calcul en machine ne coïncident que dans une fenêtre. Le programme montre la convergence, la factorisation la démontre, et la représentation des flottants explique pourquoi la table s'arrête de progresser.

0.511.52-2-112secante h = 0,5 : pente 2,75tangente en 1 : pente 1

Exercice 5 : Discriminant et nombre de racines

On veut écrire une fonction `nb_racines(a, b, c)` qui renvoie le nombre de solutions réelles de l'équation ax2+bx+c=0ax^2+bx+c=0.

  • a) Écrivez cette fonction à l'aide d'un `if`, d'un `elif` et d'un `else`.
  • b) Que renvoie-t-elle pour x24x+4=0x^2-4x+4=0, pour 2x2+x+3=02x^2+x+3=0 et pour x25x+6=0x^2-5x+6=0 ? Justifiez chaque valeur.
  • c) Que renvoie `nb_racines(0, 3, -6)` ? Pourquoi la réponse est-elle mathématiquement fausse, et comment corriger la fonction ?
  • d) Écrivez une fonction `racines(a, b, c)` qui affiche les solutions lorsqu'il y en a.

Tape tes réponses, la page te dit juste ou faux 0/5

b)
c)
Voir la correction

Réponses

  • a) Tests if d > 0, elif d == 0, else
  • b) 11 ; 00 ; 22
  • c) Renvoie 22 au lieu de 11 : traiter a=0a=0 d'abord
  • d) Calculer sqrt(d) seulement si d0d\geq 0

a) `def nb_racines(a, b, c):` puis ` d = b*b - 4*a*c` puis ` if d > 0:` puis ` return 2` puis ` elif d == 0:` puis ` return 1` puis ` else:` puis ` return 0`. L'ordre des tests importe : écrire `if d >= 0: return 2` fusionnerait à tort le cas de la racine double avec celui des deux racines distinctes.

b) Pour x24x+4x^2-4x+4 : Δ=1616=0\Delta=16-16=0, la fonction renvoie 11. L'équation admet la racine double x=42=2x=\frac{4}{2}=2, ce que confirme la factorisation (x2)2(x-2)^2. Pour 2x2+x+32x^2+x+3 : Δ=124=23<0\Delta=1-24=-23<0, la fonction renvoie 00 et la parabole ne coupe pas l'axe des abscisses. Pour x25x+6x^2-5x+6 : Δ=2524=1>0\Delta=25-24=1>0, la fonction renvoie 22, et les racines sont 512=2\frac{5-1}{2}=2 et 5+12=3\frac{5+1}{2}=3.

c) Elle calcule Δ=320=9>0\Delta=3^2-0=9>0 et renvoie 22. C'est faux : avec a=0a=0 l'équation n'est pas du second degré, elle s'écrit 3x6=03x-6=0 et n'a qu'UNE solution, x=2x=2. La formule du discriminant n'a de sens que pour a0a\ne 0, hypothèse que le programme ne vérifie pas. On corrige en plaçant un test en tête : ` if a == 0:` puis ` if b == 0:` puis ` return 0` puis ` return 1`. Ce cas a=0a=0 est régulièrement introduit en contrôle par un paramètre, par exemple (m1)x2+3x6=0(m-1)x^2+3x-6=0 avec m=1m=1, et l'oublier coûte tous les points de la question.

d) `def racines(a, b, c):` puis ` d = b*b - 4*a*c` puis ` if d > 0:` puis ` print((-b - sqrt(d))/(2*a), (-b + sqrt(d))/(2*a))` puis ` elif d == 0:` puis ` print(-b/(2*a))`, la fonction `sqrt` étant importée du module `math`. On n'écrit jamais `sqrt(d)` avant de savoir que d0d\ge 0 : la racine carrée d'un nombre négatif provoque une erreur qui interrompt le programme. Le test doit donc précéder le calcul, et non l'inverse.

Le fil : un programme de second degré est un arbre de cas, et chaque branche correspond à une phrase du cours. Les deux cas que l'on oublie sont toujours les mêmes, la racine double et le coefficient aa nul.

def nb_racines(a, b, c):
    if a == 0:
        if b == 0:
            return 0
        return 1
    d = b*b - 4*a*c
    if d > 0:
        return 2
    elif d == 0:
        return 1
    else:
        return 0

Partie B : problèmes et raisonnement (/50)

Exercice 6 : Espérance et écart-type d'une variable aléatoire

Une variable aléatoire XX prend les valeurs 00, 11, 22 et 33 avec les probabilités respectives 0,10{,}1, 0,30{,}3, 0,40{,}4 et 0,20{,}2. En Python, on stocke `x = [0, 1, 2, 3]` et `p = [0.1, 0.3, 0.4, 0.2]`.

  • a) Écrivez un programme qui calcule E(X)E(X) à l'aide d'une boucle, et donnez sa valeur.
  • b) Écrivez un programme qui calcule V(X)V(X) par la formule V(X)=E(X2)E(X)2V(X)=E(X^2)-E(X)^2, puis l'écart-type.
  • c) Écrivez une fonction `loi_valide(p)` qui vérifie que la liste des probabilités définit bien une loi. Pourquoi ne faut-il pas y écrire `if s == 1` ?
  • d) On répète l'expérience 1000010\,000 fois et l'on obtient une moyenne de 1,721{,}72. Ce résultat est-il compatible avec l'espérance calculée ? E(X)E(X) est-elle une valeur prise par XX ?

Tape tes réponses, la page te dit juste ou faux 0/6

a)
b)
c)
d)
Voir la correction

Réponses

  • a) E(X)=1,7E(X)=1{,}7
  • b) V(X)=0,81V(X)=0{,}81, σ=0,9\sigma=0{,}9
  • c) Tester abs(s - 1) < 1e-9 et la positivité
  • d) Compatible ; 1,71{,}7 n'est pas une valeur de XX

a) `E = 0` puis `for i in range(len(x)):` puis ` E = E + x[i]*p[i]` puis `print(E)`. On obtient E(X)=0×0,1+1×0,3+2×0,4+3×0,2=0+0,3+0,8+0,6=1,7E(X)=0\times 0{,}1+1\times 0{,}3+2\times 0{,}4+3\times 0{,}2=0+0{,}3+0{,}8+0{,}6=1{,}7. La boucle parcourt les INDICES et non les valeurs, parce qu'il faut avancer simultanément dans les deux listes : c'est la structure à connaître dès que deux tableaux se correspondent terme à terme.

b) `E2 = 0` puis `for i in range(len(x)):` puis ` E2 = E2 + x[i]*x[i]*p[i]`, puis `V = E2 - E*E` et `print(V, sqrt(V))`. On a E(X2)=0×0,1+1×0,3+4×0,4+9×0,2=0,3+1,6+1,8=3,7E(X^2)=0\times 0{,}1+1\times 0{,}3+4\times 0{,}4+9\times 0{,}2=0{,}3+1{,}6+1{,}8=3{,}7, donc V(X)=3,71,72=3,72,89=0,81V(X)=3{,}7-1{,}7^2=3{,}7-2{,}89=0{,}81 et σ=0,81=0,9\sigma=\sqrt{0{,}81}=0{,}9. Attention à la place des carrés : dans E(X2)E(X^2) on élève les VALEURS au carré avant de multiplier par les probabilités, alors que dans E(X)2E(X)^2 on élève au carré le résultat final. Les deux ne sont jamais égaux dès que XX n'est pas constante, et leur différence est précisément la variance.

c) `def loi_valide(p):` puis ` s = 0` puis ` for q in p:` puis ` if q < 0:` puis ` return False` puis ` s = s + q` puis ` return abs(s - 1) < 1e-9`. On n'écrit pas `s == 1` parce que la somme 0,1+0,3+0,4+0,20{,}1+0{,}3+0{,}4+0{,}2 ne vaut pas exactement 11 en machine : ces décimaux n'ont pas d'écriture finie en base deux, et la somme obtenue diffère de 11 d'environ 101610^{-16}. Le test d'égalité renverrait `False` pour une loi pourtant parfaitement valide. On teste donc un ÉCART, jamais une égalité, et l'on n'oublie pas la seconde condition d'une loi de probabilité : toutes les valeurs doivent être positives.

d) Oui, c'est compatible. La loi des grands nombres dit que la moyenne observée sur un grand nombre de répétitions se rapproche de l'espérance : 1,721{,}72 est très proche de 1,71{,}7, l'écart de 0,020{,}02 est de l'ordre de σn=0,9100=0,009\frac{\sigma}{\sqrt{n}}=\frac{0{,}9}{100}=0{,}009 à quelques unités près, ce qui est banal. En revanche E(X)=1,7E(X)=1{,}7 n'est PAS une valeur prise par XX, qui ne prend que des entiers : l'espérance est la moyenne pondérée théorique, pas un résultat possible de l'expérience. C'est la même chose que le nombre moyen d'enfants par famille.

Le fil : deux listes qui se correspondent se parcourent par les indices, et toute vérification numérique se fait avec une inégalité. Ces deux réflexes valent pour les probabilités comme pour les mesures de sciences.

E = 0
E2 = 0
for i in range(len(x)):
    E = E + x[i]*p[i]
    E2 = E2 + x[i]*x[i]*p[i]
V = E2 - E*E
print(E, V, sqrt(V))

Exercice 7 : Compléter un programme : résolution approchée par balayage

Soit ff définie sur R\mathbb{R} par f(x)=x3+x3f(x)=x^3+x-3. On admet que l'équation f(x)=0f(x)=0 possède une unique solution α\alpha, située entre 11 et 22.

Le programme suivant cherche un encadrement de α\alpha au centième. Trois éléments sont incomplets.

def f(x):
    return x**3 + x - 3

k = ...
while f(k/100) < ... :
    k = k + 1
print(..., k/100)
  • a) Complétez les trois éléments du programme.
  • b) Donnez l'encadrement obtenu, en précisant les deux valeurs de ff qui le justifient.
  • c) Démontrez que la solution est bien unique sur R\mathbb{R}.
  • d) Combien de tours la boucle effectue-t-elle ? Combien en faudrait-il pour un encadrement au millième ?

Tape tes réponses, la page te dit juste ou faux 0/4

b)
d)
Voir la correction

Réponses

  • a) k = 100 ; f(k/100) < 0 ; (k-1)/100
  • b) 1,21<α<1,221{,}21<\alpha<1{,}22
  • c) f(x)=3x2+1>0f'(x)=3x^{2}+1>0 : ff strictement croissante
  • d) 2222 tours ; 214214 au millième

a) On part de k=100k=100, ce qui correspond à x=1x=1, on avance tant que ff reste négative, et l'on affiche l'encadrement final : `k = 100`, puis `while f(k/100) < 0:`, puis `print((k-1)/100, k/100)`. Le balayage se fait sur un ENTIER kk et non directement sur xx, pour la raison vue en Seconde : additionner 0,010{,}01 des centaines de fois accumule les erreurs d'arrondi, alors qu'une division unique n'en accumule aucune.

b) La boucle s'arrête à k=122k=122, donc 1,21<α<1,221{,}21<\alpha<1{,}22. Les deux valeurs qui le justifient sont f(1,21)=1,771561+1,213=0,018439f(1{,}21)=1{,}771561+1{,}21-3=-0{,}018439, encore négative, et f(1,22)=1,815848+1,223=0,035848f(1{,}22)=1{,}815848+1{,}22-3=0{,}035848, devenue positive. La fonction change donc de signe entre ces deux abscisses. Une valeur plus fine, f(1,213)0,00223f(1{,}213)\approx -0{,}00223, montre que α1,2134\alpha\approx 1{,}2134.

c) La fonction ff est dérivable sur R\mathbb{R} avec f(x)=3x2+1f'(x)=3x^2+1. Comme 3x203x^2\ge 0, on a f(x)1>0f'(x)\ge 1>0 pour tout réel xx : ff est STRICTEMENT CROISSANTE sur R\mathbb{R}. Elle prend donc au plus une fois chaque valeur, en particulier la valeur 00, ce qui donne l'unicité. L'existence vient du changement de signe entre f(1)=1f(1)=-1 et f(2)=7f(2)=7. Le programme, lui, ne démontre rien de tout cela : il trouve UNE solution, et rien dans son affichage ne dit qu'il n'y en a pas d'autres ailleurs.

d) Elle part de k=100k=100 et s'arrête à k=122k=122, donc elle effectue 2222 tours. Pour un encadrement au millième, on balaierait avec k/1000k/1000 à partir de k=1000k=1000 jusqu'à k=1214k=1214, soit 214214 tours : diviser le pas par dix multiplie par dix le nombre de tours pour une décimale de plus. C'est le défaut du balayage, et c'est pourquoi on lui préfère la dichotomie quand la précision demandée est grande : celle-ci divise l'intervalle par deux à chaque tour et gagne une décimale toutes les trois ou quatre étapes.

Le fil : le programme FOURNIT un encadrement, le calcul de la dérivée DÉMONTRE qu'il n'y a rien d'autre à chercher. Une question de contrôle qui demande de justifier l'unicité attend le tableau de variations, jamais la sortie du programme.

def f(x):
    return x**3 + x - 3

k = 100
while f(k/100) < 0:
    k = k + 1
print((k-1)/100, k/100)
0.511.52-3-2-112345f croissante : un seul zero1,21 < alpha < 1,22

Exercice 8 : Cinq affirmations à corriger

Chacune des cinq affirmations suivantes est FAUSSE. Dites pourquoi, puis énoncez la version correcte.

  • a) « Le taux d'accroissement f(a+h)f(a)h\frac{f(a+h)-f(a)}{h} devient exactement égal à f(a)f'(a) lorsque l'on prend h=0h=0. »
  • b) « Pour tester le signe du discriminant, `if delta >= 0: return 2` suffit, puisqu'une racine double compte pour deux racines. »
  • c) « Si une suite converge vers LL, alors la boucle `while u < L` finit toujours par s'arrêter. »
  • d) « L'espérance d'une variable aléatoire est la valeur qu'elle a le plus de chances de prendre. »
  • e) « Plus le pas d'un balayage est petit, plus le résultat obtenu en machine est précis, sans limite. »

Tape tes réponses, la page te dit juste ou faux 0/5

a)
b)
c)
d)
e)
Voir la correction

Réponses

  • a) f(a)f'(a) est une limite
  • b) Δ=0\Delta=0 : une racine double
  • c) Seulement pour un seuil strictement inférieur à la limite
  • d) C'est le mode, pas l'espérance
  • e) Il existe un pas optimal

a) FAUX. Pour h=0h=0, le quotient n'existe pas : son dénominateur est nul. Le nombre dérivé est une LIMITE, c'est-à-dire la valeur dont le taux se rapproche autant qu'on veut quand hh tend vers 00, sans jamais y être évalué. Version correcte : « f(a)f'(a) est la limite du taux d'accroissement quand hh tend vers 00 ». La différence est visible sur l'exercice 4 : le taux vaut 1+3h+h21+3h+h^2, expression qui a bien une valeur en 00, mais seulement APRÈS simplification par hh, opération licite uniquement pour h0h\ne 0.

b) FAUX. Si Δ=0\Delta=0, l'équation admet UNE racine, dite double, x0=b2ax_0=-\frac{b}{2a} : la parabole est tangente à l'axe des abscisses et ne le coupe qu'en un point. Version correcte : « on teste Δ>0\Delta>0 pour deux racines, puis Δ=0\Delta=0 pour une racine double, puis Δ<0\Delta<0 pour aucune ». Dire qu'une racine double « compte pour deux » a un sens en factorisation, ax2+bx+c=a(xx0)2ax^2+bx+c=a(x-x_0)^2, mais pas quand on dénombre les solutions.

c) FAUX. Une suite convergente peut approcher sa limite sans jamais l'atteindre ni la dépasser. Avec un=1513×0,8nu_n=15-13\times 0{,}8^{\,n} de l'exercice 2, la boucle `while u < 15` ne s'arrête JAMAIS. Version correcte : « la boucle s'arrête pour tout seuil strictement inférieur à la limite, si la suite est croissante ». C'est la vérification à faire avant d'écrire tout programme de seuil : le seuil demandé est-il réellement franchi ?

d) FAUX, cela confond espérance et mode. L'espérance est la moyenne PONDÉRÉE des valeurs, E(X)=xipiE(X)=\sum x_i p_i, et elle n'est en général même pas une valeur prise par XX : à l'exercice 6, E(X)=1,7E(X)=1{,}7 alors que XX ne prend que les entiers 00 à 33. La valeur la plus probable, ici 22 avec p=0,4p=0{,}4, s'appelle le mode. Version correcte : « l'espérance est la moyenne des valeurs pondérée par leurs probabilités ».

e) FAUX. Deux erreurs s'opposent : l'erreur de méthode, proportionnelle au pas, et l'erreur d'arrondi, qui augmente quand le pas diminue, car on soustrait des nombres de plus en plus proches. En dessous d'un certain pas, le résultat se dégrade au lieu de s'améliorer, jusqu'au cas extrême de l'exercice 4 où 1+10171+10^{-17} vaut 11. Version correcte : « il existe un pas optimal, au-delà duquel la précision machine limite le gain ».

Ces cinq erreurs se ressemblent : chacune consiste à transporter en machine une propriété mathématique exacte, ou l'inverse. L'ordinateur travaille avec des nombres approchés et un nombre fini d'étapes, ce que le cours d'analyse ne fait jamais.

Exercice 9 : Décroissance radioactive et méthode d'Euler

L'iode 131131 a une demi-vie de 8,08{,}0 jours. Le nombre de noyaux restants est modélisé par N(t)=N0eλtN(t)=N_{0}\,\mathrm{e}^{-\lambda t}, où tt est en jours et λ=0,086643\lambda=0{,}086\,643 jour1^{-1}, valeur choisie pour que e8λ=12\mathrm{e}^{-8\lambda}=\frac{1}{2}. La vitesse de désintégration vérifie N(t)=λN(t)N'(t)=-\lambda N(t).

On approche l'évolution par la méthode d'Euler : sur un petit intervalle Δt\Delta t, on considère la vitesse comme constante, ce qui donne Nk+1=Nk(1λΔt)N_{k+1}=N_k\left(1-\lambda\,\Delta t\right).

  • a) Vérifiez à la calculatrice que e8λ0,5\mathrm{e}^{-8\lambda}\approx 0{,}5, puis écrivez un programme qui affiche la fraction de noyaux restants après 88 jours avec un pas Δt=1\Delta t=1 jour.
  • b) Comparez le résultat obtenu à la valeur exacte. Quel est l'écart relatif ?
  • c) Reprenez avec un pas Δt=0,1\Delta t=0{,}1 jour. Que constate-t-on sur l'erreur ?
  • d) Démontrez que la méthode d'Euler sous-estime TOUJOURS le nombre de noyaux restants.

Tape tes réponses, la page te dit juste ou faux 0/4

a)
b)
c)
Voir la correction

Réponses

  • a) e8λ0,5\mathrm{e}^{-8\lambda}\approx 0{,}5 ; programme : 0,4843\approx 0{,}4843
  • b) Écart relatif 3,1 %\approx 3{,}1\ \%
  • c) 0,4985\approx 0{,}4985, écart 0,3 %\approx 0{,}3\ \% : erreur divisée par dix
  • d) 1x<ex1-x<\mathrm{e}^{-x} pour x>0x>0

a) e8×0,086643=e0,6931440,5000\mathrm{e}^{-8\times 0{,}086\,643}=\mathrm{e}^{-0{,}693\,144}\approx 0{,}5000 : c'est bien la demi-vie de 88 jours. Le programme s'écrit `lam = 0.086643` puis `N = 1` puis `for k in range(8):` puis ` N = N*(1 - lam*1)` puis `print(N)`. On travaille en fraction, c'est-à-dire avec N0=1N_0=1, ce qui évite d'avoir à choisir un nombre de noyaux et rend le résultat directement comparable à 12\frac{1}{2}.

b) Le programme affiche environ 0,48430{,}4843. La valeur exacte est 12\frac{1}{2} par définition de la demi-vie, ce que confirme le modèle : N(8)=N0e8λ=N02N(8)=N_{0}\,\mathrm{e}^{-8\lambda}=\frac{N_{0}}{2}. L'écart relatif vaut 0,50,48430,53,1%\frac{0{,}5-0{,}4843}{0{,}5}\approx 3{,}1\%, ce qui est considérable pour une grandeur physique : la méthode d'Euler avec un pas d'un jour n'est pas utilisable ici, parce que le pas n'est pas petit devant la demi-vie.

c) On écrit `for k in range(80):` puis ` N = N*(1 - lam*0.1)`, et l'on obtient environ 0,49850{,}4985, soit un écart relatif de 0,3%0{,}3\%. Diviser le pas par dix a divisé l'erreur par dix, ce qui est la signature de la méthode d'Euler : son erreur est proportionnelle au pas. Pour gagner un facteur cent sur la précision, il faut donc cent fois plus de tours de boucle, et c'est ce compromis qui décide en pratique du pas choisi.

d) Sur un pas, la méthode donne Nk(1λΔt)N_k(1-\lambda\Delta t) alors que la solution exacte donne NkeλΔtN_ke^{-\lambda\Delta t}. Or pour tout réel x>0x>0 on a 1x<ex1-x<e^{-x} : il suffit d'étudier g(x)=ex1+xg(x)=e^{-x}-1+x, dont la dérivée g(x)=1exg'(x)=1-e^{-x} est strictement positive pour x>0x>0, avec g(0)=0g(0)=0, donc g(x)>0g(x)>0. En posant x=λΔtx=\lambda\Delta t, chaque pas d'Euler retire donc un peu TROP de noyaux, et ces sous-estimations se multiplient d'un pas à l'autre. La raison physique est claire : Euler applique pendant tout l'intervalle la vitesse de désintégration du DÉBUT du pas, alors que la vitesse réelle diminue à mesure que les noyaux disparaissent.

Le fil : la méthode d'Euler transforme la relation N=λNN'=-\lambda N en suite géométrique de raison 1λΔt1-\lambda\Delta t, objet parfaitement connu du programme de Première. L'exponentielle est la limite de ces suites quand le pas tend vers zéro, et l'inégalité 1x<ex1-x<e^{-x} dit dans quel sens on se trompe.

lam = 0.086643
N = 1
for k in range(80):
    N = N*(1 - lam*0.1)
print(N)
2468101214160.20.40.60.81courbe : modele exactpoints : Euler avec un pas de 1 jourdemi-vie : 0,5 a t = 8 jours

Exercice 10 : Problème de synthèse : trajectoire d'un ballon

Un ballon est frappé depuis une hauteur de 1,81{,}8 m. Dans un repère où xx est la distance horizontale en mètres et yy la hauteur en mètres, sa trajectoire est décrite par y(x)=0,05x2+0,8x+1,8y(x)=-0{,}05x^2+0{,}8x+1{,}8.

Un mur de 44 m de haut se dresse à 1414 m du point de frappe.

  • a) Écrivez un programme qui balaie xx de 00 à 2020 m par pas de 0,50{,}5 m et affiche la hauteur maximale atteinte, puis donnez cette valeur.
  • b) Retrouvez l'abscisse du sommet par la dérivée, et donnez la hauteur maximale exacte.
  • c) Calculez la portée du tir, c'est-à-dire la distance au bout de laquelle le ballon touche le sol.
  • d) Le ballon passe-t-il au-dessus du mur ? Écrivez le programme qui répond, et démontrez le résultat par le calcul.

Tape tes réponses, la page te dit juste ou faux 0/6

a)
b)
c)
d)
Voir la correction

Réponses

  • a) 55 m
  • b) y(x)=0,1x+0,8y'(x)=-0{,}1x+0{,}8 : sommet en 88 m, hauteur 55 m
  • c) Portée 1818 m
  • d) y(14)=3,2<4y(14)=3{,}2<4 : le ballon ne passe pas

a) `def y(x):` puis ` return -0.05*x*x + 0.8*x + 1.8`, puis `M = 0` puis `for k in range(0, 41):` puis ` if y(k/2) > M:` puis ` M = y(k/2)` puis `print(M)`. Le programme affiche 55, atteint pour x=8x=8 m. Comme d'habitude, on boucle sur l'entier kk et l'on pose x=k2x=\frac{k}{2} ; `range(0, 41)` donne bien les 4141 abscisses de 00 à 2020 m.

b) La dérivée vaut y(x)=0,1x+0,8y'(x)=-0{,}1x+0{,}8, qui s'annule en x=0,80,1=8x=\frac{0{,}8}{0{,}1}=8 m. Elle est positive avant et négative après, donc yy atteint son MAXIMUM en 88 : y(8)=0,05×64+0,8×8+1,8=3,2+6,4+1,8=5y(8)=-0{,}05\times 64+0{,}8\times 8+1{,}8=-3{,}2+6{,}4+1{,}8=5 m. Le balayage donnait la même valeur, mais par chance : le sommet tombait exactement sur une abscisse balayée. Avec un pas de 0,70{,}7 m, il aurait donné une valeur légèrement inférieure, et c'est pourquoi une hauteur maximale se justifie toujours par la dérivée ou par la forme canonique.

c) On résout 0,05x2+0,8x+1,8=0-0{,}05x^2+0{,}8x+1{,}8=0. En multipliant par 20-20 : x216x36=0x^2-16x-36=0, donc Δ=256+144=400\Delta=256+144=400 et Δ=20\sqrt{\Delta}=20. Les racines sont 16202=2\frac{16-20}{2}=-2 et 16+202=18\frac{16+20}{2}=18. Seule la racine positive a un sens physique : la portée est de 1818 m. La racine 2-2 correspond au point d'où serait parti le ballon s'il avait décollé du sol avec la même parabole, information sans objet ici.

d) `if y(14) > 4:` puis ` print("passe")` puis `else:` puis ` print("touche le mur")`. On calcule y(14)=0,05×196+0,8×14+1,8=9,8+11,2+1,8=3,2y(14)=-0{,}05\times 196+0{,}8\times 14+1{,}8=-9{,}8+11{,}2+1{,}8=3{,}2 m, ce qui est INFÉRIEUR à 44 m : le ballon ne passe pas. On peut préciser où il aurait fallu placer le mur : résoudre y(x)=4y(x)=4 donne 0,05x2+0,8x2,2=0-0{,}05x^2+0{,}8x-2{,}2=0, soit x216x+44=0x^2-16x+44=0, de discriminant 256176=80256-176=80 et de racines 16±452=8±25\frac{16\pm 4\sqrt5}{2}=8\pm 2\sqrt5, c'est-à-dire environ 3,533{,}53 m et 12,4712{,}47 m. Le ballon est donc au-dessus de 44 m entre ces deux abscisses seulement, et le mur à 1414 m est trop loin de 1,51{,}5 m environ.

Le fil de la série se referme ici : le balayage EXPLORE, la dérivée LOCALISE, le discriminant DÉCIDE. Un programme seul aurait répondu à d) mais n'aurait donné ni la hauteur exacte, ni la portée, ni l'intervalle de franchissement, qui sont les trois résultats attendus dans un exercice de contrôle.

def y(x):
    return -0.05*x*x + 0.8*x + 1.8

M = 0
for k in range(0, 41):
    if y(k/2) > M:
        M = y(k/2)
print(M)

if y(14) > 4:
    print("passe")
else:
    print("touche le mur")
2468101214161820123456sommet (8 ; 5)mur de 4 mportee 18 my(14) = 3,2 m : le ballon ne passe pas

Partie C : les classiques (/50)

Exercice 11 : Construire et exploiter une liste de termes

On considère la suite définie pour tout entier naturel nn par un=n27n+15u_{n}=n^{2}-7n+15, et le programme suivant.

L = [n*n - 7*n + 15 for n in range(10)]
print(L)
print(min(L))
  • a) Quelle liste contient la variable L ?
  • b) Que renvoie min(L) ? Pour quels rangs ce minimum est-il atteint ?
  • c) Complétez le programme pour qu'il affiche le nombre de termes de L strictement inférieurs à 1010, et donnez ce nombre.
  • d) On construit D = [L[i+1] - L[i] for i in range(9)]. Que contient D ? Justifiez par le calcul de un+1unu_{n+1}-u_{n}.
  • e) Que renvoie sum(L) ?

Tape tes réponses, la page te dit juste ou faux 0/9

a)
b)
c)
d)
e)
Voir la correction

Réponses

  • a) [15, 9, 5, 3, 3, 5, 9, 15, 23, 33]
  • b) 33, aux rangs 33 et 44
  • c) 66 termes
  • d) D = [-6, -4, ..., 10] : un+1un=2n6u_{n+1}-u_n=2n-6
  • e) 120120

a) La liste en compréhension calcule unu_{n} pour nn allant de 00 à 99, soit dix termes : L = [15, 9, 5, 3, 3, 5, 9, 15, 23, 33]. On contrôle deux termes : u0=15u_{0}=15 et u9=8163+15=33u_{9}=81-63+15=33 ✓.

b) min(L) renvoie 33, atteint aux rangs 33 et 44 (les indices 33 et 44 de la liste, qui commence à l'indice 00). C'est cohérent avec la fonction xx27x+15x\mapsto x^{2}-7x+15, dont le sommet est en x=3,5x=3{,}5, au milieu de 33 et 44, qui sont donc à égale distance du sommet.

c) On ajoute un compteur : c = 0, puis for u in L:, puis if u < 10:, puis c = c + 1, et enfin print(c). Les termes inférieurs à 1010 sont 99, 55, 33, 33, 55 et 99 : le programme affiche 66. Parcourir directement les VALEURS de la liste suffit ici, puisqu'on n'a pas besoin des rangs.

d) D = [-6, -4, -2, 0, 2, 4, 6, 8, 10]. En effet un+1un=(n+1)27(n+1)+15(n27n+15)=2n+17=2n6u_{n+1}-u_{n}=(n+1)^{2}-7(n+1)+15-(n^{2}-7n+15)=2n+1-7=2n-6. Les écarts forment une suite ARITHMÉTIQUE de raison 22 : c'est la signature d'une suite du second degré. Le signe de 2n62n-6 explique aussi b) : la suite décroît tant que n<3n<3, stagne de u3u_{3} à u4u_{4}, puis croît.

e) sum(L) renvoie 15+9+5+3+3+5+9+15+23+33=12015+9+5+3+3+5+9+15+23+33=120.

Une liste en compréhension est la traduction directe de « la liste des unu_{n} pour nn de 00 à 99 ». Les fonctions min, sum et les listes d'écarts transforment ensuite des questions de cours, minimum, sens de variation, somme, en une ligne de programme ; mais seul le calcul de un+1unu_{n+1}-u_{n} justifie ce que la liste montre.

L = [n*n - 7*n + 15 for n in range(10)]
c = 0
for u in L:
    if u < 10:
        c = c + 1
print(c)
D = [L[i+1] - L[i] for i in range(9)]
print(D, sum(L))

Exercice 12 : La méthode d'Archimède pour approcher π

Archimède encadrait π\pi par les périmètres de polygones réguliers inscrits dans un cercle de rayon 11. On note cnc_{n} le côté du polygone régulier à nn côtés inscrit ; son demi-périmètre ncn2\frac{n\,c_{n}}{2} approche π\pi par défaut.

On admet la formule de doublement c2n=24cn2c_{2n}=\sqrt{2-\sqrt{4-c_{n}^{2}}}, obtenue par le théorème de Pythagore dans le cercle.

from math import sqrt

def archimede(k):
    c = 1
    n = 6
    for i in range(k):
        ...
        ...
    return n*c/2
  • a) Justifiez que c6=1c_{6}=1, puis calculez le demi-périmètre de l'hexagone.
  • b) Calculez c12c_{12} au millionième et le demi-périmètre du dodécagone au millième.
  • c) Écrivez un programme qui part de l'hexagone et double kk fois le nombre de côtés, puis affiche le demi-périmètre. Donnez les valeurs obtenues pour 4848 et 9696 côtés, au millième.
  • d) En doublant une vingtaine de fois, le programme affiche des valeurs de plus en plus fausses, puis 00. Expliquez ce phénomène.
  • e) Montrez que 24c2=c22+4c22-\sqrt{4-c^{2}}=\frac{c^{2}}{2+\sqrt{4-c^{2}}}, et déduisez-en une formule de doublement qui évite le problème.

Tape tes réponses, la page te dit juste ou faux 0/7

a)
b)
c)
d)
e)
Voir la correction

Réponses

  • a) c6=1c_6=1, demi-périmètre 33
  • b) c120,517638c_{12}\approx 0{,}517\,638 ; 3,106\approx 3{,}106
  • c) 3,139\approx 3{,}139 et 3,141\approx 3{,}141
  • d) Soustraction de nombres presque égaux : perte des chiffres significatifs
  • e) c2n=cn2+4cn2c_{2n}=\frac{c_n}{\sqrt{2+\sqrt{4-c_n^{2}}}}

a) L'hexagone régulier inscrit se découpe en six triangles équilatéraux de côté égal au rayon : c6=1c_{6}=1. Son demi-périmètre vaut 6×12=3\frac{6\times 1}{2}=3, première approximation de π\pi, déjà connue des Babyloniens.

b) c12=230,2679490,517638c_{12}=\sqrt{2-\sqrt{3}}\approx\sqrt{0{,}267\,949}\approx 0{,}517\,638. Demi-périmètre : 12×0,51763823,106\frac{12\times 0{,}517\,638}{2}\approx 3{,}106.

c) On initialise c = 1 et n = 6, puis, dans une boucle for exécutée k fois, on remplace c par sqrt(2 - sqrt(4 - c*c)) et n par 2*n ; on affiche enfin n*c/2. Avec 4848 côtés, on obtient environ 3,139353{,}139\,35, soit 3,1393{,}139 ; avec 9696 côtés, environ 3,141033{,}141\,03, soit 3,1413{,}141. C'est l'encadrement du polygone à 9696 côtés qu'avait atteint Archimède.

d) Quand cc devient très petit, 4c2\sqrt{4-c^{2}} est extrêmement proche de 22, et la différence 24c22-\sqrt{4-c^{2}} soustrait deux nombres presque égaux. Les flottants ne gardant qu'une quinzaine de chiffres significatifs, cette différence perd presque tous ses chiffres justes, puis vaut exactement 00 quand c2c^{2} devient négligeable devant 44. C'est le même phénomène que pour le taux d'accroissement de l'exercice 4 avec un pas trop petit.

e) On multiplie par la quantité conjuguée : (24c2)(2+4c2)=4(4c2)=c2\left(2-\sqrt{4-c^{2}}\right)\left(2+\sqrt{4-c^{2}}\right)=4-(4-c^{2})=c^{2}, d'où l'égalité. Donc c2n=cn22+4cn2=cn2+4cn2c_{2n}=\sqrt{\frac{c_{n}^{2}}{2+\sqrt{4-c_{n}^{2}}}}=\frac{c_{n}}{\sqrt{2+\sqrt{4-c_{n}^{2}}}}. Cette formule n'ADDITIONNE que des nombres positifs : plus aucune soustraction de nombres voisins, et le programme converge vers 3,141592653589793{,}141\,592\,653\,589\,79 sans jamais se dégrader.

Deux formules mathématiquement égales peuvent se comporter très différemment en machine. La quantité conjuguée, outil de calcul de limites au lycée, est aussi l'outil qui réécrit une soustraction instable en une division stable : c'est un réflexe de programmeur autant que de mathématicien.

from math import sqrt

def archimede(k):
    c = 1
    n = 6
    for i in range(k):
        c = c/sqrt(2 + sqrt(4 - c*c))
        n = 2*n
    return n*c/2

print(archimede(3), archimede(4))

Exercice 13 : Géométrie repérée en Python

Un point du plan est représenté par une liste de deux nombres, par exemple A = [1, 2]. On veut écrire trois fonctions de géométrie repérée.

  • a) Écrivez une fonction alignes(A, B, C) qui renvoie True si les trois points sont alignés, à l'aide du déterminant des vecteurs AB\vec{AB} et AC\vec{AC}. Que renvoie-t-elle pour A(1;2)A(1\,;2), B(4;8)B(4\,;8) et C(2;4)C(-2\,;-4) ?
  • b) Écrivez une fonction equation(A, B) qui renvoie les coefficients aa, bb, cc d'une équation cartésienne ax+by+c=0ax+by+c=0 de la droite (AB)(AB). Donnez le résultat pour A(1;2)A(1\,;2) et B(4;8)B(4\,;8).
  • c) Écrivez une fonction perpendiculaires(A, B, C, D) qui teste si (AB)(CD)(AB)\perp(CD). Que renvoie-t-elle pour A(1;2)A(1\,;2), B(4;8)B(4\,;8), C(1;2)C(1\,;2) et D(5;0)D(5\,;0) ?
  • d) Avec des points à coordonnées décimales, alignes([0, 0], [0.1, 0.3], [0.3, 0.9]) renvoie False. Pourquoi, et comment corriger la fonction ?

Tape tes réponses, la page te dit juste ou faux 0/7

a)
b)
c)
d)
Voir la correction

Réponses

  • a) Déterminant nul : True
  • b) a=6a=6, b=3b=-3, c=0c=0 : 2xy=02x-y=0
  • c) ABCD=0\vec{AB}\cdot\vec{CD}=0 : True
  • d) Arrondis binaires : tester abs(det) < 1e-9

a) Les vecteurs AB(xBxA;yByA)\vec{AB}(x_{B}-x_{A}\,;y_{B}-y_{A}) et AC\vec{AC} sont colinéaires si et seulement si leur déterminant det=(xBxA)(yCyA)(yByA)(xCxA)\det=(x_{B}-x_{A})(y_{C}-y_{A})-(y_{B}-y_{A})(x_{C}-x_{A}) est nul. Ici AB(3;6)\vec{AB}(3\,;6) et AC(3;6)\vec{AC}(-3\,;-6) : det=3×(6)6×(3)=0\det=3\times(-6)-6\times(-3)=0. La fonction renvoie True.

b) Un vecteur directeur est AB(u;v)\vec{AB}(u\,;v) ; un vecteur normal est (v;u)(v\,;-u), d'où a=va=v, b=ub=-u, puis c=(axA+byA)c=-(a\,x_{A}+b\,y_{A}). Pour AB(3;6)\vec{AB}(3\,;6) : a=6a=6, b=3b=-3, c=(66)=0c=-(6-6)=0. La droite a pour équation 6x3y=06x-3y=0, soit 2xy=02x-y=0. Vérification avec BB : 2424=024-24=0 ✓.

c) Les droites sont perpendiculaires si et seulement si ABCD=0\vec{AB}\cdot\vec{CD}=0. AB(3;6)\vec{AB}(3\,;6) et CD(4;2)\vec{CD}(4\,;-2) : 1212=012-12=0. La fonction renvoie True.

d) Mathématiquement, det=0,1×0,90,3×0,3=0,090,09=0\det=0{,}1\times 0{,}9-0{,}3\times 0{,}3=0{,}09-0{,}09=0. Mais 0,10{,}1, 0,30{,}3 et 0,90{,}9 n'ont pas d'écriture finie en base deux : le calcul en machine donne un nombre de l'ordre de 101710^{-17}, et le test det == 0 échoue. On corrige en testant abs(det) < 1e-9. Tout test d'égalité entre flottants issus d'un calcul se remplace par un test d'écart.

La géométrie repérée se programme presque mot pour mot : un déterminant nul pour la colinéarité, un produit scalaire nul pour l'orthogonalité, l'échange des coordonnées pour passer du vecteur directeur au vecteur normal. Le seul ajout propre à la machine est la tolérance, indispensable dès que les coordonnées ne sont pas entières.

def alignes(A, B, C):
    d = (B[0]-A[0])*(C[1]-A[1]) - (B[1]-A[1])*(C[0]-A[0])
    return abs(d) < 1e-9

def equation(A, B):
    u, v = B[0]-A[0], B[1]-A[1]
    a, b = v, -u
    return a, b, -(a*A[0] + b*A[1])

def perpendiculaires(A, B, C, D):
    p = (B[0]-A[0])*(D[0]-C[0]) + (B[1]-A[1])*(D[1]-C[1])
    return abs(p) < 1e-9

Exercice 14 : La suite de Syracuse

On part d'un entier n1n\geq 1. S'il est pair, on le divise par 22 ; s'il est impair, on le multiplie par 33 et on ajoute 11. On recommence jusqu'à obtenir 11. La conjecture de Syracuse affirme qu'on atteint toujours 11, quel que soit l'entier de départ ; elle n'a jamais été démontrée.

Le TEMPS DE VOL est le nombre d'étapes pour atteindre 11, l'ALTITUDE MAXIMALE la plus grande valeur rencontrée.

  • a) Écrivez une fonction vol(n) qui renvoie la liste des valeurs, de nn jusqu'à 11 compris.
  • b) Donnez la liste obtenue pour n=7n=7, son temps de vol et son altitude maximale.
  • c) Pour n=27n=27, le programme donne un temps de vol de 111111. Quelle altitude maximale affiche-t-il ?
  • d) Écrivez un programme qui cherche, parmi les entiers de 11 à 9999, celui dont le temps de vol est le plus long. Il affiche 9797. Quel est ce temps de vol ?
  • e) Pourquoi la boucle while de la fonction vol ne constitue-t-elle pas une démonstration de la conjecture ?

Tape tes réponses, la page te dit juste ou faux 0/5

b)
c)
d)
e)
Voir la correction

Réponses

  • a) Boucle while n != 1 avec n // 2 ou 3*n + 1
  • b) Temps de vol 1616, altitude maximale 5252
  • c) 92329\,232
  • d) 118118 étapes
  • e) Un programme ne teste qu'un nombre fini d'entiers

a) On range nn dans une liste, puis tant que n != 1 : si n % 2 == 0, on remplace n par n // 2, sinon par 3*n + 1, et l'on ajoute chaque nouvelle valeur à la liste. L'opérateur // donne le quotient entier et garde un entier ; / donnerait un flottant, 11,011{,}0 au lieu de 1111.

b) 77, 2222, 1111, 3434, 1717, 5252, 2626, 1313, 4040, 2020, 1010, 55, 1616, 88, 44, 22, 11. La liste compte 1717 valeurs, donc 1616 étapes : le temps de vol vaut 1616, c'est-à-dire len(L) - 1, et non len(L). L'altitude maximale vaut 5252, bien plus que le départ.

c) L'altitude maximale est 92329\,232, atteinte en partant de 2727 : un nombre de départ modeste peut monter très haut avant de redescendre, et c'est ce comportement erratique qui rend la conjecture si difficile.

d) On garde le meilleur temps dans une variable, en parcourant for k in range(1, 100) et en comparant len(vol(k)) - 1 au record. Le record est atteint pour k=97k=97, avec un temps de vol de 118118 étapes ; son altitude maximale est aussi 92329\,232, car la trajectoire de 9797 rejoint celle de 2727.

e) Le programme vérifie la conjecture pour chaque entier TESTÉ, en s'arrêtant quand il atteint 11. Si un entier ne l'atteignait jamais, la boucle tournerait indéfiniment et le programme ne répondrait rien : il ne peut ni prouver que tous les entiers conviennent, puisqu'il y en a une infinité, ni prouver qu'un entier ne convient pas. Des vérifications ont été menées sur des milliards de milliards d'entiers ; ce ne sont pas des démonstrations.

La suite de Syracuse est définie par récurrence, mais sans aucune formule explicite ni sens de variation : c'est l'exemple type où seul le programme permet d'explorer. Il fournit des conjectures et des contre-exemples potentiels ; la démonstration, elle, reste un travail de mathématicien, ici toujours inachevé.

def vol(n):
    L = [n]
    while n != 1:
        if n % 2 == 0:
            n = n // 2
        else:
            n = 3*n + 1
        L.append(n)
    return L

print(len(vol(7)) - 1, max(vol(7)), max(vol(27)))

record, meilleur = 0, 1
for k in range(1, 100):
    t = len(vol(k)) - 1
    if t > record:
        record, meilleur = t, k
print(meilleur, record)

Exercice 15 : La fluctuation des moyennes d'échantillons

On lance un dé équilibré ; on note XX le résultat. Un ÉCHANTILLON de taille nn est une série de nn lancers indépendants, dont on calcule la moyenne mm.

Le programme ci-dessous simule 10001\,000 échantillons de taille n=100n=100 et compte la proportion de ceux dont la moyenne mm vérifie mμ2σn|m-\mu|\leq\frac{2\sigma}{\sqrt{n}}, où μ\mu et σ\sigma sont l'espérance et l'écart-type de XX.

from random import randint
from math import sqrt

def moyenne(n):
    ...

mu, sigma = 3.5, sqrt(35/12)
c = 0
for i in range(1000):
    m = moyenne(100)
    if abs(m - mu) <= 2*sigma/sqrt(100):
        c = c + 1
print(c/1000)
  • a) Calculez μ=E(X)\mu=E(X) et σ=σ(X)\sigma=\sigma(X), ce dernier au millième.
  • b) Calculez 2σ100\frac{2\sigma}{\sqrt{100}} au millième. Complétez la fonction moyenne(n) du programme.
  • c) Le programme affiche une proportion d'environ 0,950{,}95. Les résultats diffèrent d'une exécution à l'autre : est-ce une erreur ?
  • d) On passe à des échantillons de taille 400400. Que devient la demi-largeur 2σn\frac{2\sigma}{\sqrt{n}} ?
  • e) Quelle taille minimale d'échantillon faut-il pour que 2σn0,1\frac{2\sigma}{\sqrt{n}}\leq 0{,}1 ?

Tape tes réponses, la page te dit juste ou faux 0/6

a)
b)
c)
d)
e)
Voir la correction

Réponses

  • a) μ=3,5\mu=3{,}5, σ=35121,708\sigma=\sqrt{\frac{35}{12}}\approx 1{,}708
  • b) 0,342\approx 0{,}342
  • c) Non : la proportion fluctue autour de 0,950{,}95
  • d) 0,171\approx 0{,}171, divisée par deux
  • e) n1167n\geq 1\,167

a) μ=1+2+3+4+5+66=3,5\mu=\frac{1+2+3+4+5+6}{6}=3{,}5. E(X2)=1+4+9+16+25+366=916E(X^{2})=\frac{1+4+9+16+25+36}{6}=\frac{91}{6}, donc V(X)=9163,52=3512V(X)=\frac{91}{6}-3{,}5^{2}=\frac{35}{12} et σ=35121,708\sigma=\sqrt{\frac{35}{12}}\approx 1{,}708.

b) 2×1,708100,342\frac{2\times 1{,}708}{10}\approx 0{,}342. La fonction moyenne(n) additionne n tirages randint(1, 6) dans un accumulateur initialisé à 00, puis renvoie la somme divisée par n.

c) Non. Chaque exécution tire de nouveaux nombres au hasard, donc de nouveaux échantillons : la proportion observée fluctue elle aussi, en restant voisine de 0,950{,}95. C'est le résultat attendu : environ 95 %95\ \% des moyennes d'échantillons tombent à moins de 2σn\frac{2\sigma}{\sqrt{n}} de l'espérance.

d) 2σ400=2×1,708200,171\frac{2\sigma}{\sqrt{400}}=\frac{2\times 1{,}708}{20}\approx 0{,}171 : quatre fois plus de lancers divisent la demi-largeur par DEUX seulement, car 400=2100\sqrt{400}=2\sqrt{100}.

e) 2σn0,1    n20σ34,16    n(20σ)2=400×35121166,7\frac{2\sigma}{\sqrt{n}}\leq 0{,}1\iff\sqrt{n}\geq 20\sigma\approx 34{,}16\iff n\geq(20\sigma)^{2}=400\times\frac{35}{12}\approx 1\,166{,}7. Il faut au moins 11671\,167 lancers par échantillon.

La moyenne d'un échantillon fluctue autour de l'espérance, et d'autant moins que l'échantillon est grand ; mais la précision progresse comme n\sqrt{n}, pas comme nn. C'est pourquoi un sondage deux fois plus précis coûte quatre fois plus cher, et c'est ce que la simulation permet d'observer avant de le démontrer.

def moyenne(n):
    s = 0
    for i in range(n):
        s = s + randint(1, 6)
    return s/n
Chapitre précédent Les variables aléatoires

Ce chapitre resservira dans

Les chapitres qui le réclament en amont, plus tard dans l'année ou dans les années suivantes.

Voir aussi

Vous cherchez un tuteur de spécialité maths en Première à Montréal ?

Contactez-moi pour une première séance. On travaille sur des exercices calibrés sur le niveau réel des contrôles au Lycée Marie de France et au Collège Stanislas.

Site par Studio Squalli