Maths Seconde, programme français • Exercices corrigés à Montréal
Exercices corrigés : Python appliqué aux maths, à la physique et à la chimie (Seconde)
Voici une série d'exercices corrigés de Python appliqué aux mathématiques et aux sciences, au niveau de la classe de Seconde du programme français, tel qu'il est suivi au Lycée Marie de France et au Collège Stanislas à Montréal. Elle fait programmer des tableaux de valeurs, des fonctions avec print et return, des boucles for et while, la recherche de seuil, le balayage et le traitement de listes de mesures, sur des formules du cours de physique-chimie : vitesse moyenne, concentration et dilution, titrage, chute libre, loi d'Ohm, masse volumique, loi de Snell-Descartes, période et fréquence d'un son. Quinze exercices en trois parties.
À la fin de la série, vous savez dresser un tableau de valeurs avec un pas décimal (exercice 1), convertir des unités dans une fonction (exercice 2), calculer une concentration et le volume à prélever pour une dilution (exercice 3), trouver un seuil avec une boucle while (exercices 4 et 10), distinguer print et return (exercice 5), calculer moyenne et étendue d'une série de mesures (exercice 6), lire le volume équivalent d'un titrage dans deux listes (exercice 7) et encadrer une durée de chute libre par balayage (exercice 9). La partie C estime une résistance par la loi d'Ohm (exercice 11), identifie un métal par sa masse volumique (exercice 12), calcule des vitesses sur une chronophotographie (exercice 13), programme la réfraction et l'angle limite (exercice 14) et mesure une distance par écho (exercice 15).
Chaque programme de cette série calcule quelque chose qui existe déjà dans le cours : une image, une vitesse, une concentration, une moyenne. L'ordinateur n'apporte aucune mathématique nouvelle, il répète la même formule des dizaines de fois sans se tromper. Tout le travail consiste donc à écrire correctement dans la boucle la formule que l'on sait déjà poser à la main.
Les corrigés traitent les erreurs qui faussent un résultat sans message d'erreur : une durée de 1 h 48 min tapée 1.48 (exercice 2), un volume en millilitres là où la formule attend des litres (exercice 3), range qui ne produit que des entiers (exercice 1), une boucle qui ajoute 0,1 au lieu de boucler sur des entiers (exercice 9), et le test d'égalité entre deux flottants qui fait tourner une boucle sans fin (exercice 10).
Série autocorrigéeTape tes réponses et vérifie-les question par 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, et tes réponses justes restent remplies quand tu reviens.
•Une affectation x = 3 range une valeur dans une variable et se lit de droite à gauche. = affecte, == teste une égalité.
•for k in range(a, b) parcourt les entiers de a à b - 1 : la borne de droite est exclue, et range ne produit que des ENTIERS.
•Pour balayer des décimales, on boucle sur des entiers et on divise : for k in range(0, 21) puis x = k/10.
•On utilise for quand le nombre de tours est connu d'avance, et while quand il dépend d'une condition, typiquement une recherche de seuil.
•return renvoie une valeur exploitable, print se contente d'afficher. Une fonction sans return renvoie None.
•Pour une liste L : len(L) est son nombre d'éléments, L[0] le premier, L[len(L) - 1] le dernier.
•Vitesse moyenne : v=td. Pour passer des km/h aux m/s, on DIVISE par 3,6.
•Quantité de matière et concentration : n=Mm et c=Vn, donc c=M×Vm avec V en litres.
•Les nombres décimaux sont représentés de façon approchée en machine : on ne teste jamais l'égalité de deux flottants.
Partie A : les bases (/50)
Exercice 1 : Tableau de valeurs d'une fonction
On considère la fonction f définie sur R par f(x)=x2−4x+1, et le programme suivant.
for x in range(-1, 6):
print(x, x*x - 4*x + 1)
a) Dressez le tableau des valeurs affichées par ce programme.
b) Quelle valeur de x donne le plus petit résultat ? Retrouvez-la par le calcul.
c) On veut maintenant un tableau de valeurs allant de −1 à 5 avec un pas de 0,5. Écrivez le programme correspondant.
d) Un élève écrit for x in range(-1, 5). Que manque-t-il dans son tableau ?
Voir la correction
Réponses
a)6 ; 1 ; −2 ; −3 ; −2 ; 1 ; 6
b)x=2 ; f(x)=(x−2)2−3≥−3
c)for k in range(-2, 11): puis x = k/2 : 13 lignes
d)Il manque x=5
a)
La boucle range(-1, 6) parcourt les entiers de −1 à 5, la borne de droite étant EXCLUE. On calcule f pour chacun : f(−1)=1+4+1=6, f(0)=1, f(1)=1−4+1=−2, f(2)=4−8+1=−3, f(3)=9−12+1=−2, f(4)=16−16+1=1, f(5)=25−20+1=6. Le tableau affiché est donc 6;1;−2;−3;−2;1;6.
b)
Le plus petit résultat, −3, est obtenu pour x=2. Le calcul le confirme et va plus loin que la machine : la forme canonique s'écrit f(x)=(x−2)2−3, car (x−2)2=x2−4x+4 et il faut retirer 3 pour retrouver le +1. Comme un carré est toujours positif ou nul, f(x)≥−3 pour tout x, avec égalité uniquement en x=2. Le programme SUGGÈRE le minimum sur sept valeurs, le calcul le DÉMONTRE sur tous les réels : la différence est exactement celle entre une observation et une preuve.
c)
range ne fabrique que des entiers, donc on ne peut pas lui demander un pas de 0,5. On boucle sur des entiers et on divise : for k in range(-2, 11): puis x = k/2 puis print(x, x*x - 4*x + 1). Le compteur k va de −2 à 10, ce qui donne bien x de −1 à 5 par pas de 0,5, soit treize lignes.
d)
Il manque la dernière ligne, celle de x=5 : range(-1, 5) s'arrête à 4 inclus, alors que la version de l'énoncé allait jusqu'à 5. C'est l'erreur la plus fréquente du chapitre. La règle à retenir dans les deux sens : range(a, b) contient a, ne contient pas b, et compte b−a valeurs. Ici 5−(−1)=6 valeurs au lieu de sept.
Le fil de tout l'exercice : le programme ne fait rien d'autre que remplacer x par des valeurs successives dans une expression que l'on a écrite soi-même. S'il affiche des résultats faux, ce n'est presque jamais la machine, c'est la formule ou les bornes de la boucle.
for k in range(-2, 11):
x = k/2
print(x, x*x - 4*x + 1)
Coche ici les exercices faits ou à revoir : un compte gratuit, sans mot de passe, retient tes coches et tes réponses justes d'une visite à l'autre, te dit quel chapitre attaquer ensuite et te permet de demander l'exercice qui te manque. Crée ton espace, un courriel suffit.
Exercice 2 : Vitesse moyenne et conversion d'unités
Un train relie deux villes distantes de 234 km en 1 h 48 min. On veut automatiser le calcul de sa vitesse moyenne.
a) Que renvoie la fonction vitesse si d est en kilomètres et t en heures ?
b) Le programme affiche environ 158. Pourquoi ce résultat est-il faux, et que faut-il écrire ?
c) Écrivez une fonction en_ms(v) qui convertit une vitesse donnée en km/h en mètres par seconde, et appliquez-la au résultat corrigé.
d) Que se passe-t-il si l'on appelle vitesse(234, 0) ? Comment protéger la fonction ?
Voir la correction
Réponses
a)La vitesse en km/h
b)1 h 48 min =1,8 h : 130 km/h
c)return v/3.6 ; ≈36,1 m/s
d)Division par zéro ; tester t == 0
a)
Elle renvoie la vitesse moyenne en kilomètres par heure, puisque v=td et que l'unité d'un quotient est le quotient des unités : des kilomètres divisés par des heures donnent des km/h. Une fonction ne connaît pas les unités, c'est à celui qui l'appelle de fournir des données cohérentes.
b)
L'erreur n'est pas informatique, elle est physique : 1 h 48 min ne s'écrit pas 1,48 h. Les minutes se comptent par soixante, pas par cent. Il faut convertir : 48 min =6048 h =0,8 h, donc la durée vaut 1,8 h. On écrit print(vitesse(234, 1.8)), ce qui donne 1,8234=130 km/h. L'écart avec le résultat erroné est énorme, 158 contre 130, et rien dans le programme ne le signale : la machine calcule exactement ce qu'on lui a demandé.
c)
On divise par 3,6 : def en_ms(v): puis return v/3.6. En effet 1 km/h =3600s1000m=3,61 m/s. Ici en_ms(130) renvoie 3,6130≈36,1 m/s. Vérification de bon sens : un nombre exprimé en m/s est toujours PLUS PETIT que le même en km/h, donc si le résultat avait été 468, le sens de l'opération aurait été inversé.
d)
Python interrompt le programme avec une erreur de division par zéro, qui n'est pas définie en machine pas plus qu'en mathématiques. On protège la fonction par un test : def vitesse(d, t): puis if t == 0: puis return None puis return d/t. Cela reflète la réalité physique : une distance parcourue en une durée nulle n'a pas de sens.
Le fil : dans un exercice de sciences, la partie fragile n'est pas la division, c'est la préparation des données. Une durée en heures et minutes, une distance en mètres, une masse en grammes doivent être converties AVANT d'entrer dans la fonction.
def vitesse(d, t):
if t == 0:
return None
return d/t
def en_ms(v):
return v/3.6
print(vitesse(234, 1.8))
print(en_ms(vitesse(234, 1.8)))
Exercice 3 : Concentration d'une solution et dilution
On dissout une masse m (en grammes) d'un solide de masse molaire M (en g/mol) dans un volume V (en litres) de solution. On rappelle n=Mm et c=Vn.
def concentration(m, M, V):
n = m/M
return n/V
a) On dissout 5,85 g de chlorure de sodium (M=58,5 g/mol) dans 500 mL de solution. Que renvoie concentration(5.85, 58.5, 0.5) ?
b) Un élève écrit concentration(5.85, 58.5, 500). Quel résultat obtient-il, et de combien se trompe-t-il ?
c) On veut diluer la solution précédente pour obtenir 100 mL à 0,050 mol/L. Écrivez une fonction volume_a_prelever(c1, c2, V2) et donnez le résultat en millilitres.
d) Complétez cette fonction pour qu'elle refuse une dilution impossible, c'est-à-dire lorsque la concentration voulue dépasse celle de la solution de départ.
Voir la correction
Réponses
a)0,2 mol/L
b)0,0002 : facteur 1000
c)return c2*V2/c1 ; 25 mL
d)if c2 > c1: return None
a)
La quantité de matière vaut n=58,55,85=0,100 mol. Le volume vaut 500 mL =0,500 L, donc c=0,5000,100=0,200 mol/L. La fonction renvoie 0,2.
b)
Il obtient 5000,1=2×10−4, soit 0,0002. Il se trompe d'un FACTEUR MILLE, parce qu'il a fourni un volume en millilitres à une formule qui attend des litres. Aucune erreur ne s'affiche : le programme tourne, produit un nombre, et ce nombre est faux. C'est exactement pour cela qu'en chimie on écrit l'unité à côté de chaque valeur avant de taper quoi que ce soit.
c)
La dilution conserve la quantité de matière : c1V1=c2V2, donc V1=c1c2V2. On écrit def volume_a_prelever(c1, c2, V2): puis return c2*V2/c1. Ici V1=0,2000,050×0,100=0,025 L, soit 25 mL. On prélève donc 25 mL de la solution mère et l'on complète à 100 mL avec de l'eau distillée. Contrôle immédiat : la concentration a été divisée par quatre, le volume prélevé est bien le quart du volume final.
d)
On ajoute un test au début : if c2 > c1: puis return None. La raison est physique et non informatique : diluer, c'est ajouter du solvant, donc la concentration ne peut que BAISSER. Si l'on demandait c2>c1, la formule renverrait V1>V2, c'est-à-dire un volume à prélever supérieur au volume final, ce qui n'a aucun sens au laboratoire. Une fonction bien écrite refuse ce qu'elle ne sait pas faire au lieu de renvoyer un nombre absurde.
Le fil : un résultat de chimie faux d'un facteur mille vient presque toujours d'un millilitre pris pour un litre. La machine ne vérifie pas les unités, c'est le seul contrôle qui reste entièrement à la charge de l'élève.
Une culture de bactéries compte 500 individus et sa population augmente de 4% par heure. On cherche au bout de combien d'heures elle dépasse 2000 individus.
n = 500
h = 0
while n <= 2000:
n = n*1.04
h = h + 1
print(h)
a) Pourquoi une boucle while et non une boucle for ?
b) Que vaut la population après 35 heures, puis après 36 heures ? Concluez sur la valeur affichée.
c) Un élève remplace n = n*1.04 par n = n + 4. Qu'a-t-il modélisé à la place, et en combien d'heures son programme s'arrête-t-il ?
d) Que se passe-t-il si le taux d'augmentation est nul ? Comment sécuriser la boucle ?
Voir la correction
Réponses
a)Nombre de tours inconnu à l'avance
b)≈1973 puis ≈2052 : affiche 36
c)Croissance linéaire : 375 heures
d)Boucle infinie ; ajouter and h < 1000
a)
Parce que le nombre de tours n'est PAS connu à l'avance : c'est précisément la réponse cherchée. Une boucle for exige que l'on annonce le nombre de répétitions avant de commencer, ce qui reviendrait à connaître déjà le résultat. La boucle while répète tant qu'une condition est vraie et s'arrête d'elle-même dès qu'elle devient fausse.
b)
Augmenter de 4%, c'est multiplier par 1,04, donc au bout de h heures la population vaut 500×1,04h. Pour h=35 : 1,0435≈3,9461 et 500×3,9461≈1973 individus, ce qui est encore sous le seuil. Pour h=36 : 1,0436≈4,1039 et 500×4,1039≈2052 individus, ce qui dépasse. Le programme affiche donc 36. On retrouve le résultat par le raisonnement : il faut 1,04h≥4, et 36 est le premier entier qui convient.
c)
Il a modélisé une croissance LINÉAIRE, quatre bactéries de plus chaque heure, au lieu d'une croissance exponentielle de quatre pour cent par heure. Les deux modèles n'ont rien à voir : avec son programme il faudrait 42000−500=375 heures, soit plus de dix fois trop. Le point de méthode est général : un pourcentage se traduit par une MULTIPLICATION, jamais par une addition, et confondre les deux est l'erreur la plus coûteuse du chapitre sur les évolutions.
d)
Si le taux est nul, on multiplie par 1, la population ne change jamais, la condition n <= 2000 reste vraie indéfiniment et la boucle ne se termine pas : c'est une boucle infinie. Une boucle while n'est correcte que si quelque chose évolue à chaque tour DANS LE SENS de la condition d'arrêt. En pratique on ajoute une sécurité, par exemple while n <= 2000 and h < 1000:, pour garantir l'arrêt et signaler que le seuil n'a pas été atteint.
Le fil : le seuil est un motif qui revient toute l'année, en suites comme en sciences. On initialise, on répète la mise à jour, on compte les tours, et l'on vérifie toujours le résultat en calculant à la main les deux valeurs qui encadrent le seuil, ici 1973 et 2052.
Exercice 5 : Fonctions, taux d'évolution, print et return
Le prix d'un article passe de 80 dollars à 96 dollars, puis subit une baisse. On veut automatiser le calcul des taux d'évolution.
def taux(v1, v2):
print((v2 - v1)/v1*100)
a) Que fait taux(80, 96) ? Quel est le taux d'évolution en pourcentage ?
b) Un élève écrit t = taux(80, 96) puis print(t + 5). Le programme s'arrête sur une erreur. Expliquez et corrigez la fonction.
c) L'article augmente de 20% puis baisse de 20%. Calculez le prix final à partir de 80 dollars, et donnez le taux d'évolution global.
d) Écrivez une fonction applique(prix, t) qui renvoie le prix après une évolution de t pour cent, en gérant aussi bien une hausse qu'une baisse.
Voir la correction
Réponses
a)Affiche 20 : hausse de 20%
b)t vaut None ; utiliser return
c)76,8 dollars : −4%
d)return prix*(1 + t/100)
a)
Elle AFFICHE 8096−80×100=8016×100=20. Le prix a augmenté de 20%. Attention au verbe employé : la fonction affiche, elle ne renvoie rien.
b)
print envoie du texte à l'écran, ce que l'on voit ; return fournit une valeur au programme, ce que l'on peut réutiliser. Une fonction sans return renvoie automatiquement None, donc ici t ne contient aucun nombre et t + 5 provoque une erreur, car on ne peut pas additionner un nombre et l'absence de valeur. On corrige en écrivant def taux(v1, v2): puis return (v2 - v1)/v1*100, et l'on affiche à l'extérieur avec print(taux(80, 96)). Règle pratique : une fonction de calcul renvoie toujours, elle n'affiche jamais.
c)
Le prix final vaut 80×1,2×0,8=80×0,96=76,8 dollars. Le taux global est donc 8076,8−80×100=−4, soit une BAISSE de 4%. Le résultat surprend et il faut savoir l'expliquer : la hausse de 20% porte sur 80 dollars et ajoute 16 dollars, tandis que la baisse de 20% porte sur 96 dollars et en retire 19,20. Les taux successifs ne s'additionnent pas, ce sont les COEFFICIENTS MULTIPLICATEURS qui se multiplient.
d)
def applique(prix, t): puis return prix*(1 + t/100). Aucun test n'est nécessaire : pour t=20 le coefficient vaut 1,2, pour t=−20 il vaut 0,8. Une seule formule couvre les deux cas, à condition d'écrire la baisse avec un t NÉGATIF. On vérifie que applique(applique(80, 20), -20) renvoie bien 76,8, ce qui redonne la question c) en une seule ligne : c'est tout l'intérêt d'écrire une fonction plutôt que de répéter un calcul.
Le fil : +20% suivi de −20% ne ramène pas au départ, et 1,2×0,8=0,96=1 le prouve en une ligne. C'est le résultat le plus souvent demandé en contrôle sur ce chapitre.
Un capteur relève sept fois de suite la température d'une même pièce, en degrés Celsius. Les mesures sont stockées dans la liste T = [21.4, 22.1, 20.8, 21.9, 22.3, 21.0, 21.5].
a) Écrivez un programme qui calcule la moyenne de la liste T à l'aide d'une boucle, sans utiliser la fonction sum. Donnez la valeur au centième.
b) Écrivez un programme qui trouve la plus grande et la plus petite mesure, puis calculez l'étendue.
c) Combien de mesures s'écartent de la moyenne de plus de 0,5 degré ? Écrivez le programme qui les compte.
d) Le capteur mesure toujours la même pièce. Pourquoi les sept valeurs diffèrent-elles, et pourquoi retient-on la moyenne plutôt qu'une mesure isolée ?
Voir la correction
Réponses
a)7151≈21,57 °C
b)Max 22,3, min 20,8, étendue 1,5
c)4 mesures
d)Incertitudes de mesure ; la moyenne les compense en partie
a)
On utilise un ACCUMULATEUR, une variable initialisée à zéro à laquelle on ajoute chaque élément : s = 0 puis for x in T: puis s = s + x puis print(s/len(T)). La somme vaut 21,4+22,1+20,8+21,9+22,3+21,0+21,5=151,0 et il y a sept mesures, donc la moyenne vaut 7151≈21,57 degré. Le point à ne pas rater : la division se fait APRÈS la boucle, une seule fois. Écrire s = s/len(T) à l'intérieur diviserait à chaque tour et donnerait n'importe quoi.
b)
On initialise avec le premier élément, jamais avec zéro : M = T[0] puis m = T[0] puis for x in T: puis if x > M: puis M = x puis if x < m: puis m = x. On obtient M=22,3 et m=20,8, donc une étendue de 22,3−20,8=1,5 degré. Initialiser le maximum à zéro serait ici sans conséquence, mais deviendrait faux dès que toutes les mesures seraient négatives, ce qui arrive en hiver à Montréal.
c)
moy = 151/7 puis c = 0 puis for x in T: puis if abs(x - moy) > 0.5: puis c = c + 1. Les écarts à la moyenne 21,57 valent environ −0,17, +0,53, −0,77, +0,33, +0,73, −0,57 et −0,07. Quatre d'entre eux dépassent 0,5 en valeur absolue : les mesures 22,1, 20,8, 22,3 et 21,0. La valeur absolue est indispensable, car un écart de −0,77 est aussi grand qu'un écart de +0,77 : sans elle, on ne compterait que les mesures supérieures à la moyenne.
d)
Elles diffèrent à cause des incertitudes de mesure, qui viennent du capteur lui-même et des micro-variations réelles de la pièce. Aucune mesure physique n'est exacte. La moyenne est retenue parce que les erreurs se compensent en partie : les écarts positifs et négatifs s'annulent partiellement, et l'étendue de 1,5 degré donne une idée de la dispersion, donc de la confiance à accorder au résultat. On annonce ainsi une température d'environ 21,6 degré, pas 21,571428 : conserver toutes les décimales de la division reviendrait à prétendre une précision que les mesures n'ont pas.
Le fil : une liste de mesures se traite toujours de la même façon, un accumulateur pour la somme, un comparateur pour les extremums, un compteur pour les cas particuliers. Le raisonnement de sciences vient après, quand il faut décider combien de chiffres du résultat ont un sens.
s = 0
for x in T:
s = s + x
moy = s/len(T)
c = 0
for x in T:
if abs(x - moy) > 0.5:
c = c + 1
print(moy, c)
Exercice 7 : Compléter un programme : volume équivalent d'un titrage
On titre VA=20,0 mL d'une solution d'acide par une solution de soude de concentration cB=0,100 mol/L. On relève le pH pour cinq volumes de soude versés, stockés dans deux listes : V = [8.0, 9.0, 10.0, 11.0, 12.0] et pH = [3.1, 3.6, 7.4, 10.2, 10.7].
Le programme suivant cherche l'endroit où le pH fait le plus grand saut. Trois lignes sont incomplètes.
saut_max = 0
indice = 0
for i in range(1, len(pH)):
saut = ...
if ... :
saut_max = saut
indice = i
Veq = ...
print(Veq)
a) Complétez les trois lignes du programme.
b) Calculez les quatre sauts de pH et donnez la valeur du volume équivalent obtenue.
c) Déduisez-en la concentration de la solution d'acide.
d) Pourquoi la boucle démarre-t-elle à 1 et non à 0 ? Que se passerait-il avec range(0, len(pH)) ?
d)pH[-1] est le dernier élément : saut faux sans message
a)
La ligne du saut compare une valeur à la précédente : saut = pH[i] - pH[i-1]. Le test conserve le plus grand : if saut > saut_max:. Enfin le volume équivalent est situé au MILIEU de l'intervalle où le saut se produit : Veq = (V[indice] + V[indice-1])/2. Chacune de ces trois lignes traduit une phrase du cours, et c'est dans cet ordre qu'il faut les écrire, jamais l'inverse.
b)
Les sauts successifs valent 3,6−3,1=0,5, puis 7,4−3,6=3,8, puis 10,2−7,4=2,8, puis 10,7−10,2=0,5. Le plus grand est 3,8, obtenu pour i = 2, c'est-à-dire entre V=9,0 mL et V=10,0 mL. Le programme affiche donc Veˊq=29,0+10,0=9,5 mL. Cette lecture correspond exactement à ce que l'on fait à la main sur la courbe de titrage : on repère le saut brutal de pH et l'on place l'équivalence en son milieu.
c)
À l'équivalence, les réactifs ont été introduits dans les proportions de l'équation, donc cAVA=cBVeˊq, d'où cA=VAcBVeˊq=20,00,100×9,5=0,0475 mol/L. Les volumes peuvent rester en millilitres des deux côtés puisqu'ils apparaissent en quotient : c'est le seul endroit du chapitre où l'on n'est pas obligé de convertir, et il faut savoir dire pourquoi.
d)
Parce que la ligne pH[i-1] a besoin d'un élément PRÉCÉDENT. Avec i = 0, on écrirait pH[-1], qui en Python désigne le DERNIER élément de la liste : le programme ne signalerait aucune erreur mais comparerait le premier pH au dernier, donc calculerait un saut de 3,1−10,7=−7,6, sans aucun sens chimique. C'est le piège le plus dangereux du chapitre sur les listes, parce qu'il ne produit pas de message d'erreur, seulement un résultat faux. La règle : dès qu'une boucle compare un élément au précédent, elle commence à l'indice 1.
Le fil : le programme ne fait que formaliser la lecture graphique. Savoir où est l'équivalence, c'est savoir que le saut de pH est brutal, et le milieu de l'intervalle est la meilleure estimation que l'on puisse tirer d'un relevé espacé de 1 mL.
saut_max = 0
indice = 0
for i in range(1, len(pH)):
saut = pH[i] - pH[i-1]
if saut > saut_max:
saut_max = saut
indice = i
Veq = (V[indice] + V[indice-1])/2
print(Veq)
Exercice 8 : Cinq affirmations à corriger
Chacune des cinq affirmations suivantes est FAUSSE. Dites pourquoi, puis énoncez la version correcte.
a) « L'instruction x == 3 range la valeur 3 dans la variable x. »
b) « La boucle for k in range(1, 10) effectue dix tours. »
c) « Une fonction qui se termine par un calcul renvoie ce calcul, même sans return. »
d) « Pour convertir une vitesse de km/h en m/s, on multiplie par 3,6. »
e) « En Python, 0.1 + 0.2 == 0.3 renvoie True. »
Voir la correction
Réponses
a)Faux : == teste, = affecte
b)Faux : 9 tours
c)Faux : sans return, la fonction renvoie None
d)Faux : on divise par 3,6
e)Faux : False
a)
FAUX. == est un TEST d'égalité : il ne modifie rien et renvoie True ou False. C'est = qui affecte. Version correcte : « l'instruction x = 3 range la valeur 3 dans x, tandis que x == 3 demande si x vaut déjà 3 ». La confusion est d'autant plus facile qu'en mathématiques le signe = sert aux deux usages.
b)
FAUX. range(1, 10) parcourt 1,2,…,9, la borne de droite étant exclue : cela fait 10−1=9 tours. Version correcte : « la boucle effectue neuf tours ». Pour obtenir dix tours à partir de 1, on écrit range(1, 11).
c)
FAUX. Sans return, une fonction exécute ses instructions puis renvoie None, c'est-à-dire aucune valeur exploitable. Version correcte : « une fonction ne renvoie une valeur que si elle contient explicitement une instruction return ». Le symptôme classique est une erreur quelques lignes plus loin, quand on essaie de calculer avec le résultat.
d)
FAUX, c'est l'inverse. Puisque 1 km/h =36001000 m/s =3,61 m/s, on DIVISE par 3,6 pour aller des km/h vers les m/s. Version correcte : « on divise par 3,6 pour passer des km/h aux m/s, et l'on multiplie par 3,6 dans l'autre sens ». Le contrôle mental est immédiat : 90 km/h vaut 25 m/s, un nombre plus petit.
e)
FAUX, cela renvoie False. Les nombres décimaux sont stockés en base deux, et ni 0,1 ni 0,2 n'y ont d'écriture finie : la somme obtenue vaut 0,30000000000000004. Version correcte : « on ne teste jamais l'égalité de deux flottants, on teste si leur écart est petit », par exemple abs(0.1 + 0.2 - 0.3) < 1e-9. C'est la même limitation qu'avec 31=0,333… en base dix, à ceci près que ce sont d'autres fractions qui posent problème.
Ces cinq erreurs représentent la grande majorité des points perdus en algorithmique au niveau Seconde. Aucune ne relève des mathématiques : ce sont des règles de lecture d'un programme, et elles se vérifient à la main, sans machine.
Exercice 9 : Chute libre : encadrer une durée par balayage
Un objet est lâché sans vitesse initiale du haut d'un immeuble. En négligeant les frottements, la distance parcourue au bout de t secondes vaut d(t)=21gt2 avec g=9,8 m/s2, et sa vitesse vaut v(t)=gt.
On cherche au bout de combien de temps l'objet a chuté de 20 mètres.
La figure n'est pas à l'échelle.
a) Écrivez une fonction distance(t) puis affichez un tableau de valeurs de 0 à 2,5 s par pas de 0,5 s.
b) Écrivez un programme qui balaie le temps par pas de 0,1 s et affiche le premier instant où la distance atteint 20 m. Donnez l'encadrement obtenu.
c) Résolvez l'équation 21gt2=20 et comparez à l'encadrement. Quelle est alors la vitesse, en m/s puis en km/h ?
d) Un élève écrit t = 0 puis répète t = t + 0.1 dans une boucle while. Pourquoi vaut-il mieux boucler sur des entiers et poser t = k/10 ?
Voir la correction
Réponses
a)0 ; 1,225 ; 4,9 ; 11,025 ; 19,6 ; 30,625 m
b)2,0<t<2,1 s
c)t≈2,02 s ; v≈19,8 m/s ≈71,3 km/h
d)Boucler sur un entier évite l'accumulation d'erreurs
a)
def distance(t): puis return 0.5*9.8*t*t, puis for k in range(0, 6): puis t = k/2 puis print(t, distance(t)). Les valeurs sont d(0)=0, d(0,5)=1,225, d(1)=4,9, d(1,5)=11,025, d(2)=19,6 et d(2,5)=30,625 mètres. On voit immédiatement que la réponse cherchée est entre 2 et 2,5 s, et le tableau montre aussi que les écarts s'agrandissent, ce qui est la signature d'un mouvement accéléré : chaque demi-seconde fait tomber plus loin que la précédente.
b)
k = 0 puis while 0.5*9.8*(k/10)**2 < 20: puis k = k + 1 puis print(k/10). Le programme s'arrête à k=21. En effet d(2,0)=0,5×9,8×4=19,6 m, encore insuffisant, alors que d(2,1)=0,5×9,8×4,41=21,609 m dépasse. L'encadrement est donc 2,0<t<2,1 s. Un pas de 0,01 s donnerait une décimale de plus, au prix de dix fois plus de tours.
c)
On isole : t2=9,82×20=9,840≈4,0816, donc t=4,0816≈2,02 s, en ne gardant que la solution positive puisqu'il s'agit d'une durée. La valeur exacte tombe bien dans l'encadrement du balayage ✓. La vitesse vaut alors v=9,8×2,02≈19,8 m/s, soit 19,8×3,6≈71,3 km/h : un objet lâché de six étages arrive au sol à la vitesse d'une voiture en ville.
d)
Parce que 0,1 n'a pas d'écriture exacte en machine. En ajoutant 0,1 vingt et une fois, on n'obtient pas 2,1 mais 2,0999999999999996, et l'erreur s'accumule à chaque tour. Le test d'arrêt peut alors basculer un cran trop tôt ou trop tard, et un affichage brut fait apparaître des durées comme 1,7000000000000004. En bouclant sur l'entier k et en posant t=10k, on ne fait qu'UNE division au lieu de vingt et une additions : l'erreur ne s'accumule plus. C'est la bonne habitude à prendre pour tous les balayages.
Le fil : le balayage n'est pas une méthode de secours, c'est la méthode générale. Elle s'applique même quand l'équation ne se résout pas, et elle fournit toujours un ENCADREMENT, dont la largeur est le pas choisi.
def distance(t):
return 0.5*9.8*t*t
k = 0
while distance(k/10) < 20:
k = k + 1
print((k-1)/10, k/10)
Exercice 10 : Problème de synthèse : dilutions successives
On dispose d'une solution colorée de concentration c0=0,20 mol/L. À chaque étape, on prélève 10 mL de la solution courante et l'on complète à 100 mL avec de l'eau distillée : la concentration est donc divisée par 10.
On cherche le nombre d'étapes nécessaires pour descendre sous 10−6 mol/L, seuil au-dessous duquel la coloration n'est plus détectable.
a) Écrivez un programme utilisant une boucle while qui affiche le nombre d'étapes nécessaires, et donnez ce nombre.
b) Vérifiez le résultat par le calcul, en donnant les concentrations obtenues à l'avant-dernière et à la dernière étape.
c) On change de protocole : on dilue désormais de moitié à chaque étape. Combien d'étapes faut-il pour descendre sous 10−3 mol/L ?
d) Un élève écrit while c != 1e-6: au lieu de while c >= 1e-6:. Que se passe-t-il, et pourquoi cette erreur est-elle grave ?
Voir la correction
Réponses
a)6 étapes
b)c5=2×10−6, c6=2×10−7 mol/L
c)8 étapes
d)Boucle infinie : on écrit toujours une inégalité
a)
c = 0.20 puis n = 0 puis while c >= 1e-6: puis c = c/10 puis n = n + 1 puis print(n). Le programme affiche 6. La structure est celle de l'exercice 4, à un détail près qui change tout : la condition est un seuil à franchir VERS LE BAS, donc on continue tant que la concentration reste trop grande.
b)
La concentration après n étapes vaut cn=10n0,20. Pour n=5 : c5=1000000,20=2×10−6 mol/L, ce qui est encore au-dessus du seuil de 10−6. Pour n=6 : c6=10000000,20=2×10−7 mol/L, ce qui passe bien en dessous. Il faut donc six étapes, ce qui confirme l'affichage. Remarquez que le facteur 2 du numérateur suffit à décider : sans lui, cinq étapes auraient suffi.
c)
On remplace la division par 10 par une division par 2, et le seuil par 10−3. Il faut 2n0,20<10−3, c'est-à-dire 2n>200. Or 27=128 donne c7≈1,56×10−3, encore trop, tandis que 28=256 donne c8≈7,81×10−4, qui convient. Il faut donc HUIT étapes pour perdre un facteur 200, alors que six suffisaient pour en perdre 200000 dans le protocole précédent. C'est toute la différence entre diviser par deux et diviser par dix : à chaque étape, le facteur choisi se retrouve en exposant.
d)
La boucle ne s'arrête jamais. Les valeurs prises par c sont 0,02, 0,002, 0,0002 et ainsi de suite : elles PASSENT À CÔTÉ de 10−6 sans jamais l'égaler, donc la condition c != 1e-6 reste vraie indéfiniment. Même si une valeur devait tomber exactement sur le seuil, la représentation approchée des décimaux en machine rendrait l'égalité douteuse. La règle est absolue et vaut bien au-delà de cet exercice : la condition d'arrêt d'une boucle numérique s'écrit toujours avec une INÉGALITÉ, jamais avec == ni !=. C'est le même principe qu'à l'exercice 8 e).
Le fil de la série entière se lit dans cet exercice : la boucle répète une opération que l'on sait poser à la main, la vérification passe par le calcul exact, et la seule difficulté réelle est la condition d'arrêt. Un programme faux ne se signale presque jamais par un message d'erreur, il se signale par un résultat que le calcul de contrôle contredit.
c = 0.20
n = 0
while c >= 1e-6:
c = c/10
n = n + 1
print(n)
Partie C : les classiques (/50)
Exercice 11 : Loi d'Ohm : exploiter une série de mesures
On mesure la tension U (en volts) aux bornes d'un conducteur ohmique et l'intensité I (en ampères) du courant qui le traverse. La loi d'Ohm s'écrit U=R×I, où R est la résistance en ohms.
Le programme suivant estime R à partir des mesures.
Le schéma représente le montage : le voltmètre mesure U aux bornes du conducteur ohmique, l'ampèremètre mesure I.
U = [0, 1.5, 3.0, 4.5, 6.0]
I = [0, 0.032, 0.063, 0.097, 0.128]
s = 0
for i in range(1, len(U)):
s = s + U[i]/I[i]
R = s/(len(U) - 1)
print(R)
a) Pourquoi la boucle commence-t-elle à l'indice 1 et non à l'indice 0 ?
b) Quelle valeur, arrondie au dixième, le programme affiche-t-il ?
c) Pourquoi divise-t-on la somme par len(U) - 1 et non par len(U) ?
d) On retient R=47Ω. Quelle tension faut-il appliquer pour obtenir une intensité de 0,20 A ?
e) Un élève saisit les intensités en milliampères : I = [0, 32, 63, 97, 128]. Quelle valeur de R obtient-il, et d'un facteur combien se trompe-t-il ?
Voir la correction
Réponses
a)Éviter la division 00
b)≈46,9Ω
c)4 rapports additionnés
d)9,4 V
e)≈0,0469Ω : facteur 1000
a)
Pour i=0, le programme calculerait U[0]/I[0], soit 00 : une division par zéro, qui arrête le programme sur une erreur. Le premier point de mesure, courant nul et tension nulle, ne donne aucune information sur R : on l'écarte en commençant à 1.
b)
Les quatre rapports valent 0,0321,5≈46,9 ; 0,0633,0≈47,6 ; 0,0974,5≈46,4 ; 0,1286,0≈46,9. Leur moyenne vaut environ 46,9Ω. Les rapports ne sont pas rigoureusement égaux : ce sont des mesures, entachées d'incertitude, et la moyenne en atténue l'effet.
c)
La somme contient 4 rapports, un par tour de boucle, puisque l'indice 0 a été écarté. Diviser par len(U), qui vaut 5, donnerait 5187,8≈37,6Ω, une valeur fausse d'un cinquième. On divise toujours par le nombre de valeurs réellement additionnées.
d)
U=R×I=47×0,20=9,4 V.
e)
Les intensités sont mille fois trop grandes, donc les rapports mille fois trop petits : R≈0,0469Ω. L'erreur est d'un facteur 1000, et le programme ne la signale pas. Le seul contrôle possible est l'ordre de grandeur : un conducteur ohmique courant fait des dizaines ou des centaines d'ohms, pas un centième.
Le fil : un programme de traitement de mesures ne vaut que par ses données. Le choix des indices, du diviseur et des unités est la partie scientifique du travail, la boucle n'est que l'outil.
Exercice 12 : Masse volumique et identification d'un métal
La masse volumique d'un matériau vaut ρ=Vm. Valeurs de référence, en g/cm³ : aluminium 2,70 ; fer 7,87 ; cuivre 8,96 ; plomb 11,3.
Un échantillon métallique a une masse de 43,2 g. On le plonge dans une éprouvette graduée contenant 50,0 mL d'eau : le niveau monte à 66,0 mL.
noms = ['aluminium', 'fer', 'cuivre', 'plomb']
valeurs = [2.70, 7.87, 8.96, 11.3]
def identifie(rho):
meilleur = 0
for i in range(1, len(valeurs)):
if abs(rho - valeurs[i]) < abs(rho - valeurs[meilleur]):
meilleur = i
return noms[meilleur]
a) Quel est le volume de l'échantillon, en cm³ ?
b) Calculez sa masse volumique en g/cm³.
c) Convertissez cette masse volumique en kg/m³.
d) La fonction identifie(rho) renvoie le nom du métal de référence dont la masse volumique est la plus proche. Quel métal renvoie-t-elle pour l'échantillon ? Et pour ρ=8,9 g/cm³ ?
e) Quelle est la masse d'un cube de fer de 5 cm d'arête, au gramme près ?
Voir la correction
Réponses
a)16,0 cm³
b)2,70 g/cm³
c)2700 kg/m³
d)Aluminium ; cuivre pour 8,9
e)≈984 g
a)
Le volume d'eau déplacé est le volume de l'objet : 66,0−50,0=16,0 mL, soit 16,0 cm³, puisque 1 mL =1 cm³.
b)
ρ=16,043,2=2,70 g/cm³.
c)
1 g/cm³ =10−6m310−3kg=1000 kg/m³. Donc ρ=2700 kg/m³. Un mètre cube d'aluminium pèse près de trois tonnes.
d)
La fonction calcule l'écart abs(rho - valeurs[i]) pour chaque métal et garde le plus petit. Pour 2,70, l'écart avec l'aluminium est nul : elle renvoie « aluminium ». Pour 8,9 : écarts 6,2 ; 1,03 ; 0,06 ; 2,4. Le plus petit est celui du cuivre. Comme pour un maximum, on initialise la recherche avec le premier élément de la liste, jamais avec une valeur arbitraire.
e)
Volume du cube : 53=125 cm³. Masse : m=ρ×V=7,87×125=983,75 g, soit environ 984 g. Un cube de fer qui tient dans la main pèse presque un kilogramme.
Le point de méthode : la masse volumique identifie un matériau parce qu'elle ne dépend pas de la taille de l'échantillon, et la mesure du volume par déplacement d'eau évite tout calcul géométrique.
Exercice 13 : Mouvement d'un palet : vitesses à partir de relevés
Une chronophotographie donne les positions de deux palets toutes les 0,2 s. Les instants sont dans t, les positions du palet A dans x et celles du palet B dans y, en mètres.
t = [0, 0.2, 0.4, 0.6, 0.8] ; x = [0, 0.30, 0.60, 0.90, 1.20] ; y = [0, 0.10, 0.40, 0.90, 1.60].
Les points Ak et Bk sont les positions à l'instant tk=0,2×k s.
for i in range(len(t) - 1):
v = (x[i+1] - x[i]) / (t[i+1] - t[i])
print(v)
a) Combien de valeurs le programme affiche-t-il ?
b) Quelles vitesses affiche-t-il pour le palet A ? Quelle est la nature de son mouvement ?
c) On remplace x par y. Quelles vitesses obtient-on ? De combien la vitesse augmente-t-elle d'un intervalle à l'autre ?
d) Quelle est la vitesse moyenne du palet B entre 0 et 0,8 s ?
e) Pourquoi la boucle s'arrête-t-elle à len(t) - 1 ?
Voir la correction
Réponses
a)4 valeurs
b)1,5 m/s constante : rectiligne uniforme
c)0,5 ; 1,5 ; 2,5 ; 3,5 m/s : +1 m/s par intervalle
d)2,0 m/s
e)x[i+1] sortirait de la liste
a)
range(len(t) - 1) vaut range(4) : 4 tours, donc 4 vitesses. Cinq positions délimitent quatre intervalles de temps.
b)
Chaque intervalle : 0,20,30=1,5 m/s. Les quatre vitesses sont égales et le palet se déplace en ligne droite : le mouvement est rectiligne UNIFORME.
c)
0,20,10=0,5 ; 0,20,30=1,5 ; 0,20,50=2,5 ; 0,20,70=3,5 m/s. La vitesse augmente de 1,0 m/s à chaque intervalle : le mouvement est rectiligne ACCÉLÉRÉ.
d)
Distance totale sur durée totale : 0,81,60=2,0 m/s. C'est aussi la moyenne des quatre vitesses, parce que les intervalles ont la même durée : 40,5+1,5+2,5+3,5=2,0 ✓.
e)
La formule utilise x[i+1]. Pour i = len(t) - 1, l'indice i+1 vaudrait 5, qui n'existe pas dans une liste de cinq éléments : le programme s'arrêterait sur une erreur d'indice. Quand on compare un élément au SUIVANT, la boucle s'arrête un cran avant la fin.
Le fil : une vitesse moyenne est une variation de position sur une variation de temps, et une liste de positions en donne une par intervalle. Leur régularité, ou leur croissance, révèle la nature du mouvement.
Exercice 14 : Problème : réfraction et loi de Snell-Descartes
Quand la lumière passe d'un milieu d'indice n1 à un milieu d'indice n2, les angles d'incidence i1 et de réfraction i2 vérifient n1sini1=n2sini2. On prend n=1,00 pour l'air et n=1,33 pour l'eau.
La fonction suivante renvoie l'angle de réfraction en degrés, ou None s'il n'existe pas. Les angles sont arrondis au centième de degré.
La figure représente un rayon qui arrive de l'air sur l'eau, sous l'angle d'incidence i1 mesuré à partir de la normale.
from math import sin, asin, radians, degrees
def refraction(n1, n2, i1):
s = n1 * sin(radians(i1)) / n2
if s > 1:
return None
return degrees(asin(s))
a) Que renvoie refraction(1.00, 1.33, 30) ?
b) Que renvoie refraction(1.00, 1.33, 60) ? Le rayon se rapproche-t-il ou s'éloigne-t-il de la normale ?
c) Que renvoie refraction(1.33, 1.00, 40), de l'eau vers l'air ?
d) Que renvoie refraction(1.33, 1.00, 60) ? Interprétez.
e) Calculez l'angle limite au-delà duquel la lumière ne sort plus de l'eau. Pourquoi la fonction utilise-t-elle radians et degrees ?
Voir la correction
Réponses
a)≈22,08∘
b)≈40,63∘ : se rapproche de la normale
c)≈58,75∘
d)None : réflexion totale
e)≈48,75∘ ; sin travaille en radians
a)
sini2=1,331,00×sin30∘=1,330,5≈0,376, donc i2≈22,08∘.
b)
sini2=1,33sin60∘≈1,330,866≈0,651, donc i2≈40,63∘. L'angle de réfraction est plus petit que l'angle d'incidence : en entrant dans un milieu plus réfringent, le rayon se RAPPROCHE de la normale.
c)
sini2=1,33×sin40∘≈0,855, donc i2≈58,75∘. En sortant de l'eau, le rayon s'éloigne de la normale.
d)
1,33×sin60∘≈1,152. Un sinus ne peut pas dépasser 1 : aucun angle ne convient et la fonction renvoie None. Physiquement, il n'y a pas de rayon réfracté : la lumière est entièrement réfléchie dans l'eau, c'est la RÉFLEXION TOTALE. Sans le test if s > 1, la fonction asin provoquerait une erreur.
e)
L'angle limite vérifie 1,33×siniℓ=1, soit siniℓ=1,331 et iℓ≈48,75∘. Les fonctions sin et asin de Python travaillent en RADIANS : il faut convertir l'angle donné en degrés avant d'en prendre le sinus, puis reconvertir le résultat. Oublier radians ferait calculer le sinus de 30 radians, un angle sans rapport.
Ce problème montre ce qu'un programme ajoute à une formule : il oblige à prévoir le cas où la formule n'a pas de solution, et ce cas est justement un phénomène physique réel.
Exercice 15 : Problème : période d'un son et mesure par écho
Un microphone enregistre un son. Le programme relève les instants, en millisecondes, de cinq maximums successifs du signal : tmax = [1.2, 3.7, 6.2, 8.7, 11.2].
On rappelle que la fréquence f (en hertz) et la période T (en secondes) vérifient f=T1, et que le son se propage à environ 340 m/s dans l'air.
tmax = [1.2, 3.7, 6.2, 8.7, 11.2]
T = (tmax[-1] - tmax[0]) / (len(tmax) - 1)
f = 1000 / T
print(T, f)
a) Que vaut T, en millisecondes ?
b) Que vaut la fréquence f affichée, en hertz ?
c) Pourquoi calculer T à partir du premier et du dernier maximum plutôt qu'à partir de deux maximums voisins ?
d) On émet un bref cri face à une falaise, et l'écho revient 0,35 s plus tard. À quelle distance est la falaise ?
e) Un sonar de bateau reçoit l'écho du fond 0,080 s après l'émission. Le son se propage à 1500 m/s dans l'eau. Quelle est la profondeur ?
Voir la correction
Réponses
a)T=2,5 ms
b)f=400 Hz
c)L'incertitude se répartit sur quatre périodes
d)59,5 m
e)60 m
a)
Entre le premier et le dernier maximum, il y a 4 périodes : T=5−111,2−1,2=410,0=2,5 ms. Le programme écrit tmax[-1] pour le dernier élément et len(tmax) - 1 pour le nombre d'intervalles.
b)
T=2,5 ms =0,0025 s, donc f=0,00251=400 Hz. Le programme écrit 1000 / T parce que T est en millisecondes : c'est la conversion d'unité, cachée dans le 1000.
c)
Chaque instant relevé est entaché d'une incertitude, par exemple 0,1 ms. Sur un seul intervalle de 2,5 ms, cette erreur pèse 4% ; répartie sur quatre périodes, elle ne pèse plus que 1%. Mesurer plusieurs périodes d'un coup améliore la précision : c'est la méthode employée au laboratoire avec un oscilloscope.
d)
Le son fait l'ALLER-RETOUR : il parcourt 340×0,35=119 m, et la falaise est à la moitié, soit 59,5 m. Oublier de diviser par deux est l'erreur classique de tous les exercices d'écho.
e)
Aller-retour : 1500×0,080=120 m, donc une profondeur de 60 m. Le son va plus de quatre fois plus vite dans l'eau que dans l'air, ce qui explique qu'un écho sous-marin revienne si vite.
Le fil : la période se mesure sur plusieurs oscillations pour gagner en précision, et une distance par écho se divise toujours par deux.
Il manque quelque chose dans cette série ?Un type d'exercice que ton prof donne, un énoncé qui te bloque, une erreur repérée : dis-le-moi, je lis chaque demande.
L'envoi passe par ton espace gratuit : c'est ce qui me permet de te répondre et de te prévenir quand l'exercice est ajouté. Un courriel suffit, pas de mot de passe. Crée ton espace.
Pas envie de créer un compte ? Écris-moi directement.
Vous cherchez un tuteur de maths en Seconde à 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.