TP1 đ„ Calcul de racines
Un ordinateur, câest trĂšs rapide, mais pas trĂšs intelligent. On va en profiter pour lui faire calculer la racine carrĂ©e⊠de façon trĂšs bĂȘte.
Vous devez implĂ©menter deux mĂ©thodes de calcul « brutales » dâune racine carrĂ©e :
- Une méthode chiffre par chiffre, par essais successifs
- Une méthode par dichotomie (recherche binaire)
Puis vous devrez :
- Comparer ces méthodes à la fonction standard
math.sqrt()en termes de performance - Ătendre le calcul Ă une racine n-iĂšme
Ă la fin de ce travail, vous serez capable de :
- Utiliser des variables, types de base, opérateurs et fonctions
- Utiliser des structures conditionnelles et expressions logiques
- Utiliser des structures répétitives
- Décomposer un algorithme en fonctions réutilisables
- Ăvaluer la performance dâun algorithme avec des mesures de temps
- Appliquer la logique pour résoudre un problÚme numérique complexe sans bibliothÚque
- Valider le fonctionnement de vos algorithmes Ă l'aide de jeux d'essais
Pour faire ce TP, vous devez créer un nouveau projet PyCharm et utiliser un répertoire GitHub dÚs le début.
- Si votre enseignant utilise GitHub Classroom, utilisez le répertoire créé par votre enseignant.
- Si votre enseignant n'utilise pas GitHub Classroom, créez votre propre répertoire et partagez-lui l'accÚs en lecture.
âđ€ đ đ«
Si votre travail est suspecté de plagiat (code copié d'un.e autre étudiant.e, code généré par IA, notions non abordées en classe, etc.), deux choses peuvent se produire :
- Le plagiat est prouvé par nos outils : note de 0, automatiquement.
- Le plagiat est plutÎt évident, mais une validation est requise : vous serez convoqué(e) au bureau de votre enseignant(e). Vous devrez répondre à certaines questions pour prouver que vous comprenez et maßtrisez le code qui a été utilisé. Si vous ne réussissez pas à répondre à certaines questions, vous aurez la note de 0 (si vous ne comprenez pas votre propre code, c'est que vous avez plagié, d'une maniÚre ou d'une autre).
- Au moins 5 commits de tailles comparables (il n'y a pas un commit avec tout dedans et les autres vides)
- Les commits décrivent l'avancement du projet dans un français sans faute (voir instructions)
- Chaque fonction doit ĂȘtre documentĂ©e Ă l'aide d'un docstring dans un français sans faute : description de la fonction, paramĂštres, valeur retournĂ©e, exceptions possibles, etc.
- Votre projet doit contenir exactement 3 scripts Python et rien d'autre :
tp1/
âââ racine.py # doit contenir vos 2 fonctions pour les 2 mĂ©thodes diffĂ©rentes du calcul de la racine carrĂ©e
âââ validation.py # doit contenir vos tests validant le bon fonctionnement des fonctions du module "racine.py"
âââ performance.py # doit contenir vos tests de performance des fonctions du module "racine.py"
Dans le script racine.py, vous devez créer 2 fonctions, soit une pour chacune des deux méthodes du calcul de la racine carrée d'un nombre.
Pour décrire ces méthodes de calcul, supposons que nous cherchons la racine carrée de .
On construit le résultat décimale par décimale, en commençant par la plus grande.
Pour , on commence donc par l'unité :
Comme est entre et , on sait que la racine de est entre et , car est plus grand que . Donc, la racine de ressemble Ă point quelque chose (ex : ).
On passe à la premiÚre décimale :
La racine de ressemble donc Ă , car est plus grand que .
Et on fait ainsi de suite pour les dĂ©cimales suivantes. On fait des essais successifs pour chaque dĂ©cimale jusquâĂ la prĂ©cision dĂ©sirĂ©e.
On cherche la racine dans un intervalle qui se réduit de moitié à chaque étape.
On commence par déterminer l'intervalle initial :
Par la suite, on va réduire l'intervalle de moitié de la maniÚre suivante :
- On calcule le , puis :
On rĂ©pĂšte l'opĂ©ration de rĂ©duction de l'intervalle jusqu'Ă ce que la largeur de lâintervalle () soit infĂ©rieure Ă la prĂ©cision souhaitĂ©e. Ă ce moment, la racine est approximĂ©e par .
Exemple (racine de , avec décimales de précision)
On arrĂȘte quand la largeur de lâintervalle :
- â â on continue
- â â on continue
- â â on continue
- ...
- â â on arrĂȘte
Résultat (arrondi à décimales).
Les 2 fonctions doivent prendre un seul paramÚtre, un nombre, et retourner sa racine carrée.
La prĂ©cision doit ĂȘtre entre 4 et 12 dĂ©cimales Ă votre discrĂ©tion.
SupĂ©rieur Ă 12 dĂ©cimales, le calcul peut prendre trop de temps et le programme peut arrĂȘter de fonctionner.
Mettez la précision de votre choix dans une variable globale constante (ex : PRECISION = 8), avant vos définitions de fonctions.
RACINE PROPREVotre module racine doit contenir uniquement ces 2 fonctions et aucune instruction dans ce module ne doit ĂȘtre placĂ©e Ă l'extĂ©rieur de ces 2 fonctions (sauf la constante).
Dans le script validation.py, importez le module racine puis tester vos 2 fonctions Ă l'aide d'appels de fonction similaires Ă ceux-ci :
try:
print("*** VĂRIFICATION DU BON FONCTIONNEMENT ***")
print("attendu : 0.0 ")
print(" obtenu :", racine.nom_de_la_fonction(0))
print("attendu : 0.31622776601683794")
print(" obtenu :", racine.nom_de_la_fonction(0.1))
print("attendu : 0.4472135954999579")
print(" obtenu :", racine.nom_de_la_fonction(0.2))
print("attendu : 0.9486832980505138")
print(" obtenu :", racine.nom_de_la_fonction(0.9))
print("attendu : 2.8284271247461903")
print(" obtenu :", racine.nom_de_la_fonction(8))
print("attendu : 3.0")
print(" obtenu :", racine.nom_de_la_fonction(9))
print("attendu : 9.0")
print(" obtenu :", racine.nom_de_la_fonction(81))
print("attendu : 11.090536506409418")
print(" obtenu :", racine.nom_de_la_fonction(123))
print("attendu : 31.606961258558215")
print(" obtenu :", racine.nom_de_la_fonction(999))
print(nom_de_la_fonction(-3)) # Doit lever une exception
except e as Exception:
print(f"erreur {e}")
Remarque : les résultats attendus affichés sont les résultats de math.sqrt().
Assurez-vous pour tous les tests que les décimales obtenues sont les bonnes et les arrondis sont cohérents selon votre niveau de précision.
Voici 2 exemples d'erreurs :
attendu : 2.8284271247461903
obtenu : 2.82842 # Mauvaise rĂ©ponse, car le dernier 2 aurait dĂ» ĂȘtre un 3
attendu : 2.8284271247461903
obtenu : 2.8284265122345312 # Mauvaise réponse, car certaines décimales sont fausses
Dans le script performance.py, vous allez comparer vos 2 fonctions du module racine avec la fonction math.sqrt() pour comparer leurs performances.
Pour chacune des 3 méthodes (fonction 1, fonction 2, math.sqrt()) vous devez :
- à l'aide d'une boucle, appeler la fonction 100 000 fois avec un nombre flottant aléatoire
- Utilisez un nombre flottant aléatoire différent à chaque appel
- Les nombres flottants gĂ©nĂ©rĂ©s doivent ĂȘtre compris entre 10 et 10 000
- Calculer le temps total nécessaire pour réaliser les 100 000 appels (en ms)
- Afficher :
- Le temps de calcul total pour les 100 000 appels (en millisecondes)
- Le temps moyen par appel de la fonction
Exemple d'affichage attendu (les valeurs sont fictives) :
Résultats des performances :
Méthode 1 (chiffre par chiffre) : Temps total = 150 ms, Temps moyen = 0.0015 ms
Méthode 2 (dichotomie) : Temps total = 50 ms, Temps moyen = 0.0005 ms
Méthode 3 (math.sqrt) : Temps total = 10 ms, Temps moyen = 0.0001 ms
Vous devez transformer vos 2 fonctions du module racine afin qu'elles puissent calculer la racine n-iĂšme d'un nombre.
Pour cela :
- Vous devez ajouter un paramĂštre
baseĂ vos fonctions (ex. : 2 pour racine carrĂ©e, 3 pour racine cubique, etc.). Ce paramĂštre doit ĂȘtre optionnel et avoir par dĂ©faut la valeur 2. - La racine carrĂ©e d'un nombre nĂ©gatif doit ĂȘtre possible uniquement si la base est impaire (ex. : la racine cubique de -27 est -3), sinon une exception doit encore ĂȘtre levĂ©e.
- La valeur du paramĂštre
basene doit pas ĂȘtre infĂ©rieure Ă 2 (validation de la valeur passĂ©e en paramĂštre nĂ©cessaire).
Appelez chacune de ces 2 nouvelles fonctions et affichez les résultats pour la racine carrée, cubique et quatriÚme de 8, 9, 81 et 123.
try:
print("*** RACINE DEUX ***")
print("attendu : 2.8284271247461903")
print(" obtenu :", racine.nom_de_la_fonction(8,2))
print("attendu : 3.0")
print(" obtenu :", racine.nom_de_la_fonction(9,2))
print("attendu : 9.0")
print(" obtenu :", racine.nom_de_la_fonction(81,2))
print("attendu : 11.090536506409418")
print(" obtenu :", racine.nom_de_la_fonction(123,2))
print("*** RACINE CUBIQUE ***")
print("attendu : 2.0")
print(" obtenu :", racine.nom_de_la_fonction(8,3))
print("attendu : 2.080083823051904")
print(" obtenu :", racine.nom_de_la_fonction(9,3))
print("attendu : 4.3267487109222245")
print(" obtenu :", racine.nom_de_la_fonction(81,3))
print("attendu : 4.97318983326859")
print(" obtenu :", racine.nom_de_la_fonction(123,3))
print("*** RACINE QUATRIEME ***")
print("attendu : 1.681792830507429")
print(" obtenu :", racine.nom_de_la_fonction(8,4))
print("attendu : 1.7320508075688772")
print(" obtenu :", racine.nom_de_la_fonction(9,4))
print("attendu : 3.0")
print(" obtenu :", racine.nom_de_la_fonction(81,4))
print("attendu : 3.3302457126178266")
print(" obtenu :", racine.nom_de_la_fonction(123,4))
except e as Exception:
print(f"erreur {e}")
Le projet fonctionne sans plantage et correctement, et le code est clair et facile à lire. Ce pointage fonctionne en négatif. Si le projet fonctionne correctement en tout temps, vous conservez votre note. Dans le cas contraire, vous perdez des points avec un maximum de 2.
- Plantage -1 point
- Code illisible -1 point
- Information affichée incohérente -1 point
- Autre cas...