Tp1 33 (Tres Important)
Tp1 33 (Tres Important)
Tp1 33 (Tres Important)
TP : Rattrapage des TP 1 et 2 15
TP 3 : Boucles for 19
TP 4 : Instructions conditionnelles 25
TP 5 : Boucles while 29
TP 6 : Sommes et produits 33
TP 7 : Listes 41
TP 11 : Chaînes de caractères 67
TP 15 : Représentations graphiques 91
• Cliquer sur l’icône S PYDER et attendre que S PYDER apparaisse (c’est un peu long) ;
• Aller dans Affichage/Fenêtres et barres d’outils et selectionner (uniquement) :
3 Éditeur
3 Explorateur de variables
3 Consoles
3 Barre d’outil fichiers
3 Barre d’outil exécution
Exercice 1 ( P YTHON comme une calculatrice) : Taper les commandes suivantes dans une console
(ouvrir une nouvelle console si-besoin) et noter ce qui se passe (le symbole ↵ désigne la touche
Entrée, par la suite on ne l’indiquera plus) :
5+3↵
2-9↵
7+3*4↵
(7+3)*4↵
3**3↵
3**0.5↵
5/2↵ BL’opération / appliquée à des entiers réalise une division entière
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp1.pdf
5.0/2↵
5/2.0↵
float(5)/2↵
4*2.5/3↵
Les commandes suivantes définissent et utilisent des variables (regarder ce qui se passe dans l’ex-
plorateur de variable au fur et à mesure) :
x=10↵
x=x+1↵
largeur=20↵
hauteur=5*9.3↵
v=largeur*hauteur↵
print v↵
largeur=10↵
print v↵
Astuce : x=x+1 peut aussi s’écrire x+=1. Pour finir, tester les commandes :
type(largeur)↵
type(hauteur)↵
type(v)↵
Écrire cette fonction dans un nouveau programme, l’enregistrer sous un nom approprié puis
l’exécuter. Taper ensuite dans la console :
surf_canette(5) ¦ Astuce : dans une console, appuyer sur la touche ↑ (flèche vers
surf_canette(6) le haut) permet de répéter (et éventuellement modifier) les com-
surf_canette(7) mandes entrées précédemment.
surf_canette(8)
surf_canette(9)
Retrouver avec quelques essais dans la console la valeur de h pour laquelle la surface est mi-
nimale.
(f) . Justifier mathématiquement la valeur obtenue à la question précédente.
¦ Pour représenter graphiquement une fonction, par exemple la fonction surf_canette précé-
dente sur l’intervalle [1, 15], on utilisera les commandes suivantes (dont la signification sera vue
ultérieurement) :
800
import numpy as np
import matplotlib.pyplot as plt 700
hv=np.linspace(1,15,100) 600
400
300
plt.show()
200
0 2 4 6 8 10 12 14 16
TP 2 : Nombres et calculs avec Python
¦ Avant tout :
Exercice 1 Quelques calculs avec le module math : On utilisera en général ce module en écrivant :
au début d’un programme ou dans une console. On a ainsi accès directement à toutes les fonctions
du module math, par exemple :
Utiliser les fonctions du module math pour traiter les calculs des questions suivantes.
(a) Datation au carbone 14. À la mort d’un être vivant, le carbone 14 présent dans son organisme
se désintègre au fil des années de sorte que, si p est la proportion de C 14 restante au bout de
N années, alors N = −8310 ln(p).
• Écrire une fonction datation_C14(p) qui calcule N en fonction de p.
• La momie Ötzi retrouvée dans un glacier en 1991 contenait 52.8% du C 14 initial à 1%
près. Donner un encadrement de son âge.
• L’Australopithecus afarensis Lucy, découverte en 1974 a un âge estimé à 4.4 millions d’an-
nées. Estimer la proportion de C 14 restante. A-t-on pu effectuer la datation du squelette
au C 14 ?
(b) Calculs de distances. Un bateau navigue en suivant un certain cap. À un instant donné, le ba-
teau est en position B 1 et le commandant repère un récif R sous un angle de 22◦ . Un mile plus
loin, en position B 2 , le commandant repère ce même récif R sous un angle de 34◦ . Calculer la
distance H R (distance entre le récif et la trajectoire).
22◦ 34◦
B1 B2 H Trajectoire
1 mile
tan(22◦ )
On pourra commencer par calculer la distance : B 2 H = .
tan(34◦ ) − tan(22◦ )
BLes fonctions trigonométriques sin, cos, tan de P YTHON travaillent en radians et non en
degrés.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp2.pdf
Exercice 2 Nombres complexes avec P YTHON et module cmath : On peut définir et calculer avec
des nombres complexes. Un nombre complexe z = a + ib se note a+bj ou complex(a,b) avec
P YTHON. Attention : le complexe i se note ici complex(0,1) ou 0+1j ou plus simplement 1j.
(a) Tester dans une console les commandes suivantes :
z1=2+1j z1.real
z2=complex(1,2) z1.imag
z1+z2 z1.conjugate()
z1*z2
z1/z2 BIl y a bien des parenthèses après
z1**2 conjugate (et pas après real et imag).
(b) Chercher dans la documentation en ligne de P YTHON le module cmath et regarder les diffé-
rentes fonctions proposées. À quoi correspondent les fonctions abs, phase, polar et rect ?
(c) Écrire sous forme algébrique les nombres complexes :
1 − 2i 2+i (1 − 4i)(1 − i)
, ,
3+i 2−i (1 + i)2
def ecriture_base_10(n):
if n==0:
print 0
else:
print n%10
ecriture_base_10(n/10)
Exercice 5 Les nombres flottants : Un nombre flottant x est représenté dans l’ordinateur sous la
forme :
x = m · 2p
où m et p sont des entiers relatifs (il y a de plus quelques conditions sur m et p). . Le nombre 0.25
peut-il se représenter exactement sous cette forme ? . Montrer que le nombre 0.1 ne peut pas être
représenté exactement sous cette forme. Ceci explique que même un calcul simple comme 0.1 + 0.2
présente déjà des problèmes d’approximation.
TP 2 : Nombres et calculs avec Python
Éléments de correction
Ex. 3 : Pour afficher les chiffres de la décomposition de la gauche vers la droite :
def ecriture_base_10_gauche(n):
if n==0:
print 0
else:
ecriture_base_10_gauche(n/10)
print n%10
Par exemple :
ecriture_base_10_gauche(209)
0 2 0 9
Pour avoir des décompositions en binaire, on remplace les 10 par des 2 dans les programmes précé-
dents.
Ex. 4 : (a) Le plus grand nombre que l’on peut écrire avec au plus p chiffres en base 10 est :
99 · · · 9 = 10p − 1
p chiffres
Par exemple le plus grand nombre qui s’écrit avec 3 chiffres en base 10 est 999 = 1000 − 1 =
103 − 1.
(b) Le plus petit nombre qui s’écrit avec exactement p chiffres en base 10 est :
100 · · · 0 = 10p−1
p chiffres
Par exemple le plus petit nombre qui s’écrit avec 3 chiffres en base 10 est 100 = 102 .
(c) Si n s’écrit avec p chiffres en base 10, alors d’après ce qui précède 10p−1 É n É 10p − 1, ou
encore :
ln(n)
p −1 É <p
ln(10)
On en déduit l’encadrement de p :
ln(n) ln(n)
<pÉ +1
ln(10) ln(10)
(d) Dans le cas de la base 2 :
• Le plus grand nombre qui s’écrit avec p chiffres en base 2 est 2p − 1 ;
• Le plus petit nombre qui s’écrit avec exactement p chiffres en base 2 est 2p−1 ;
• Si un entier n s’écrit avec exactement p chiffres en base 2, alors 2p−1 É n É 2p − 1 ou
encore 2p−1 É n < 2p ;
• En appliquant la fonction ln, on obtient (p − 1) ln(2) É ln(n) < p ln(2) et on en déduit :
ln(n) ln(n)
<pÉ +1
ln(2) ln(2)
Ex. 5 : Le nombre 0.25 est égal à 1/4, on a donc 0.25 = 2−2 . Par conséquent, 0.25 peut s’écrire sous
la forme m · 2p avec m = 1 et p = −2. Pour montrer que 0.1 ne peut pas s’écrire exactement sous
la forme m · 2p , on fait un raisonnement par l’absurde. On suppose donc que le nombre 0.1 peut
s’écrire 0.1 = m · 2p avec m et p des entiers. Alors m est un entier strictement positif, donc m Ê 1.
Comme 0.1 < 1, on a nécessairement p < 0 (car si o avait p Ê 0, on aurait 2p Ê 1 et m ·2p Ê 1). Notons
q = −p de sorte que q > 0. L’égalité 0.1 = m · 2p peut également s’écrire 2q = 10m. On en déduit que
le nombre 2q doit être divisible par 5, or ceci est impossible. On donne deux justifications possibles :
— On remarque qu’une puissance de 2 a nécessairement pour dernier chiffre 2, 4, 6 ou 8 (excepté
20 ) alors qu’un nombre divisible par 5 a pour dernier chiffre 0 un 5. Ainsi, une puissance de 2
n’est jamais divisible par 5 ;
— Le seul facteur premier qui apparait dans la décomposition de 2q est 2 alors que le nombre 5
apparait dans la décomposition en facteurs premiers de 10m. Par conséquent 2q ne peut pas
être égal à10m.
On en déduit donc que 0.1 ne peut pas s’écrire sous la forme m · 2p . Par conséquent, le nombre 0.1
ne peut pas être représenté de manière exacte par un flottant dans l’ordinateur.
TP : Rattrapage des TP 1 et 2
Mise en place de l’environnement Spyder
• Cliquer sur l’icône S PYDER et attendre que S PYDER apparaisse (c’est un peu long) ;
• Aller dans Affichage/Fenêtres et barres d’outils et selectionner (uniquement) :
3 Éditeur
3 Explorateur de variables
3 Consoles
3 Barre d’outil fichiers
3 Barre d’outil exécution
Exercice 1 ( P YTHON comme une calculatrice) : Taper les commandes suivantes dans une console
(ouvrir une nouvelle console si-besoin) et noter ce qui se passe (le symbole ↵ désigne la touche
Entrée, par la suite on ne l’indiquera plus) :
5+3↵
2-9↵
7+3*4↵
(7+3)*4↵
3**3↵
3**0.5↵
5/2↵ BL’opération / appliquée à des entiers réalise une division entière
5.0/2↵
5/2.0↵
float(5)/2↵
4*2.5/3↵
Les commandes suivantes définissent et utilisent des variables (regarder ce qui se passe dans l’ex-
plorateur de variable au fur et à mesure) :
x=10↵
x=x+1↵
largeur=20↵
hauteur=5*9.3↵
v=largeur*hauteur↵
print v↵
largeur=10↵
print v↵
Astuce : x=x+1 peut aussi s’écrire x+=1. Pour finir, tester les commandes :
type(largeur)↵
type(hauteur)↵
type(v)↵
Exercice 3 Quelques calculs avec le module math : On utilisera en général ce module en écrivant :
au début d’un programme ou dans une console. On a ainsi accès directement à toutes les fonctions
du module math, par exemple :
print pi, sin(pi),cos(pi)
print e, exp(1), log(e)
Utiliser les fonctions du module math pour traiter les calculs des questions suivantes.
(a) Datation au carbone 14. À la mort d’un être vivant, le carbone 14 présent dans son organisme
se désintègre au fil des années de sorte que, si p est la proportion de C 14 restante au bout de
N années, alors N = −8310 ln(p).
• Écrire une fonction datation_C14(p) qui calcule N en fonction de p.
• La momie Ötzi retrouvée dans un glacier en 1991 contenait 52.8% du C 14 initial à 1%
près. Donner un encadrement de son âge.
• L’Australopithecus afarensis Lucy, découverte en 1974 a un âge estimé à 4.4 millions d’an-
nées. Estimer la proportion de C 14 restante. A-t-on pu effectuer la datation du squelette
au C 14 ?
(b) Calculs de distances. Un bateau navigue en suivant un certain cap. À un instant donné, le ba-
teau est en position B 1 et le commandant repère un récif R sous un angle de 22◦ . Un mile plus
loin, en position B 2 , le commandant repère ce même récif R sous un angle de 34◦ . Calculer la
distance H R (distance entre le récif et la trajectoire).
22◦ 34◦
B1 B2 H Trajectoire
1 mile
tan(22◦ )
B2 H =
tan(34◦ ) − tan(22◦ )
BLes fonctions trigonométriques sin, cos, tan de P YTHON travaillent en radians et non en
degrés.
Exercice 4 Nombres complexes avec P YTHON et module cmath : On peut définir et calculer avec
des nombres complexes. Un nombre complexe z = a + ib se note a+bj ou complex(a,b) avec
P YTHON. Attention : le complexe i se note ici complex(0,1) ou 0+1j ou plus simplement 1j.
(a) Tester dans une console les commandes suivantes :
z1=2+1j
z2=complex(1,2)
z1+z2
z1*z2
z1/z2
z1**2
z1.real
z1.imag
z1.conjugate()
BIl y a bien des parenthèses après conjugate (et pas après real et imag).
(b) Chercher dans la documentation en ligne de P YTHON le module cmath et regarder les diffé-
rentes fonctions proposées. À quoi correspondent les fonctions abs, phase, polar et rect ?
(c) Écrire sous forme algébrique les nombres complexes :
1 − 2i 2+i (1 − 4i)(1 − i)
, ,
3+i 2−i (1 + i)2
Remarques.
• Ce TP consiste à programmer différentes suites ; on insiste sur ce concept car les algorithmes
numériques que l’on verra au deuxième semestre consistent en général à définir une suite et
à calculer ses termes ;
• Vouc pourrez utiliser un seul fichier pour écrire toutes les fonctions demandées dans les exer-
cices qui suivent car toutes les suites considérées portent un nom différent ;
• On vous demande explicitement dans chaque exercice de vérifier votre programme en calcu-
lant les premières valeurs de la suite, à l’avenir il faudrait penser à faire vous même ce type de
vérification.
u0 = 1
u n (6 − u n2 )
∀n ∈ N, u n+1 =
4
v0 = 0
(−1)n
∀n ∈ N, v n+1 = v n +
n +1
Exercice 3 Somme des termes d’une suite : On considère la suite (w n ) définie par :
w0 = 1
wn
∀n ∈ N, w n+1 = −
(2n + 1)(2n + 2)
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp3.pdf
Exercice 4 Suite a n+2 = f (an , an−1 ) : On considère la suite (an ) définie par :
a0 = 0
a1 = 1
∀n ∈ N, a n+2 = a n+1 + a n
Représentations graphiques
p
¦ Pour représenter graphiquement une suite, par exemple la suite (u n ) définie par u n = n/en pour
0 É n É 10, on utilisera les commandes suivantes (dont la signification sera vue ultérieurement) :
0.35
0.10
0.05
plt.show() 0.00
0 2 4 6 8 10
Exercice 5 :
(a) Représenter graphiquement les premiers termes de la suite (u n ) de l’exercice 1.
(b) Quelle(s) propriété(s) sur la suite (u n ) peut-on conjecturer ?
(c) . Le démontrer.
TP 3 : Boucles for
Éléments de correction
Ex. 1 :
def u(n):
u=1
for k in range(n):
u=u*(6-u**2)/4.0
return u
print u(1)
print u(100)
1.25 1.41421356237
Ex. 2 :
Ex. 3 :
0.540302305868 0.540302305868
Cette manière de faire, pour la fonction s, n’est pas très efficace. En effet, pour calculer s(100) par
exemple, il faut successivement calculer w(0), w(1), etc. jusqu’à w(100). Or, le calcul de w(k)
demande k étapes de calcul et le calcul de s(100) demande alors 1 + 2 + · · · + 100 étapes de calcul.
Plus généralement, le calcul de s(n) demande :
n(n + 1)
1+2+···+n =
2
0.540302305868 0.540302305868
Maintenant, le calcul de s(n) demande n étapes de calcul (ce qui est plus efficace que n(n + 1)/2).
Ex. 4 :
def a(n):
a=0
b=1
for k in range(n):
c=a+b
a=b
b=c
return a
print a(0),a(1),a(2),a(3)
print float(a(100))/a(99), (1+5**0.5)/2
0 1 1 2 1.61803398875 1.61803398875
Autre possibilité plus dans l’esprit de P YTHON :
def a(n):
a=0
b=1
for k in range(n):
(a,b)=(b,a+b)
return a
print a(0),a(1),a(2),a(3)
print float(a(100))/a(99), (1+5**0.5)/2
0 1 1 2 1.61803398875 1.61803398875
Ex. 5 :
1.40
1.30
1.25
plt.show() 1.20
1.15
1.10
1.05
1.00
0 2 4 6 8 10
La suite (u n ) semble croissante. Pour le vérifier, on calcule pour n ∈ N :
u n (6 − u n2 ) u n (6 − u n2 ) − 4u n 2u n − u n2 u n (2 − u n2 )
u n+1 − u n = − un = = =
4 4 4 4
Il faut alors connaitre le signe de u n (2 −pu n2 ). Toujours d’après la représentation graphique, il semble
que u n soit toujours compris pentre 0 et 2. Démontrons-le par récurrence en posant l’hypothèse de
récurrence H (n) : 0 É u n É 2. p
• H (0) est vraie car u 0 = 1 et 0 É 1 É 2 ;
• Soit n ∈ N et supposons H (n) vraie. Par définition de u n+1 , on peut écrire :
u n (6 − u n2 ) x(6 − x 2 )
u n+1 = = f (u n ) en définissant la fonction f : x 7→
4 4
On étudie rapidement la fonction f , elle est dérivable sur R et :
3
∀x ∈ R, f 0 (x) = (2 − x 2 )
4
On obtient alors le tableau de variations de f :
p p
x −∞ − 2 0 2 +∞
0
f (x) (−) 0 (+) 0 (−)
p p
f (x) +∞ & − 2 % 0 % 2 & −∞
p p
Par hypothèse de récurrence, 0 É upn É 2 et la fonction f est croissante p sur l’intervalle
p [0, 2].
Par conséquentpf (0) É f (u n ) É f ( 2), or f (0) = 0, f (u n ) = u n+1 et f ( 2) = 2. On en déduit
que 0 É u n+1 É 2, donc H (n + 1) est vraie ; p
• Par récurrence, H (n) est vraie quel que soit n ∈ N, c’est à dire : ∀n ∈ N, 0 É u n É 2.
Pour n ∈ N, on a alorspu n Ê 0 et 2 − u n2 Ê 0, donc u n+1 − u n Ê 0 et la suite (u n ) est croissante. Elle est
de plus majorée (par 2), donc elle converge. On note ` sa limite, on sait que :
u n (6 − u n2 )
∀n ∈ N, u n+1 =
4
et en faisant tendre n vers +∞, on obtient :
`(6 − `2 )
`=
4
p
En simplifiant,
p on obtient 2` − `3 = 0 c’est à dire `(2 − `2 ) = 0. Par conséquent, ` = 0 ou ` = 2 ou
` = − 2. Notons que comme la suite p(u n ) est croissante et u 0 = 1, on a nécessairement ` Ê 1, la seule
valeur possible pour ` est donc ` = 2.
TP 4 : Instructions conditionnelles
B Penser à :
• Démarrer chaque exercice en ouvrant un nouveau fichier dans l’éditeur (menu Fichier / Nou-
veau Fichier) ;
• Sauvegarder immédiatement ce nouveau fichier (menu Fichier / Enregistrer sous) en lui don-
nant un nom approprié. Pour vous aider, des noms sont suggérés pour chaque exercice.
Applications directes
Exercice 1 Une suite chaotique / suite_chaotique.py : On considère la suite (u n ) définie par :
u 0 = 0.1; ∀n ∈ N, u n+1 = 3u n si 3u n < 1
3u n − 1 si 1 É 3u n < 2
3u n − 2 sinon
(a) Écrire une fonction u(n) qui calcule les termes de cette suite. Vérifier que u(10) est proche
de 0.9. Noter la valeur de u(1000).
(b) On prend maintenant u 0 = 0.1 + 10−10 . Calculer à nouveau u(1000).
On dit que le système décrit par la suite (u n ) est chaotique : de petites variations sur la condition
initiale peuvent conduire à des variations importantes à long terme.
Exercice 2 Une fonction / fonction_triangle.py : On considère la fonction f dont la repré-
sentation graphique est la suivante :
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,3,100)
plt.plot(x,[f(xi) for xi in x])
plt.show()
Mise en œuvre
Exercice 3 Méthode Rde Monte Carlo / monte_carlo.py : On veut déterminer une valeur appro-
b
chée d’une intégrale a f (t ) dt où f est une fonction continue et positive sur l’intervalle [a, b]. On
suppose de plus que l’on connait un réel m tel que : ∀x ∈ [a, b], f (x) É m.
La méthode de Monte Carlo consiste à tirer aléatoirement des valeurs
x ∈ [a, b] et y ∈ [0, m] ; si on effectue ainsi N tirage aléatoires et si m
P designe le nombre de ces tirages pour lesquels y É f (x), alors on
Rb
obtient une valeur approchée de a f (x) dx avec :
Z b P
f (x) dx ' (b − a)m
a N
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp4.pdf
(a) Écrire une fonction monte_carlo(f,a,b,m,N) qui calcule l’approximation de l’intégrale
de f sur [a, b] en appliquant cette méthode. Quelques indications :
• Dans cette fonction, on devra répéter N fois l’opération qui consiste à faire un tirage
aléatoire de x et y ;
• Une fois ce tirage effectué, on testera si la condition y É f (x) est satisfaite ou pas et on
augmentera la valeur de P en conséquence ;
• À la fin de la fonction, on renverra la valeur appropriée ;
• Pour tirer aléatoirement un nombre dans l’intervalle [a, b], on écrira au début du pro-
gramme :
x=uniform(a,b)
monte_carlo(lambda x:x,0,1,2,1000)
monte_carlo(lambda x:x**2,0,1,2,1000)
Utiliser la fonction précédente pour déterminer la longueur de l’orbite de Mercure avec les
données numériques : r 1 = 57,9 · 106 km et r 2 = 56,7 · 106 km. Faire de même avec Pluton :
r 1 = 5900,0 · 106 km et r 2 = 5715,7 · 106 km. Pour vérifier les résultats obtenus, on pourra com-
parer avec le périmètre des cercles de rayons respectifs r 1 et r 2 .
TP 4 : Instructions conditionnelles
Éléments de correction
def u(u0,n):
u=u0
for k in range(n):
if 3*u<1:
u=3*u
elif 1<=3*u<2:
u=3*u-1
else:
u=3*u-2
return u
print u(0.1,10)
0.9
0.289955755927 0.820641585216
Ex. 2 : Sur l’intervalle [−1, 0], la fonction f est égale à la fonction affine x 7→ x + 1 et sur l’intervalle
[0, 2], f est égale à la fonction affine x 7→ 1 − x/2.
def f(x):
if -1<=x<=0:
return x+1
elif 0<x<=2:
return 1-float(x)/2
else:
return 0
print f(-2), f(-0.5), f(0), f(0.5), f(1), f(2)
x=np.linspace(-2,3,100)
0.6
0.2
plt.show()
0.0
−2 −1 0 1 2 3
Ex. 3 :
from random import uniform
def monte_carlo(f,a,b,m,N):
P=0
for k in range(N):
x=uniform(a,b)
y=uniform(0,m)
if y<=f(x):
P=P+1
return m*(b-a)*float(P)/N
R1
Pour 0 x dx, on doit trouver une valeur proche de 1/2. Vérification :
0.46
R1
Pour 0 x 2 dx, on doit trouver une valeur proche de 1/3 :
0.368 Rπ
Un troisième exemple avec le calcul de 0 sin x dx qui doit donner une valeur proche de 2 :
1.89123877746
Calcul de la longueur de l’orbite de Mercure :
r1=5900
r2=5715.7
(on prend comme unité de longueur le million de kilomètres). On considère la fonction f : t 7→
q
r 12 sin2 t + r 22 cos2 t , on remarque que :
q
∀t ∈ R, 0 É f (t ) É r 12 + r 22
q
La fonction f est bien positive et on peut prendre m = r 12 + r 22 . On calcule la longueur de l’orbite :
f=lambda t:sqrt(r1**2*sin(t)**2+r2**2*cos(t)**2)
m=sqrt(r1**2+r2**2)
print monte_carlo(f,0,2*pi,m,10000)
36330.8769882
On vérifie en comparant avec les périmètres des cercles de rayons r 1 et r 2 :
37070.7933124 35912.8022602
La longueur de l’orbite obtenue numériquement est bien comprise entre ces deux périmètres. On
procède de même pour Pluton.
TP 5 : Boucles while
B Penser à :
• Démarrer chaque exercice en ouvrant un nouveau fichier dans l’éditeur ;
• Sauvegarder immédiatement ce nouveau fichier en lui donnant le nom proposé dans l’énoncé.
Applications directes
Exercice 1 Algorithme de Babylone / babylone.py : On considère la suite (u n ) définie par :
u0 = 2
1 2
µ ¶
∀n ∈ N, u n+1 = un +
2 un
p
On admet que la suite (u n ) est décroissante et converge vers 2.
(a) On pose np= 10. Calculer u n en utilisant une boucle for. Vérifier que le résultat obtenu est
proche de 2.
(b) On pose ε = 10−2 . En utilisant une boucle while, calculer le premier terme de la suite pour
lequel (u n − ε)2 É 2.
(c) Réécrire les deux programmes des questions précédentes pour les présenter sous forme de
deux fonctions :
— Une fonction u(n) qui calcule u n à partir de n ;
— Une fonction approx(epsilon) qui calcule le premier terme de la suite (u n ) pour
lequel (u-epsilon)**2<=2.
Mise en œuvre
Exercice 2 Mise en place complète d’un algorithme numérique / eqkepler.py : On s’intéresse à
l’équation de Képler qui intervient dans des calculs astronomiques :
x − e sin x = m (E )
L’inconnue est x et e et m sont deux paramètres réels avec 0 < e < 1. On considère la fonction
f : R → R
x 7→ x − e sin x − m
∀n ∈ N, x n+1 = g (x n )
(d) Écrire une fonction approx(e,m,n) qui calcule x n pour les valeurs de e, m et n données.
Vérifier que approx(0.5,1,10) est proche de 1.5.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp5.pdf
(e) . Vérifier que, pour n ∈ N :
Z xn
g 0 (x) dx = x n+1 − α
α
Notes
¦ L’équation de Képler apparait lorsque l’on cherche à déterminer la position P (t ) d’une planète ou
d’un corps en orbite du soleil en fonction du temps. Un tel corps suit une trajectoire elliptique dont
le soleil occupe l’un des foyers (noté S sur le dessin ci-dessous).
Au temps t 0 , le corps occupe la position de l’orbite où il est le plus
proche du soleil (noté P (t 0 ) sur le dessin, ce point est appelé périhélie
P (t ) de l’orbite). Si on note r (t ) la distance entre S et P (t ), on a la relation :
r (t ) d × (1 + e)
r (t ) = cos(E )−e
S P (t 0 ) 1 + e × 1−e cos(E )
2π(t − t 0 )
x − e sin(x) = (T est la période de révoution du corps céleste)
T
On voit ainsi apparaitre l’équation de Képler.
¦ Pour obtenir une valeur approché de la solution de l’équation x − e sin(x) = m, on a écrit cette
équation sous la forme x = g (x) en posant g (x) = e sin(x)+m. On a ensuite défini une suite (x n ) telle
que x n+1 = g (x n ). L’idée générale qui explique cette construction est que si on arrive à démontrer
que la suite (x n ) converge vers une limite `, alors on aura :
Par unicité de la limite, on a alors e sin(`)+m = ` et ainsi ` est solution de l’équation x −e sin(x) = m.
TP 5 : Boucles while
Éléments de correction
Ex. 1 : (a) On définit n = 100 puis on calcule u 100 avec une boucle for :
n=10
u=2
for k in range(n):
u=0.5*(u+2.0/u)
print u
1.41421356237
(b) On définit ε = 10−4 puis on calcule le terme u n recherché à l’aide d’une boucle while :
epsilon=1e-2
u=2
while (u-epsilon)**2>2:
u=0.5*(u+2.0/u)
print u
1.41666666667
(c) Il y a très peu de modifications à effectuer pour présenter les programmes précédents sous
formes de fonctions :
def u(n):
u=2
for k in range(n):
u=0.5*(u+2.0/u)
return u
def approx(epsilon):
u=2
while (u-epsilon)**2>2:
u=0.5*(u+2.0/u)
return u
Pour calculer u 10 :
print u(10)
1.41421356237
p
Pour obtenir une valeur approchée de 2 à 10−2 près :
print approx(1e-2)
1.41666666667
1.49870113352
(d) Pour n ∈ N :
Z xn ¤x
g 0 (x) dx = g (x) αn = g (x n ) − g (α) = x n+1 − α
£
α
0
Par ailleurs, on a |g (x)| É e pour tout x, donc :
¯Z x ¯
¯ n 0
|x n+1 − α| = ¯
¯
¯ g (x) dx ¯¯ É e |x n − e|
e
(e) Par récurrence avec la question précédente : ∀n ∈ N, |x n − α| É e n |x 0 − α|.
(f) Comme 0 < e < 1, on a e n −−−−−→ 0 et par encadrement x n −−−−−→ α.
n→+∞ n→+∞
(g) Supposons f (x n − ε) É 0 et f (x n + ε) Ê 0. La fonction f est continue, donc d’après le théo-
rème des valeurs intermédiaires, f s’annule sur l’intervalle [x n − ε, x n + ε]. Par conséquent
α ∈ [x n − ε, x n + ε] et ainsi |x n − α| É ε. Notons également que comme x n −−−−−→ α, il existe
n→+∞
nécessairement un entier n tel que x n − ε É α et x n + ε Ê α. Conséquence : on peut utiliser la
condition f (x n − ε) É 0 et f (x n + ε) Ê 0 comme condition d’arrêt. À REFORMULER.
(h)
m=2
e=0.5
a=eqkepler(e,m,1e-4)
print a
print a-e*sin(a)-m
2.35417205822 -9.56465070927e-05
On trouve bien une valeur proche de 0. Pour m = 10 et e = 0.9 :
m=10
e=0.9
a=eqkepler(e,m,1e-4)
print a
print a-e*sin(a)-m
9.72984542447 0.000167196589832
TP 6 : Sommes et produits
B• Penser à ouvrir un nouveau fichier pour chaque exercice et à l’enregister immédiatement en
lui donnent le nom proposé dans l’énoncé.
• On documentera chaque fonction écrite en expliquant en une ligne ce qu’elle calcule (comme
on l’a vu en cours).
Exercice 1 Somme des carrés / somme_carres.py : Le programme suivant calcule et affiche la
valeur de la somme
s=0
10
2 for k in range(1,11):
X
k
k=1 s=s+k**2
print s
X s=0
ij for i in range(1,11):
1Éi , j É10
for j in range(1,11):
s=s+i*j
print s
X X i
Pour n ∈ N∗ , on définit les sommes S n = min(i , j ) et Tn = .
1Éi , j Én 1Éi É j Én j +1
(a) Écrire deux fonctions S(n) et T(n) qui calculent respectivement S n et Tn (on pourra utiliser
la fonction min qui existe dans P YTHON).
(b) Tester ces fonctions en vérifiant, pour quelques valeurs de n, les égalités :
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp6.pdf
Exercice 4 Approximation de fonctions / approx_exp.py : Pour x ∈ R et N ∈ N, on pose :
XN xn
A exp (N , x) =
n=0 n!
(a) Écrire une fonction Aexp(N,x) qui calcule A exp (N , x). Vérifier que Aexp(10,1) est une
valeur approchée de exp(1).
(b) Représenter les fonctions x 7→ ex et x 7→ A exp (3, x) sur l’intervalle [−2, 2] sur le même dessin.
On donne pour cela les commandes :
(c) Représenter les fonctions x 7→ ex et x 7→ A exp (10, x) sur l’intervalle [−2, 2] sur le même dessin.
Nom :
Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1
Algorithmique et programmation
Nom :
Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1
Algorithmique et programmation
Éléments de correction
Ex. 1 :
def somme_carres(n):
"""Calcule 1^2+2^2+...+n^2"""
s=0
for k in range(1,n+1):
s=s+k**2
return s
print somme_carres(3)
14
def produit_carres(n):
"""Calcule 1^2*2^2*...*n^2"""
s=1
for k in range(1,n+1):
s=s*k**2
return s
print produit_carres(3)
36
Ex. 2 :
def probabilite(n):
"""Calcule la probabilité que parmi n personnes,
deux aient leur anniversaire le même jour"""
p=1
for k in range(1,n): # Dans le produit, k va de 1 jusqu’à n-1
p=p*(1-float(k)/365)
# p contient le produit (1-1/365)*...*(1-(n-1)/365)
return 1-p
print probabilite(35)
0.814383238875
Ex. 3 :
def S(n):
"""Calcule la somme des min(i,j) pour 1<=i,j<=n"""
s=0
for i in range(1,n+1):
for j in range(1,n+1):
s=s+min(i,j)
return s
print S(10), 10*(10+1)*(2*10+1)/6
385 385
def T(n):
"""Calcule la somme des i/(j+1) pour 1<=i<=j<=n"""
s=0
for i in range(1,n+1):
for j in range(i,n+1):
s=s+float(i)/(j+1)
return s
print T(10), float(10*(10+1))/4
27.5 27.5
def T(n):
"""Calcule la somme des i/(j+1) pour 1<=i<=j<=n"""
s=0
for i in range(1,n+1):
for j in range(1,n+1):
if i<=j:
s=s+float(i)/(j+1)
return s
print T(10), float(10*(10+1))/4
27.5 27.5
Ex. 4 :
2.71828180115
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,2,100)
plt.plot(x,[exp(xi) for xi in x])
plt.plot(x,[Aexp(3,xi) for xi in x])
8
−1
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x=np.linspace(-2,2,100)
plt.plot(x,[exp(xi) for xi in x])
plt.plot(x,[Aexp(10,xi) for xi in x])
0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
TP 7 : Listes
B• Penser à ouvrir un nouveau fichier pour chaque exercice et à l’enregister immédiatement en
lui donnant un nom approprié.
• On documentera chaque fonction écrite en expliquant en une ligne ce qu’elle calcule.
• Penser à tester les fonctions sur des exemples simples.
Applications directes
Exercice 1 Calculs sur des listes : On pensera à tester les fonctions suivantes sur des exemples
simples.
(a) Écrire une fonction somme(L) qui calcule la somme des éléments de la liste L (si cette liste
est vide, le résultat renvoyé devra être 0).
(b) Écrire une fonction moyenne(L) qui calcule la moyenne des éléments de la liste L (cette liste
ne devra pas être vide).
(c) Écrire une fonction variance(L) qui calcule la variance de la liste L définie par :
1 n−1
(L[k] − m)2
X
variance(L) =
n k=0
Exercice 2 Sélection des éléments d’une liste : Écrire une fonction selectionner(L,a,b) qui
construit une nouvelle liste obtenue en ne gardant que les éléments de L qui sont compris (au sens
large) entre a et b (on supposera a É b).
Exercice 3 Liste des termes d’une suite : On considère la suite (u n ) définie par :
u0 = 1
p
∀n ∈ N, u n+1 = 1 + u n
Mise en œuvre
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp7.pdf
Spectre d'émission du soleil
2.0
1.5
1.0
φ (W ·m−2 ·nm−1 )
0.5
0.0
−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
λ (nm)
Les données numériques correspondant à ces points se trouvent dans deux listes, une liste
Lambda pour les abscisses et une liste Phi pour les ordonnées. On pourra obtenir ces deux
listes par copier coller depuis l’adresse :
http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/donneesTP7ex4.html
Déterminer l’indice k tel que Phi[k] soit maximal puis déterminer Lambda_max=Lambda[k].
On peut alors obtenir une valeur approchée de la température T de la surface du soleil en uti-
lisant la loi du déplacement de Wien :
2.898 · 106
T=
λmax
2.5
2.0
1.5
1.0
0.5
0.0
0 500 1000 1500 2000 2500 3000 3500 4000
2.5
2.0
1.5
1.0
0.5
0.0
−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
Les abscisses des « points rouges » sont eregistrées dans une liste Lambda et les ordonnées corres-
pondantes dans une liste Phi. On cherche Lambda[k] tel que Phi[k] soit maximal.
¦ On considère une liste :
X = [x 0 , x 1 , . . . , x n−1 ]
On réalise une fonction indice_max(X) qui calcule la valeur k telle que x k soit le maximum de
x 0 , . . . , x n−1 .
def indice_max(X):
"""
Calcule k tel que X[k] soit maximal
X : liste non vide
"""
k=0
for i in range(1,len(X)):
if X[i]>X[k]:
k=i
return k
¦ On peut alors déterminer la température T de la face externe du soleil par application de la loi de
Wien : on note λmax la valeur Lambda[k] avec k=indice_max(Phi) et on calcule
2.898 · 106
T=
λmax
lambda_max=Lambda[indice_max(Phi)]
print "Température :", 2.898e6/lambda_max, "K"
Température : 5733.45323741 K
¦ Pour finir on superpose les mesures ainsi que l’approximation effectuée à la représentation gra-
phique de la luminance du corps noir à 5733 K (en appliquant un facteur d’échelle) :
1.5
1.0
0.5
0.0
−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
TP 7 : Listes
Éléments de correction
Ex. 1 :
def somme(L):
s=0
for x in L:
s=s+x
return s
def moyenne(L):
return float(somme(L))/len(L)
def variance(L):
m=moyenne(L)
s=0
for x in L:
s=s+(x-m)**2
return float(s)/len(L)
T=[1,2]
print somme(T), moyenne(T), variance(T)
3 1.5 0.25
Ex. 2 :
def selection(L,a,b):
"""
Je suppose a<=b
"""
M=[]
for x in L:
if a<=x<=b:
M.append(x)
return M
def liste_termes(u0,n):
u=u0
L=[u]
for i in range(n):
u=(1+u)**0.5
L.append(u)
return L
print liste_termes(1,10)
Ex. 4 :
Lambda=[...]
Phi=[...]
def indice_max(X):
"""
Calcule k tel que X[k] soit maximal
X : liste non vide
"""
k=0
for i in range(1,len(X)):
if X[i]>X[k]:
k=i
return k
lambda_max=Lambda[indice_max(Phi)]
print "Temp. :", 2.898e6/lambda_max, "K"
Temp. : 5733.45323741 K
TP 8 : Listes (2) et preuves de programmes
Exercice 1 :
(a) Écrire une fonction nocc(x,L) qui calcule le nombre de fois où x apparait dans la liste L.
On utilisera une boucle while et on donnera un invariant de boucle permettant de démontrer
que cette fonction est correcte.
(b) Écrire une fonction majoritaire(L) qui détermine un élément x qui soit majoritaire dans
L (autrement dit qui apparait plus souvent dans L que tout autre élément de L). On utilisera
une boucle while et on donnera un invariant de boucle permettant de démontrer que cette fonc-
tion est correcte.
1.5
1.0
φ (W ·m−2 ·nm−1 )
0.5
0.0
−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
λ (nm)
Les données numériques correspondant à ces points se trouvent dans deux listes, une liste
Lambda pour les abscisses et une liste Phi pour les ordonnées. On pourra obtenir ces deux
listes par copier coller depuis l’adresse :
http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/donneesTP8ex2.html
Déterminer l’indice k tel que Phi[k] soit maximal puis déterminer Lambda_max=Lambda[k].
On peut alors obtenir une valeur approchée de la température T de la surface du soleil en uti-
lisant la loi du déplacement de Wien :
2.898 · 106
T=
λmax
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp8.pdf
TP 8 : Listes (2) et preuves de programmes
Éléments de correction
Ex. 1 :
def nocc(x,L):
"""
Calcule le nombre d’apparitions de x dans L
"""
n=0
i=0
while i<len(L): # len(L)-i est >=0 et strict. déc.
if L[i]==x:
n=n+1
i=i+1
# Invariant de boucle : n=nocc(x,L[0..i])
return n
def majoritaire(L):
"""
Détermine _un_ élément majoritaire de L
"""
xmaj=L[0]
nmaj=nocc(xmaj,L)
i=1
while i<len(L): # len(L)-i est >=0 et strict. déc.
if nocc(L[i],L)>nmaj:
xmaj=L[i]
nmaj=nocc(xmaj,L)
i=i+1
# Invariant de boucle : xmaj est l’élément de L[0:i]
# qui apparait le plus souvent dans L
return xmaj
Ex. 2 :
Lambda=[...]
Phi=[...]
def indice_max(X):
"""
Calcule k tel que X[k] soit maximal
X : liste non vide
"""
k=0
for i in range(1,len(X)):
if X[i]>X[k]:
k=i
return k
lambda_max=Lambda[indice_max(Phi)]
print "Temp. :", 2.898e6/lambda_max, "K"
Temp. : 5733.45323741 K
TP 9 : Simulation d’un système en physique, chimie, SII
Exercice 1 SII / Moteur à courant continu : On alimente un moteur initialement à l’arrêt par une
tension constante U = 10 V. La vitesse de rotation w du moteur est solution de l’équation différen-
tielle :
dw Ke Kc Kc
µ ¶
J + + f w(t ) = U
dt R R
avec w(0) = 0
où :
• J est l’inertie du moteur, J = 5.5 · 10−5 kg · m2 ;
• R est la résistance électrique du système, R = 5.2 Ω ;
• K c et K e sont des constantes, K c = 0.24 N · m · A−1 et K e = 0.24 V · rad−1 · s ;
• f est un coefficient caractérisant les forces de frottement, f = 0.05 N · m · s · rad−1 .
On notera cette équation différentielle sous la forme :
dw 1 Kc Ke
µ ¶
= aw(t ) + b avec a = − +f
dt J R
KcU
b=
JR
On réalise une simulation avec N = 100 étapes de calcul et un pas de temps ∆t = 10−4 s.
(a) Définir les différentes constantes intervenant dans le problème.
(b) Définir la liste t = [t 0 , . . . , t N −1 ] avec t i = i ∆t ainsi qu’une liste w de taille N , dont tous les
termes sont pour l’instant nuls (et qui contiendra, une fois les calculs effectués, les valeurs
w(t 0 ), . . . , w(t N −1 )).
(c) À partir de l’équation différentielle, déterminer comment on va définir w[i +1] à partir de w[i ].
(d) Écrire la boucle réalisant ce calcul.
(e) Représenter graphiquement w en fonction de t avec :
(f) Vérifier (numériquement) que la vitesse du moteur tend vers une limite pour t assez grand et
que cette limite est −b/a.
(g) On pose w 0 = −b/a (vitesse limite du moteur). Écrire une boucle while permettant de déter-
miner la plus petite valeur de k telle que w[k] Ê 0.95w 0 . Déterminer le temps t [k] correspon-
dant. Que représente t [k] ?
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp9.pdf
Exercice 2 Chimie / Réaction d’ordre 1 : On considère la réaction de décomposition des ions per-
oxodisulfate :
1
S 2O 82− + H2O = 2SO 42− + O 2 + 2H +
2
On note C la concentration en S 2O 82− . L’évolution de cette concentration est décrite par l’équation
différentielle :
dC
= −kC
dt
avec k = 5.0 · 10−3 min−1 et C 0 = 10−2 mol · L−1 . On réalise une simulation avec le pas de temps
∆t = 0.1 s et N = 2500 étapes de calcul.
(a) Définir les différentes constantes intervenant dans le problème.
(b) Définir les listes t = [t 0 , . . . , t N −1 ] avec t i = i ∆t et C la liste de taille N dont tous les termes sont
pour l’instant nuls.
(c) À partir de l’équation différentielle, déterminer comment on va définir C [i +1] à partir de C [i ].
(d) Écrire la boucle réalisant ce calcul.
(e) Représenter graphiquement C en fonction de t avec :
Définir les listes t_mes et C_mes correspondant à ces valeurs puis représenter simultané-
ment les valeurs mesurées et les valeurs calculées avec :
plt.plot(t,C)
plt.plot(t_mes,C_mes,’+’,markersize=12)
plt.legend(["Calculs","Mesures"])
plt.title("C en fonction de t")
plt.xlabel("t")
plt.ylabel("C")
plt.show()
Notes
¦ Pour que les valeurs obtenues par la simulation soit pertinentes, il faut que le pas de temps ∆t soit
choisi judicieusement. Disons simplement que ∆t doit être « petit » devant le temps de réaction du
système. Ceci a pour conséquence qu’il faut déjà avoir une certaine connaissance du système avant
de le simuler.
¦ Cette méthode de résolution approchée d’une équation différentielle est appelée méthode d’Euler.
TP 9 : Simulation d’un système en physique, chimie, SII
Éléments de correction
Ex. 1 :
# Constantes du problème
U=10.0
J=5.5e-5
R=5.2
Kc=0.24
Ke=0.24
f=0.05
a=-1.0/J*(Kc*Ke/R+f)
b=Kc*U/(J*R)
# Paramètres de la simulation
N=100
Delta_t=1e-4
w[i + 1] − w[i ]
' aw[i ] + b
t [i + 1] − t [i ]
for i in range(N-1):
w[i+1]=w[i]+(t[i+1]-t[i])*(a*w[i]+b)
Représentation graphique :
plt.plot(t,w)
plt.xlabel("$t$")
plt.ylabel("$w$")
plt.title("Vitesse de rotation du moteur")
Vitesse de rotation du moteur
8
4
w
0
0.000 0.002 0.004 0.006 0.008 0.010
t
w0=-b/a
k=0
while w[k]<0.95*w0:
k=k+1
print w0, w[k], t[k]
Ex. 2 :
# Paramètres de la simulation
Delta_t=0.1
N=2500
# Constantes du problème
k=5.0e-3
C[0]=1e-2
Comme t [i + 1] − t [i ] est « petit », l’équation différentielle donne :
C [i + 1] −C [i ]
' −kC [i ]
t [i + 1] − t [i ]
for i in range(N-1):
C[i+1]=C[i]-k*(t[i+1]-t[i])*C[i]
Représentation graphique :
t_mes=[0,50,100,150,200,250]
C_mes=[1e-2,7.8e-3,6.05e-3,4.72e-3,3.68e-3,2.86e-3]
plt.plot(t,C)
plt.plot(t_mes,C_mes,’+’,markersize=12)
plt.legend(["Calculs","Mesures"])
plt.title("C en fonction de t")
plt.xlabel("t")
plt.ylabel("C")
0.010
C en fonction de t
Calculs
Mesures
0.009
0.008
0.007
0.006
C
0.005
0.004
0.003
0.002
0 50 100 150 200 250
t
TP 10 : Listes (3) et complexité
Exercice 1 Somme pondérée : On considère deux listes N et C de même taille n. On veut calculer
la somme pondérée s :
M = [M 0 , M 1 , . . . , M n−1 ]
V = [V0 ,V1 , . . . ,Vn−1 ]
toutes deux de même taille n. On veut ranger certains de ces objets dans un sac pouvant contenir
une masse totale maximale M max de manière à ce que la valeur totale soit la plus grande possible.
Une sélection d’objets est une liste :
S = [S 0 , S 1 , . . . , S n−1 ]
de taille n telle que chaque élément S k est égal à 0 ou 1 (1 signifiant que l’on prend l’objet k et 0
signifiant qu’on ne le prend pas). Pour tester les fonctions, on pourra utiliser les valeurs suivantes :
M = [12, 2, 1, 4, 3]
V = [4, 2, 1, 10, 2]
M max = 15
(a) Écrire une fonction valeur_selection(V,S) qui calcule la valeur totale des objets de la
sélection S (pour la liste de valeurs V ). Donner un ordre de grandeur du temps d’exécution de
cette fonction, en fonction de n.
(b) Écrire une fonction masse_selection(M,S) qui calcule la masse totale des objets de la
sélection S (pour la liste de masses M ). Donner un ordre de grandeur du temps d’exécution
de cette fonction, en fonction de n.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp10.pdf
(c) On considère la fonction suivante :
def selections(n):
S=[]
for k in range(2**n):
L=[]
x=k
for i in range(n):
L.append(x%2)
x=x/2
S.append(L)
return S
Elle retourne la liste de toutes les sélections possibles pour n objets. Par exemple :
print selections(3)
[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0,
1, 1], [1, 1, 1]]
Donner un ordre de grandeur du temps d’exécution de cette fonction, en fonction de n.
(d) Écrire une fonction selection_maximale(Mmax,V,M) (utilisant la fonction donnée à la
question précédente), qui retourne une sélection des n objets dont la masse totale est infé-
rieure à M max et dont la valeur totale est la plus grande possible. Donner un ordre de grandeur
du temps d’exécution de cette fonction, en fonction de n.
Nom :
Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1
Algorithmique et programmation
Nom :
Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1
Algorithmique et programmation
Éléments de correction
Ex. 1 :
def somme_ponderee(N,C):
"""
Calcule la somme N[0]*C[0]+...+N[n-1]*C[n-1]
C et N : listes de même taille
"""
s=0
for i in range(len(N)):
s=s+C[i]*N[i]
return s
print somme_ponderee([1,1,1],[1,-1,1])
1
Temps d’exécution : Tsomme_ponderee (n) = O(n).
def syracuse(u0,n):
"""
Construit la liste [u0,u1,...,un]
constituée des (n+1) premiers termes de la suite de Syracuse
partant de u0
"""
u=u0
L=[u0]
for k in range(n):
if u%2==0:
u=u/2
else:
u=3*u+1
L.append(u)
return L
print syracuse(5,6)
[5, 16, 8, 4, 2, 1, 4]
Le temps d’exécution est un O(n). Remarque : si on définit une fonction qui calcule u n puis on
l’utilise ensuite pour construire la liste, on obtient un temps d’exéction en O(n 2 ).
ex_M=[12,2,1,4,3]
ex_V=[4,2,1,10,2]
ex_Mmax=15
def valeur_selection(V,S):
"""
Calcule la valeur de la sélection définie par S
"""
v=0
for i in range(len(S)):
if S[i]==1:
v=v+V[i]
return v
print valeur_selection(ex_V,[1,0,0,0,1])
def masse_selection(M,S):
"""
Calcule la masse totale de la sélection définie par S
"""
m=0
for i in range(len(S)):
if S[i]==1:
m=m+M[i]
return m
print masse_selection(ex_M,[1,0,0,0,1])
15
Remarque. Ces deux fonctions sont identiques (c’est même la fonction somme_ponderee de
l’exercice 1). Leur temps d’exécution est un O(n).
def selections(n):
S=[]
for k in range(2**n):
L=[]
x=k
for i in range(n):
L.append(x%2)
x=x/2
S.append(L)
return S
Le temps d’exécution de cette fonction est un O(n2n ). On supposera que la sélection [0, . . . , 0] est
toujours valide.
def selection_maximale(Mmax,V,M):
n=len(V)
Smax=[0]*n
vmax=0
for S in selections(n):
if valeur_selection(V,S)>vmax and masse_selection(M,S)<=Mmax:
Smax=S
vmax=valeur_selection(V,Smax)
return Smax
print selection_maximale(ex_Mmax,ex_V,ex_M)
[0, 1, 1, 1, 1]
Le temps d’exécution est un O(n2n ).
TP 11 : Chaînes de caractères
B BBUn exemple du résumé de cours 11 est faux. La version corrigée est la suivante (les chan-
gements sont indiqués en gras, la version sur le site web est correcte) :
Exemple Python. Les chaînes de caractères interviennent typiquement lorsqu’il faut demander
des informations à l’utilisateur par l’intermédaire du clavier. Le programme suivant demande un
nombre (entier) et affiche le carré de ce nombre :
Noter que le programme produira une erreur si on entre, par exemple, un nombre flottant tel que
1.2.
B Les différents exercices sont liés. On pourra donc utiliser un seul fichier pour la totalité du TP.
Applications directes
Exercice 1 : On considère deux chaînes de caractères txt et mot et on veut déterminer à quelles
positions on retrouve mot dans txt en convenant qu’un point dans mot peut désigner n’importe
quel caractère dans txt. Par exemple si :
txt = "abcabbab"
mot = "ab."
alors mot apparait dans txt aux positions 0 et 3. Adapter la fonction positions(txt,mot) vue
en cours pour qu’elle réponde à ce problème. Vérifier son fonctionnement sur quelques exemples
pertinents.
Exercice 2 : Modifier la fonction précédente pour réaliser une nouvelle fonction nbocc(txt,mot)
qui renvoie le nombre de fois où mot apparait dans txt (avec les conventions de l’exercice précé-
dent). Vérifier son fonctionnement sur quelques exemples pertinents. Remarque : on veut simple-
ment compter le nombre de fois où mot apparait dans txt, il sera donc inutile de créer une liste conte-
nant les positions où mot apparait.
Mise en œuvre
Exercice 3 Séquences exceptionnelles dans des chaînes d’ADN : Une chaîne d’ADN (on dira aussi
séquence) est une chaîne de caractères dans laquelle apparaissent uniquement les lettres a, t, c, g.
On appelle nucléotides les quatre chaînes de caractères "a", "t", "c" et "g".
(a) Étant donnée une chaîne d’ADN (notée simplement adn) et un nucléotide n, on note ϕadn (n)
la proportion de n dans adn (c’est à dire le nombre de fois où n apparait dans adn divisé par
le nombre de caractères de la chaîne adn). Écrire une fonction phi(adn,n) qui réalise ce
calcul (on utilisera la fonction nbocc de l’exercice précédent). Faire quelques tests en utilisant
la chaîne d’ADN :
adn = "ttcagttgtgaatgaatgga"
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp11.pdf
(b) Si n 1 et n 2 sont deux nucléotides, on note τadn (n 1 , n 2 ) le nombre de fois où apparait la chaîne
n 1 + n 2 dans adn divisé par le nombre de fois où apparait n 1 + "." (le point désignant n’im-
porte quelle lettre, on reprend les conventions des exercices précédents). Écrire une fonction
tau(adn,n1,n2) qui réalise ce calcul (on utilisera la fonction nbocc de l’exercice pré-
cédent). Faire quelques tests. Donner un ordre de grandeur du temps d’exécution de cette
fonction, en fonction de N (longueur de la chaîne adn).
(c) Étant donnée une chaîne de nucléotides ch de longueur `, on appelle fréquence théorique
d’apparition de ch dans adn le nombre :
ϕadn (ch[0]) × τadn (ch[0], ch[1]) × · · · × τadn (ch[` − 2], ch[` − 1])
http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/Sequences3.html
Parmi ces séquences, déterminer celle pour laquelle delta est le plus grand.
(f) Reprendre la question précédente sur une séquence ADN réelle : le gène Antennapedia de la
drosophile. Pour cela, télécharger le fichier :
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/
Antennapedia-adn.txt
et l’enregistrer dans le même répertoire que votre programme P YTHON. Utiliser ensuite les
commandes :
f=open(’Antennapedia-adn.txt’,’r’)
adn=f.readline().replace("\n","")
f.close()
Notes
¦ Dans une chaîne d’ADN donnée, les généticiens étudient spécifiquement les chaînes de nucléo-
tides qui apparaissent significativement plus souvent que leur fréquence théorique d’apparition. Le
programme réalisé ici n’est pas du tout efficace : on recalcule πadn (n) et τadn (n 1 , n 2 ) de nombreuses
fois alors qu’il serait beaucoup plus efficace de faire le calcul une fois pour toutes.
Nom :
Écrire du code
Mettre des commentaires 1
Écrire une fonction 1
Gérer l’indentation 1
Algorithmique et programmation
Nom :
Écrire du code
Mettre des commentaires 1
Écrire une fonction 1
Gérer l’indentation 1
Algorithmique et programmation
Éléments de correction
Ex. 1 :
def positions(txt,mot):
"""
La liste des positions où mot apparait dans txt
mot est une chaine de caractères dans laquelle ’.’ désigne
un caractère quelconque
"""
Pos=[]
for i in range(len(txt)-len(mot)+1):
nb_egaux=0
for j in range(len(mot)):
if mot[j]=="." or mot[j]==txt[i+j]:
nb_egaux=nb_egaux+1
if nb_egaux==len(mot):
Pos.append(i)
return Pos
print positions("abcabbac","ab.")
[0, 3]
Ex. 2 :
def nbocc(txt,mot):
"""
Le nombre de fois où mot apparait dans txt
mot est une chaine de caractères dans laquelle ’.’ désigne
un caractère quelconque
"""
n=0
for i in range(len(txt)-len(mot)+1):
nb_egaux=0
for j in range(len(mot)):
if mot[j]=="." or mot[j]==txt[i+j]:
nb_egaux=nb_egaux+1
if nb_egaux==len(mot):
n=n+1
return n
print nbocc("abcabbac","ab.")
Ex. 3 :
# Les exemples :
adn_exemple="ttcagttgtgaatgaatgga"
f=open(’/home/ba/Enseignement/PC/Python/Data/Antennapedia-adn.txt’,’r’)
adn_antennapedia=f.readline().replace("\n","")
f.close()
def phi(adn,n):
"""
adn : chaine de caractères non vide
n : nucléotide (chaine d’un seul caractère)
Résultat : fréquence de n dans adn
"""
return float(nbocc(adn,n))/len(adn)
print phi(adn_exemple,"a")
0.3
def tau(adn,n1,n2):
"""
adn : chaine de caractères non vide
n1,n2 : nucléotides (chaines d’un caractère)
Résultat : fréquence de n1n2 dans adn
"""
return float(nbocc(adn,n1+n2))/nbocc(adn,n1+".")
print tau(adn_exemple,"a","t")
0.4
def freq_th(adn,ch):
"""
adn,ch : chaines de caractères non vides
Résultat : fréquence théorique d’apparition de ch
dans la séquence adn
"""
f=phi(adn,ch[0])
for i in range(0,len(ch)-1):
f=f*tau(adn,ch[i],ch[i+1])
return f
def freq_obs(adn,ch):
"""
adn,ch : chaines de caractères non vides
Résultat : fréquence observée d’apparition de ch
dans la séquence adn
"""
return float(nbocc(adn,ch))/(len(adn)-len(ch)+1)
def delta(adn,ch):
"""
adn,ch : chaines de caractères non vides
Résultat : différence entre les fréquences observée et théorique
"""
return freq_obs(adn,ch)-freq_th(adn,ch)
Sequences3=[’ttt’,’ttc’,’ttg’,’tta’,’tct’,...]
def max_delta(adn,mots):
"""
Résultat : élément de la liste de mots pour lequel
la différence entre fréquences observée et théorique
est maximale ainsi que la valeur de la différence
"""
s0=mots[0]
m0=delta(adn,s0)
for i in range(1,len(mots)):
s=mots[i]
m=delta(adn,s)
if m>m0:
m0=m
s0=s
return (s0,m0)
# Séquence de taille 3 pour laquelle delta_freq est maximal
print max_delta(adn_exemple,Sequences3)
(’aat’, 0.0631111111111111)
#print max_delta(adn_antennapedia,Sequences3)
TP 12 : Gestion des fichiers
(a) Écrire un programme P YTHON qui ouvre ce fichier et construit une chaîne de caractères à
partir des différentes lignes en ne gardant que l’information sur les nucléotides (on enlère les
nombres, les espaces, etc. on ne garde en fait que les lettres a, t, c, g).
(b) Compléter le programme pour qu’il enregistre cette chaîne de caractères dans un nouveau
fichier nommé Antennapediat-brut.txt.
Rappel : on peut parcourir une chaîne de caractères de la même manière qu’une liste. Exemple :
>>> s="abc"
>>> for c in s:
... print c
...
a
b
c
Exercice 2 Écrire une image au format PBM : On considère une image rectangulaire constituée
uniquement de pixels (points) noirs et blancs. La largeur de l’image est de ` pixels et et hauteur est
de n pixels. Cette image sera représentée par une liste P YTHON et on désire l’enregistrer dans un
fichier en utilisant le format PBM. Par exemple :
L’image : La liste P YTHON : Le fichier PBM correspondant :
L=[[1,1,0,0], P1
[0,1,1,0], 4 3
[0,0,1,1]] 1 1 0 0
0 1 1 0
(largeur 4 et hauteur 3).
0 0 1 1
Un fichier au format PBM est construit de la manière suivante : la première ligne est la chaîne de ca-
ractères "P1", la deuxième donne la largeur et la hauteur de l’image (séparées par un espace) et
chaque ligne suivante correspond à une ligne de l’image en donnant les couleurs de pixels (1 pour
noir et 0 pour blanc), séparées par des espaces également.
Écrire une fonction ecrire_pbm(L,nom) qui construit le fichier nommé nom à partir de la liste
L en respectant le format PBM.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp12.pdf
Exercice 3 Compter les mots :
(a) Écrire une fonction nombre_mots(s) qui compte combien de mots il y a dans la chaîne
de caractères s. Note : pour simplifier cette première question, on supposera que la chaîne de
caractère s est composée uniquement de mots séparés par un espace simple, par exemple
(b) Utiliser cette fonction pour compter combien de mots comporte le premier chapitre de L’Île
Mystérieuse de Jules Verne (fichier IleMysterieuseChap1.txt).
(c) On veut reprendre la fonction nombre_mots de la première question pour qu’elle fonctionne
dans un cas plus général. On définit pour cela la liste :
Separateurs=[" ",",",";",".","!","?",":","(",")","-","\n"]
("\n" est le caractère « retour à la ligne »). Si s est une chaîne de caractères, on appelle mot de
s toute chaîne non vide, contenue dans s et délimitée par deux éléments de la liste ci-dessus.
Modifier la fonction nombre_mots pour qu’elle compte les mots de s avec cette nouvelle
définition.
TP 12 : Gestion des fichiers
Éléments de correction
Ex. 1 :
FICHIER=’Antennapedia-formate.txt’
FICHIERADN=’Antennapedia-brut.txt’
f=open(FICHIER,’r’)
adn=""
s=f.readline()
while s!="":
for i in range(len(s)):
if s[i] in [’a’,’t’,’c’,’g’]:
adn=adn+s[i]
s=f.readline()
f.close()
print adn[0:20]+"..."
ttcagttgtgaatgaatgga...
f=open(FICHIERADN,’w’)
f.write(adn)
f.close()
Ex. 2 :
def ecrire_pbm(L,nom):
f=open(nom,’w’)
f.write("P1\n")
# Largeur de l’image = len(L[0])
# Hauteur de l’image = len(L)
# Une possibilité pour l’écrire :
f.write("%i %i\n" % (len(L[0]),len(L)))
# Autre possibilité :
# f.write(str(len(L[0]))+" "+str(len(L))+"\n")
for ligne in L:
for pixel in ligne :
f.write(str(pixel)+" ")
f.write("\n")
f.close()
ecrire_pbm([[1,1,0,0],[0,1,1,0],[0,0,1,1]],’test.pbm’)
Le contenu du fichier :
P1
4 3
1 1 0 0
0 1 1 0
0 0 1 1
Ex. 3 : (a) Vu les conditions données dans l’énoncé, le nombre de mots dans une chaîne de ca-
ractères est égal au nombre d’espaces plus 1.
def nombre_mots(s):
n=0
for i in range(len(s)):
if s[i]==" ":
n=n+1
return n+1
print nombre_mots("Une phrase simple")
3
(b) Il suffit maintenant de prendre le fichier ligne à ligne et totaliser le nombre de mots de chaque
ligne :
FICHIER="IleMysterieuseChap1.txt"
f=open(FICHIER,’r’)
N=0
s=f.readline()
while s!="":
N=N+nombre_mots(s)
s=f.readline()
f.close()
print N
1996
(c) On va modifier la fonction nombre_mots pour que son fonctionnement soit plus réaliste.
On utilise une chaîne de caractères intermédiaire notée ch_int. On parcourt la chaîne s et,
si le caractère rencontré n’est pas un séparateur, on l’ajoute à ch_int. Si le caractère rencon-
tré est un séparateur, on regarde le contenu de la chaîne ch_int qui contient les caractères
rencontrés depuis le dernier séparateur. Si cette chaîne est vide, c’est que l’on se trouve entre
deux séparateurs adjacents et il ne faut pas augmenter le nombre de mots. Si elle n’est pas
vide, alors on augmente le nombre de mots et on vide la chaine ch_int.
def nombre_mots(s):
Separateurs=[" ",",",";",".","!","?",":","(",")","-","\n"]
ch_int=""
n=0
for i in range(len(s)):
if s[i] in Separateurs:
if ch_int!="":
n=n+1
ch_int=""
else:
ch_int=ch_int+s[i]
return n
print nombre_mots(" Une chaine, sans doute... plus complexe !\n")
6
f=open(FICHIER,’r’)
N=0
s=f.readline()
while s!="":
N=N+nombre_mots(s)
s=f.readline()
f.close()
print N
2095
TP 13 : Tableaux à 2 dimensions, images et calcul matriciel
Exercice 1 Calcul matriciel, systèmes : On pourra traiter cet exercice directement dans la console.
£ 1 −2 ¤ 1
(a) Définir avec N UMPY la matrice A = et le vecteur x = . Calculer A −1 ainsi que le
£ ¤
1 1 −1
produit Ax.
(b) On considère le système :
x + 2y + 3z = 6
4x + 5y + 6z = 15
7x + 8y + 9z = 24
Traitement d’images
¦ On commencera par récupérer un exemple d’image :
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/papillon.txt
(à enregistrer dans le même répertoire que vos programmes P YTHON). Tous les exercices de ce TP
pourront être traités dans le même fichier où l’on commencera par entrer les commandes :
import numpy as np
import matplotlib.pyplot as plt
def afficher_image(A):
plt.xticks([])
plt.yticks([])
plt.imshow(A,cmap=plt.cm.gray)
plt.show()
On utilisera comme exemple l’image associée au fichier papillon.txt que l’on vient de téléchar-
ger :
Papillon=np.fromfile("papillon.txt",float,-1," ").reshape(240,320)
afficher_image(Papillon)
Exécuter le programme, l’image du papillon doit s’afficher. Fermer la fenêtre correspondante et pas-
ser aux exercices.
B [i , j ] = A[i , m − j − 1]
Par exemple :
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp13.pdf
Papillon Miroir vertical
On commencera par écrire dans la fonction (n,m)=A.shape afin que n représente le nombre
de lignes de A et m le nombre de colonnes. On définira ensuite B=np.zeros((n,m)) afin
de construire un tableau B de même taille que A et dont tous les coefficients sont nuls. On
définira alors B [i , j ] avec la relation ci-dessus en utilisant deux boucles.
(b) Définir de même la fonction miroir_horiz(A) :
Papillon Miroir horizontal
Exercice 3 Détection des contours : On présente ici une méthode simple permettant de mettre en
évidence les contours dans une image. Pour une image contenue dans un tableau A, on construit
un nouveau tableau D de même taille que A et tel que :
q
D[i , j ] = 255 − (A[i , j − 1] − A[i , j + 1])2 + (A[i − 1, j ] − A[i + 1, j ])2
Exercice 4 Histogramme d’une image : L’histogramme d’une image représentée par un tableau A
est la liste H de taille 256 telle que H [i ] est égal au nombre de cases de valeur i dans A. Écrire une
fonction histogramme(A) qui construit et retourne la liste H . On pourra ensuite effectuer le tracé
de l’histogramme avec (par exemple) :
2500
plt.plot(histogramme(Papillon))
2000
1500
1000
500
0
0 50 100 150 200 250 300
TP 13 : Tableaux à 2 dimensions, images et calcul matriciel
Éléments de correction
Ex. 1 :
hxi
Résolution du système A y =b :
z
Ex. 2 :
def miroir_vert(A):
(n,m)=A.shape
B=np.zeros((n,m))
for i in range(n):
for j in range(m):
B[i,j]=A[i,m-j-1]
return B
def miroir_horiz(A):
(n,m)=A.shape
B=np.zeros((n,m))
for i in range(n):
for j in range(m):
B[i,j]=A[n-i-1,j]
return B
Ex. 3 :
import numpy as np
import matplotlib.pyplot as plt
Papillon=np.fromfile("/home/ba/Enseignement/PC/Python/Data/papillon.txt",float,
def detecter_contours(A):
(n,m)=A.shape
D=np.zeros((n,m))
for i in range(1,n-1):
for j in range(1,m-1):
D[i,j]=255-((A[i,j-1]-A[i,j+1])**2+(A[i-1,j]-A[i+1,j])**2)**0.5
return D
plt.subplot(1,2,1)
plt.xticks([])
plt.yticks([])
plt.imshow(Papillon,cmap=plt.cm.gray)
plt.title(’Papillon’)
plt.subplot(1,2,2)
plt.xticks([])
plt.yticks([])
plt.imshow(detecter_contours(Papillon),cmap=plt.cm.gray)
plt.title(’Contours’)
Papillon Contours
Papillon Contours
Ex. 4 :
def histogramme(A):
(n,m)=A.shape
H=[0]*256
for i in range(n):
for j in range(m):
H[int(A[i,j])] += 1
return H
TP 14 : Présentation générale de Scilab
Remarque. Le logiciel S CILAB est un logiciel spécialisé dans le calcul numérique. Conformément
au programme, la partie calcul numérique (correspondant au second semestre) peut être mise en
œuvre aussi bien avec P YTHON qu’avec S CILAB. On donne ici une présentation rapide de S CILAB.
• Lancer S CILAB ;
• Fermer le Navigateur de fichiers et l’Historique des commandes ; ne conserver que les fenêtres
Console et Navigateur de variables.
Remarque. S CILAB accepte également la notation ** à la place de ^. Cependant, on verra plus loin
la notation .^ avec S CILAB qui ne peut pas être remplacée par .**.
a=2 ¦ Entrer les commandes ci-contre dans la console et observer les résultats
a=a+1 obtenus.
A=2*%pi
Remarques.
a+A
• On peut supprimer la variable a en écrivant clear a. On sup-
ans+a
prime toutes les variables en écrivant clear sans plus de précision.
a=1.2e-3
B S CILAB fait la distinction entre majuscules et minuscules (tout
a=rand()
comme P YTHON).
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp14.pdf
x=[1 2 3 4] Construction de vecteurs / listes
x=[1,2,3,4] ¦ On considère :
y=[1;2;3;4]
x’ x = [ 1 2 3 4 ] ∈ M1,4 (R); z = [ 1 3 5 7 9 ] ∈ M1,5 (R)
1
y’ ·1¸ 0
x(1) y= 2 ∈ M4,1 (R); t = ... ∈ M20,1 (R)
3
4 0
y(1) 1
x(2)=3
y(2)=3 Entrer les commandes ci-contre dans la console et observer les résultats
x(2:3) obtenus.
z=[1:2:9]
Remarques.
t(1)=1
• La virgule (ou un espace) sépare deux coefficients sur une même
t(20)=1
ligne, le point virgule permet de passer à la ligne suivante.
t
• La transposée de x (notation mathématique x > ) est notée x’.
length(x)
• La construction a:k:b construit la ligne dont les coefficients sont
length(t)
a, a + k, a + 2k, etc. tant que les valeurs obtenues sont É b.
B Contrairement à P YTHON, les numérotations commencent à 1.
(a) Définir dans S CILAB les· matrices A ∈ M4 (R) et B ∈ M4,1 (R) telles que le système (S ) s’écrive
x ¸
y
AX = B en posant X = z .
t
(b) Définir dans S CILAB la matrice U = A −1 .
(c) Calculer avec S CILAB les produits AU et U A.
(d) Résoudre le système (S ).
Utilisation de SciNotes
• Aller dans le menu Applications et choisir Sci-
function y=u(n)
Notes.
y=1
• Dans la fenêtre S CI N OTES, entrer le pro-
for k=1:n
gramme ci-contre ;
y=(y+1)^0.5
• Dans le menu Fichiers, choisir Enregistrer le
end
fichier dans... et enregistrer le fichier dans le
endfunction
répertoire TPinfo, par exemple sous le nom
clf()
dessin_suite.sce ;
plot(0:10,feval(0:10,u),’bo’)
• Dans le menu Exécuter, choisir Enregistrer le
title("Suite u")
fichier et exécuter (enregister le fichier dans le
xlabel("n")
répertoire TPinfo, par exemple sous le nom
ylabel("u")
dessin_suite.sce) ;
• On doit alors obtenir une représentation gra-
phique du type :
Suite u
1.7
1.65
1.6
1.55
1.5
1.45
1.4
1.35
u
1.3
1.25
1.2
1.15
1.1
1.05
1
0 1 2 3 4 5 6 7 8 9 10
n
TP 15 : Représentations graphiques
Exercice 1 Comparer une fonction et ses DL :
(a) Représenter sur le même graphique la fonction exp (en trait plein) ainsi que les fonctions x 7→
1 + x et x 7→ 1 + x + x 2 /2 (en pointillés) sur l’intervalle [−2, 2].
(b) De même, représenter sur le même graphique la fonction cos ainsi que son DL2 (0) et son
DL4 (0) sur l’intervalle [−π, π].
Exercice 2 Visualiser le rôle d’un paramètre : On considère l’équation différentielle du second ordre
sous forme canonique :
1 d2 u c 2ξ du c
+ + uc = 0
ω20 dt 2 ω0 dt
u c (t ) = A cos(ωa t ) exp(−ξω0 t )
0.1, 0.2, . . . , 0.9 sur [0, 4T ] avec T = 2π/ω0 . La première courbe (ξ = 0.1) sera tracée en bleu, la dernière
(ξ = 0.9) en rouge et les autres en vert. Préciser les axes (et les unités).
A : t 7→ C 0 e−kt
B : t 7→ 2(C 0 − A(t ))
avec k = 5.0 · 10−3 min−1 et C 0 = 10−2 mol · L−1 . On réalise par ailleurs les mesures suivantes :
Représenter sur le même dessin les courbes théoriques pour A et B ainsi que les valeurs expérimen-
tales.
(a) Définir ces trois suites et représenter sur le même dessin les premiers termes des suites (u n )
et (v n ).
(b) Quelles propriétés observe-t-on sur les suites (u n ) et (v n ) ? Les démontrer.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp15.pdf
TP 15 : Représentations graphiques
Éléments de correction
Ex. 1 :
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,2,100)
plt.plot(x,np.exp(x),’r-’)
plt.plot(x,1+x,’b--’)
plt.plot(x,1+x+(x**2)/2,’b--’)
plt.xlabel("x")
plt.ylabel("y")
plt.legend(["exp(x)","DL_1(0)","DL_2(0)"],loc="upper left")
8
exp(x)
7 DL_1(0)
DL_2(0)
6
4
y
−1
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-np.pi,np.pi,100)
plt.plot(x,np.cos(x),’r-’)
plt.plot(x,1-(x**2)/2,’b--’)
plt.plot(x,1-(x**2)/2+(x**4)/24,’b--’)
plt.xlabel("x")
plt.ylabel("y")
plt.legend(["cos(x)","DL_2(0)","DL_4(0)"],loc="lower left")
1
−1
−2
−3
cos(x)
DL_2(0)
DL_4(0)
−4
−4 −3 −2 −1 0 1 2 3 4
x
Ex. 2 :
import numpy as np
import matplotlib.pyplot as plt
w_0=1e4
A=1
T=2*np.pi/w_0
t=np.linspace(0,4*T,100)
# La première courbe (xi=0.1)
xi=0.1
w_a=w_0*np.sqrt(1-xi**2)
plt.plot(t,A*np.cos(w_a*t)*np.exp(-xi*w_0*t),’b-’)
# La dernière courbe (xi=0.9)
xi=0.9
w_a=w_0*np.sqrt(1-xi**2)
plt.plot(t,A*np.cos(w_a*t)*np.exp(-xi*w_0*t),’r-’)
plt.legend(["x1=0.1","xi=0.9"])
# Les autres courbes
for xi in [0.2,0.3,0.4,0.5,0.6,0.7,0.8]:
w_a=w_0*np.sqrt(1-xi**2)
plt.plot(t,A*np.cos(w_a*t)*np.exp(-xi*w_0*t),’g-’)
plt.xlabel("t (s)")
plt.ylabel("u_c (V)")
1.0
x1=0.1
0.8
xi=0.9
0.6
0.4
0.2
u_c (V)
0.0
−0.2
−0.4
−0.6
−0.8
0.0000 0.0005 0.0010 0.0015 0.0020 0.0025 0.0030
t (s)
Ex. 3 :
import numpy as np
import matplotlib.pyplot as plt
t_mes=[0,50,100,150,200,250]
A_mes=[1e-2,7.8e-3,6.05e-3,4.72e-3,3.68e-3,2.86e-3]
C_0=1e-2
k=5e-3
t=np.linspace(0,250,100)
plt.plot(t,C_0*np.exp(-k*t),’b-’)
plt.plot(t,2*C_0*(1-np.exp(-k*t)),’r-’)
plt.plot(t_mes,A_mes,’b+’)
plt.legend(["A (modele)","B (modele)","A (mesures)"],loc="upper left")
plt.xlabel("t (min)")
plt.ylabel("Concentration (mol/L)")
0.016
A (modele)
B (modele)
0.014 A (mesures)
0.012
0.010
Concentration (mol/L)
0.008
0.006
0.004
0.002
0.000
0 50 100 150 200 250
t (min)
Ex. 4 :
import matplotlib.pyplot as plt
def S(n):
s=0
for k in range(1,n+1):
s=s+float((-1)**(k+1))/(k**0.5)
return s
def u(n):
return S(2*n)
def v(n):
return S(2*n+1)
plt.plot(range(1,15),[u(k) for k in range(1,15)],’bo’)
plt.plot(range(1,15),[v(k) for k in range(1,15)],’ro’)
plt.legend(["u_n","v_n"])
plt.xlabel("n")
0.9
u_n
v_n
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0 2 4 6 8 10 12 14
n
x n+1
xn α a
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp16.pdf
(a) Vérifier que la droite d’équation :
f (x n ) − f (a)
y= (x − a) + f (a)
xn − a
La méthode des cordes consiste à définir la suite (x n ) à partir d’une valeur x 0 en utilisant la relation
précédente. Sous certaines conditions, cette suite converge vers une solution de l’équation f (x) = 0.
(c) Programmer une fonction cordes(f,a,x0,n) qui réalise cette méthode d’approximation.
(d) Utiliser cette fonction pour déterminer une valeur approchée de la solution de l’équation de
l’exercice précédent.
f : x 7→ xe−x
x
g : x 7→
1 + x2
Éléments de correction
Ex. 1 : On définit la fonction f et on réalise sa représentation graphique de f sur [1, 2] :
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return x-np.sin(x)/2-1
Remarque : en définissant f avec la fonction sin de N UMPY, cette fonction pourra s’appliquer aussi
bien à des nombres qu’à des tableaux. Représentation graphique :
x=np.linspace(1,2,100)
plt.plot(x,f(x),’b-’)
plt.axhline(y=0,color=’k’)
0.6
0.4
0.2
0.0
−0.2
−0.4
−0.6
1.0 1.2 1.4 1.6 1.8 2.0 2.2
La fonction f s’annule sur [1, 2]. On applique la méthode de Newton en prenant x 0 = 2 (par exemple)
et on note alpha_1 l’approximation obtenue :
alpha_1=newton_eps(f,lambda x:1-np.cos(x)/2,2,1e-3)
print alpha_1
1.49932951966
Vérifions que f (α) est effectivement proche de 0 avec l’approximation obtenue :
print f(alpha_1)
0.000605852416689
Avec la fonction fsolve :
[ 1.49870113]
L’approximation est du même ordre que celle obtenue par la méthode de Newton (à 10−3 près).
Ex. 2 : On vérifie facilement que la droite passe bien par les points (a, f (a)) et (x n , f (x n )). Le point
d’intersection de cette droite avec l’axe des abscisse a pour coordonnées (x n+1 , 0) avec :
f (x n ) − f (a)
0= (x n+1 − a) + f (a)
xn − a
et on en déduit que :
xn − a
x n+1 = a − f (a)
f (x n ) − f (a)
def cordes(f,a,x0,n):
x=x0
for k in range(n):
x=a-float(f(a)*(x-a))/(f(x)-f(a))
return x
alpha_2=cordes(f,2,1,5)
print alpha_2
1.49869031762
On remarque que pour les approximations obtenues, f (α1 ) et f (α2 ) sont de signes contraires :
print f(alpha_1)*f(alpha_2)
-6.31681113462e-09
Par conséquent, la solution α de l’équation f (x) = 0 est encadrée par α1 et α2 .
Ex. 3 :
def f(x):
return x*np.exp(-x)
def f1(x):
return (1-x)*np.exp(-x)
x=np.linspace(-1,5,100)
plt.plot(x,f(x),’b-’)
plt.axhline(y=0,color=’k’)
plt.axvline(x=0,color=’k’)
0.5
0.0
−0.5
−1.0
−1.5
−2.0
−2.5
−3.0
−1 0 1 2 3 4 5
def g(x):
return x*1.0/(1+x**2)
def g1(x):
return (1-x**2)*1.0/(1+x**2)**2
x=np.linspace(-2,2,100)
plt.plot(x,g(x),’b-’)
plt.axhline(y=0,color=’k’)
plt.axvline(x=0,color=’k’)
0.6
0.4
0.2
0.0
−0.2
−0.4
−0.6
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
y
A
O M x
1 ³p 2 ´2
E p (x) = k L + x 2 − `0
2
³p ´2
on posera également f (x) = L 2 + x 2 − `0
Les abscisses des points d’équilibre stables du système correspondent aux minimums locaux de la
fonction E p ou, de manière équivalente, de la fonction f . On prendra `0 = 1 pour la suite.
(a) Vérifier que :
³p ´
dE p kx L 2 + x 2 − `0
= p
dx L2 + x 2
³p ´
On définit dans la suite g (x) = x L 2 + x 2 − `0 .
(b) On suppose ici que L = 0.5. Représenter graphiquement la fonction f sur l’intervalle [−2, 2].
Déterminer les abscisses des minimums locaux de E p .
(c) On suppose ici que L = 1.5. Représenter graphiquement la fonction f sur l’intervalle [−2, 2].
Déterminer les abscisses des minimums locaux de E p .
(d) Sur le même graphique, représenter les fonctions f pour L ∈ {0.1, 0.2, 0.3, . . . , 1.8, 1.9, 2.0} (on
représentera en bleu les courbes pour L < 1, en vert les courbes pour L > 1 et en rouge la
courbe pour L = 1). Commenter.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp17.pdf
def newton_eps(f,f_prim,x0,eps): def dichotomie(f,a,b,epsilon):
x=x0 N=0
N=0 while (b-a)>epsilon:
while f(x-eps)*f(x+eps)>0: c=float(a+b)/2
x=x-f(x)*1.0/f_prim(x) if f(a)*f(c)<=0:
N=N+1 b=c
return (x,N) else:
a=c
N=N+1
return (float(a+b)/2,N)
http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/dicho_newton_eps.html
Dichotomie Newton
ε = 10 −2
ε = 10−3
ε = 10−4
ε = 10−5
ε = 10−10
(on prendra x 0 = 2 comme point de départ dans la méthode de Newton et pour la méthode de
dichotomie on utilisera l’intervalle [1, 2]).
Exercice 3 Comparaison avec la méthode des cordes : On reprend la méthode des cordes (TP 16).
Partant de deux valeurs x 0 et a, on définit la suite (x n ) en posant :
xn − a
x n+1 = a − f (a)
f (x n ) − f (a)
(a) Programmer une fonction cordes_eps(f,a,x0,eps) qui met en œuvre cette méthode
d’approximation et renvoie le couple (x, N ) où x est l’approximation obtenue et N le nombre
d’étapes de calcul effectuées.
(b) Comparer cette méthode avec les méthodes de dichotomie et de Newton en reprenant l’exemple
de l’exercice précédent.
TP 17 : Approximations de racines et d’intégrales (2)
Éléments de correction
Ex. 1:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve
L=0.5
x=np.linspace(-2,2,100)
plt.plot(x,(np.sqrt(L**2+x**2)-1)**2,’b-’)
plt.xlabel(’x’)
plt.ylabel(’f(x)’)
plt.title(’Fonction f pour L=0.5’)
1.0
0.8
f(x)
0.6
0.4
0.2
0.0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x
Pour obtenir les abscisses des minimums locaux, on détermine les solutions de l’équation g (x) = 0
(les solutions non nulles car f présente un maximum local en 0). En fait les deux abscisses cherchées
sont opposées et il suffit de déterminer celle qui est strictement positive :
[ 0.8660254]
Pour L = 1.5 :
L=2.5
plt.plot(x,(np.sqrt(L**2+x**2)-1)**2,’b-’)
plt.xlabel(’x’)
plt.ylabel(’f(x)’)
plt.title(’Fonction f pour L=1.5’)
Fonction f pour L=1.5
5.0
4.5
4.0
f(x)
3.5
3.0
2.5
2.0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x
for L in np.linspace(0.1,2,20):
if L<1:
style=’b-’
elif L>1:
style=’g-’
else:
style=’r-’
plt.plot(x,(np.sqrt(L**2+x**2)-1)**2,style)
plt.xlabel(’x’)
plt.ylabel(’f(x)’)
3.5
3.0
2.5
2.0
f(x)
1.5
1.0
0.5
0.0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
Ex. 2 :
def f(x):
return x**2-2
def f1(x):
return 2*x
for eps in [1e-2,1e-3,1e-4,1e-5,1e-10]:
print newton_eps(f,f1,2,eps)[1]
print dichotomie(f,1,2,eps)[1]
print "\n"
2 7
3 10
3 14
3 17
4 34
35
Nombre d'itérations pour une précision de 10**(-k)
Newton
Dichotomie
30
25
20
N
15
10
0
0 2 4 6 8 10
k
Ex.
def3 : cordes_eps(f,a,x0,eps):
x=x0
N=0
while f(x-eps)*f(x+eps)>0:
x=a-f(a)*float(x-a)/(f(x)-f(a))
N=N+1
return (x,N)
for eps in [1e-2,1e-3,1e-4,1e-5,1e-10]:
print cordes_eps(f,1,2,eps)[1]
print newton_eps(f,f1,2,eps)[1]
print dichotomie(f,1,2,eps)[1]
print "\n"
3 2 7
4 3 10
5 3 14
7 3 17
13 4 34
TP 18 : Approximations de racines et d’intégrales (3)
Exercice 1 Calcul de la période d’oscillation d’un pendule :
On considère un pendule simple pouvant osciller dans le plan verti-
cal constitué d’une masse m suspendue par un fil de longueur `. La
position du pendule par rapport à la verticale est repérée par un angle
θ. Lorsque les oscillations sont de faible amplitude, la période T des θ0
oscillations est donnée en première approximation par la relation :
θ
g
r
T = 2π
`
où θ0 est l’amplitude des oscillations. En utilisant la commande quad du module S CIPY, calculer T
pour ` = 1 m et θ0 = 50◦ .
(a) Écrire l’approximation obtenue comme une somme, à la manière de ce qui a été fait pour la
méthode des rectangles.
(b) Programmer une fonction rectangles_milieu(f,a,b,n) qui réalise cette approxima-
tion où n est le nombre d’intervalles de la subdivision.
(c) Proposer une méthode permettant de comparer le précision de cette approximation avec celle
obtenue pour la méthode des rectangles et des trapèzes.
Exercice 3 Valeur moyenne et valeur efficace d’une tension : On considère une tension sinusoïdale
u(t ) définie par la relation :
1 T
Z
u moy = u(t ) dt
T 0
s
1 T
Z
u eff = u(t )2 dt
T 0
(a) Représenter la fonction u sur [−2T, 2T ] (penser à donner des noms aux axes en précisant les
unités).
(b) Déterminer des valeurs approchées de u moy et u eff .
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp18.pdf
TP 18 : Approximations de racines et d’intégrales (3)
Éléments de correction
Ex. 1 :
20.6592186152
Ex.
def2 : rectangles_milieu(f,a,b,n):
s=0
for k in range(n):
s=s+f(a+(k+0.5)*float(b-a)/n)
return float(b-a)/n*s
for n in [10,100,1000,10000,100000,1000000]:
print rectangles_milieu(lambda x:x**2,0,1,n)
print "\n"
0.3325
0.333325
0.33333325
0.3333333325
0.333333333325
0.333333333333
On remarque que l’on gagne approximativement 2 chiffres significatifs en passant de n = 10k à
10k+1 .
Ex. 3 :
10
6
u(t) (V)
−2
−0.04 −0.03 −0.02 −0.01 0.00 0.01 0.02 0.03 0.04 0.05
t (s)
umoy=quad(u,0,T)[0]/T
ueff=(quad(lambda t:u(t)**2,0,T)[0]/T)**0.5
print umoy
print ueff
5.0 6.5574385243
TP 19 : Équations différentielles d’ordre 1
B Pour les représentations graphiques, penser à donner des noms aux axes en précisant les unités.
Fig. 2
Exercice 2 Chute d’un grêlon : On étudie la chute d’un grêlon de masse m = 3.6 · 10−3 kg. On note
v la composante de la vitesse en projection sur un axe vertical descendant. On étudie deux modèles
de forces de frottements :
• Le modèle des forces de frottements linéaires conduit à l’équation différentielle :
dv
m = mg − k 1 v
dt
• Le modèle des frottements quadratiques conduit à l’équation différentielle :
dv
m = mg − k 2 v 2
dt
Données numériques : k 1 = 1.8 · 10−3 Nsm−1 , k 2 = 9.2 · 10−5 et la condition initiale est v(0) = 0 pour
les deux modèles.
(a) Représenter sur le même dessin les solutions des deux équations sur l’intervalle [0, 15].
(b) Estimer numériquement la vitesse limite v lim atteinte par le grêlon dans chacun des deux mo-
dèles.
(c) Placer sur le dessin une droite horizontale située 95% de v lim . Estimer graphiquement le temps
nécessaire pour atteindre 95% de la vitesse limite dans chaque modèle.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp19.pdf
TP 19 : Équations différentielles d’ordre 1
Éléments de correction
Ex. 1 :
R=1000
C=1e-6
f=100
def ue(t):
return 10*np.sin(2*pi*f*t)
def F(u,t):
return (ue(t)-u)/(R*C)
t=np.linspace(0,5.0/f,100)
plt.plot(t,ue(t),’b-’)
plt.plot(t,odeint(F,0,t),’r-’)
plt.legend(["ue","u"])
plt.xlabel("t (s)")
plt.ylabel("u (V)")
10
ue
u
5
u (V)
−5
−10
0.00 0.01 0.02 0.03 0.04 0.05 0.06
t (s)
def ue(t):
if (t<=0):
return 0
elif (t<=1e-2):
return 1000*t
else:
return 10
def F(u,t):
return (ue(t)-u)/(R*C)
t=np.linspace(0,0.02,100)
10
6
u (V)
ue
u
0
0.000 0.005 0.010 0.015 0.020 0.025
t (s)
Ex. 2 :
m=3.6e-3
g=9.81
k1=1.8e-3
k2=9.2e-5
tau=m/k1
def F(v,t):
return g-k1/m*v
def G(v,t):
return g-k2/m*v**2
t=np.linspace(0,15,100)
v1=odeint(F,0,t)
v2=odeint(G,0,t)
vlim=v1[-1]
plt.plot(t,v1,’b-’)
plt.plot(t,v2,’r-’)
plt.axhline(y=vlim*0.95,color=’k’)
plt.xlabel("t (s)")
plt.ylabel("v (m/s)")
plt.legend([u"Linéaire","Quadratique"],loc="lower right")
20
15
v (m/s)
10
Linéaire
Quadratique
0
0 2 4 6 8 10 12 14 16
t (s)
TP 20 : Méthode d’Euler
¦ On reprend la fonction P YTHON qui met en œuvre la méthode d’Euler présentée en classe :
def euler(F,y0,t):
N=len(t)
y=[0]*N
y[0]=y0
for i in range(N-1):
y[i+1]=y[i]+(t[i+1]-t[i])*F(y[i],t[i])
return y
y0 = y
½
y(0) = 1
dont on connait la solution exacte. On va l’utiliser pour estimer l’efficacité de la méthode d’Euler.
On va travailler sur l’intervalle [0, 1].
(a) Définir la fonction F(y,t) correspondant à cette équation différentielle.
(b) Définir la fonction ecart(n) qui renvoie la valeur e définie par :
e=np.mean(np.abs(y-np.exp(t)))
Exercice 2 Adapter la méthode d’Euler à un problème spécifique : On considère la chute d’un grêlon
de masse m = 3.6 · 10−3 kg modélisée par l’équation différentielle avec condition initiale :
dv k
= g − v2
dt m
v(0) = 0
(modèle des forces de frottements quadratiques). On veut étudier l’influence du paramètre k sur le
mouvement. Pour cela, on va utiliser la méthode d’Euler en l’adaptant pour qu’elle puisse prendre
en compte des équations différentielles avec paramètres, de la forme :
y 0 = F (k, y, t )
où k est un paramètre.
(a) Définir la fonction F(k,v,t) correspondant au problème de la chute du grêlon.
(b) Écrire une fonction euler_param(F,k,y0,t) qui adapte la méthode d’Euler au cas d’une
fonction F avec paramètre.
(c) Représenter graphiquement sur l’intervalle [0, 15] la solution du problème de Cauchy lorsque
k = 5 · 10−5 , 6 · 10−5 , 7 · 10−5 , . . . , 15 · 10−5 . Quelle est l’influence de k sur la vitesse limite ?
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp20.pdf
TP 20 : Méthode d’Euler
Éléments de correction
Ex. 1 :
import numpy as np
def F(y,t):
return y
def ecart(n):
t=np.linspace(0,1,n)
y=euler(F,1,t)
e=np.mean(np.abs(y-np.exp(t)))
return e
print ecart(10), ecart(100), ecart(1000)
0.40
0.35
0.30
0.25
Ecart
0.20
0.15
0.10
0.05
0.00
0 2 4 6 8 10 12 14 16 18
n
plt.clf()
plt.plot([ecart(n)**(-1) for n in range(2,21)],’bo’)
plt.xlabel("n")
plt.ylabel("Ecart**(-1)")
40
35
30
25
Ecart**(-1) 20
15
10
0
0 2 4 6 8 10 12 14 16 18
n
Ex. 2 :
g=9.81
m=3.6e-3
def F(k,v,t):
return g-float(k)/m*v**2
def euler_param(F,k,y0,t):
N=len(t)
y=[0]*N
y[0]=y0
for i in range(N-1):
y[i+1]=y[i]+(t[i+1]-t[i])*F(k,y[i],t[i])
return y
t=np.linspace(0,15,100)
plt.clf()
for p in range(5,16):
if p==5:
style=’g-’
else:
style=’b-’
k=p*1e-5
y=euler_param(F,k,0,t)
plt.plot(t,y,style)
plt.xlabel("t")
plt.ylabel("v(t)")
30
25
20
v(t) 15
10
0
0 2 4 6 8 10 12 14 16
t
TP 21 : Calcul matriciel et systèmes linéaires
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp21.pdf
¦ Si on travaille sur une matrice extraite de A (ici la première ligne
A=np.identity(2)
de A), le même problème apparait.
x=A[:,0]
x[0]=2
print x
print A
1 2 1
A= 1 2 1
−1 −2 −1
B Les vecteurs sont des tableaux à une dimension et les matrices sont des tableaux à deux dimen-
sions. Ainsi, les vecteur ne sont pas vraiment des cas particuliers de matrices. La commande shape
sert à obtenir la forme du vecteur ou de la matrice.
x.shape
A.shape
Les colonnes et les lignes extraites d’une matrice sont des vecteurs (une dimension) :
u=A[:,1] v=A[1,:]
u.shape v.shape
a 11 x 1 + · · · + a 1n x n = b 1
..
.
a n1 x 1 + · · · + a nn x n = b n
a 11 ··· a 1n b1
.. .. .
peut s’écrire matriciellement Ax = b avec A = et b = .. .
. .
a n1 · · · a nn bn
• Si A est inversible, alors le système admet une unique solution qui est A −1 b ;
• Si x 0 est une solution particulière du système, alors l’ensemble des solutions est {x 0 + x |
x ∈ Rn et Ax = 0}.
A=np.array([[2,1,1],[0,2,1],[0,0,2]])
b=np.array([1,1,1])
print np.linalg.inv(A)
x=np.dot(np.linalg.inv(A),b)
print x
np.dot(A,x)
np.linalg.solve(A,b)
x
2x + y = 1
x + 2y + z = −1
2y + z = 0
Les conventions supplémentaires de Python/Numpy
¦ Avec N UMPY :
• Le produit * désigne le produit composantes par composantes, de même pour la puissance
** ;
• On peut ajouter un nombre à chaque composante ;
• Les fonctions mathématiques usuelles de N UMPY peuvent être appliquées à des vecteurs ou
des matrices (ce qui revient à appliquer la fonction à chaque composante).
L’intérêt est essentiellement de pouvoir appliquer des fonctions à des vecteurs. Par exemple :
t=nplinspace(-1,1,100)
y=np.exp(-t**2)
print t.shape
print y.shape
Ce sont ces conventions qui permettent d’effectuer facilement des représentations graphiques :
2
(représentation graphique de t 7→ sin(t )e−t sur [−1, 1]).
x+y =1
½
x+y =2
A=np.array([[1,1],[1,1]])
b=np.array([1,2])
print np.linalg.lstsq(A,b)
On obtient un tuple consitué de 3 composantes. Seule la première nous intéresse ici : c’est (0.75, 0.75)
qui constitue la solution approchée du système. On donne ci-dessous une application pratique de
ce type de résolution et on donne ensuite quelques explications sur la notion de solution approchée.
t0 t1 t2 t3 t4
t (min) 50 100 150 200 250
C (mol · L−1 ) 7.85 · 10−3 6.25 · 10−3 4.68 · 10−3 3.60 · 10−3 2.82 · 10−3
y = ln(C ) −4.85 −5.07 −5.36 −5.63 −5.87
y0 y1 y2 y3 y4
L’évolution de la concentration C est modélisée par une relation C (t ) = C 0 e−r t ou encore :
ln(C (t )) = ln(C 0 ) − r t
¦ Pour définir plus précisément ce que l’on entend par solution approchée, considérons un sys-
tème :
ax + b y = c
½
a0 x + b0 y = c 0
On lui associe une fonction f définie par :
Cette fonction f est positive. De plus, si le système admet une solution (x 0 , y 0 ), alors f (x 0 , y 0 ) = 0.
Dans le cas général, on appelle solution approchée du système tout couple (x 0 , y 0 ) tel que f (x 0 , y 0 )
est minimal. On doit en fait parler de solution au sens des moindres carrés au lieu de « solution
approchée. »
Éléments de correction
Ex. 1 :
import numpy as np
A=np.array([[1,2,1],[1,2,1],[-1,-2,-1]])
for k in range(6):
print np.linalg.matrix_power(A,k)
[[1 0 0] [0 1 0] [0 0 1]]
[[ 1 2 1] [ 1 2 1] [-1 -2 -1]]
[[ 2 4 2] [ 2 4 2] [-2 -4 -2]]
[[ 4 8 4] [ 4 8 4] [-4 -8 -4]]
[[ 8 16 8] [ 8 16 8] [ -8 -16 -8]]
[[ 16 32 16] [ 16 32 16] [-16 -32 -16]]
Conjecture : pour n Ê 1, A n = 2n−1 A et A 0 = I3 .
Ex. 2 :
A=np.array([[2,1,0],[1,2,1],[0,2,1]])
b=np.array([1,-1,0])
print np.dot(np.linalg.inv(A),b)
[-1. 3. -6.]
ou alors :
print np.linalg.solve(A,b)
[-1. 3. -6.]
Ex. 3 :
−5.0
−5.2
y
−5.4
−5.6
−5.8
−6.0
50 100 150 200 250
t (min)
Les points ne sont pas alignés donc le système (S ) ne possède pas de solution. Ce système dont les
inconnues sont a et b s’écrit matriciellement :
t0 1 y0
t 1 a y1
· ¸
1
= ..
.. ..
. . b .
t4 1 y4
A=np.array([t,np.ones(5)]).transpose()
b=np.array(y)
print np.linalg.lstsq(A,b)[0]
[-0.0052 -4.576 ]
La solution approchée est donc a = −5.2 · 10−3 et b = −4.576. Vérifions en superposant le tracé de la
droite d’équation y = at + b :
plt.plot(t,y,’g--’)
plt.plot(t,(-5.2e-3)*t-4.576,’b-’)
plt.plot(t,y,’k+’)
plt.xlabel("t (min)")
plt.ylabel("y")
−4.8
−5.0
−5.2
y
−5.4
−5.6
−5.8
−6.0
50 100 150 200 250
t (min)
La droite obtenue est proche des points de coordonnées (t i , y i ) (ceci correspond en fait à une ré-
gression linéaire).
UA a b PA
· ¸ · ¸· ¸
= 0
UB a b0 PB
CA PA UA a b PA
· ¸ · ¸ · ¸ µ · ¸¶ · ¸
= − = I2 − 0
CB PB UB a b0 PB
=A
CA PA CA
· ¸ · ¸ · ¸
Connaissant , on obtient = A −1 :
CB PB CB
M=np.array([[0.2,0.05],[0.2,0.1]])
A=np.identity(2)-M
C=np.array([10,100])
print np.dot(np.linalg.inv(A),C)
[ 19.71830986 115.49295775]
La production de produit A doit donc être de 19.7 et celle de produit B de 115.5 (approximative-
ment).
TP 22 : Systèmes d’équations
import numpy as np
EPSILON=1e-10
def nul(x):
return abs(x)<=EPSILON
Pour tester si x est nul, on écrira alors nul(x) au lieu de x==0 (qui n’a pas vraiment de sens pour
un flottant). On considère un système linéaire à deux équations et deux inconnues :
ax + b y = c
½
a0 x + b0 y = c 0
a b c
· ¸
Ce système est décrit par la matrice M = 0 .
a b0 c 0
(a) Écrire la fonction resoudreM1(M), vue en classe, qui détermine les solutions du système
représenté par la matrice M dans le cas M 1 étudié en classe.
(b) Écrire de même les fonctions resoudreM2(M) et resoudreM0(M) qui déterminent les
solutions du système représenté par la matrice M dans les cas M 2 et M 0 étudiés en classe.
(c) Écrire les fonctions echange(M) et combinaison(M,c) qui réalisent respectivement les
opérations L 1 ↔ L 2 (échange des deux lignes de la matrice M ) et L 2 ← L 2 − c · L 1 .
(d) Écrire la fonction resoudre2x2(M) qui résout le système décrit par la matrice M en le
mettant d’abord sous l’une des formes M 1 , M 2 , M 0 apropriée puis en appelant la fonction qui
convient.
(e) Tester la fonction resoudre2x2(M) sur les systèmes suivants :
Ce problème est assez facile à résoudre explicitement. Cependant, la recherche d’une solution ap-
prochée va faire intervenir une technique intéressante qui peut être utilisée dans d’autres situations
semblables. On va considérer 6 valeurs de t régulièrement espacées t 0 , t 1 , . . . , t 5 et on va déterminer
y 0 , . . . , y 5 valeurs approchées de y(t 0 ), . . . , y(t 5 ).
t0 t1 t2 t3 t4 t5
y1 h
y2
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp22.pdf
Pour 1 É k É 4, on utilise l’approximation :
y k−1 − 2y k + y k+1
y 00 (t k ) '
h2
(a) En utilisant cette approximation, écrire les 4 équations obtenues à partir de l’équation diffé-
rentielle de départ.
(b) On ajoute les conditions y 0 = 0 et y 5 = 0. On obtient alors un système de 6 équations à 6
inconnues. Écrire ce système sous forme matricielle puis le résoudre.
(c) Représenter graphiquement les points (t i , y i ).
(d) Résoudre explicitement l’équation de départ et représenter graphiquement la solution obte-
nue sur le même dessin que l’approximation pour comparer.
Remarque. Pour justifier l’approximation de y 00 (t k ) utilisée dans cet exercice, on peut utiliser la
formule de Tayloy-Young :
y 00 (a)
y(a + h) = y(a) + h y 0 (a) + h 2 + o (h 2 )
2 h→0
Appliquée avec −h :
y 00 (a)
y(a − h) = y(a) − h y 0 (a) + h 2 + o (h 2 )
2 h→0
On en déduit que :
Éléments de correction
Ex. 1 :
import numpy as np
import numpy as np
EPSILON=1e-10
def nul(x):
return abs(x)<=EPSILON
def resoudre_M0(M):
u=M[0,2]
v=M[1,2]
if nul(u) and nul(v):
# Le second membre est nul, tout (x,y) est solution
return [np.array([0,0]),np.array([1,0]),np.array([0,1])]
else:
# Le second membre n’est pas nul : pas de solution
return []
def resoudre_M2(M):
b=M[0,1]
u=M[0,2]
v=M[1,2]
if nul(v):
# v est nul, le système est compatible
return [np.array([0,float(u)/b]),np.array([1,0])]
else:
# v n’est pas nul : pas de solution
return []
def resoudre_M1(M):
a=M[0,0]
b=M[0,1]
u=M[0,2]
d=M[1,1]
v=M[1,2]
if nul(d):
# d est nul : il faut regarder v
if nul(v):
# v est nul également
return [np.array([float(u)/a,0]),np.array([-float(b)/a,1])]
else:
# v n’est pas nul : pas de solution
return []
else:
# d n’est pas nul : unique solution
return [np.array([(u-b*float(v)/d)/a,float(v)/d])]
def resoudre2x2(M):
if nul(M[0,0]) and nul(M[1,0]):
# Le première colonne est nulle
if nul(M[0,1]) and nul(M[1,1]):
# La deuxième colonne est nulle
return resoudre_M0(M)
else:
# La deuxième colonne n’est pas nulle
# On permute si besoin
if nul(M[0,1]):
echange(M)
combinaison(M,float(M[1,1])/M[0,1])
return resoudre_M2(M)
else:
# La première colonne n’est pas nulle
# On permute si besoin
if nul(M[0,0]):
echange(M)
combinaison(M,float(M[1,0])/M[0,0])
return resoudre_M1(M)
£1 1 5¤
Système (S 1 ) : M = 123
print resoudre2x2(np.array([[1,1,5],[1,2,3]]))
print resoudre2x2(np.array([[1,1,5],[2,2,10]]))
[]
Ce système n’admet pas de solution.
y k−1 − 2y k + y k+1
− y k = sin(t k )
h2
ou encore :
kπ
µ ¶
2 2
y k−1 − (2 + h )y k + y k+1 = h sin
5
y0 = 0
2 2
y − (2 + h )y + y 2 = h sin (π/5)
0 1
y − (2 + h 2 )y + y = h 2 sin
(2π/5)
1 2 3
2 2
y 2 − (2 + h )y 3 + y 4 = h sin (3π/5)
2 2
y 3 − (2 + h )y 4 + y 5 = h sin (4π/5)
y5 = 0
· y0 ¸
..
Ce système s’écrit sous la forme A . = b avec :
y5
1 0 0 0 0 0 0
1 −(2 + h 2 ) 1 0 0 0 h 2 sin(π/5)
0 1 −(2 + h 2 ) 1 0 0 h 2 sin(2π/5)
A= ; b= 2
0 0 1 −(2 + h 2 ) 1 0 h sin(3π/5)
−(2 + h 2 )
2
0 0 0 1 1 h sin(4π/5)
0 0 0 0 0 1 0
import numpy as np
import matplotlib.pyplot as plt
h=np.pi/5
A=np.array([[1,0,0,0,0,0],[1,-(2+h**2),1,0,0,0],[0,1,-(2+h**2),1,0,0],[0,0,1,-(
b=np.array([0,h**2*np.sin(h),h**2*np.sin(2*h),h**2*np.sin(3*h),h**2*np.sin(4*h)
y=np.linalg.solve(A,b)
plt.plot([k*h for k in range(6)],y,’k+’)
0.0
−0.1
−0.2
−0.3
−0.4
−0.5
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5
1
y : t 7→ − sin t
2
est la solution du problème considéré. On représente graphiquement cette fonction et les valeurs
approchées obtenues :
t=np.linspace(0,np.pi,100)
plt.plot(t,-0.5*np.sin(t),’b--’);
plt.plot([k*h for k in range(6)],y,’k+’)
0.0
−0.1
−0.2
−0.3
−0.4
−0.5
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5
TP 23 : Systèmes d’équations différentielles
Exercice 1 Mise sous tension d’un moteur à courant continu :
On alimente un moteur initialement à l’arrêt par une tension u(t )
dont la représentation graphique est donnée ci-contre. On note w(t ) u(t )
la vitesse de rotation du moteur et i (t ) l’intensité du courant. On a les
40 V
équations différentielles :
di
u(t ) = Ri (t ) + L + K w(t )
dt
dw
J = K i (t ) − f w(t ) 0.1 s t
dt
où :
• J est le moment d’inertie J = 3.2 · 10−4 kg · m2 ;
• f est un coefficient de frottement f = 2.4 · 10−3 N · m · s · rad−1 ;
• R est la résistance du bobinage R = 0.67 Ω ;
• L est l’inductance du bobinage L = 3.8 · 10−3 H ;
• K est la constante de force électromotrice du couple K = 0.12 N/A.
(a) Définir la fonction u(t).
(b) Vérifier que i (t ) et w(t ) sont solutions d’un système d’équations différentielles :
di
= ···
dt
dw
= ···
dt
(d) Résoudre le sytème avec la condition initiale w(0) = 0 et i (0) = 0 sur l’intervalle [0, 0.4] et re-
présenter les fonctions obtenues.
(e) Écrire la fonction associée au système sous la forme F(X,t,K) afin que l’inertie K soit prise
comme un paramètre. On place une charge sur le moteur ce qui a pour effet d’augmenter son
inertie à K 1 = 0.2 N/A. Résoudre alors le système pour cette valeur et représenter sur le même
graphique les deux vitesses de rotation. Quelle est l’influence de K sur la vitesse de rotation ?
Exercice 2 Cinétique chimique / Réactions successives : On considère les réactions successives d’hy-
drolyse d’un diester A :
k1
A + H2O −→ B
k2
B + H2O −→ C +???
(A est le diester et B le monoester). On note a(t ) (respectivement b(t ), c(t )) la concentration [A]
(respectivement [B ], [C ]) à l’instant t . La cinétique est décrite par les équations différentielles :
da
= −k 1 a(t )
dt
db
= −k 2 b(t ) + k 1 a(t )
dt
dc
= k 2 b(t )
dt
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp23.pdf
On donne les valeurs numériques :
L’intuition du chimiste : comme k 1 << k 2 , la concentration de B va rester très faible et on peut donc
considérer que db/dt = 0.
(a) Résoudre numériquement le système d’équations différentielles, représenter conjointement
les fonctions a, b et c et vérifier l’intuition du chimiste (déterminer en particulier le maximum
de b). On travaillera sur un intervalle de temps de... 10 jours !
(b) Pour contrôler, vérifier numériquement les points suivants :
• à l’état final, c = a(0) et a = 0 ;
• a(t ) + b(t ) + c(t ) est constante égale à a(0).
TP 23 : Systèmes d’équations différentielles
Éléments de correction
Ex. 1 : (a)
J=3.2e-4
f=2.4e-3
R=0.67
L=3.8e-3
K=0.12
def u(t):
if t<0:
return 0
elif t>0.1:
return 40
else:
return 400*t
(b) On obtient le système d’équations différentielles :
di K R 1
= − w(t ) − i (t ) + u(t )
dt L L L
dw f K
= − w(t ) + i (t )
dt J J
(c)
def F(X,t):
i=X[0]
w=X[1]
iprim=-K/L*w-R/L*i+1/L*u(t)
wprim=-f/J*w+K/J*i
return [iprim,wprim]
(d)
t=np.linspace(0,0.4,100)
X=odeint(F,[0,0],t)
plt.plot(t,X[:,0])
plt.xlabel("t")
plt.ylabel("i(t)")
plt.title(u"Intensité")
Intensité
14
12
10
i(t)
6
0
0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45
plt.plot(t,X[:,1])
plt.xlabel("t")
plt.ylabel("w(t)")
plt.title("Vitesse de rotation")
Vitesse de rotation
350
300
250
200
w(t)
150
100
50
0
0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45
t
(e)
def F(X,t,K):
i=X[0]
w=X[1]
iprim=-K/L*w-R/L*i+1/L*u(t)
wprim=-f/J*w+K/J*i
return [iprim,wprim]
t=np.linspace(0,1,200)
X=odeint(F,[0,0],t,args=(K,))
X1=odeint(F,[0,0],t,args=(0.2,))
plt.plot(t,X[:,1],’b’)
plt.plot(t,X1[:,1],’r’)
plt.xlabel("t")
plt.ylabel("w(t)")
plt.legend([u"À vide",u"Chargé"],loc="lower right")
plt.title("Vitesse de rotation")
350
Vitesse de rotation
300
250
200
w(t)
150
100
50
À vide
Chargé
0
0.0 0.2 0.4 0.6 0.8 1.0
t
plt.plot(t,X[:,0],’b’)
plt.plot(t,X1[:,0],’r’)
plt.xlabel("t")
plt.ylabel("i(t)")
plt.legend([u"À vide",u"Chargé"])
plt.title(u"Intensité")
14
Intensité
À vide
Chargé
12
10
i(t)
6
0
0.0 0.2 0.4 0.6 0.8 1.0
t
Ex. 2 :
a0=1e-3
b0=0
c0=0
k1=8.02e-6
k2=1.51e-4
def F(X,t):
a=X[0]
b=X[1]
c=X[2]
return [-k1*a,-k2*b+k1*a,k2*b]
t=np.linspace(0,10*24*3600,100)
X=odeint(F,[a0,b0,c0],t)
plt.plot(t,X[:,0])
plt.plot(t,X[:,1])
plt.plot(t,X[:,2])
plt.legend(["a(t)","b(t)","c(t)"])
plt.xlabel("t (s)")
plt.ylabel("Concentrations (mol/L)")
0.0010
a(t)
b(t)
c(t)
0.0008
Concentrations (mol/L)
0.0006
0.0004
0.0002
0.0000
0 100000 200000 300000 400000 500000 600000 700000 800000 900000
t (s)
# Le maximum de b :
print X[:,1].max()
4.47434545101e-05
Numériquement, on a bien c = a(0) dans l’état final et a = 0. Représentons graphiquement la somme
des concentrations :
plt.plot(t,X[:,0])
plt.plot(t,X[:,1])
plt.plot(t,X[:,2])
plt.plot(t,X[:,0]+X[:,1]+X[:,2])
plt.legend(["a(t)","b(t)","c(t)","a+b+c"])
plt.box(False)
plt.axhline(y=0,color=’k’)
plt.axvline(x=0,color=’k’)
plt.xlabel("t (s)")
plt.ylabel("Concentrations (mol/L)")
0.0010
a(t)
b(t)
c(t)
0.0008 a+b+c
Concentrations (mol/L)
0.0006
0.0004
0.0002
0.0000
0 100000 200000 300000 400000 500000 600000 700000 800000 900000
t (s)
TP 24 : Équations différentielles d’ordre 2
Exercice 1 Projectile dans le champ de pesanteur terrestre avec frottements quadratiques : Un mobile
de masse m = est lancé de la position x = 0, y = h = 1 m avec une vitesse initiale de norme v 0 =
27.7 m/s dont la direction fait un angle α = π/4 avec l’horizontale. La trajectoire du mouvement est
décrite par les équations différentielles :
s
¶2 ¶2
d2 x k 2 dx
#–
dx dy v0
µ µ
+ + =0
dt 2 m dt dt dt
s
¶2 ¶2 α
d2 y k 2 dy dx dy
µ µ
+ + = −g
dt 2 m dt dt dt h
O
x ¸
dx dy
·
y
On rappelle que g = 9.81 m/s2 . On pose v x = et v y = et on note X = vx .
dt dt vy
(a) Vérifier que x, y, v x , v y sont solution d’un système d’équations différentielles de la forme :
dx
= ···
dt
dy = · · ·
dt
dv x
= ···
dt
dv y
= ···
dt
Déterminer également la condition initiale associée.
(b) Définir la fonction F(X,t,m,k2) qui décrit ce système d’équations différentielles.
(c) Résoudre numériquement ce système et représenter graphiquement sur le même dessin les
trajectoires obtenues pour m = 0.45 kg, k 2 = 8.9 · 10−3 kg/m (ballon de football) puis pour
m = 5 · 10−3 kg, k 2 = 1.6 · 10−3 kg/m (volant de badminton).
(d) Dans les deux situations précédentes, représenter graphiquement la norme de la vitesse en
fonction du temps.
(e) On prend m = 0.45 kg, k 2 = 8.9 · 10−3 kg/m. Représenter simultanément les trajectoires pour
plusieurs valeurs de l’angle α.
Exercice 2 Modélisation d’une suspension de véhicule : On modélise une suspension d’un véhicule
par un ressort de raideur k et un amortisseur de coefficient d’amortissement c, montés en parallèles.
On ramène le poids du véhicule à une masse globale m.
On prendra :
m Habitacle m = 100 kg
s(t )
c = 1.13 · 103 N · s · m−1
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp24.pdf
On note respectivement e(t ) et s(t ) les déplacements verticaux du châssis et de l’habitacle par rap-
port à la position d’équilibre du système. On supposera que le véhicule se déplace horizontalement
à vitesse constante. On étudie la situation où l’axe de la roue est légèrement excentré par rapport à
son centre ; ceci provoque un déplacement e(t ) du châssis en fonction de la vitesse de rotation de
la roue ω : e(t ) = e 0 sin(ωt ) avec e 0 = 0.05 m. On veut modéliser la réponse en déplacement verti-
cal de l’habitacle en fonction de la pulsation ω. Le principe fondamental de la dynamique permet
d’obtenir l’équation différentielle :
d2 s d(s − e)
m +c + k(s − e) = 0
dt 2 dt
c’est à dire :
d2 s ds de
m +c + ks = ke + c
dt 2 dt dt
Éléments de correction
dx
= vx
dt
dy
= vy
dy
dv x k2 q
= − v x v x2 + v 2y
dt m
dv y
k2 q 2
= − v y v x + v 2y − g
dt m
h=1
v0=27.7
alpha=pi/4
g=9.81
def F(X,t,m,k2):
x=X[0]
y=X[1]
vx=X[2]
vy=X[3]
xprim=vx
yprim=vy
vxprim=-k2/m*vx*sqrt(vx**2+vy**2)
vyprim=-k2/m*vy*sqrt(vx**2+vy**2)-g
return [xprim,yprim,vxprim,vyprim]
(c)
t=np.linspace(0,10,100)
X1=odeint(F,[0,h,v0*cos(alpha),v0*sin(alpha)],t,args=(0.45,8.9e-3))
X2=odeint(F,[0,h,v0*cos(alpha),v0*sin(alpha)],t,args=(5e-3,1.6e-3))
plt.plot(X1[:,0],X1[:,1])
plt.plot(X2[:,0],X2[:,1])
plt.axhline(y=0,color=’k’)
20
−20
−40
−60
−80
−100
−120
−140
0 10 20 30 40 50 60
(d) Les composantes v x et v y correspondent aux deux dernières colonnes des matrices X 1 et X 2
donc :
plt.plot(t,np.sqrt(X1[:,2]**2+X1[:,3]**2))
plt.plot(t,np.sqrt(X2[:,2]**2+X2[:,3]**2))
30
25
20
15
10
0
0 2 4 6 8 10
(e) On a pris α ' 0.78. Prenons par exemple α = 0.2, 0.3, . . . , 1.5 (la courbe pour α = 0.1 est tracée
en rouge). Notons que le changement sur α ne change que la condition initiale :
for k in range(2,16):
alpha=float(k)/10
couleur="r" if k==2 else "b"
X=odeint(F,[0,h,v0*cos(alpha),v0*sin(alpha)],t,args=(0.45,8.9e-3))
plt.plot(X[:,0],X[:,1],couleur)
plt.axhline(y=0,color=’k’)
50
−50
−100
−150
−200
0 10 20 30 40 50 60 70
ds
=v
dt
dv 1 de
µ ¶
ke + c − c v − ks
=
dt m dt
(b)
m=100.0
c=1.13e3
k=80e3
w0=sqrt(k/m)
e0=0.05
T=2*pi/w0
def F(X,t,w):
s=X[0]
v=X[1]
sprim=v
vprim=1/m*(k*e0*sin(w*t)+c*w*e0*cos(w*t)-c*v-k*s)
return [sprim,vprim]
t=np.linspace(0,5*T,100)
plt.clf()
for w in [w0/2,27.7,2*w0]:
X=odeint(F,[0,0],t,args=(w,))
plt.plot(t,X[:,0])
plt.legend(["w0/2","27.7","2w0"])
0.15
w0/2
27.7
2w0
0.10
0.05
0.00
−0.05
−0.10
−0.15
0.0 0.2 0.4 0.6 0.8 1.0 1.2
TP 25 : Régressions linéaires
Exercice 1 Mesure du pas d’un réseau : On réalise une diffraction par un réseau de pas a. On
rappelle la formule du réseau :
λ
sin i = k
a
où i est l’angle sous lequel est vue la raie de longueur d’onde λ et k est l’ordre du spectre. On réalise
les mesures suivantes pour le spectre d’ordre 1 (k = 1) avec une lampe au cadmium :
On définira :
lambda_mes=np.array([643.8,508.6,480.0,467.8])
i_mes=np.array([22.9,17.9,16.9,16.4])
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp25.pdf
TP 25 : Régressions linéaires
Éléments de correction
Ex. 1 :
lambda_mes=np.array([643.8,508.6,480.0,467.8])
i_mes=np.array([22.9,17.9,16.9,16.4])
i_radians=i_mes*pi/180
Comme λ = a sin i dans le cadre de l’expérience, on obtient a en effectuant une regression linéaire
en prenant les valeurs de sin i en abscisse et les valeurs de λ en ordonnée :
(a,b,rho,_,_)=linregress(np.sin(i_radians),lambda_mes)
print "a=%f nm, rho=%f" % (a,rho)
n=1/(a*10**(-6))
print "Nombre de traits / mm : %f" % n
t=np.linspace(0,pi/4,100)
plt.plot(t,a*np.sin(t),’r-’)
plt.plot(i_radians,lambda_mes,’bo’)
plt.xlabel("i (rad)")
plt.ylabel("lambda (nm)")
plt.legend([u"Modèle (rho=%f)" % rho,"Mesures"],loc="lower right")
1200
1000
800
lambda (nm)
600
400
200
Modèle (rho=0.999965)
Mesures
0
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
i (rad)
Ex. 2 :
t_mes=np.array([20,40,60,80,100,120])
C_mes=np.array([2.78e-4,1.92e-4,1.47e-4,1.19e-4,1.0e-4,0.86e-4])
On définit le tableau y=1/C_mes, on effectue alors la régression linéaire en prenant t_mes comme
abscisses et y pour ordonnées :
y=1/C_mes
(a,b,rho,_,_)=linregress(t_mes,y)
print "a=%f, b=%f, rho=%f" % (a,b,rho)
print "C(0)=%e mol/L" % b**(-1)
t=np.linspace(0,140,100)
plt.plot(t,1/(a*t+b),’r-’)
plt.plot(t_mes,C_mes,’bo’)
plt.xlabel("t (s)")
plt.ylabel("C (mol/L)")
plt.legend([u"Modèle (rho=%f)" % rho,"Mesures"])
0.0006
Modèle (rho=0.999996)
Mesures
0.0005
0.0004
C (mol/L)
0.0003
0.0002
0.0001
0.0000
0 20 40 60 80 100 120 140
t (s)
TP 26 : Calcul numérique – TP noté
Avant tout :
• Lancer S PYDER.
• Aller dans le menu Fichier, choisir Nouveau fichier.
• Aller dans le menu Fichier, choisir Enregistrer sous.
• Sélectionner le répertoire Documents, créer un nouveau dossier intitulé Devoirs et
sélectionner ce dossier.
• Créer un nouveau dossier intitulé BOISSEAUA et sélectionner ce dossier.
• Enregistrer votre fichier en lui donnant le nom tp_votrenom.py (où votrenom est à
remplacer par votre nom de famille).
Vous ferez TOUS LES EXERCICES de la feuille de TP DANS CE FICHIER. en signalant claire-
ment où se trouve chaque exercice par des commentaires dans le fichier.
Exercice 1 Résolution d’une équation numérique : Utiliser P YTHON pour déterminer une solution
approchée de l’équation
1
ln(x) =
x
y 00 + m y 0 + y = c
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp26.pdf
Exercice 4 Propagation d’une épidémie / Système d’équations différentielles : On propose le modèle
simple suivant représentant la propagation d’une épidémie (appelé modèle SIR) :
— La population est divisé en trois groupes : sains (S), infectés (I) et résistants (R), dont les effec-
tifs au temps t sont notés respectivement s(t ), i (t ) et r (t ) ;
— Les fonctions s, i et r sont solution d’un système d’équations différentielles du type :
0
s (t ) = −bs(t )i (t )
i 0 (t ) = bs(t )i (t ) − ci (t )
r 0 (t ) = ci (t )
2
0 1 3
On décrira un tel graphe en P YTHON en donnant la liste de ses arêtes. Par exemple le graphe G 1 est
représenté par la liste :
G1=[[0,1],[1,0],[1,2],[2,3],[3,1]]
Une arête reliant le sommet s 1 au sommet s 2 (dans cet ordre) est représentée par la liste [s 1 , s 2 ]. On
appelle taille du graphe le nombre de sommets de ce graphe et on conviendra que si G est un graphe
de taille n, alors :
• Ses sommets sont 0, 1, . . . , n − 1 ;
• Tout sommet du graphe apparait au moins dans une arête (comme point de départ ou d’arri-
vée).
2
4 3
0 5 1
Donner la taille de ce graphe et sa représentation en P YTHON sous forme d’une liste G2.
Question 3 : Écrire une fonction taille(G) qui détermine la taille du graphe G (G est la liste des
arêtes).
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp27.pdf
¦ On considère le problème suivant : dans un tableur, certaines cellules se calculent en fonction
des autres et, lorsqu’une valeur change, il faut recalculer les valeurs des cellules. Cependant, l’ordre
dans lequel on effectue ce calcul doit être tel que, si une cellule c 1 dépend de la valeur d’une cellule
c 2 , alors c 2 doit être recalculée avant c 1 .
Notes
¦ Les graphes servent à modéliser de nombreux problèmes : réseaux de communication, relation
de dépendance, systèmes de transitions etc. C’est pourquoi de nombreux problèmes sur les graphes
ont été étudiés. Le problème que l’on vit de considérer est celui du tri topologique. Bien que l’algo-
rithme proposé dans ce TP soit correct, il est cependant peu permormant. Quelques liens :
www-sop.inria.fr/members/Frederic.Havet/FeteScience/Graphes-reseaux.pdf
https://fr.wikipedia.org/wiki/Théorie_des_graphes
https://fr.wikipedia.org/wiki/Tri_topologique
TP 27 : Introduction à la structure de graphe
Éléments de correction
Q. 1 : Le graphe G 1 est de taille 4.
G2=[[1,0],[0,4],[4,3],[3,0],[3,5],[3,2],[2,3],[2,5],[5,2],[2,1],[1,5],[5,1]]
Q. 3 : Avec les hypothèses faites sur les graphes considérées, la taille de G et m + 1 où m est le plus
grand nombre apparaissant des la liste G. Ainsi :
def taille(G):
m=0
for a in G:
# a est une arête de G,
# donc une liste à 2 éléments a[0] et a[1]
if a[0]>m:
m=a[0]
if a[1]>m:
m=a[1]
return m+1
print taille(G1)
print taille(G2)
Q. 4 :
import numpy as np
def matrice(G):
n=taille(G)
M=np.zeros((n,n))
for a in G:
M[a[0],a[1]]=1
return M
M1=matrice(G1)
print M1
M2=matrice(G2)
print M2
print np.linalg.matrix_power(M1,8)[0,1]
3.0
Il y a donc 3 chemins de taille 8 allant de 0 à 1 dans G 1 :
0, 1, 2, 3, 1, 0, 1, 0, 1
0, 1, 0, 1, 2, 3, 1, 0, 1
0, 1, 0, 1, 0, 1, 2, 3, 1
Q. 5 : Un ordre possible : B1, A2, A3, C1, C2. On peut modéliser les dépendances entre cellules par
un graphe orienté dans lequel les sommets sont les cellules considérées et une arête de c 1 à c 2 signi-
fie que la valeur de c 1 dépend de celle de c 2 . Sur l’exemple considéré, on obtient le graphe :
C1
A3 A2 B1
C2
3
1 0 2
4
Q. 6 : La liste T obtenue à la fin contient tous les sommets du graphe G rangés dans un ordre tel que
si il y a une arête allant du sommet c 1 au sommet c 2 dans G, alors c 2 apparait avant c 1 dans la liste
T.
def tri(G):
n=taille(G)
S=range(n)
T=[]
while S!=[]:
c=S[0] # On prend le 1er élément de S
S=S[1:] # et on le retire
remettre=False
for x in S:
if [c,x] in G:
remettre=True
if remettre:
S.append(c) # On remet c à la fin de S
else:
T.append(c)
return T
G3=[[3,1],[4,1],[1,0],[0,2]]
print tri(G3)
[2, 0, 1, 3, 4]
TP 28 : Introduction aux BDD
¦ Il y a essentiellement 3 zones :
• À gauche, la zone Schema, elle va permettre de parcourir la base de données et ses différentes
tables ;
• En bas à droite, la zone Vue, elle va afficher le contenu des différentes tables. On restera tou-
jours sur l’onglet Vue complète ;
• En haut à droite, le cadre SQL (voir utilisation plus loin).
¦ Double cliquer sur Tables dans la zone Schema. Noter les noms des différentes tables qui appa-
raissent. Double cliquer sur chaque table et observer son contenu qui apparait dans la zone Vue.
Question 1 : Donner la liste des tables qui composent cette base de données et pour chacune des
ces tables, donner son schéma. Mettre en évidence (par exemple avec différentes couleurs) les clés
primaires et les clés étrangères qui apparaissent.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp28.pdf
Question 2 : On considère la table emprunte. Chercher les emprunts pour lesquels le numéro de
client est égal à 66. Pour ces emprunts, donner le nom du client et le titre du film emprunté.
Question 3 : En cherchant dans les différentes tables, déterminer les noms des clients qui ont
emprunté le film HOT SHOTS 2.
cliquer ensuite sur Ï, observer le résultat dans la zone Vue. Faire de même avec la commande :
Question 4 :
(a) Taper une commande SQL permettant de lister les emprunts pour lesquels le numéro de client
est égal à 66.
(b) Pour ces emprunts, faire afficher également le nom du client.
(c) Faire également afficher le titre du film emprunté.
Question 5 :
(a) Taper une commande SQL permettant de lister le film pour lequel idFilm vaut 41.
(b) Pour ce film, afficher également la valeur de numInventaire.
(c) Faire également afficher les noms des clients qui ont emprunté ce film.
acteur client
idPersonne idFilm numClient prenom nom ville credit bonus
emprunte exemplaire
numClient numInventaire dateEmprunt numInventaire idFilm format
film
idFilm titre_VO titre_VF annee pays
historique personne
numClient numInventaire dateEmprunt dateRetour idPersonne nom
realisateur tarif
idPersonne idFilm format prix
Pour chacune des questions suivantes, on déterminera la réponse à l’aide d’une requête SQL appro-
priée (noter la requête sur la feuille) :
(a) Déterminer les enregistrements de la table exemplaire dont le format est Blu-ray.
(b) Déterminer les titres (en VO) des films qui sont au format Blu-ray.
(c) Déterminer les emprunts qui correspondent à des films au format Blu-ray.
(d) Déterminer les noms des clients qui ont emprunté des films au format Blu-ray.
Exercice 2 Base de données poteries.sqlite : Ouvrir cette base de données dans le logiciel
SQL ITEMAN. Elle n’est constituée que d’une seule table qui répertorie les proportions de différents
métaux (Al, Fe, Mg, Ca et Na) présents dans des échantillons de poteries trouvés sur différents sites
archéologiques désignés par une lettre (L, C , I ou A).
(a) Donner le schéma de cette table.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp29.pdf
(b) Écrire une requête SQL permettant de sélectionner les enregistrements qui correspondent au
site L uniquement.
(c) Écrire une requête SQL permettant d’afficher uniquement les champs Al, Fe et Site unique-
ment.
(d) Déterminer la moyenne des valeurs du champ Al pour le site L, puis faire de même pour les
autres sites.
B Si ce n’est pas déjà fait, pensez à déplacer le fichier poteries.sqlite dans votre répertoire
TPinfo.
import sqlite3
bdd=sqlite3.connect(’poteries.sqlite’)
Éléments de correction
Ex. 1 : Enregistrements dont le format est Blu-ray (on n’affiche que les 10 premiers) :
import sqlite3
bdd=sqlite3.connect(’/home/ba/Enseignement/PC/Python/Data/Videoclub.db3’)
requete="""
SELECT * FROM exemplaire WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall()[0:10]:
print e
(3, 5, u'Blu-ray')
(12, 12, u'Blu-ray')
(32, 30, u'Blu-ray')
(36, 31, u'Blu-ray')
(43, 37, u'Blu-ray')
(51, 41, u'Blu-ray')
(72, 69, u'Blu-ray')
(75, 77, u'Blu-ray')
(78, 79, u'Blu-ray')
(82, 83, u'Blu-ray')
Les titres des films qui sont au format Blu-ray (on n’affiche que les 10 premiers) :
requete="""
SELECT titre_VO FROM film
JOIN exemplaire
ON film.idFilm=exemplaire.idFilm
WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall()[0:10]:
print e
(u'Ruthless people',)
(u'Rue du Bac',)
(u'What ever happened to Baby Jane?',)
(u'Four for Texas',)
(u'Too late for heroes',)
(u'The Mean Machine or the longest yard',)
(u'The Uninvited',)
(u'Take the money and run',)
(u'Sleeper',)
(u'Manhattan',)
Les noms des clients ayant emprunté des films qui sont au format Blu-ray :
requete="""
SELECT nom, prenom FROM client
JOIN emprunte
ON client.numClient=emprunte.numClient
JOIN exemplaire
ON emprunte.numInventaire=exemplaire.numInventaire
WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall():
print e
bdd.close()
(u'FOURNIER', u'Romain')
(u'GIRAUD', u'Louise')
(u'ROUX', u'Jules')
(u'ANDRE', u'Baptiste')
(u'ROUX', u'Jules')
bdd=sqlite3.connect(’/home/ba/Enseignement/PC/Python/Data/poteries.sqlite’)
requete="""
SELECT * FROM poteries WHERE Site=’L’
"""
for e in bdd.execute(requete).fetchall():
print e
(14.4, 7.0, 4.3, 0.15, 0.51, u'L')
(13.8, 7.08, 3.43, 0.12, 0.17, u'L')
(14.6, 7.09, 3.88, 0.13, 0.2, u'L')
(11.5, 6.37, 5.64, 0.16, 0.14, u'L')
(13.8, 7.06, 5.34, 0.2, 0.2, u'L')
(10.9, 6.26, 3.47, 0.17, 0.22, u'L')
(10.1, 4.26, 4.26, 0.2, 0.18, u'L')
(11.6, 5.78, 5.91, 0.18, 0.16, u'L')
(11.1, 5.49, 4.52, 0.29, 0.3, u'L')
(13.4, 6.92, 7.23, 0.28, 0.2, u'L')
(12.4, 6.13, 5.69, 0.22, 0.54, u'L')
(13.1, 6.64, 5.51, 0.31, 0.24, u'L')
(12.7, 6.69, 4.45, 0.2, 0.22, u'L')
(12.5, 6.44, 3.94, 0.22, 0.23, u'L')
On sélectionne les champs Al, Fe et Site (on affiche uniquement les 10 premiers enregistrements) :
requete="""
SELECT Al, Fe, Site FROM poteries
"""
for e in bdd.execute(requete).fetchall()[0:10]:
print e
requete="""
SELECT AVG(Al) FROM poteries WHERE Site=’L’
"""
print bdd.execute(requete).fetchall()
[(12.564285714285713,)]
Pour les quatre sites :
Ex. 3 : Les moyennes des proportions des différents métaux pour le site L :
bdd=sqlite3.connect(’/home/ba/Enseignement/PC/Python/Data/poteries.sqlite’)
requete="""
SELECT AVG(Al), AVG(Fe), AVG(Mg), AVG(Ca), AVG(Na)
FROM poteries
WHERE Site=’L’
"""
print bdd.execute(requete).fetchall()
Moy_L=bdd.execute(requete).fetchall()[0]
Moy_L_Al=Moy_L[0]
print Moy_L_Al
12.5642857143
On sélectionne les enregistrements pour lesquels Al est situé à ±10% de cette valeur moyenne :
requete="""
SELECT * FROM poteries
WHERE %f<=Al and Al<=%f
""" % (Moy_L_Al*0.9,Moy_L_Al*1.1)
for e in bdd.execute(requete).fetchall():
print e
8
L
A
7 C
I
6
4
Fe
0
10 12 14 16 18 20 22
Al
Il semble que le couple (Al, Fe) permette de distinguer entre les échantillons issus des sites L et C
d’une part et A et I d’autre part.
TP 30 : Exemple d’utilisation d’une BDD
Question 1 : Si la vitesse du vent est v, on note P (v) la puissance obtenue à la sortie de la turbine
de l’éolienne. On suppose que :
• P (v) = 0 si v < Vmin ou v > Vmax ;
1
• P (v) = ρC p Sv 3 si Vmin É v É Vnom ;
2
1 3
• P (v) est constant égal à ρC p SVnom si Vnom < v É Vmax ].
2
(a) Définir la fonction P(v) qui réalise ce calcul.
(b) Représenter graphiquement cette fonction sur l’intervalle [0, 26].
Question 2 : On considère que la vitesse du vent suit une loi de probabilité appelée loi de Rayleigh.
La densité de probabilité de cette loi est la fonction notée R et définie par :
2v v2 2Vmoy
µ ¶
R(v) = 2 exp − 2 avec A = p
A A π
Rappelons que ceci signifie en particulier que pour v 2 Ê v 1 Ê 0, la probabilité que la vitesse du vent
v soit comprise entre v 1 et v 2 est :
Z v2
P(v 1 É v É v 2 ) = R(v) dv
v1
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp30.pdf
(b) Estimer numériquement la probabilité que la vitesse du vent v soit comprise entre Vmin et
Vmax .
(c) Estimer numériquement la probabilité que la vitesse du vent v soit comprise entre Vnom et
Vmax .
(d) Représenter graphiquement la fonction R sur l’intervalle [0, 26].
Énergie produite en un an
Question 3 : On estime la quantité d’énergie E produite en un an (en kWh) par la relation :
8760
Z Vmax
E= R(v)P (v) dv
1000 Vmin
Calculer numériquement E .
Éléments de correction
Q. 1 :
import numpy as np
import matplotlib.pyplot as plt
S=9.08
Cp=0.3
Vmin=4.0
Vmax=25.0
Vnom=12.0
Vmoy=7.41
rho=1.25
def P(v):
if v<Vmin or v>Vmax:
return 0
elif Vmin<=v<=Vnom:
return 0.5*rho*Cp*S*v**3
else:
return 0.5*rho*Cp*S*Vnom**3
vv=np.linspace(0,26,100)
plt.plot(vv,[P(vi) for vi in vv],’b-’)
plt.xlabel("v (m/s)")
plt.ylabel("P (W)")
plt.title("Puissance P fournie en fonction de la vitesse du vent v")
2500
2000
P (W)
1500
1000
500
0
0 5 10 15 20 25 30
v (m/s)
Q. 2 :
def R(v):
A=2*Vmoy/np.sqrt(np.pi)
return 2*v*A**(-2)*np.exp(-v**2*A**(-2))
plt.plot(vv,R(vv))
plt.title(u"Densité de probabilité de la v.a.r. v")
plt.xlabel("v")
plt.ylabel("R(v)")
0.12
Densité de probabilité de la v.a.r. v
0.10
0.08
0.06
R(v)
0.04
0.02
0.00
0 5 10 15 20 25 30
v
(0.7953073454295636, 1.971260414970532e-12)
Estimation numérique de la probabilité que v soit compris entre Vnom et Vmax :
(0.12735391116070854, 1.4139124444668532e-15)
Q. 3 : Calcul numérique de E :
E=8627.497276 (kWh)
Q. 4 :
import sqlite3
FICHIER_BDD=’/home/ba/Enseignement/PC/Python/Data/eoliennes.sqlite’
bdd=sqlite3.connect(FICHIER_BDD)
print bdd.execute("""
SELECT * FROM eoliennes
WHERE Vnom=%f AND Vmin=%f AND Vmax=%f and Surf=%f
""" % (Vnom,Vmin,Vmax,S)).fetchall()
[(3, 24.0, 3.4, 9.08, 0.3, 4.0, 12.0, 25.0)]
Pour récupérer le numéro n et la hauteur h :
(n,h)=bdd.execute("""
SELECT Num,Haut FROM eoliennes
WHERE Vnom=%f AND Vmin=%f AND Vmax=%f and Surf=%f
""" % (Vnom,Vmin,Vmax,S)).fetchone()
print n,h
3 24.0
print bdd.execute("""
SELECT * FROM vents
WHERE Vmoy=%f AND Haut=%f
""" % (Vmoy,h)).fetchall()
print bdd.execute("""
SELECT * FROM terrains
WHERE Type=7
""").fetchall()
e c o l e p o l y t e c h n i q u e
4 2 14 11 4 15 14 11 24 19 4 2 7 13 8 16 20 4
t=[4,2,14,11,4,15,14,11,24,19,4,2,7,13,8,16,20,4]
On utilisera cette liste t pour tester les fonctions écrites dans les question 2, 3, 4, 5 et 7.
Question 4 : Écrire la fonction frequences(tc) qui prend en argument une liste tc qui re-
présente le texte crypté et qui retourne une liste de taille 26 dont l’élément d’indice i est le nombre
d’apparitions de i dans tc.
Question 5 : Écrire la fonction decodageAuto(tc) qui prend en argument la liste tc qui repré-
sente le texte crypté et qui retourne la liste t correspondant au texte d’origine (en calculant la clé
pour que la lettre e soit la plus fréquente dans le texte de départ).
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp31.pdf
Partie 3 Codage de Vigenère
Au XVIe siècle, Blaise de Vigenère a modernisé le codage de César très peu résistant de la manière
suivante. Au lieu de décaler toutes les lettres du texte de la même manière, on utilise un texte clé qui
donne une suite de décalages.
Prenons par exemple la clé concours. Pour crypter un texte, on code la première lettre en uti-
lisant le décalage qui envoie le a sur le c (la première lettre de la clé). Pour la deuxième lettre, on
prend le décalage qui envoie le a sur le o (la seconde lettre de la clé) et ainsi de suite. Pour la hui-
tième lettre, on utilise le décalage a vers s puis, pour la neuvième, on reprend la clé à partir de sa
première lettre. Sur l’exemple ecolepolytechnique avec la clé concours, on obtient :
e c o l e p o l y t e c h n i q u e
g q b n s j f d a h r e v h z i w s
c o n c o u r s c o n c o u r s c o
(la première ligne donne le texte, la deuxième le texte crypté et la troisième la lettre de la clé utilisée
pour le décalage).
Question 6 : Donner le codage de becunfromage en utilisant la clé jean.
Question 7 : Écrire la fonction codageVigenere(t,c) qui prend comme arguments une liste
t représentant le texte à crypter et une liste d’entiers c donnant la clé servant au codage et qui
retourne la liste tc contenant le texte crypté. Écrire la fonction decodageVigenere(tc,c) qui
réalise le décodage.
TP 31 : Ave Cesar (zud bdrzq)
Éléments de correction
Partie 1 Codage de César
Q. 2 :
def codageCesar(t,d):
n=len(t)
tc=[0]*n
for i in range(n):
tc[i]=t[i]-d
if tc[i]<0:
tc[i]=tc[i]+26
return tc
print codageCesar(t,5)
[25, 23, 9, 6, 25, 10, 9, 6, 19, 14, 25, 23, 2, 8, 3, 11, 15, 25]
On peut aussi utiliser un calcul de reste de division euclidienne.
Q. 3 :
def decodageCesar(tc,d):
n=len(tc)
t=[0]*n
for i in range(n):
t[i]=tc[i]+d
if t[i]>25:
t[i]=t[i]-26
return t
print decodageCesar(codageCesar(t,5),5)==t
True
print decodageCesar(codageCesar(t,22),22)==t
True
def frequences(tc):
f=[0]*26
for c in tc:
f[c]=f[c]+1
return f
print frequences(codageCesar(t,2))
[2, 0, 4, 0, 0, 1, 1, 0, 0, 2, 0, 1, 2, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
0]
Q. 5 :
def decodageAuto(tc):
f=frequences(tc)
# On recherche c tq f[c] est maximal
c=0
for i in range(2,26):
if f[i]>f[c]:
c=i
# Le nombre 4 (caractère e) a été codé en c
# donc 4-d=c
d=4-c
if d>25:
d=d-26
if d<0:
d=d+26
return decodageCesar(tc,d)
print decodageAuto(codageCesar(t,5))==t
True
def codageVigenere(t,c):
n=len(t)
tc=[0]*n
j=0 # Position dans la clé c
for i in range(n):
tc[i]=t[i]-c[j]
if tc[i]<0:
tc[i]=tc[i]+26
j=j+1
if j>=len(c):
j=0
return tc
def decodageVigenere(tc,c):
n=len(tc)
t=[0]*n
j=0 # Position dans la clé c
for i in range(n):
t[i]=tc[i]+c[j]
if t[i]>25:
t[i]=t[i]-26
j=j+1
if j>=len(c):
j=0
return t
print decodageVigenere(codageVigenere(t,[5,25]),[5,25])==t
True
TP 32 : Dépouillement d’élections
Le problème consiste à faire le décompte du résultat des élections dans le pays X . La règle élec-
torale y est très laxiste, puisqu’on peut être élu sans s’être présenté. En effet, chaque citoyen est
identifié par un numéro i (avec 0 É i < n) et l’ensemble des votes est représenté par une liste V où
V[i] représente le vote du citoyen i . La liste V est de taille n (on utilisera l’instruction n=len(V)).
Un citoyen ayant obtenu strictement plus de 50% des voix est élu au premier tour.
Question 1 : Écrire une fonction nb_voix(V,x) qui compte le nombre de fois où x apparait
dans la liste V (c’est à dire le nombre de voix obtenues par le candidat x).
Question 2 : Écrire la fonction gagnant_tour1(V) qui retourne le gagnant du premier tour s’il
existe. S’il n’existe pas, on retournera −1. Donner l’ordre de grandeur du temps d’exécution de cette
fonction en fonction de n. Tester cette fonction sur les exemples suivants :
V1=[1,2,3,4,5,6,7,8,9,0] V4=[1,1,0,1,0,1,0,0,2,2]
V2=[1,0,2,2,1,0,1,0,1,1] V5=[1,1,1,2,2,2,2,2,2,5]
V3=[1,0,1,2,1,0,1,0,1,1] V6=[1,1,1,2,3,3,3,4,4,4]
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp32.pdf
Décrire ce que fait cette fonction. Donner un invariant de boucle permettant de justifier cette affir-
mation. Donner un ordre de grandeur du temps d’exécution de cette fonction, en fonction de n.
Question 5 : Écrire une fonction gagnants_tour2(V) qui construit est renvoie la liste des
gagnants du deuxième tour (attention : chaque gagnant ne devra apparaitre qu’une seule fois dans
la liste renvoyée). Donner un ordre de grandeur du temps d’exécution de cette fonction en fonction
de n.
Éléments de correction
Q. 1 :
def nb_voix(V,x):
k = 0
for y in V:
if y==x:
k = k+1
return k
def gagnant_tour1(V):
n = len(V)
for x in V:
if nb_voix(V,x)>float(n)/2:
return x # Et la boucle s’arrête
# La boucle est allée jusqu’au bout
# il n’y a pas de gagnant au premier tour donc :
return -1
print gagnant_tour1(V1)
-1
print gagnant_tour1(V2)
-1
print gagnant_tour1(V3)
print gagnant_tour1(V4)
-1
print gagnant_tour1(V5)
print gagnant_tour1(V6)
-1
Voici un moyen d’écrire ceci plus simplement :
for i in range(1,7):
print eval("gagnant_tour1(V%s)" % i)
-1 -1 1 -1 2 -1
Comme le temps d’exécution de nb_voix(V,x) est en O(n), celui de gagnant_tour1(V) est
en O(n 2 ).
Q. 3 : La liste W est triée. S’il y a un gagnant x au premier tour, alors il occupe plus de 50% des
éléments de W donc l’élément « au milieu » de W est nécessairement egal à x. Pour savoir s’il y a
un gagnant au premier tour, il suffit donc de regarder si l’élément au mileu de V a obtenu stricte-
ment plus de 50% des voix. La fonction mystere donne donc également le gagnant éventuel du
premier tour. Comme sorted(V) est en O(n ln(n)) et nb_voix en O(n), le temps d’exécution de
mystere(V) est en O(n) + O(n ln n) = O(n ln n).
for i in range(1,7):
print eval("mystere(V%s)" % i)
-1 -1 1 -1 2 -1
Q. 4 : Cette fonction calcule le plus grand nombre de voix obtenu par un candidat (les gagnants
du deuxième tour seront donc les candidats qui totalisent ce nombre de voix). On peut considérer
l’invariant de boucle :
Comme nb_voix s’exécute en O(n) et la boucle while est faite exactement n fois, donc le temps
d’exécution de mystere2(V) est en O(n 2 ). Pour plus de clarté dans la suite, on pose :
nb_voix_max=mystere2
def gagnants_tour2(V):
m = nb_voix_max(V)
G = []
for x in V:
if (x not in G) and (nb_voix(V,x)==m):
G.append(x)
return G
for i in range(1,7):
print eval("gagnants_tour2(V%s)" % i)
Q. 6 : La première chose à faire est de calculer le nombre maximum de voix obtenues par un candi-
dat. Pour cela, on parcourt la liste V et à chaque fois que l’on observe un changement on calcule le
nombre d’éléments correspondant et on retient le maximum. On parcourt ensuite la liste. Si on est
à l’indice i et si V [i + m − 1] et V [i ] sont égaux, alors V [i ] est un gagnant du second tour. Pour éviter
de sortir de la liste, il faut considérer les indices de i = 0 jusqu’à i = n − m.
def gagnants_tour2_trie(V):
n = len(V)
i0 = 0
m = 0
for i in range(n):
if V[i]!=V[i0]:
i0 = i
t = i-i0+1
if t>m:
m = t
G = [] # ou :
for i in range(n-m+1): # for i in range(n):
if V[i+m-1]==V[i]: # if i+m-1<n and V[i+m-1]==V[i]
G.append(V[i]) # ...
return G
for i in range(1,7):
print eval("gagnants_tour2(V%s)" % i)
¦ On peut avoir besoin dans un programme de demander des informations à l’utilisateur. Pour de-
mander un nombre entier (par exemple le nombre d’élèves dans une classe), on écrira :
et le nombre entré au clavier sera alors enregistré dans la variable n. Pour demander un nombre réel
(par exemple le rayon d’un cercle) :
B Dans ce TP, il n’y aura pas besoin d’écrire de fonction. On utilisera un fichier différent pour
chaque exercice (par exemple epidemie.py, melange.py et marchands.py).
Exercice 1 Contrôle d’une épidémie : Afin de pouvoir mieux combattre les différentes épidémies,
parfois très graves, qui se développent régulièrement dans la région, le département de médecine
de l’université a lancé une grande étude. En particulier, les chercheurs s’intéressent à la vitesse de
propagation d’une épidémie et donc à la vitesse à laquelle des mesures sanitaires doivent êtres mises
en place.
Ce que doit faire votre programme : Votre programme doit d’abord lire un entier, la population
totale de la ville. Sachant qu’une personne était malade au jour 1 et que chaque malade contamine
deux nouvelles personnes le jour suivant (et chacun des jours qui suivent), vous devez calculer à
partir de quel jour toute la population de la ville sera malade.
Exemple 1 : Exemple 2 :
entrée : entrée :
3 10
sortie : sortie :
2 4
Commentaires. On a 1 malade le premier jour, donc 2 nouveaux malades le second jour, soit un
total de 3 malades. On a donc 6 nouveaux malades au troisième jour, soit un total de 9 malades. On
a donc 18 nouveaux malades au quatrième jour, soit...
Exercice 2 Mélange explosif : Les chimistes de l’université ont mis au point un nouveau procédé
de fabrication d’un onguent qui permet une cicatrisation très rapide des blessures. Ce procédé est
cependant très long et nécessite une surveillance de tous les instants de la préparation en train de
chauffer, et ce parfois pendant des heures. Confier cette tâche à un étudiant n’est pas possible, ils
s’endorment toujours ou ne font pas attention... et cela risque alors d’exploser ! Un dispositif auto-
matique de surveillance de la préparation serait donc intéressant. Celui-ci surveillerait la tempéra-
ture toutes les 15 secondes et si celle-ci devient anormale alors une alarme devrait sonner, afin de
prévenir tout le monde.
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp33.pdf
Ce que doit faire votre programme : Votre programme devra lire trois entiers : le nombre total de
mesures envisagées ainsi que la température minimum et maximum autorisées. Les entiers suivants
seront les différentes températures relevées au cours du temps. Tant que les températures relevées
restent dans le bon intervalle, votre programme devra écrire le texte "Rien à signaler" mais dès que
la température n’est pas bonne il doit écrire le texte "Alerte ! !" et s’arrêter.
Exemple 1 Exemple 2
entrée : entrée :
5 3
10 0
20 100
15 15
10 50
20 75
0 sortie :
15 Rien à signaler
sortie : Rien à signaler
Rien à signaler Rien à signaler
Rien à signaler
Rien à signaler
Alerte !!
Attention. Dans l’exemple 1, le programme doit s’arrêter de demander les mesures dès qu’il dé-
clenche l’alerte, bien que nombre total de mesures n’ait pas été entré.
Exercice 3 Répartition du poids : Après seulement quelques heures de route, au sein d’une longue
caravane de marchands, certains chevaux montrent déjà des signes de fatigue alors que d’autres sont
en pleine forme. En cherchant la raison de ce phénomène, vous vous rendez compte que certaines
charrettes sont bien plus lourdes que les autres ! Vous décidez donc de mieux répartir le poids, afin
que toutes les charrettes aient exactement le même poids 1 .
Ce que doit faire votre programme : On vous décrit les charrettes qui com- Exemple
posent une caravane, en vous donnant pour chacune, le poids des marchan- entrée :
dises qu’elle transporte. Votre programme doit déterminer quel poids ajouter 5
ou retirer à chaque charrette, pour qu’elles transportent toutes ensuite le même 40.0
poids, et ce sans modifier le poids total transporté par l’ensemble des charrettes 12.0
de la caravane. 20.0
Entrée : L’entrée commence par un entier nbCharrettes : le nombre de 5.0
charrettes de la caravanne. Les nbCharrettes lignes suivantes décrivent 33.0
chacune une charrette par un nombre décimal : le poids qu’elle transporte ini- sortie :
tialement. -18.0
Sortie : Vous devez afficher nbCharrettes nombres décimaux sur la sor- 10.0
tie : le poids à ajouter à chaque charrette (ce qui revient à en retirer si ce nombre 2.0
est négatif), dans le même ordre que celui de l’entrée. Il n’y a pas d’arrondis à 17.0
faire. -11.0
Commentaires : Dans cet exemple, on modifie toutes les charettes pour qu’elles transportent cha-
cune un poids de 22.0, soit un total de 110 pour la caravane, comme au départ.
Éléments de correction
Ex. 1 : On définit les variables population (population totale), malades (nombre de personnes
malades) et jour (numéro du jour concerné). Initialement, malades=1 et jour=1. À chaque
fois que jour augmente de 1, malades est multiplié par 3. On continue jusqu’à ce que l’on ait
malades>=population (i.e. on continue tant que malades<population). Dans la suite, les
valeurs soulignées sont celles entrées par l’utilisateur.
Ex. 2 : La difficulté est que le programme peut s’arrêter de deux manières : soit parce que toutes les
mesures ont été traitées, soit parce que la mesure est hors de l’intervalle. Première possibilité :
Ex. 3 : Dans ce type de problème, on remarque que l’on ne pourra donner la réponse qu’une fois
toutes les valeurs entrées et on ne connait pas leur nombre à l’avance. On va donc utiliser une liste
Poids dans laquelle on enregistre le poids de chacune des charettes.
m = 0
for i in range(nbCharettes):
m = m+Poids[i]
m = m/nbCharettes
for i in range(nbCharettes):
print m-Poids[i]