diff --git a/.gitignore b/.gitignore index 2a6ba993dbd92d4d7473219fc743d3cd886fa99b..65c19004bbac99c5cb9cf9cecb18edc14a3e8fad 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ __pycache__/ build/ dist/ *.egg-info/ -*.spec # Ignore les fichiers de configuration locaux .env @@ -22,4 +21,5 @@ FIXME.md *.txt *.csv -# Ignore les fichiers de sauvegarde +# Ignore les fichiers des résultats générés par l'exécution du programme +Résultats/ diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000000000000000000000000000000000000..3e8dd1e16b5afde3f81dcf82bb2ddfa3f39fec5a --- /dev/null +++ b/BUILD.md @@ -0,0 +1,58 @@ +# Instructions de construction + +Ce document décrit les étapes nécessaires pour compiler l'application "Calcul R pour pont diviseur" à partir des sources. + +## Fichiers necessaires pour la compilation + +L'application utilise les fichiers suivants : + +calculateur-de-resistances-pour-pont-diviseur-de-tension +├── main.spec +├── requirements.txt +├── assets +│ ├── logo-laplace.ico +│ └── voltage-divider.png +└── src + ├── calculator + │ ├── e_series_gererator.py + │ ├── e_series_values.py + │ ├── voltage_divider.py + │ └── __init__.py + └── main.py + +* `requirements.txt` : Les dépendances Python requises pour l'application. +* `main.spec` : Le fichier de configuration pour PyInstaller. +* `src/main.py` : Le point d'entrée de l'application. +* `src/calculator/` : Les autres sources du programme nécessaires à l'application. +* `assets/` : Icône de l'application et images utilisées dans l'interface graphique. + +Assurez-vous que ces fichiers sont présents dans les répertoires correspondants avant de procéder à la compilation. Normalement, vous devriez les avoir si vous avez cloné le dépôt Git. + +`git clone https://src.koda.cnrs.fr/laplace-service-commun-electronique/membres/arnauld-biganzoli/python/calculateur-de-resistances-pour-pont-diviseur-de-tension.git` + +## Prérequis + +Pour compiler l'application, vous aurez besoin des éléments suivants : + +* Python 3.x (testé avec les versions de Python 3.11 à 3.13) +* Créer un environnement virtuel Python à la racine du dossier du projet (installable via `python -m venv .env`) +* Avoir activé l'environnement virtuel (sous Windows : `.env\Scripts\activate`, sous Linux/macOS : `source .env/bin/activate`) +* Mettre à jour `pip` (exécutez `python -m pip install --upgrade pip`) +* Les dépendances Python listées dans `requirements.txt` (installables via `pip install -r requirements.txt`) +* Ajouter PyInstaller pour créer l'exécutable (installable via `pip install pyinstaller`) + +## Compiler l'exécutable + +Exécutez la commande suivante : + +```bash +pyinstaller main.spec +``` + +ou en ajoutant `--noconfirm` pour éviter la question de confirmation si vous êtes sûr de vouloir écraser les répertoires existants (build et dist) : + +```bash +pyinstaller main.spec --noconfirm +``` + +PyInstaller va créer un dossier `dist` contenant l'exécutable `main.exe` (ou `main` sous Linux/macOS). Vous aurez aussi besoin du dossier `_internal` à côté de l'exécutable pour que l'application fonctionne correctement. diff --git a/CHANGELOG.md b/CHANGELOG.md index 97e235357a878964e5c395e0482dfa0b1a8ed2af..16d167e4433cad879947e25ce651472e8a31ff4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,23 +4,41 @@ Toutes les modifications apportées à ce projet seront documentées dans ce fic Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/), voir un [exemple de guide de style pour le suivit des modifications](https://github.com/vweevers/common-changelog). -Ce projet adhère à [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +Ce projet adhère à [Semantic Versioning 2](https://semver.org/spec/v2.0.0.html). -- [Version 1.3.0 - 2025-02-09](#version-130---2025-02-09) +- [Version 1.4.0 - 2025-03-02](#version-140---2025-03-02) - [Ajouté](#ajouté) - [Modifié](#modifié) +- [Version 1.3.0 - 2025-02-09](#version-130---2025-02-09) + - [Ajouté](#ajouté-1) + - [Modifié](#modifié-1) - [Corrigé](#corrigé) - [Version 1.2.0 - 2025-02-04](#version-120---2025-02-04) - - [Ajouté](#ajouté-1) -- [Version 1.1.0 - 2025-02-03](#version-110---2025-02-03) - [Ajouté](#ajouté-2) - - [Modifié](#modifié-1) +- [Version 1.1.0 - 2025-02-03](#version-110---2025-02-03) + - [Ajouté](#ajouté-3) + - [Modifié](#modifié-2) - [Version \[1.0.0\] - 2025-01-23](#version-100---2025-01-23) --- <br /> +## Version 1.4.0 - 2025-03-02 + +### Ajouté + +- Ajout d'un menu `Aide` dans l'interface graphique, avec l'affichage des informations sur le développement de l'application +- Ajout du fichier BUILD.md pour la documentation de la procédure de construction de l'application + +### Modifié + +- Amélioration de la sauvegarde des résultats des calculs dans un dossier dédié `Résultats`, permettant une meilleure organisation des fichiers générés + +--- + +<br /> + ## Version 1.3.0 - 2025-02-09 ### Ajouté diff --git a/README.md b/README.md index 31ef54a7f2a1b953b857e4378a305762d43d89d9..9a4c117111f4309e148079497dfeb299f34aae65 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [](https://www.python.org/downloads/release/python-3131/) [](https://www.gnu.org/licenses/gpl-3.0.txt) -[](https://src.koda.cnrs.fr/laplace-service-commun-electronique/membres/arnauld-biganzoli/python/calculateur-de-resistances-pour-pont-diviseur-de-tension/-/tags) +[](https://src.koda.cnrs.fr/laplace-service-commun-electronique/membres/arnauld-biganzoli/python/calculateur-de-resistances-pour-pont-diviseur-de-tension/-/tags) <h3> <a href="" title="" target="_blank"> @@ -45,7 +45,7 @@ ## Introduction -Le pont diviseur de tension est un des circuits du monde de l'électronique le plus simple. Il permet d'obtenir une tension inférieure à une tension d'alimentation. Constitué de deux résistances en série, il est utilisé en électronique pour créer des références de tension ou atténuer des signaux. +Le pont diviseur de tension est un des circuits du monde de l'électronique le plus simple. Il permet d'obtenir une tension inférieure à une tension d'alimentation, utilisée en électronique pour créer des références de tension ou atténuer des signaux. Il existe deux types de pont diviseur de tension. Le premier qui est aussi le cas le plus simple et courant est constitué de deux résistances en série, c'est celui que nous traiterons ici. Le second, aussi appelé pont diviseur de tension chargé, est composé de deux résistances en série et d'une charge en parallèle sur la résistance de sortie. Le [principe de fonctionnement du pont diviseur de tension](https://fr.wikipedia.org/wiki/Diviseur_de_tension) est basé sur la loi d'Ohm et la loi des mailles. La tension de sortie du pont diviseur est calculée en fonction de la tension d'entrée et des valeurs des résistances. diff --git a/assets/icon-app-calc-r.ico b/assets/icon-app-calc-r.ico new file mode 100644 index 0000000000000000000000000000000000000000..0641c3ec0c8504510a0a33faa9ba6bd2d1de3daf Binary files /dev/null and b/assets/icon-app-calc-r.ico differ diff --git "a/ersbiganzoliDesktop20250218-BigBlueButton - Caf\303\251 Guix-000571.png\357\200\233\357\200\233" "b/ersbiganzoliDesktop20250218-BigBlueButton - Caf\303\251 Guix-000571.png\357\200\233\357\200\233" deleted file mode 100644 index 18ab741487433943cfaa6baa18760faf1f677dd8..0000000000000000000000000000000000000000 --- "a/ersbiganzoliDesktop20250218-BigBlueButton - Caf\303\251 Guix-000571.png\357\200\233\357\200\233" +++ /dev/null @@ -1,23 +0,0 @@ -c40d83d Nouvelle mise à jour importante, avec mise en forme des fichiers de résultat Sun Feb 9 01:11:52 2025 +0100 Sun Feb 9 01:11:52 2025 +0100 -0e2e677 Changement de mise en forme Thu Feb 6 13:29:15 2025 +0100 Thu Feb 6 13:29:15 2025 +0100 -314fb58 Update function name in README Thu Feb 6 13:20:48 2025 +0100 Thu Feb 6 13:20:48 2025 +0100 -a74efe1 Ajout du fichier NOTICE Thu Feb 6 12:06:16 2025 +0100 Thu Feb 6 12:06:16 2025 +0100 -d4120b8 Grosse MAJ avec l'aide de Jérôme !!! MERCI Tue Feb 4 00:24:18 2025 +0100 Tue Feb 4 00:24:18 2025 +0100 -29db9f5 Modification de la funct de calcul avec retour de l'ensemble des résultats Mon Feb 3 21:19:48 2025 +0100 Mon Feb 3 21:19:48 2025 +0100 -a8b7b23 Validation de l'interface sous tkinter Mon Feb 3 16:11:46 2025 +0100 Mon Feb 3 16:11:46 2025 +0100 -68a0ea0 Merge branch 'feature/ui-design' Thu Jan 30 00:48:58 2025 +0100 Thu Jan 30 00:48:58 2025 +0100 -826bfb1 Ajout de la saisie utilisateur dans la partie exemple à la console Thu Jan 30 00:48:02 2025 +0100 Thu Jan 30 00:48:02 2025 +0100 -dbe07a4 MAJ de l'affichage pour le tri des valeurs calculées de meilleure solution à la moins bonne Mon Jan 27 16:55:31 2025 +0100 Mon Jan 27 16:55:31 2025 +0100 -8cf8ab2 Ajout de l'image de l'interface et correction des chemins d'importation Mon Jan 27 11:12:51 2025 +0100 Mon Jan 27 11:12:51 2025 +0100 -9e827b0 Re-structuration du projet, et intégration de l'UI Mon Jan 27 01:39:17 2025 +0100 Mon Jan 27 01:39:17 2025 +0100 -a163582 Modification du calcul de R1 et R2 avec l'algo de tri de Jérôme et la bibliothèque Numpy Sun Jan 26 01:17:57 2025 +0100 Sun Jan 26 01:17:57 2025 +0100 -a1a2bf4 MAJ finale Fri Jan 24 00:57:48 2025 +0100 Fri Jan 24 00:57:48 2025 +0100 -13cbc65 MAJ Fri Jan 24 00:46:34 2025 +0100 Fri Jan 24 00:46:34 2025 +0100 -36df0ed MAJ README Fri Jan 24 00:26:18 2025 +0100 Fri Jan 24 00:26:18 2025 +0100 -21a3adf Correction des import suite à l'ajout d'un fichier dédié à l'affichage Fri Jan 24 00:01:42 2025 +0100 Fri Jan 24 00:01:42 2025 +0100 -401fb94 MAJ README Thu Jan 23 21:00:51 2025 +0100 Thu Jan 23 21:00:51 2025 +0100 -d1e2c33 MAJ README avec tableau pour mise en page Wed Jan 22 18:38:35 2025 +0100 Wed Jan 22 18:38:35 2025 +0100 -90305b9 Suppression de la condition d'arrêt de la boucle for et MAJ de la documentation Wed Jan 22 17:46:12 2025 +0100 Wed Jan 22 17:46:12 2025 +0100 -a14a49e Correction des fautes d'orthographe Sun Jan 19 20:34:02 2025 +0100 Sun Jan 19 20:34:02 2025 +0100 -59fb7db Correction de bugs dans la précision des réponses Sun Jan 19 20:11:45 2025 +0100 Sun Jan 19 20:11:45 2025 +0100 -f077f7e Initial commit Sun Jan 19 01:31:11 2025 +0100 Sun Jan 19 01:31:11 2025 +0100 diff --git a/main.spec b/main.spec new file mode 100644 index 0000000000000000000000000000000000000000..e59f9cbb03e99ae65aafeb88dae97fed62da4ceb --- /dev/null +++ b/main.spec @@ -0,0 +1,41 @@ +# -*- mode: python ; coding: utf-8 -*- + +block_cipher = None + +a = Analysis(['src/main.py'], + pathex=['.'], + binaries=[], + datas=[('assets/logo-laplace.ico', 'assets'), + ('assets/voltage-divider.png', 'assets')], + hiddenimports=['src.calculator.e_series_gererator', + 'src.calculator.e_series_values', + 'src.calculator.voltage_divider', + 'src.display.table_formatting'], + hookspath=[], + runtime_hooks=[], + excludes=['examples', 'images'], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + [], + exclude_binaries=True, + name='Calcul R pour pont diviseur', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=False, + icon='assets/icon-app-calc-r.ico') +coll = COLLECT(exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name='Application-calculateur-pont-diviseur') diff --git a/src/main.py b/src/main.py index 7a4894a1286e39c0454c04f8237291b9548038a3..3301ac852263f01ee1757fb2ff71509143d816eb 100644 --- a/src/main.py +++ b/src/main.py @@ -34,14 +34,17 @@ Description: Module for calculating the resistance values of a divider bridge # ============================================================================= # INFO DEVELOPPEUR # ============================================================================= -__author__ = ["Arnauld BIGANZOLI"] -__copyright__ = "Copyright (c) 2025 LAPLACE, UMR INP-UPS-CNRS N°5213" -__credits__ = ["Arnauld BIGANZOLI", "Jérôme BRIOT"] +__status__ = "Development" +__version__ = "1.4.0" __license__ = "GNU GPLv3" -__version__ = "1.0.0" -__maintainer__ = "Arnauld BIGANZOLI" +__company__ = "Service commun d'électronique du laboratoire Laplace" +__author__ = ["Arnauld BIGANZOLI"] __email__ = "arnauld.biganzoli@laplace.univ-tlse.fr" -__status__ = "Development" +__maintainer__ = "Arnauld BIGANZOLI" +__developer__ = __author__ +__credits__ = ["Arnauld BIGANZOLI", "Jérôme BRIOT"] +__copyright__ = "Copyright (c) 2025 LAPLACE, UMR INP-UPS-CNRS N°5213" +# __copyright__ = f"Copyright (c) 2025, {__company__}" # ============================================================================= @@ -69,7 +72,8 @@ from src.calculator.voltage_divider import ( get_resistor_bridge_values, get_output_voltage_bridge, ) -from src.display.table_formatting import print_list_items_by_line + +# from src.display.table_formatting import print_list_items_by_line # ============================================================================= @@ -91,6 +95,34 @@ number_of_results_for_positives_vout = 0 # Variable globale pour stocker le nom # ============================================================================== # FUNCTIONS # ============================================================================== + + +# Créer une fenêtre "À propos" qui affiche la version, le développeur, l'entreprise, le copyright. +def afficher_a_propos(): + """Fonction pour afficher la fenêtre 'À propos', en gérant __developer__ comme liste.""" + developer_affichage = "" # Initialisation pour stocker le nom à afficher + + if isinstance(__developer__, list): # Vérifie si __developer__ est une liste + if __developer__: # Vérifie si la liste n'est pas vide + developer_affichage = __developer__[ + 0 + ] # Prend le premier élément de la liste + else: + developer_affichage = "Non spécifié" # Liste vide, message par défaut + else: + developer_affichage = ( + __developer__ # Si ce n'est pas une liste, utilise la valeur telle quelle + ) + + messagebox.showinfo( + title="À propos de l'application", + message=f"{__company__}\n" + f"Application Version: {__version__}\n" + f"Développeur: {developer_affichage}\n" # Utilise la variable formatée pour l'affichage + f"{__copyright__}", + ) + + def calculate_resistances(): # global results # Utilisation de la variable globale global results_for_negatives_vout # Variable globale pour stocker les résultats des valeurs de Vout négatives @@ -139,7 +171,7 @@ def calculate_resistances(): # Initialisation des variables calculated_vout, error, error_percent = 0, 0, 0 - + # Calcul de la tension de sortie avec les valeurs de résistances trouvées try: calculated_vout = get_output_voltage_bridge(vin, r1, r2) @@ -184,15 +216,20 @@ def calculate_resistances(): ) -# results_for_negatives_vout = [] # Variable globale pour stocker les résultats des valeurs de Vout négatives -# results_for_positives_vout = [] # Variable globale pour stocker les résultats des valeurs de Vout positives def save_results(): # Logique pour sauvegarder l'ensemble des résultats + # Définition du dossier de sauvegarde + save_folder = "Résultats" + # TODO: Ajouter à la sauvegarde le nombre de résultats pour les valeurs de Vout négatives et positives try: + # Vérification et création du dossier s'il n'existe pas + if not os.path.exists(save_folder): + os.makedirs(save_folder) + # Capture de la date et heure pour le prefixe du nom du fichier datetime_prefixe = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_") - + # Extraction des valeurs pour la date et l'heure sauvegardées depuis le préfixe annee = datetime_prefixe[:4] mois = datetime_prefixe[4:6] @@ -201,6 +238,8 @@ def save_results(): minute = datetime_prefixe[11:13] seconde = datetime_prefixe[13:15] + datetime_prefixe = f"{save_folder}/{datetime_prefixe}" + results = f""" ----------------------------------------------- Résultats du calcul de pont diviseur de tension @@ -320,11 +359,45 @@ root.minsize(340, 480) root.resizable(False, False) # Ajout icone à la fenêtre -ico_path = os.path.join("assets", "logo-laplace.ico") -root.iconbitmap(ico_path) +# ico_path = os.path.join("assets", "logo-laplace.ico") +# root.iconbitmap(ico_path) + +if hasattr(sys, "_MEIPASS"): + # L'application est exécutée à partir d'un exécutable PyInstaller + icon_path = os.path.join(sys._MEIPASS, "assets", "logo-laplace.ico") +else: + # L'application est exécutée directement à partir de Python + icon_path = os.path.join("assets", "logo-laplace.ico") + +try: + root.wm_iconbitmap(icon_path) +except tk.TclError as e: + print(f"Erreur lors du chargement de l'icône : {e}") # Code pour les widgets et la logique de l'application +# ---------------------------------------------------------------------- +# Création de la barre de menu +# ---------------------------------------------------------------------- +menubar = tk.Menu(root) + +# Menu "Aide" +menu_aide = tk.Menu( + menubar, tearoff=0 +) # tearoff=0 pour désactiver le "détachement" du menu +menu_aide.add_command(label="À propos", command=afficher_a_propos) +menubar.add_cascade(label="Aide", menu=menu_aide) + +# Configuration de la barre de menu dans la fenêtre principale +root.config(menu=menubar) +# ---------------------------------------------------------------------- + + +# Ajout d'un label pour le contenu principal (exemple) +# label_principal = tk.Label(root, text="Contenu principal de l'application ici...") +# label_principal.pack(padx=20, pady=20) + + # Entrées utilisateur frame_inputs = tk.Frame(root) frame_inputs.pack(pady=10) @@ -390,7 +463,13 @@ frame_image.pack(pady=10) # Charger l'image try: - image_path = os.path.join("assets", "voltage-divider.png") + if hasattr(sys, "_MEIPASS"): + # Application exécutée à partir de PyInstaller + image_path = os.path.join(sys._MEIPASS, "assets", "voltage-divider.png") + else: + # Application exécutée directement à partir de Python + image_path = os.path.join("assets", "voltage-divider.png") + img = Image.open(image_path) # AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS'