Enquêter sur une erreur dans un calcul de $\pi$
La somme des inverses des carrés des nombres entiers converge vers $\dfrac{\pi^2}{6}$.
$$\sum_{k=1}^{\infty} \dfrac{1}{k^2} = \dfrac{\pi^2}{6}$$
On utilise cette formule pour trouver une approximation de $\pi$.
|
|
-
Lors de l’exécution de
approxpi(1000)
une exception est levée à l’exécution de la ligne 4. Quel est le type d’exception ?a.
ValueError
b.SyntaxError
c.TypeError
d.ZeroDivisionError
e.IndexError
f.NameError
Réponse
|
|
- Bien que l’exécution soit interrompue ligne 4, la source de l’erreur est ailleurs
Expliquer d’où provient l’erreur et proposer un correctif.
Réponse
- $k$ ne doit jamais prendre la valeur 0, donc
range
doit commencer à 1. - Si on veut que la dernière valeur de la boucle soit $n$, comme l’indique le commentaire dans le code, la borne supérieure doit être égale à $n+1$.
|
|
ou
|
|
Enquêter sur une erreur de calcul de produit scalaire
Le produit scalaire de deux vecteurs $\vec{u}$ et $\vec{v}$ de l’espace, de coordonnées respectives $(u_1, u_2, u_3)$ et $(v_1, v_2, v_3)$, est le nombre réel $u_1 v_1 + u_2 v_2 + u_3 v_3$.
Le code suivant permet de calculer des produits scalaires. Il est testé sur des vecteurs de l’espace choisis au hasard :
|
|
Prises séparément, les deux fonctions semblent opérationnelles :
|
|
Pourtant, lorsqu’on exécute la fonction main()
, le programme n’affiche que quelques produits scalaires (ici 12, 118 et −104) puis lève une exception :
|
|
- En analysant le
traceback
donné plus haut, indiquer quel est le type d’exception qui a été levée, et sur quelle ligne de code.
Réponse
- L’exception est de type
IndexError
. - Cette exception est levée à la ligne 9 du code.
- Sur la ligne en question, qu’est-ce qui pourrait avoir provoqué l’erreur ?
Réponse
L’exception IndexError
est levée si on essaie d’accéder à une valeur stockée dans une séquence en utilisant un indice invalide, par exemple si on essaie d’accéder à la quatrième valeur d’une liste, d’un tuple ou d’une chaîne de caractères qui n’en contient que 3. À la ligne 9, l’exception a donc été provoquée par l’accès à v1[k]
ou par l’accès à v2[k]
, car l’un des deux vecteurs (ou les deux) n’a pas de case pour la valeur de k
à ce tour de boucle. Or k
varie entre 0
et len(v1)
. On en déduit que c’est le vecteur v2
qui est trop court : soit v1
a plus de 3 valeurs (et v2
en a bien 3), soit v1
a bien 3 valeurs et il en manque dans v2
.
- Proposer d’ajouter un affichage
print(...)
à un endroit du programme pour essayer de mettre en évidence la nature du problème, puis exécuter à nouveau le code.
Réponse
Il faut vérifier quelles valeur de v1
et v2
.
|
|
- Expliquer l’erreur. Pourquoi ne se produit-elle pas toujours au même moment ?
Réponse
- Exemple de résultat :
|
|
- L’erreur a pour origine la façon dont
v1
etv2
sont créés :
|
|
On constate que si val
prend la valeur 0 rien n’est ajouté à la liste v
. On ne peut donc pas être certain de la longueur de v
puisque le nombre de tour de boucle est lui fixé.
- Proposer un correctif.
Réponse
La solution consiste à utiliser plutôt une boucle TantQue
avec un test sur la longueur de la liste générée.
|
|
Calculer la valeur d’un mot : arithmancie
On souhaite associer une valeur numérique à une chaîne de caractères. La valeur associée à la chaîne est la somme des valeurs associées à chacun des caractères qui la composent. Aux lettres non accentuées de A à Z, qu’elles soient en minuscules ou en majuscules, on associe leur numéro d’ordre dans l’alphabet, de 1 à 26. À tous les autres symboles (lettres accentuées, chiffres, espaces, ponctuations), on associe la valeur 0.
On rappelle que ord("a")
donne le code numérique associé à la lettre "a"
passée en paramètre.
La chaîne string.ascii_uppercase
est définie dans le module string
et vaut "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
.
- Pour chacune des propositions suivantes, proposer un test qui montre que la fonction ne répond pas au cahier des charges de l’énoncé.
Proposition 1
|
|
Proposition 2
|
|
Proposition 3
|
|
-
Proposer un ensemble complet de tests pour la fonction que l’on veut créer (on nomme cette fonction
valeur
). -
Proposer le code de cette fonction (il est possible de s’inspirer d’une des versions vues à la question 1. en la corrigeant). Ne pas oublier de vérifier que la fonction écrite passe bien les tests de la question 2.
Module d’arithmétique
Créer un module contenu dans un fichier nommé arithmetique.py
. Ce module contient des fonctions sur l’arithmétique des nombres entiers. En particulier :
– expo
qui prend en paramètres les entiers $a$, $b$ et $n$ et calcule le reste de la division par $n$ de $a^b$ ;
– pgcd
qui prend en paramètres les entiers $a$ et $b$ et renvoie le plus grand diviseur commun de $a$ et $b$ (définition du pgcd) ;
– decomposition
qui prend un entier positif $n$ en paramètre et renvoie la liste de ses facteurs premiers ainsi que leur multiplicité.
- Créer le module avec les trois fonctions proposées.
- Proposer des dosctrings pour le module et les trois fonctions décrites. Annoter les fonctions avec les annotations de type.
- Ajouter quelques tests sous forme d’assertions.
Algorithme naïf pour la fonction decomposition
La première idée consiste à balayer la liste des nombres premiers en testant si le nombre premier $p$ divise $n$. Si oui, on recommence l’algorithme pour $n//p$, en ne testant que les diviseurs premiers encore envisageables. On s’arrête quand le nombre premier à tester devient supérieur à la racine carrée du nombre qu’il est censé diviser.
Ainsi pour décomposer 2088 en produit de facteurs premiers
2088 | 2 | 2 divise 2088 le quotient est 1044 | |
1044 | 2 | 2 divise 1044, le quotient est 522 | |
522 | 2 | 2 divise 522, le quotient est 261 | |
261 | 3 | 2 ne divise pas 261, mais 3 divise 261 et le quotient est 87 | |
87 | 3 | 3 divise 87 et le quotient est 29 | |
29 | ni 3, ni 5 ne divisent 29 et $7^2$ est plus grand que 29 (fin) |
On obtient la décomposition attendue : $2088=2^3 \times 3^2 \times 29$.