Un musée souhaite informatiser la gestion de son stock d’objets archéologiques. Dans les anciens registres les quantités des objets sont exprimées en chiffres romains.
On souhaite développer une application Python munie de deux interfaces graphiques qui permet :
- de saisir la désignation d’un objet archéologique et sa quantité en chiffres romains,
- de convertir la quantité en chiffres romains en son équivalent décimal,
- d’enregistrer l’objet dans un fichier d’enregistrements,
- de consulter et d’afficher de manière triée les objets enregistrés.
On supposera qu’un nombre romain est une chaine de caractères non vide, composée de chiffres romains choisis uniquement parmi les lettres suivantes : I, V, X, L, C, D et M et qu’elle ne contient pas plus de trois lettres identiques consécutives.
Chaque chiffre correspond à une valeur décimale comme indiqué dans le tableau ci-dessous :

Pour convertir un nombre romain en un nombre décimal, on parcourt la chaîne de gauche à droite en appliquant les règles suivantes :
- Si un chiffre romain a une valeur supérieure ou égale à celle du chiffre suivant, on ajoute sa valeur.
- Si un chiffre romain a une valeur strictement inférieure à celle du chiffre suivant, on retranche sa valeur.
- Si un chiffre romain est en dernière position, on ajoute sa valeur.
Exemples :
- CXCII vaut 192 en décimal. En effet on a : C > X on ajoute 100, X < C on retranche 10, C > I on ajoute 100, I = I on ajoute 1 et enfin on ajoute 1 qui correspond à la valeur de la dernière lettre du nombre romain. Donc on aura : 100 – 10 + 100 + 1 + 1 = 192
- XLVI vaut 46 en décimal. En effet on a : X < L on retranche 10, L > V on ajoute 50, V > I on ajoute 5 et enfin on ajoute 1 qui correspond à la valeur de la dernière lettre du nombre romain. Donc on aura : –10 + 50 + 5 + 1 = 46
- MDCCL vaut 1750 en décimal. En effet on a : M > D on ajoute 1000, D>C on ajoute 500, C=C on ajoute 100, C > L on ajoute 100 et enfin on ajoute 50 qui correspond à la valeur de la dernière lettre du nombre romain. Donc on aura :1000 + 500+100 + 100 + 50 = 1750.
Travail demandé :
1- En se basant sur la figure Fig.1 de l’annexe, compléter l'interface graphique "InterfAjout.ui" par les éléments manquants (un objet LineEdit et un bouton).
2- Apporter les modifications nécessaires au fichier "AjoutObjet.py" afin de réaliser les actions suivantes :
a. Développer le module RomainToDecimal qui s'exécute suite au clic sur le bouton "Convertir" et qui permet :
- d'afficher un message d’erreur via une boite de dialogue QMessageBox si la quantité saisie n’est pas un nombre romain valide (voir figure Fig.2).
NB : Faire appel à la fonction Valider déjà développée pour vérifier la validité de la quantité saisie.
- de convertir cette quantité en décimal et de l’afficher dans le label nommé QD si elle est valide (voir figure Fig.3).
b. Développer le module Ajouter qui s'exécute suite au clic sur le bouton "Ajouter" et qui permet :
- d'afficher un message d'erreur via une boite de dialogue QMessageBox si aucun nom d’objet archéologique n’a été saisi (voir la figure Fig.4),
- d’afficher un message d'erreur via une boite de dialogue QMessageBox si le label nommé QD est vide (voir la figure Fig.5),
- de récupérer, dans le cas contraire, le nom de l’objet archéologique, la quantité en chiffres romains et la quantité en décimal et d’ajouter ces informations dans le fichier "Objets.dat". Chaque enregistrement de ce fichier est composé des champs suivants :
- Objet : représente le nom de l’objet archéologique.
- QR : représente la quantité en chiffres romains.
- QD : représente la quantité en décimal équivalente à QR.
NB :
- Pour récupérer le contenu d’un label, utiliser la méthode text().
- Le fichier "Objets.dat" doit être créé dans le dossier de travail.
- Après l’ajout d’un nouvel enregistrement, le module doit vider les deux objets LineEdit ainsi que le label QD, puis afficher un message, via une boite de dialogue QMessageBox, indiquant que l’ajout a été effectué avec succès (voir la figure Fig.6).
c. Compléter la partie exploitation de l’interface graphique "InterfAjout.ui" par les noms
adéquats afin :
- de charger l’interface graphique depuis le fichier "InterfAjout.ui",
- d’appeler le module nommé RomainToDecimal suite au clic sur le bouton intitulé "Convertir",
- d’appeler le module nommé Ajouter suite au clic sur le bouton intitulé "Ajouter".
3- En se basant sur la figure Fig.7 de l’annexe, compléter l'interface graphique "InterfManipulation.ui" par les éléments manquants (un label et un objet ListWidget).
4- Apporter les modifications nécessaires au fichier "Manip.py" afin de réaliser les actions suivantes :
a. Développer le module Recherche qui s'exécute suite au clic sur le bouton "Rechercher" et qui permet :
- de récupérer le nom de l’objet archéologique,
- d’afficher, si l’objet existe dans le fichier "Objets.dat", ses quantités en chiffres romains et décimaux dans les labels correspondants nommés QR et QD (voir figure Fig.8),
- d’afficher, si l’objet n’existe pas dans le fichier "Objets.dat", un message d’erreur via une boite de dialogue QMessageBox (voir figure Fig.9).
b. Implémenter le module Tri ci-dessous, qui permet de trier récursivement les éléments d’un tableau d’enregistrements T de la case d’indice i à la case d’indice j-1 dans l’ordre croissant du champ QD.

NB : Chaque enregistrement du tableau T a la même structure qu’un enregistrement du fichier "Objets.dat".
c. Développer le module TriAffiche qui s'exécute suite au clic sur le bouton "Trier et afficher" et qui permet :
- d'appeler le module Tri afin de trier le contenu du fichier "Objets.dat" dans l’ordre croissant du champ QD, puis de sauvegarder le contenu trié dans le même fichier,
- d’afficher dans l’objet "ListWidget" le contenu du fichier "Objets.dat", trié dans l’ordre croissant du champ QD.
Selon l’option sélectionnée dans la liste déroulante, chaque ligne de l’objet "ListWidget" doit contenir :
- soit le nom de l’objet suivi de sa quantité en chiffres romains, puis de sa quantité en décimale (voir la figure Fig.10) ;
- soit le nom de l’objet suivi de sa quantité en décimale (voir la figure Fig.11).
NB : Utiliser les caractères "- - -" pour séparer les différentes valeurs de chaque ligne de l’objet "ListWidget", conformément aux figures Fig.10 et Fig.11.
- d’afficher un message d’erreur conformément à la figure Fig.12 lorsque l’option "Choisir une valeur" est sélectionnée dans la liste déroulante.
d. Compléter la partie exploitation de l’interface graphique "InterfManipulation.ui" par les noms adéquats afin :
- de charger l’interface graphique depuis le fichier "InterfManipulation.ui",
- d’appeler le module nommé Recherche suite au clic sur le bouton intitulé "Rechercher",
- d’appeler le module nommé TriAffiche suite au clic sur le bouton intitulé "Trier et afficher".


a- Ouvrez Qt Designer et créez un nouveau fichier de type Main Window.
b- Ajoutez ces widgets :
- QLineEdit : nommé "Objet" pour saisir le nom de l'objet archéologiques.
- QLineEdit : nommé "QR" pour saisir la quantité en chiffres romains.
- QLabel : nommé "QD" pour afficher la quantité en chiffres décimal.
- QPushButton : nommé "btConvertir" pour convertir la quantité en décimal.
- QPushButton : nommé "btAjouter" pour ajouter les informations de l'objet dans un fichier nommé Objets.dat.

|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# ========================================================= # IMPORTATION DES BIBLIOTHÈQUES # ========================================================= from PyQt5.uic import loadUi # Charger l'interface graphique depuis un fichier .ui from PyQt5.QtWidgets import * # Importer les composants PyQt5 from pickle import load, dump # Importer les fonctions de lecture/écriture binaire # ========================================================= # CRÉATION DU DICTIONNAIRE POUR STOCKER LES DONNÉES # ========================================================= # Ce dictionnaire représente un objet à enregistrer objet_enregistrement = dict( Objet=str(), # Nom de l'objet QR=str(), # Quantité en chiffres romains QD=int() # Quantité en chiffres décimaux ) # ========================================================= # FONCTION DE VALIDATION D’UN NOMBRE ROMAIN # ========================================================= def Valider(ch): # Chaîne contenant les symboles romains autorisés r = "IVXLCDM" # Vérifier si la chaîne est vide if ch == "": return False else: test = True i = 0 # Vérification caractère par caractère while (i < len(ch)) and (r.find(ch[i]) != -1) and test: # Vérifier qu’un symbole ne se répète pas 4 fois if ch.find(ch[i] + ch[i] + ch[i] + ch[i]) != -1: test = False else: i = i + 1 # Retourner True si toute la chaîne est valide return i == len(ch) # ========================================================= # FONCTION QUI RETOURNE LA VALEUR D’UN SYMBOLE ROMAIN # ========================================================= def chiffre(c): # Conversion symbole romain → valeur décimale if c == 'I': return 1 if c == 'V': return 5 if c == 'X': return 10 if c == 'L': return 50 if c == 'C': return 100 if c == 'D': return 500 if c == 'M': return 1000 # ========================================================= # FONCTION DE CONVERSION ROMAIN → DÉCIMAL # ========================================================= def romaintodecimal(): # Récupérer la quantité romaine saisie ch = w.QR.text() # Vérifier que le champ n’est pas vide if ch != '': # Vérifier si le nombre romain est valide if Valider(ch): nbr = 0 # Parcours des caractères du nombre romain for i in range(len(ch) - 1): # Cas où la valeur actuelle est supérieure ou égale à la suivante if chiffre(ch[i]) >= chiffre(ch[i + 1]): nbr = nbr + chiffre(ch[i]) # Cas où la valeur actuelle est inférieure à la suivante if chiffre(ch[i]) < chiffre(ch[i + 1]): nbr = nbr - chiffre(ch[i]) # Ajouter la valeur du dernier caractère nbr = nbr + chiffre(ch[len(ch) - 1]) # Afficher le résultat décimal w.QD.setText(str(nbr)) else: # Message d’erreur si le nombre romain est invalide QMessageBox.critical(w, 'Erreur', "Nombre romain invalide") else: # Message d’erreur si aucun nombre romain n’est saisi QMessageBox.critical(w, 'Erreur', "Veuillez saisir la quantité en chiffres romains") # ========================================================= # FONCTION D’AJOUT D’UN OBJET DANS LE FICHIER # ========================================================= def ajouter(): # Récupérer le nom de l’objet nom_objet = w.Objet.text() # Vérifier si le nom est saisi if nom_objet != '': # Récupérer la quantité décimale qd = w.QD.text() # Vérifier si la quantité décimale existe if qd != '': # Récupérer la quantité romaine qr = w.QR.text() # Ouvrir le fichier binaire en écriture binaire f_objets = open("Objets.dat", "wb") # Remplir le dictionnaire avec les données objet_enregistrement['Objet'] = nom_objet objet_enregistrement['QR'] = qr objet_enregistrement['QD'] = int(qd) # Effacer les champs après ajout w.QD.clear() w.QD.clear() # Enregistrer le dictionnaire dans le fichier dump(objet_enregistrement, f_objets) # Afficher un message de confirmation QMessageBox.critical(w, 'Confirmation', "Objet ajouté avec succès") # Fermer le fichier f_objets.close() else: # Message d’erreur si la conversion n’est pas effectuée QMessageBox.critical(w, 'Erreur', "Veuillez convertir la quantité romaine en décimal") else: # Message d’erreur si le nom de l’objet est vide QMessageBox.critical(w, 'Erreur', "Veuillez saisir le nom de l'objet") # ========================================================= # PROGRAMME PRINCIPAL # ========================================================= # Création de l’application PyQt5 app = QApplication([]) # Chargement de l’interface graphique w = loadUi("InterfAjout.ui") # Affichage de la fenêtre w.show() # Association des boutons avec les fonctions w.btConvertir.clicked.connect(romaintodecimal) w.btAjouter.clicked.connect(ajouter) # Exécution de l’application app.exec_() |
a- Ouvrez Qt Designer et créez un nouveau fichier de type Main Window.
b- Ajoutez ces widgets :
- QLineEdit : nommé "Objet" pour saisir le nom de l'objet.
- QLabel : nommé "QR" pour afficher la quantité de l'objet en chiffres romains.
- QLabel : nommé "QD" pour afficher la quantité de l'objet en chiffres décimal.
- QPushButton : nommé "btRech" pour chercher et afficher l'objet s'il existe dans le fichier "Objets.dat".
- QPushButton : nommé "btTriAffich" pour trier le contenu du fichier "Objets.dat" et l'afficher dans le composant listWidget.
- QComboBox : nommé "cbChoix" pour le type d'affichage du contenu du ficher "Objets.dat".

|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# ========================================================= # IMPORTATION DES BIBLIOTHÈQUES # ========================================================= from PyQt5.uic import loadUi # Charger l’interface graphique (.ui) from PyQt5.QtWidgets import * # Importer les composants PyQt5 from numpy import array # Importer la structure tableau from pickle import load, dump # Importer les fonctions de lecture/écriture binaire # ========================================================= # CRÉATION D’UN TABLEAU DE 50 CASES # ========================================================= # Tableau destiné à stocker les objets lus depuis le fichier t = array([{}] * 50) # ========================================================= # CRÉATION DU DICTIONNAIRE D’ENREGISTREMENT # ========================================================= # Structure représentant un objet objet_enregistrement = dict( Objet=str(), # Nom de l’objet QR=str(), # Quantité en chiffres romains QD=int() # Quantité en chiffres décimaux ) # ========================================================= # FONCTION DE RECHERCHE D’UN OBJET # ========================================================= def Recherche(): # Récupérer le nom de l’objet saisi nom_objet = w.Objet.text() # Vérifier que le champ n’est pas vide if nom_objet != '': # Ouvrir le fichier binaire en lecture f_objets = open("Objets.dat", "rb") # Variable indiquant si l’objet est trouvé trouver = False # Parcourir le fichier tant que l’objet n’est pas trouvé while True and trouver == False: try: # Lire un objet depuis le fichier objet_enregistrement = load(f_objets) # Afficher le nom de l’objet dans la console print(objet_enregistrement['Objet']) # Vérifier si le nom correspond if objet_enregistrement['Objet'] == nom_objet: trouver = True except EOFError: # Arrêter la boucle à la fin du fichier break # Fermer le fichier f_objets.close() # Si l’objet est trouvé if trouver == True: # Afficher les informations dans les champs w.QR.setText(objet_enregistrement['QR']) w.QD.setText(str(objet_enregistrement['QD'])) else: # Message d’erreur si l’objet n’existe pas QMessageBox.critical(w, 'Erreur', "Objet inexistant") else: # Message d’erreur si le champ est vide QMessageBox.critical(w, 'Erreur', "Veuillez saisir le nom de l'objet") # ========================================================= # FONCTION DE TRI DES OBJETS # ========================================================= def tri(t, i, j): # Comparer les quantités décimales de deux objets if t[i]['QD'] > t[j - 1]['QD']: # Permutation des objets v = t[i] t[i] = t[j - 1] t[j - 1] = v # Continuer le tri si la taille du tableau est supérieure à 2 if (j - i) > 2: # Calcul du tiers du tableau k = (j - i) // 3 # Tri récursif tri(t, i, j - k) tri(t, i + k, j) tri(t, i, j - k) # ========================================================= # FONCTION DE TRI ET D’AFFICHAGE # ========================================================= def TriAffiche(): # Ouvrir le fichier en lecture binaire f_objets = open("objets.dat", "rb") # Effacer les anciens éléments de la liste w.listWidget.clear() # Initialisation du compteur n = 0 # Lecture des objets du fichier while True: try: # Création d’un dictionnaire vide objet_enregistrement = dict( Objet=str(), QR=str(), QD=int() ) # Lire un objet depuis le fichier objet_enregistrement = load(f_objets) # Ajouter l’objet dans le tableau t[n] = objet_enregistrement n = n + 1 except EOFError: # Fin du fichier break # Fermer le fichier f_objets.close() # Trier les objets selon la quantité décimale tri(t, 0, n) # Ouvrir le fichier en écriture binaire f_objets = open("Objets.dat", "wb") # Réécrire les objets triés dans le fichier for i in range(n): dump(t[i], f_objets) # Fermer le fichier f_objets.close() # ===================================================== # AFFICHAGE DES DONNÉES SELON LE CHOIX UTILISATEUR # ===================================================== # Affichage : Objet --- QR --- QD if w.cbChoix.currentText() == "Objet --- QR --- QD": for i in range(n): # Construire la chaîne à afficher liste = t[i]['Objet'] + '---' + t[i]['QR'] + '---' + str(t[i]['QD']) # Ajouter dans le ListWidget w.listWidget.addItems([liste]) # Affichage : Objet --- QD elif w.cbChoix.currentText() == "Objet --- QD": for i in range(n): # Construire la chaîne à afficher liste = t[i]['Objet'] + '---' + str(t[i]['QD']) # Ajouter dans le ListWidget w.listWidget.addItems([liste]) else: # Message d’erreur si aucun choix n’est sélectionné QMessageBox.critical(w, 'Erreur', "Choisir l'option d'affichage") # ========================================================= # PROGRAMME PRINCIPAL # ========================================================= # Création de l’application PyQt5 app = QApplication([]) # Chargement de l’interface graphique w = loadUi("InterfManipulation.ui") # Affichage de la fenêtre w.show() # Association des boutons aux fonctions w.btRech.clicked.connect(Recherche) w.btTriAffich.clicked.connect(TriAffiche) # Lancement de l’application app.exec_() |
La robotique éducative joue un rôle important dans l'éducation des enfants et des jeunes en les aidant à acquérir des compétences en science et technologie.
Dans ce cadre notre site web représente une excellente ressource pour les parents, les enseignants et les enfants qui souhaitent découvrir la robotique.
Zaouiet Kontech-Jemmel-Monastir-Tunisie
Site robotique réalisé par Mohamed Ali Haj Salah - Prof Info