Lyc ´ee Thiers
TP PYTHON - 02 - CORRECTION
PARTIE A - Quelques rappels de cours
1. D´efinir des fonctions
[Qu. 1] Deux fonctions très simples ...
Après avoir saisi dans l’éditeur le code source suivant et l’avoir validé
def perimetreC(r):
print(2*pi*r)
def plusProcheEntier(x):
if x % 1 < 0.5:
return x//1
else:
return x//1+1
On voit apparaître (dans le shell) un message (executing lines 1 to 8 of "tp-2.py") indiquant que
l’interprétation s’est déroulée normalement.
Ensuite, l’instruction
>>> perimetreC(1); plusProcheEntier(-1.3)
déclenche une erreur :
...
NameError: global name ’pi’ is not defined
ce qui est normal puisque la constante pi n’est pas définie par défaut. On rectifie en ajoutant (juste
avant la définition de perimetreC) :
from math import pi
après quoi, les choses se déroulent comme souhaité :
>>> perimetreC(1); plusProcheEntier(-1.3)
6.283185307179586
-1.0
[Qu. 2] Pour obtenir le multiple de ple plus proche de x,il sut de calculer l’entier le plus proche de
x/ppuis de le multiplier par p.Bien entendu, cela n’a aucun sens si pest nul, et ce cas doit donc être
traité à part :
TP PYTHON - 02 - CORRECTION 2
def plusProche(x, p):
if p == 0:
return 0
else:
return plusProcheEntier(x/p) * p
[Qu. 3] Permutation de deux valeurs
1) On essaie le script proposé ...
2) ... et la permutation n’a pas eu lieu ! Cela s’explique par le fait que les objets référencés par aet
bne sont pas mutables . Signalons que les variables locales xet y(qui sont créées au moment de
l’invocation de la fonction permute), après avoir été initialisées à 1 et 2 respectivement, voient
leurs valeurs eectivement échangées : on peut le constater en ajoutant l’instruction print(x, y)
dans le corps de la fonction (à la suite des trois aectations). Mais, encore une fois, cela reste sans
eet sur aet b. Voilà ce qui se passe (en bleu les variables locales) :
ab
12
bab
12
b
x y
ab
12
b
x yz
ab
12
b
x yz
ab
12
b
x yz
Appel z=x
x=y
y=zSortie
a
12
b
mercredi 9 octobre 13
3) Une solution : renvoyer le couple inversé, avec la fonction
def permuteMieux(x, y):
return (y, x)
puis exécuter l’instruction (a, b) = permuteMieux(a, b)
2. manipulations avanc ´ees sur les listes
[Qu. 4] L’expression [k**2 for k in range(1,11)] calcule la liste des carrés des entiers de 1 à 10.
En s’inspirant de cet exemple, écrire :
1) L’expression suivante calcule la liste des 10 premiers nombres impairs :
>>> [2*k-1 for k in range(1,11)]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
2) Fonction achant la liste des npremiers nombres impairs :
def affiche_impairs(n):
print([2*k-1 for k in range(1, n + 1)])
3) Fonction renvoyant la liste des npremiers nombres impairs :
def impairs(n):
return [2*k-1 for k in range(1, n + 1)]
TP PYTHON - 02 - CORRECTION 3
[Qu. 5]
1) Rien à signaler :)
2) Les deux versions demandées :
2.a) Première version, avec une liste en compréhension :
def non_multiples(a, b, d):
return [k for k in range(a, b + 1) if k % d != 0]
2.b) Deuxième version, en supprimant des termes :
def non_multiples(a, b, d):
L = [k for k in range(a, b+1)]
for n in L:
ifn%d==0:
L.remove(n)
return L
PARTIE B - Questions de divisibilité
3. Nombres parfaits
[Qu. 6] Liste croissante des diviseurs stricts d’un entier :
def diviseurs_stricts(n):
L = []
for d in range(1, n // 2 + 1):
ifn%d==0:
L.append(d)
return L
ou, plus simplement :
def diviseurs_stricts(n):
return [d for d in range(1, n // 2 + 1) if n % d == 0]
Attention ! ! Ce qui suit ne donne pas le résultat escompté. Essayer de comprendre pour quelle raison
...
def divs(n):
L = [k for k in range(1, n//2 + 1)]
for k in L:
if n % k != 0:
L.remove(k)
return L
On retiendra que c’est a priori une mauvaise idée de modifier, au fur et à mesure qu’une boucle se
déroule, la liste parcourue pour établir cette boucle.
[Qu. 7] Prédicat indiquant si un entier est parfait :
def parfait(n):
return sum(diviseurs_stricts(n)) == n
La fonction (prédéfinie) sum, lorsqu’elle est appliquée à une liste, renvoie la somme de ses termes.
[Qu. 8] Nombres parfaits inférieurs ou égaux à 104:
TP PYTHON - 02 - CORRECTION 4
def liste_parfaits(nmax):
for n in range(1, nmax + 1):
if parfait(n):
print(n)
>>> liste_parfaits(10**4)
6
28
496
8128
4. Nombres premiers,parfaits,amicaux
[Qu. 9] Crible d’Eratosthène, permière version :
def crible(n):
# On démarre avec la liste des entiers de 2 à n
primes_list = [k for k in range(2, n + 1)]
i=0
while i < len(primes_list) - 1:
# L est la liste des multiples stricts du primes_list[i]
L = [k for k in primes_list[i+1:] if k % primes_list[i] == 0]
# on supprime de primes_list[] chaque terme de L
for k in L:
primes_list.remove(k)
i += 1
return primes_list
[Qu. 10] Si n<P,il existe des entiers a,b>1 tels que n=ab.L’hypothèse a>net b>n
entraînerait ab >n,et c’est absurde. Donc l’un au moins des entiers aou best compris entre 2 et jnk.
[Qu. 11] On voit par récurrence qu’à l’issue de chaque tour de boucle, les entiers cochés sont des
nombres premiers consécutifs. C’est le cas au début, puisque 2 est le plus petit nombre premier. Si
cette propriété est vraie à l’issue d’un certain tour de boucle, alors le plus petit entier non coché est
premier, sans quoi il serait multiple d’un nombre premier plus petit que lui et donc aurait été coché
auparavant. En cochant cet entier et en supprimant ses multiples stricts, on préserve donc la propriété
un cran plus loin.
Lorsque tous les nombres premiers inférieurs ou égaux à jnkont été cochés , il devient inutile de
poursuivre car les entiers non cochés qui restent sont tous premiers (et donc la liste des nombres
premiers inférieurs ou égaux à nest établie). En eet, un entier qnon coché ne possède aucun diviseur
entre 2 et jnket donc aucun diviseur entre 2 et jqk: il est premier d’après le point précédent.
Deuxième version du crible d’Eratosthène :
def crible(n):
primes_list = [k for k in range(2, n + 1)]
i=0
while primes_list[i] ** 2 <= n:
L = [k for k in primes_list[i+1:] if k % primes_list[i] == 0]
for k in L:
primes_list.remove(k)
i += 1
return primes_list
TP PYTHON - 02 - CORRECTION 5
[Qu. 12] Notons Dl’ensemble des diviseurs de nsupérieurs ou égaux à 2.Soit ple plus petit élément
de D.Si pn’était pas premier, il possèderait un facteur premier qqui serait donc élément de Det
strictement inférieur à p: absurde !
On en déduit que pour savoir si nest premier, il sut de parcourir (dans l’ordre croissant) la liste L
des entiers entre 2 et jnk: dès qu’un diviseur de nest détecté, on interrompt le parcours et l’on sait
que n<P.Et si aucun diviseur de nne figure dans L,alors nP.
On peut gagner un facteur 2 en commençant par tester la parité de npuis (si nest impair) en ne
cherchant plus que des diviseurs impairs. Noter que la présence de l’instruction return dans la
branche “if” d’un test dispense d’utiliser “else” :
def ppfp(n):
ifn%2==0:
return 2
d=3
while d * d <= n:
ifn%d==0:
return d
d += 2
return n
[Qu. 13] Facteurs premiers de n=5888069 (avec répétition) :
while n > 1:
p = ppfp(n)
print(p)
n //= p
11
17
23
37
37
[Qu. 14] Liste “brute” des facteurs premiers d’un entier n>1 :
def pre_dfp(n):
L = []
q=n
while q > 1:
p = ppfp(q)
L.append(p)
q=q//p
return L
>>> pre_dfp(5888069)
[11, 17, 23, 37, 37]
>>> pre_dfp(1)
[]
[Qu. 15]
1) Réduction d’une liste en une liste de couples (valeur, nb de termes successifs égaux à cette valeur) :
1 / 9 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans l'interface ou les textes ? Ou savez-vous comment améliorer l'interface utilisateur de StudyLib ? N'hésitez pas à envoyer vos suggestions. C'est très important pour nous!