La programmation Python au lycée
Proposition de correction de certaines activités du livret de formation
I - Python : prise en main
A) EduPython : un éditeur parmi d’autres
B) L’interface d’EduPython
C) Premiers programmes
1. Notion de fonction
script
def discr(a, b, c) :
return b**2 - 4*a*c
def x_sommet(a, b, c) :
return -b / (2 * a)
console
discr(5, 3, 1)
x_sommet(5, 3, 1)
2. Appeler une fonction ; instruction conditionnelle
script
def nombre_racines_trinome(a, b, c) :
if discr(a, b, c) < 0 :
message = "Pas de solution"
if discr(a, b, c) = 0 :
message = "Une solution unique"
if discr(a, b, c) > 0 :
message = "Deux solutions"
return message
console
discr(5, 3, 1)
3. Utiliser des bibliothèques
4. Boucles Pour et Tant_que
script Application 1
def fibo(k):
# Initialisation de la liste
L = [1, 1]
for compteur in range (2 , k) :
n = L[compteur - 2] + L[compteur - 1]
L.append(n)
return L
console
fibo(10)
script
def fibo(k, u0, u1):
# Initialisation de la liste
L = [u0, u1]
for compteur in range (2, k) :
n = L[compteur - 2] + L[compteur - 1]
L.append(n)
return L
console
fibo(10,0,1)
script Application 2
from math import sqrt
def liste_des_termes() :
liste = [7]
u = 7
while (abs(u - sqrt(5)) > 10**-6) :
u = 1 / 2 * (u + 5 / u)
liste.append(u)
return(liste)
console
liste_des_termes()
D) Suite de Syracuse et représentations graphiques
1. Suite de Syracuse : calcul des termes
script
def syracuse(u) :
liste = [u]
while u != 1 :
if u % 2 == 0 :
u = u // 2
else :
u = u * 3 + 1
liste.append(u)
return liste
console
syracuse(17)
2. Représentation graphique d’une suite de Syracuse
script
import matplotlib.pyplot as plt
def syracuse(u) :
liste = [u]
while u != 1 :
if u % 2 == 0 :
u = u // 2
else :
u = u * 3 + 1
liste.append(u)
return liste
def graph_syracuse(u) :
Y_liste = syracuse(u)
X_liste = range(len(Y_liste))
plt.plot(X_liste , Y_liste , "b.")
plt.show()
def graph_double_syracuse(u,v) :
Yu_liste = syracuse(u)
Xu_liste = range(len(Yu_liste))
Yv_liste = syracuse(v)
Xv_liste = range(len(Yv_liste))
plt.plot(Xu_liste , Yu_liste , "b.")
plt.plot(Xv_liste , Yv_liste , "r*")
plt.show()
console
graph_syracuse(17)
graph_double_syracuse(17, 13)
II - Premières applications de Python
A) Python dès la seconde
1. Applications rapides en géométrie repérée
script
def milieu(xA, yA, xB, yB) :
return [(xA + xB) / 2 , (yA + yB) / 2]
def parallélogramme(A, B, C, D) : # A,B,C,D sont des listes
if milieu(A[0], A[1], C[0], C[1]) == milieu(B[0], B[1], D[0], D[1]) :
return "ABCD est un parallélogramme"
else :
return "ABCD n'est pas un parallélogramme"
console
milieu(1, 1, 3, 5)
parallélogramme([1, 1], [2, 4], [3, 5], [4, 6])
2. Déterminer l’équation d’une droite passant par deux points
script
def coeff(x1, y1, x2, y2):
a = (y1 - y2) / (x1 - x2)
return a
def ord_origine(x1, y1, a) :
b = y1 - a*x1
return b
def equation(x1, y1, x2, y2) :
a = coeff(x1, y1, x2, y2)
b = ord_origine(x1, y1, a)
if b > 0 :
msg = "L'équation de votre droite est : y=" + str(a) + "x+" + str(b)
elif b < 0 :
msg = "L'équation de votre droite est : y=" + str(a) + "x" + str(b)
else :
msg = "L'équation de votre droite est : y=" + str(a) + "x"
return(msg)
console
equation(1, 1, 3, 5)
3. Petit jeu « Devine le nombre auquel je pense »
script
from random import *
def jeu(n) :
nb = randint(1, n)
ch = nb + 1 # ch est à coup sûr différent de nb au départ
compteur = 1
print("Je pense à un nombre entier entre 1 et 100, à vous de deviner lequel...")
while nb != ch :
ch = int(input("Votre proposition ?"))
if ch < nb :
print("Trop petit")
if ch > nb :
print("Trop grand")
compteur = compteur + 1
return "Bravo, le nombre était " + str(ch) + " , vous avez gagné au bout de " + str(compteur) + " essais"
console
jeu(100)
4. Statistiques
script
from random import *
import matplotlib.pyplot as plt # (partie graphique)
# Création d'une série de 20 valeurs aléatoires entre 1 et 100
serie = [randint(1, 100) for i in range(20)]
# Statistiques - indicateurs position et dispersion
def moyenne(L) :
somme = 0
for compteur in range(len(L)) :
somme = somme + L[compteur]
return somme / len(L)
def quartiles(L) :
L.sort() # Tri de la liste L
if len(L)%2 == 0 :
mediane = (L[len(L) // 2 - 1] + L[len(L) // 2]) / 2
else :
mediane = L[len(L) // 2]
if len(L)%4 == 0 :
Q1 = L[len(L) // 4 - 1]
else :
Q1 = L[len(L) // 4]
if (3*len(L))%4 == 0 :
Q3 = L[(3 * len(L)) // 4 - 1]
else:
Q3 = L[(3 * len(L)) // 4]
return [Q1, mediane, Q3]
# Statistiques - Echantillonnage
univers=[1, 2, 2, 4, 5, 6]
# Choisir au hasard un nombre dans la liste univers
choice(univers)
def echantillon(L,n) :
echant = []
for compteur in range(n) :
echant.append(choice(L))
return echant
def frequence(L,issue) :
effectif = 0
for compteur in range(len(L)) :
if L[compteur] == issue :
effectif = effectif + 1
return effectif / len(L)
def frequencegraph(L,issue) : # necessite matplotlib.pyplot
effectif = 0
X_liste = []
Y_liste = []
for compteur in range(len(L)) :
if L[compteur] == issue:
effectif = effectif + 1
X_liste.append(compteur)
Y_liste.append(effectif/(compteur + 1))
plt.plot(X_liste,Y_liste, "b.")
plt.show()
console
serie = [randint(1, 100) for i in range(20)]
serie
moyenne(serie)
quartiles(serie)
univers=[1, 2, 2, 4, 5, 6]
ech = echantillon(univers, 10)
ech
frequence(ech, 4)
frequencegraph(ech, 4)
5. Instruction conditionnelle
script
#Calcul du pgcd avec l'algorithme des différences
def pgcd(a,b) :
while a != b : # a différent de b
if a > b :
a = a - b
else :
b = b - a
return a
def irreductible(num,denum) :
d = pgcd(num, denum) # Appel à la fonction pgcd
if d == 1 : # d égal à 1
retour = "la fraction est irréductible"
else :
num2 = num // d # Division entière
denum2 = denum // d
msg = "la fraction " + str(num) + "/" + str(denum) + " se simplifie en " + str(num2) + "/" + str(denum2)
return(msg)
console
irreductible(25,15)
6. Arithmétique en seconde : pgcd et théorème de Césaro
script
from random import *
def pgcd(a,b) :
while b > 0 :
r = a % b
a = b
b = r
return a
# question 1 :
def simulation_cesaro(n):
f = 0
for i in range(n) :
a = randint(1, 100)
b = randint(1, 100)
if pgcd(a,b) == 1 :
f = f + 1
f = f / n
return f
# question 2 :
def proba_cesaro() :
num = 0
for a in range(1, 101) :
for b in range(1, 101) :
if pgcd(a,b) == 1 :
num = num + 1
p = num / (100**2)
return p
console
simulation_cesaro(100)
proba_cesaro()
B) Python en prolongement de Scratch et de la calculatrice
1. La Tortue Python en prolongement de Scratch
ATTENTION : étrangement, une fois sur deux, la console répondra par un message d’erreur finissant sur :
Il suffit de relancer la commande dans la console ...
script
from turtle import *
# Triangle équilateral
def triangle_equi(longueur) :
pensize(2)
up()
clear()
setheading(0)
goto(-100, -100)
down()
for i in range(3) :
forward(longueur) # La tortue avance de longueur
left(120) # La tortue tourne à gauche de 120°
up()
mainloop()
# 1. Polygone régulier à n côtés
def poly_reg(n, longueur) :
for i in range(n) :
forward(longueur) # La tortue avance de longueur
left(360 / n) # La tortue tourne à gauche de 360°/n
# Programme d'application du polygone régulier
def trace_poly_reg(n,longueur) :
pensize(2)
up()
clear()
setheading(0)
goto(-100, -100)
down()
poly_reg(n, longueur)
up()
mainloop()
console
triangle_equi(200)
trace_poly_reg(20, 50)
script à rajouter à la suite du script précédent
# 2. Rosace
def rosace() :
up()
clear()
for compteur in range(6) :
setheading(60 * compteur)
goto(0, 0)
down()
poly_reg(6, 100)
up()
mainloop()
console
rosace()
script à rajouter à la suite du script précédent
# 3. Pour aller plus loin
from math import sqrt
def prochain_point(u, v) :
return [u[0] + (v[0] - u[0]) / 4, u[1] + (v[1] - u[1]) / 4]
def carre(n) : # n : nb étapes avec carré de côté 300
speed(0)
color("black")
up()
clear()
goto(-200, -200)
down()
for compteur in range(n) :
setheading(18.43494882 * compteur)
poly_reg(4, 300 * (sqrt(10)/4)**compteur)
forward((300 * (sqrt(10) / 4)**compteur) / 4)
up()
def trace_figure(n) :
carre(n)
mainloop()
def fourmi(n) : # n : nb étapes avec carré de côté 300
carre(n)
longueur = 0
u = [-200, -200]
v = [-125, -200]
goto(-200, -200)
down()
color("red")
for compteur in range(n) :
setheading(18.43494882 * compteur)
forward((300 * (sqrt(10) / 4)**compteur) / 4)
longueur +=(300 * (sqrt(10) / 4)**compteur) / 4
u, v = v, prochain_point(u, v)
write(longueur)
up()
mainloop()
console
trace_figure(10)
fourmi(10)
2. Autour des courbes de fonctions
script
from math import *
import matplotlib.pyplot as plt
# Exploration des fonctions de variable réelle avec Python
def f(x) :
return x**2 - exp(x / 2)
def courbe(f,a,b) :
X = []
Y = []
for k in range(a, b + 1) :
X.append(k)
Y.append(f(k))
plt.plot(X,Y,"b-")
plt.show()
def courbe_pas(f, a, b, pas) :
X = []
Y = []
while a < b :
X.append(a)
Y.append(f(a))
a = a + pas
plt.plot(X,Y,"b-")
plt.show()
console
# Mise en oeuvre : courbe de la fonction f definie au debut, pas de 0.1
courbe_pas(f,-2, 10, 0.1)
# Mise en oeuvre : courbe de la fonction f definie au debut, pas de 0.1
courbe_pas(f,-2, 10, 0.1)
script
from math import *
import matplotlib.pyplot as plt
# Application à la parabole
def abscisse_minmax(a, b, c) :
return -b/(2 * a)
def image(a, b, c, x) :
return a* x**2 + b*x + c
def tracer_courbe(a, b, c, pas) :
# Calcul des coordonneées du min/max
# pour définir un intervalle l'incluant
x_minmax = abscisse_minmax(a, b, c)
y_minmax = image(a, b, c, x_minmax)
debut = x_minmax - 5
fin = x_minmax + 5
X_liste = []
Y_liste = []
curseur = debut
while curseur < fin :
X_liste.append(curseur)
Y_liste.append(image(a, b, c, curseur))
curseur = curseur + pas
plt.plot(X_liste , Y_liste , "r-")
# Un point bleu pour le sommet
plt.plot(x_minmax , y_minmax , "b.")
plt.grid() # Affichage de la grille
plt.show()
console
tracer_courbe(1, 2, 3, 0.1)
3. Méthode de Monte-Carlo
script
from random import *
from math import *
import matplotlib.pyplot as plt
def montecarlo(n) : # n étant le nombre de tirages de points aléatoires à effectuer
nb_points_endessous = 0
for compteur in range(n) :
x = random() # x prend une valeur aléatoire entre 0 et 1 selon la loi uniforme sur [0;1]
y = random()
if y < sqrt(1 - x**2) :
nb_points_endessous = nb_points_endessous + 1
# Gare à la double indentation !
f = nb_points_endessous / n
return f
def montecarlo2(n) : # n étant le nombre de tirages de points aléatoires à effectuer
plt.axis("equal") # repère orthonormé
plt.grid()
## initialisation des variables
nb_points_endessous = 0
X_liste_rouge = []
Y_liste_rouge = []
X_liste_bleu = []
Y_liste_bleu = []
for compteur in range(n) :
x = random() # x prend une valeur aléatoire entre 0 et 1 selon la loi uniforme sur [0;1]
y = random()
if y < sqrt(1-x**2) :
nb_points_endessous = nb_points_endessous + 1
X_liste_rouge.append(x) # le point est en-dessous, il est rouge
Y_liste_rouge.append(y) # On stocke ses coordonnées dans les listes "rouges"
else :
X_liste_bleu.append(x) # le point est en-dessous, il est rouge
Y_liste_bleu.append(y) # On stocke ses coordonnées dans les listes "bleues"
f = nb_points_endessous / n
# Tracé du graphique : les 2 tableaux de valeurs
# Premier tableau : les points rouges
plt.plot(X_liste_rouge , Y_liste_rouge , "r.")
# Second tableau : les points bleus
plt.plot(X_liste_bleu , Y_liste_bleu , "b.")
# Affichage du graphique
plt.show()
# renvoi de la fréquence
return f
console
montecarlo(1000)
montecarlo2(1000)
III - Python : pour aller plus loin
A) Manipulations plus expertes
1. Fonction exponentielle et courbe d’Euler
script
def methode_euler(x,y,h,n) :
X_liste=[x]
Y_liste=[y]
for i in range(n) :
x = x+h
y = y+y*h
X_liste.append(x)
Y_liste.append(y)
return X_liste,Y_liste
import matplotlib.pyplot as plt
# Configuration des axes
ax=plt.gca()
ax.spines["bottom"].set_position("zero") # axe positionné à 0
ax.spines["left"].set_position("zero") # axe positionné à 0
ax.spines["right"].set_color("none") # pas de couleur à droite
ax.spines["top"].set_color("none") # pas de couleur en haut
ax.xaxis.set_ticks_position("bottom") # Position des abscisses en dessous
ax.yaxis.set_ticks_position("left") # Position des ordonnées à gauche
plt.grid() # grille activée
# Partie de la courbe pour x > 0
X_liste1, Y_liste1 = methode_euler(0, 1, 0.1, 20)
# Partie de la courbe pour x < 0
X_liste2, Y_liste2 = methode_euler(0, 1, -0.1, 20)
# Concaténation des listes
X_liste = X_liste1 + X_liste2
Y_liste = Y_liste1 + Y_liste2
# Tracé du graphique
plt.plot(X_liste,Y_liste,"b.")
# Affichage du graphique
plt.show()
2. Algorithme de Kaprekar
script de la version 1
def grand(n) :
chiffre_unite = n % 10
chiffre_dizaine = (n % 100) // 10
chiffre_centaine = n // 100
maxi = max(chiffre_centaine,chiffre_dizaine,chiffre_unite)
mini = min(chiffre_centaine,chiffre_dizaine,chiffre_unite)
moyen = (chiffre_centaine+chiffre_dizaine+chiffre_unite)-(maxi+mini)
s = maxi*100 + moyen*10 + mini
return s
def petit(n) :
chiffre_unite = n % 10
chiffre_dizaine = (n % 100) // 10
chiffre_centaine = n // 100
maxi = max(chiffre_centaine,chiffre_dizaine,chiffre_unite)
mini = min(chiffre_centaine,chiffre_dizaine,chiffre_unite)
moyen = (chiffre_centaine+chiffre_dizaine+chiffre_unite)-(maxi+mini)
s = mini*100 + moyen*10 + maxi
return s
def kaprekar(n) :
u = n
liste_valeurs = [u]
while u != 495 :
u = grand(u) - petit(u)
liste_valeurs.append(u)
return liste_valeurs
console
kaprekar(217)
script de la version 2
# Dans toutes ces fonctions : la première ligne ("assert") est optionnelle.
# Elle sert à vérifier que le "n" entré est de type entier.
def petit_chaine(n) :
assert type(n) == int , "n n'est pas entier"
chaine = str(n) # Conversion de n en chaine
liste_triee = sorted(chaine) # Tri de la chaine ; le résultat est une liste
chaine = "".join(liste_triee) # Concaténation de la liste en une chaine
return int(chaine) # On retourne la chaine convertie en entier
def inversion(n) :
assert type(n) == int , "n n'est pas entier"
chaine = str(n) # Conversion de n en chaine
longueur = len(chaine) # Longueur de la chaine
r = "" # Initialisation de la variable de retour (chaine)
for k in range(longueur): # Reconstruction de la chaine
r = r + chaine[longueur-1-k] # en partant du dernier caractère
return int(r)
# Variante pour seulement 3 chiffres à inverser
def inversion_trois_chiffres(n): # n entier à 3 chiffres
assert type(n) == int , "n n'est pas entier"
N = str(n)
L = [N[2],N[1],N[0]]
return int("".join(L))
def kaprekar(n) :
assert type(n) == int, "n n'est pas entier"
u = n
liste_valeurs = [u]
while u != 495 :
u = petit_chaine(u)
u = inversion(u)-u
liste_valeurs.append(u)
return liste_valeurs
console
kaprekar(436)
script de la version 3
# Dans toutes ces fonctions : la première ligne ("assert") est optionnelle.
# Elle sert à vérifier que le "n" entré est de type entier.
def petit_par_minimum(n) :
assert type(n) == int , "n n'est pas entier"
liste = list(str(n)) # Conversion de n en chaine, puis en liste
k = len(liste) # Longueur de la liste
r = "" # Initialisation de la variable de retour (chaine)
while k > 0 : # Tant que la liste n'est pas vide
mini = min(liste) # Trouver le plus petit élément de la liste
liste.remove(mini) # L'enlever
r = r + mini # Le placer dans la chaine résultat
k = k - 1 # La taille de la liste décroit
return int(r) # On retourne la chaine convertie en entier
# Variante sans calcul de la longueur de la liste
def petit_par_minimum_variante(n) : # n entier à 3 chiffres
assert type(n) == int, "n n'est pas entier"
N1 = str(n)
L1 = [N1[0], N1[1], N1[2]]
L2 = []
while L1 != [] :
element = min(L1)
L1.remove(element)
L2.append(element)
return int("".join(L2))
def inversion(n) :
assert type(n) == int , "n n'est pas entier"
chaine = str(n) # Conversion de n en chaine
longueur = len(chaine) # Longueur de la chaine
r = "" # Initialisation de la variable de retour (chaine)
for k in range(longueur) : # Reconstruction de la chaine
r = r + chaine[longueur - 1 - k] # en partant du dernier caractère
return int(r)
# Variante pour seulement 3 chiffres à inverser
def inversion_trois_chiffres(n) : # n entier à 3 chiffres
N = str(n)
L = [N[2], N[1], N[0]]
return int("".join(L))
def kaprekar(n) :
assert type(n) == int , "n n'est pas entier"
u = n
liste_valeurs = [u]
while u != 495 :
u = petit_par_minimum(u)
u = inversion(u) - u
liste_valeurs.append(u)
return liste_valeurs
console
kaprekar(517)
3. La traversée du pont
script
import matplotlib.pyplot as plt
from random import *
def traversee_une_fois() :
# Réglages d'appoint de la fenêtre graphique
ax = plt.gca()
ax.spines["bottom"].set_position("zero")
plt.grid(True)
plt.plot([0, 10], [-2, -2], "-b") # Trace des
plt.plot([0, 10], [2,2], "-b") # bords du pont
plt.axis([0, 10, -3, 3])
# Initialisation des listes
# des abscisses et ordonnées du marcheur
X = [0]
Y = [0]
while X[-1] < 10 and abs(Y[-1]) <= 2 :
de = randint(0,2)
X.append(X[-1] + 1)
Y.append(Y[-1] + de - 1)
plt.plot(X, Y, "-or")
plt.show()
if abs(Y[-1]) <= 2 and X[-1] == 10 :
s = 1
else :
s = 0
return s
def traversee_une_fois_sans_graphe() :
X = [0]
Y = [0]
while X[-1] < 10 and abs(Y[-1]) <= 2 :
de = randint(0, 2)
X.append(X[-1] + 1)
Y.append(Y[-1] + de - 1)
if abs(Y[-1]) <= 2 and X[-1] == 10 :
s = 1
else :
s = 0
return s
def traversee_multiple(n): # n traversées
effectif = 0
for compteur in range(n) :
if traversee_une_fois_sans_graphe() == 1 :
effectif = effectif + 1
return effectif / n
def explore_chemin(n, y) :
r = 0
if n == 0 :
if abs(y) <= 2 :
r = 1
else :
r = 0
else :
if abs(y) <= 2 :
for p in [-1, 0, 1] :
r = r + explore_chemin(n - 1, y + p)
return r
console
traversee_une_fois()
traversee_multiple(10)
explore_chemin(3, 0)
B) Albums de vignettes et rareté ressentie : le problème du collectionneur
1. Écriture d’un algorithme en Python modélisant le problème
script
from random import *
from math import *
import matplotlib.pyplot as plt
######################################
# Ecriture d'un algorithme en Python modélisant le problème
######################################
def collection() :
ALBUM = []
FREQ = []
for compteur in range(480) :
ALBUM.append(0)
while min(ALBUM) == 0 :
ALBUM[randint(0, 479)] += 1
for compteur in range(480) :
FREQ.append(ALBUM[compteur] / sum(ALBUM))
p = 1 / 480
freq_mini = p - 1.96 * sqrt(p * (1 - p) / sum(ALBUM))
freq_maxi = p + 1.96 * sqrt(p * (1 - p) / sum(ALBUM))
return max(ALBUM), sum(ALBUM), freq_mini, freq_maxi, FREQ
console
collection()
2. Taille de la collection variable
script à rajouter à la suite du script précédent
######################################
# Taille de la collection variable
######################################
def album(n) : # n taille de la collection
ALBUM = []
for compteur in range(n) :
ALBUM.append(0)
while min(ALBUM) == 0 :
ALBUM[randint(0, n - 1)] += 1
return sum(ALBUM)
def achats_moyen(n,e) : # n taille collection, e nombre d'essais
nb_achats = 0
for compteur in range(e) :
nb_achats = nb_achats + album(n)
return nb_achats / e
def album_graph() :
X_liste = []
Y_liste = []
for compteur in range(1, 480+1) :
X_liste.append(compteur)
Y_liste.append(achats_moyen(compteur, 10))
plt.plot(X_liste, Y_liste,"b.")
plt.show()
console
album_graph()
3. Nombre de collectionneurs variable
script à rajouter à la suite du script précédent
######################################
# Nombre de collectionneurs variables
######################################
def album_echange(n,p) : # n taille collection, p collectionneurs
ALBUM = []
for compteur in range(n) :
ALBUM.append(0)
while min(ALBUM) < p :
ALBUM[randint(0,n-1)] += 1
return sum(ALBUM)
def achats_moyen2(n, p, e) : # n taille collection, p collectionneurs, e nombre d'essais
nb_achats = 0
for compteur in range(e) :
nb_achats = nb_achats + album_echange(n, p)
return (nb_achats / e) / p
def album_graph2(n, p, e) : # n taille collection, p collectionneurs, e nombre d'essais
X_liste = []
Y_liste = []
for compteur in range(1, p + 1) :
X_liste.append(compteur)
Y_liste.append(achats_moyen2(n,compteur,e))
plt.plot(X_liste, Y_liste,"b.")
plt.show()
console
album_graph2(200, 20, 100)
album_graph2(480, 2, 10) # Si votre ordinateur le permet ...