son corrigé

publicité
Gaudino, casier 5
P.C.S.I. 834
1
Corrigé du Devoir Maison d’Info 2016/2017
1. Écrire une fonction qui prend en argument une liste de flottants qu’on sait non vide, et qui affiche (attention,
pas renvoie) sa moyenne.
def moyenne(liste):
| somme = 0. #le . pour avoir un flottant
| for x in liste:
|
| somme = somme + x
| #fin for
| print( somme / float(len(liste)) )#float pour éviter le transtypage
#fin def
2. Écrire une fonction verif ication qui prend en argument une liste non vide, et qui vérifie que c’est une liste
d’entiers. Elle retournera un booléen. On essaiera de minimiser les calculs.
En Python, le fait pour n d’être un entier est donné par le test isinstance(n, int) qui renvoie un booléen :
isinstance(4, int) vaut True, isinstance(4.5, int) vaut False.
On passe en revue toute la liste, et on teste l’appartenance. Si on rencontre autre-chose qu’un entier, on stoppe
tout avec un return. Si on sort de la boucle for, c’est que tous sont des entiers. On peut aussi programmer avec
un drapeau et un while.
def verification(liste):
| for n in liste:
|
| if isinstance(n, int) == False:
|
|
| return False
|
| #fin si
| #fin for
| return True
#fin def
3. Pour tester qu’il s’agit d’une liste d’entiers vraiment non vide, on propose la commande suivante :
verification(liste) and ( len(liste) != 0 )
Expliquer l’erreur, et corriger.
Il faut vérifier que la liste n’est pas vide avant d’utiliser verification(liste) : le caractère paresseux du test fait
qu’il suffit d’intervertir les tests. En fait, le code proposé plus haut ne génère pas d’erreur, car la boucle for
est alors vide : verification(liste) renvoie True, et comme le ( len(liste) != 0 ) renvoie False, cela marche. Mais
d’autres fonctions verification pourraient générer une erreur en respectant les spécifications requises.
4. Écrire une fonction sigma qui prend un nombre entier écrit en base dix, et qui retourne la somme de ses digits.
Par exemple sigma(12345) = 1 + 2 + 3 + 4 + 5 = 15. On rappelle que la fonction int() convertit un caractère
en entier, et que la fonction str() convertit un entier en caractère (ou en chaine si l’entier n’est pas un chiffre).
Il existe des fonctions évoluées en Python pour extraire ces valeurs, mais ce n’est pas le but ! On peut suivre
deux pistes : faire de l’arithmétique pour calculer ces digits, ou au contraire utiliser les chaînes de caractères et
faire des conversions (dans les deux sens).
def somme(n):
| somme = 0
| chaine = str(n)
| for x in chaine:
|
| somme = somme + int(x)
| #fin for
| return somme
#fin def
5. (a) Expliquer à quoi sert le code suivant. En particulier, préciser les valeurs choisies pour le range range(1,len(l),1).
Que contiendra la variable resultat à la fin ?
L = [0,1,3,2]
resultat = True
for i in range(1,len(L),1):
| if L[i-1] > L[i]:
|
| resultat = False
1
Le code compare les valeurs de la liste deux-à-deux. Le range commence à 1 car le premier couple comparé
est le couple L[0], L[1] et pas L[−1], L[0]. Le range finit à len(L) car le dernier indice effectif est comme
d’habitude len(L) − 1. Le drapeau resultat bascule à False (et y reste) lorsqu’il existe deux valeurs consécutives classées dans l’ordre décroissant. Ce code teste donc si la liste est classée par ordre croissant . Dans
notre exemple, resultat vaut False (à cause de la dernière comparaison).
(b) Que se passe-t-il si on met un range range(0,len(L),1) ? Dans quel cas la variable résultat contient-elle
alors True à la fin (on attend une réponse qui porte sur L) ?
Il n’y a aura pas d’erreur, puisque L[−1] est la dernière valeur de la liste. Ce code testera donc si la liste
suivante est classée (on note n sa longueur) : la liste initiale à qui on rajoute un terme devant
h
i
L[−1], L[0], L[1], · · · , L[n − 2], L[n − 1]
En particulier, le dernier terme est aussi le premier ! Le programme détecte que les termes sont tous égaux.
6. Le jeu des erreurs : ce code contient de nombreuses erreurs (plus celles involontaires, probablement. . .). Corrigezles.
On écrit une fonction premjum, qui prend un argument n, et qui calcule la liste des couples d’entiers [k, k + 2]
premiers jumeaux, c’est-à-dire tels que k et k + 2 sont premiers, avec k ≤ n. La liste jum sera donc quelque
chose comme :
h
i
[3, 5], [5, 7], [11, 13], . . .
On commence à k = 2 car 1 n’est pas premier.
On veut que la fonction retourne la liste finale (stockée dans la variable jum) pour une utilisation ultérieure
en dehors de la fonction (ici, le calcul de sa longueur pour n déjà connu de Python).
1
2
3
4
5
6
7
def premjum(n)
| jum = 0
| for k in range(2,n,1):
|
| if isprime(k) = true and isprime(k+2) = true :
|
|
| jum = jum + [k,k+2]
|
| print(jum)
print(len(jum)) #ligne qui doit rester en dehors de la fonction
C’est un festival :
(a) il manque les : à la fin du def
(b) on initialise à la liste vide [], pas à l’entier 0
(c) il faut aller jusqu’à n+1 pour tester k = n
(d) le test d’égalité est un ==, et True prend une majuscule
(e) la nouvelle valeur à ajouter est elle-même un couple (on concatène deux listes, et pas on ajoute un entier à
une liste – ce qui n’a pas de sens) : il faut ajouter +[[k, k + 2]].
(f) le print est un mauvais choix : on affichera le résultat mais sans pouvoir le réutiliser. On a besoin d’un
return.
De plus, il est au mauvais endroit à cause de son indentation : dans le for, ce print va afficher successivement
toutes les listes intermédiaires, et pas la finale uniquement. Avec un return, c’est pire : la boucle for est
stoppée dès le premier tour de boucle.
(g) jum est locale : elle ne sort pas de la fonction ! De plus, n est une variable muette de la fonction : la valeur
numérique déjà connue de Python ne sera pas réutilisée de cette manière.
def premjum(n):
| jum = []
| for k in range(2,n+1,1):
|
| if isprime(k) == True and isprime(k+2) == True :
|
|
| jum = jum + [ [k,k+2] ] #ou jum.append([k,k+2])
| return jum
print( len( premjum(n) ) ) #espaces pour mieux lire
2
Téléchargement