0% ont trouvé ce document utile (0 vote)
19 vues31 pages

New Data Base 2

Transféré par

lkr hammouda
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
19 vues31 pages

New Data Base 2

Transféré par

lkr hammouda
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 31

import tkinter as tk

from tkinter import ttk, messagebox


import sqlite3
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from datetime import datetime
from scipy.stats import norm
import numpy as np
import csv
import pickle
from tkinter import PhotoImage
from PIL import Image, ImageTk
from tkinter import Canvas

class InitialWindow:

def __init__(self, root):


self.root = root
self.root.title("Initial Window")
self.root.geometry("400x400")

# Créer un canvas pour l'arrière-plan


self.canvas = Canvas(self.root, bg="white")
self.canvas.place(relwidth=1, relheight=1)

# Charger l'image de fond et la redimensionner


self.background_image = PhotoImage(file="C:\\Users\\meddeb
mannoubi\\Desktop\\images.png")
self.background_image = self.background_image.subsample(1) # Ajustez
le facteur de sous-échantillonnage selon vos besoins

# Afficher l'image de fond sur le canvas


self.canvas.create_image(1, 1, anchor="nw",
image=self.background_image)

new_process_button = tk.Button(self.canvas, text="New Process",


font=("courrier",12), command=self.open_new_process_window,bg="#FFA500",
width=20, height=4)
new_process_button.pack(side=tk.RIGHT)

# Bouton "Open Process" pour ouvrir un processus existant


open_process_button = tk.Button(self.canvas, text="Open
Process",font=("courrier",12),
command=self.open_existing_process_window,bg="#27408B", width=20, height=4)
open_process_button.pack(side=tk.LEFT)
# Liste pour stocker les fenêtres de mesures
self.measure_windows = []
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS processus
(
reference_produit TEXT,
reference_machine TEXT,
id_parametre TEXT,
sample_size INTEGER,
tolerance_sup FLOAT,
tolerance_inf FLOAT,
target_value FLOAT,
PRIMARY KEY (reference_produit, reference_machine,
id_parametre),
FOREIGN KEY(reference_produit) REFERENCES
produit(reference_produit),
FOREIGN KEY(reference_machine) REFERENCES
machine(reference_machine),
FOREIGN KEY(id_parametre) REFERENCES
parametre(id_parametre))''')

def open_new_process_window(self):
# Ouvrir la fenêtre de création d'un nouveau processus en appelant la
classe SPCApplication
new_process_window = tk.Toplevel(self.root)
app = SPCApplication(new_process_window)

def open_existing_process_window(self):
# Créer une nouvelle fenêtre pour afficher la liste des processus
existing_process_window = tk.Toplevel(self.root)
existing_process_window.title("Existing Processes")

# Créer un Treeview dans la nouvelle fenêtre pour afficher les


processus existants
processus_treeview = ttk.Treeview(existing_process_window,
columns=("Référence Produit", "Référence Machine", "ID Paramètre",

"Taille d'échantillon", "Tolérance Sup", "Tolérance Inf",


"Valeur Cible"))

processus_treeview.heading("#1", text="Référence Produit")


processus_treeview.heading("#2", text="Référence Machine")
processus_treeview.heading("#3", text="ID Paramètre")
processus_treeview.heading("#4", text="Taille d'échantillon")
processus_treeview.heading("#5", text="Tolérance Sup")
processus_treeview.heading("#6", text="Tolérance Inf")
processus_treeview.heading("#7", text="Valeur Cible")

processus_treeview.pack(padx=10, pady=10)

# Effacer les données précédentes du tableau


for row in processus_treeview.get_children():
processus_treeview.delete(row)

# Récupérer les données des processus depuis la base de données


conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM processus")
processus = cursor.fetchall()
conn.close()

# Afficher les données des processus dans le tableau


for processus_row in processus:
processus_treeview.insert("", "end", values=processus_row)

class SPCApplication:

def __init__(self, root):


self.root = root
self.root.title("SPC Application")
self.root.title("SPC Application")
self.root.geometry("1920x1080")
self.root.iconbitmap("23810f77-6e2c.ico")

# Variables pour stocker les données

self.sample_size = tk.StringVar()
self.tolerance_min = tk.DoubleVar()
self.target_value = tk.DoubleVar()
self.tolerance_max = tk.DoubleVar()
self.d2_constant = tk.DoubleVar()

self.reference_produit = tk.StringVar()
self.reference_machine = tk.StringVar()
self.id_parametre = tk.StringVar()

self.fichier_csv = tk.StringVar()
self.fichier_pickle = tk.StringVar()

# Récupérer la valeur de sample_size depuis InitialWindow


# self.sample_size.set(self.initial_window.sample_size.get()) #
Utilisez la référence à InitialWindow

# Liste pour stocker les fenêtres de mesures


self.measure_windows = []

# Création des widgets


self.create_widgets()

def create_widgets(self):

label_title = tk.Label(self.root, text="SPC APPLICATION",


font=("Courrier",36))
label_title.grid(row=0, column=0, padx=10, pady=5, sticky=tk.E)

#frame pour les boutons


f = tk.Frame(self.root, bd=1, relief="sunken")
f.grid(row=1, column=2, rowspan=1, columnspan=12, padx=10, pady=5)

# Bouton "Créer Produit" pour afficher la deuxième fenêtre de création


de produits
creer_produit_button = tk.Button(f, text="Créer Produit", command=
self.creer_fenetre_creation_produit)
creer_produit_button.grid(row=2, column=1)

# Bouton "Créer Machine" pour afficher la deuxième fenêtre de création


de machines
creer_machine_button = tk.Button(f, text="Créer Machine", command=
self.creer_fenetre_creation_machine)
creer_machine_button.grid(row=2, column=2)

# Bouton "parametre" pour ajouter un nouveau parametre


creer_parametre_button = tk.Button(f, text="Créer parametre",
command=self.creer_fenetre_creation_parametre)
creer_parametre_button.grid(row=2, column=3, columnspan=2)
# Ajouter un bouton "Liste Produit" qui appelle la fonction
afficher_liste_produits
creer_bouton_liste_produit = tk.Button(f, text="liste produits",
command=self.afficher_liste_produits)
creer_bouton_liste_produit.grid(row=2, column= 5)

# Ajouter un bouton "Liste Produit" qui appelle la fonction


afficher_liste_produits
creer_bouton_liste_machine = tk.Button(f, text="liste machines",
command=self.afficher_liste_machines)
creer_bouton_liste_machine.grid(row=2, column= 6)

# Ajouter un bouton "Liste Produit" qui appelle la fonction


afficher_liste_produits
creer_bouton_liste_machine = tk.Button(f, text="liste parametre",
command=self.afficher_liste_parametres)
creer_bouton_liste_machine.grid(row=2, column= 7)

# Bouton "Supprimer Produit"


supprimer_produit_button = tk.Button(f, text="Supprimer Produit",
command=self.supprimer_produit)
supprimer_produit_button.grid(row=2, column=8)

# Bouton "Supprimer Machine"


supprimer_machine_button = tk.Button(f, text="Supprimer Machine",
command=self.supprimer_machine)
supprimer_machine_button.grid(row=2, column=9)

# Bouton "Supprimer Machine"


supprimer_machine_button = tk.Button(f, text="Supprimer parametre",
command=self.supprimer_parametre)
supprimer_machine_button.grid(row=2, column=10)

# Bouton pour enregistrer les données saisies


enregistrer_button = tk.Button(self.root, text="Enregistrer",
command=self.enregistrer_processus)
enregistrer_button.grid(row=12, column=3, padx=10, pady=5)

#frame pour selectionner les donées


frame = tk.Frame(self.root, bd=1, relief="sunken")
frame.grid(row=3, column=2, rowspan=8, columnspan=2, padx=10, pady=5)

# Cases pour sélectionner la liste des produits et des machines


produit_label = tk.Label(frame, text="Sélectionner Produit:")
produit_label.grid(row=3, column=2, padx=10, pady=5, sticky=tk.E)
self.produit_combobox = ttk.Combobox(frame, state='readonly',
width=20, textvariable=self.reference_produit)
self.produit_combobox.grid(row=3, column=3, padx=10, pady=5)

machine_label = tk.Label(frame, text="Sélectionner Machine:")


machine_label.grid(row=4, column=2, padx=10, pady=5, sticky=tk.E)
self.machine_combobox = ttk.Combobox(frame, state='readonly',
width=20, textvariable=self.reference_machine)
self.machine_combobox.grid(row=4, column=3, padx=10, pady=5)

# Cases pour sélectionner le parametre

parametre_label = tk.Label(frame, text="Sélectionner parametre:")


parametre_label.grid(row=6, column=2, padx=10, pady=5, sticky=tk.E)
self.parametre_combobox = ttk.Combobox(frame, state='readonly',
width=20, textvariable=self.id_parametre)
self.parametre_combobox.grid(row=6, column=3, padx=10, pady=5)

# Autres entrées de données


tk.Label(frame, text="Taille de l'échantillon:").grid(row=7, column=2,
padx=10, pady=5, sticky=tk.E)
tk.Entry(frame, textvariable=self.sample_size).grid(row=7, column=3,
padx=10, pady=5)

tk.Label(frame, text="Tolérance Min:").grid(row=8, column=2, padx=10,


pady=5, sticky=tk.E)
tk.Entry(frame, textvariable=self.tolerance_min).grid(row=8, column=3,
padx=10, pady=5)

tk.Label(frame, text="Valeur Cible:").grid(row=9, column=2, padx=10,


pady=5, sticky=tk.E)
tk.Entry(frame, textvariable=self.target_value).grid(row=9, column=3,
padx=10, pady=5)

tk.Label(frame, text="Tolérance Max:").grid(row=10, column=2, padx=10,


pady=5, sticky=tk.E)
tk.Entry(frame, textvariable=self.tolerance_max).grid(row=10,
column=3, padx=10, pady=5)

# Créer la base de données si elle n'existe pas


conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS produit
(reference_produit TEXT PRIMARY KEY,
nom TEXT NOT NULL,
client TEXT NOT NULL)''')

cursor.execute('''CREATE TABLE IF NOT EXISTS machine


(reference_machine TEXT PRIMARY KEY,
nom TEXT NOT NULL,
section TEXT NOT NULL)''')

cursor.execute('''CREATE TABLE IF NOT EXISTS parametre


(id_parametre TEXT PRIMARY KEY,
nom TEXT NOT NULL,
mesurande TEXT NOT NULL,
instrument TEXT NOT NULL,
unite TEXT NOT NULL)''')
conn.commit()
conn.close()

# Mettre à jour les listes de produits, de machines et d'instruments


au démarrage de l'application
self.mettre_a_jour_liste_elements()

def creer_fenetre_creation_produit(self):
def ajouter_produit():
nom = nom_entry.get()
reference = reference_entry.get()
client = client_entry.get()
if nom and reference and client :

conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO produit (reference_produit,nom,
client) VALUES (?,?,?)', (reference, nom, client ))
conn.commit()
conn.close()
messagebox.showinfo("Succès", "Produit ajouté avec succès !")
fenetre_creation_produit.destroy()
else:
messagebox.showerror("Erreur", "Veuillez remplir tous les champs
!")

# Mettre à jour la liste des paramètres dans le combobox


self.mettre_a_jour_liste_elements()

fenetre_creation_produit =tk.Toplevel(self.root)
fenetre_creation_produit.title("Création produit")
fenetre_creation_produit.geometry("400x400")

reference_label = tk.Label(fenetre_creation_produit, text="reference:")


reference_label.grid(row=2, column=0)
reference_entry = tk.Entry(fenetre_creation_produit)
reference_entry.grid(row=2, column=1)

nom_label = tk.Label(fenetre_creation_produit, text="nom:")


nom_label.grid(row=3, column=0)
nom_entry = tk.Entry(fenetre_creation_produit)
nom_entry.grid(row=3, column=1)

client_label = tk.Label(fenetre_creation_produit, text="client:")


client_label.grid(row=4, column=0)
client_entry = tk.Entry(fenetre_creation_produit)
client_entry.grid(row=4, column=1)

ajouter_button = tk.Button(fenetre_creation_produit, text="Ajouter",


command=ajouter_produit)
ajouter_button.grid(row=5, columnspan=2)

def creer_fenetre_creation_machine(self):
def ajouter_machine():
reference = reference_entry.get()
nom = nom_entry.get()
section = section_entry.get()
if nom and reference and section :

conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO machine (reference_machine,
nom, section) VALUES (?,?,?)', (reference, nom, section ))
conn.commit()
conn.close()
messagebox.showinfo("Succès", "Machine ajouté avec succès !")
fenetre_creation_machine.destroy()
else:
messagebox.showerror("Erreur", "Veuillez remplir tous les champs
!")

# Mettre à jour la liste des paramètres dans le combobox


self.mettre_a_jour_liste_elements()

fenetre_creation_machine =tk.Toplevel(self.root)
fenetre_creation_machine.title("Création Machine")
fenetre_creation_machine.geometry("400x300")
reference_label = tk.Label(fenetre_creation_machine, text="reference:")
reference_label.grid(row=2, column=0)
reference_entry = tk.Entry(fenetre_creation_machine)
reference_entry.grid(row=2, column=1)

nom_label = tk.Label(fenetre_creation_machine, text="nom:")


nom_label.grid(row=3, column=0)
nom_entry = tk.Entry(fenetre_creation_machine)
nom_entry.grid(row=3, column=1)

section_label = tk.Label(fenetre_creation_machine, text="section:")


section_label.grid(row=4, column=0)
section_entry = tk.Entry(fenetre_creation_machine)
section_entry.grid(row=4, column=1)

ajouter_button = tk.Button(fenetre_creation_machine, text="Ajouter",


command=ajouter_machine)
ajouter_button.grid(row=5, columnspan=2)

def creer_fenetre_creation_parametre(self):
def ajouter_parametre():
id_parametre=id_entry.get()
nom = nom_entry.get()
mesurande = mesurande_entry.get()
instrument = instrument_entry.get()
unite = unite_entry.get()

if id_parametre and nom and mesurande and instrument and unite :


conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO parametre (id_parametre, nom,
mesurande, instrument, unite) VALUES (?, ?, ?, ?, ?)',
(id_parametre, nom, mesurande, instrument, unite))
conn.commit()
conn.close()
messagebox.showinfo("Succès", "Paramètre ajouté avec succès !")
fenetre_creation_parametre.destroy()
else:
messagebox.showerror("Erreur", "Veuillez remplir tous les champs
!")

# Mettre à jour la liste des paramètres dans le combobox


self.mettre_a_jour_liste_elements()

fenetre_creation_parametre = tk.Toplevel(self.root)
fenetre_creation_parametre.title("Création d'un Paramètre")
fenetre_creation_parametre.geometry("400x300")

id_label = tk.Label(fenetre_creation_parametre, text="id parametre:")


id_label.grid(row=1, column=0)
id_entry = tk.Entry(fenetre_creation_parametre)
id_entry.grid(row=1, column=1)

nom_label = tk.Label(fenetre_creation_parametre, text="Nom:")


nom_label.grid(row=2, column=0)
nom_entry = tk.Entry(fenetre_creation_parametre)
nom_entry.grid(row=2, column=1)

mesurande_label = tk.Label(fenetre_creation_parametre, text="Mesurande:")


mesurande_label.grid(row=3, column=0)
mesurande_entry = tk.Entry(fenetre_creation_parametre)
mesurande_entry.grid(row=3, column=1)

instrument_label = tk.Label(fenetre_creation_parametre,
text="Instrument:")
instrument_label.grid(row=4, column=0)
instrument_entry = tk.Entry(fenetre_creation_parametre)
instrument_entry.grid(row=4, column=1)

unite_label = tk.Label(fenetre_creation_parametre, text="Unité:")


unite_label.grid(row=5, column=0)
unite_entry = tk.Entry(fenetre_creation_parametre)
unite_entry.grid(row=5, column=1)

ajouter_button = tk.Button(fenetre_creation_parametre, text="Ajouter",


command=ajouter_parametre)
ajouter_button.grid(row=6, columnspan=2)

def mettre_a_jour_liste_elements(self):
# Récupérer la liste des produits, des machines et des instruments
depuis la base de données
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('SELECT reference_produit FROM produit')
produits = cursor.fetchall()
cursor.execute('SELECT reference_machine FROM machine')
machines = cursor.fetchall()
cursor.execute('SELECT id_parametre FROM parametre')
parametres= cursor.fetchall()

conn.close()
# Mettre à jour les combobox des produits, des machines et des
instruments
self.produit_combobox['values'] = [produit[0] for produit in produits]
self.machine_combobox['values'] = [machine[0] for machine in machines]
self.parametre_combobox ['values'] = [parametre[0] for parametre in
parametres ]

def supprimer_produit(self):
selected_product = self.produit_combobox.get()
if selected_product != "Sélectionner":
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('DELETE FROM produit WHERE reference_produit=?',
(selected_product,))
conn.commit()
conn.close()
messagebox.showinfo("Succès", "Produit supprimé avec succès !")
self.mettre_a_jour_liste_elements()

def supprimer_machine(self):
selected_machine = self.machine_combobox.get()
if selected_machine != "Sélectionner":
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('DELETE FROM machine WHERE reference_machine=?',
(selected_machine,))
conn.commit()
conn.close()
messagebox.showinfo("Succès", "Machine supprimée avec succès !")
self.mettre_a_jour_liste_elements()

def supprimer_parametre(self):
selected_parametre = self.parametre_combobox.get()
if selected_parametre != "Sélectionner":
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('DELETE FROM parametre WHERE id_parametre=?',
(selected_parametre,))
conn.commit()
conn.close()
messagebox.showinfo("Succès", "Parametre supprimée avec succès !")
self.mettre_a_jour_liste_elements()

def afficher_liste_produits(self):
# Création de la fenêtre pour afficher la liste des produits
fenetre_liste_produits = tk.Toplevel(self.root)
fenetre_liste_produits.title("Liste des Produits")
# Récupérer tous les produits depuis la base de données
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('SELECT reference_produit, nom , client FROM produit')
produits = cursor.fetchall()
conn.close()

# Création du tableau pour afficher les produits


tableau_produits = ttk.Treeview(fenetre_liste_produits,
columns=("Produit", "Référence", "Nom","client"), show="headings")
tableau_produits.heading("Produit", text="Produit")
tableau_produits.heading("Référence", text="Référence")
tableau_produits.heading("Nom", text="Nom")
tableau_produits.heading("client", text="client")
# Ajout des données dans le tableau
for indice, produit in enumerate(produits, start=1):
tableau_produits.insert("", "end", values=(indice,) + produit)

# Afficher le tableau
tableau_produits.pack(expand=True, fill="both")

def afficher_liste_machines(self):
# Création de la fenêtre pour afficher la liste des machines
fenetre_liste_machines = tk.Toplevel(self.root)
fenetre_liste_machines.title("Liste des Machines")

# Récupérer toutes les machines depuis la base de données


conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('SELECT reference_machine, nom, section FROM machine')
machines = cursor.fetchall()
conn.close()

# Création du tableau pour afficher les machines


tableau_machines = ttk.Treeview(fenetre_liste_machines,
columns=("Machine", "Référence", "Nom","section"), show="headings")
tableau_machines.heading("Machine", text="Machine")
tableau_machines.heading("Référence", text="Référence")
tableau_machines.heading("Nom", text="Nom")
tableau_machines.heading("section", text="section")
# Ajout des données dans le tableau
for indice, machine in enumerate(machines, start=1):
tableau_machines.insert("", "end", values=(indice,) + machine)

# Afficher le tableau
tableau_machines.pack(expand=True, fill="both")

def afficher_liste_parametres(self):
# Création de la fenêtre pour afficher la liste des paramètres
fenetre_liste_parametres = tk.Toplevel(self.root)
fenetre_liste_parametres.title("Liste des Paramètres")

# Récupérer tous les paramètres depuis la base de données


conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('SELECT id_parametre, nom, mesurande, instrument, unite
FROM parametre')
parametres = cursor.fetchall()
conn.close()

# Création du tableau pour afficher les paramètres


tableau_parametres = ttk.Treeview(fenetre_liste_parametres,
columns=("ID", "Nom", "Mesurande", "Instrument", "Unité"), show="headings")
tableau_parametres.heading("ID", text="ID")
tableau_parametres.heading("Nom", text="Nom")
tableau_parametres.heading("Mesurande", text="Mesurande")
tableau_parametres.heading("Instrument", text="Instrument")
tableau_parametres.heading("Unité", text="Unité")

# Ajout des données dans le tableau


for indice, parametre in enumerate(parametres, start=1):
tableau_parametres.insert("", "end", values=(indice,) + parametre[1:])

# Afficher le tableau
tableau_parametres.pack(expand=True, fill="both")

def enregistrer_processus(self):
# Récupérer les données saisies par l'utilisateur
reference_produit = self.reference_produit.get()
reference_machine = self.reference_machine.get()
id_parametre = self.id_parametre.get()
sample_size = self.sample_size.get()
tolerance_inf = self.tolerance_min.get()
tolerance_sup = self.tolerance_max.get()
valeur_cible = self.target_value.get()

# Vérifier si un processus avec les mêmes valeurs existe déjà


conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('''SELECT * FROM processus WHERE reference_produit=? AND
reference_machine=? AND id_parametre=?''',
(reference_produit, reference_machine, id_parametre))
existing_processus = cursor.fetchone()
conn.close()

if existing_processus:
# Si le processus existe déjà, ouvrir la fenêtre MeasureWindow
correspondante
nom_fichier =
f"{reference_produit}_{reference_machine}_{id_parametre}_{sample_size}.csv"
nom_fichier_pickle =
f"{reference_produit}_{reference_machine}_{id_parametre}_{sample_size}.pickle"
nom_fichier_text =
f"{reference_produit}_{reference_machine}_{id_parametre}_{sample_size}.text"
measure_window = MeasureWindow(self, nom_fichier, nom_fichier_pickle,
nom_fichier_text,reference_produit, reference_machine, id_parametre,
sample_size, tolerance_inf, tolerance_sup, valeur_cible)

self.measure_windows.append(measure_window)
measure_window.charger_mesures_depuis_csv()
else:
# Si le processus n'existe pas encore, l'insérer dans la base de
données
conn = sqlite3.connect('ma_base_de_donnees0.db')
cursor = conn.cursor()
cursor.execute('''INSERT INTO processus (reference_produit,
reference_machine, id_parametre,
sample_size, tolerance_inf, tolerance_sup,
sample_size)
VALUES (?, ?, ?, ?, ?, ?, ?)''',
(reference_produit, reference_machine, id_parametre,
sample_size, tolerance_inf,
tolerance_sup, valeur_cible))
conn.commit()
conn.close()

# Créer des noms de fichiers uniques pour le processus


nom_fichier =
f"{reference_produit}_{reference_machine}_{id_parametre}_{sample_size}.csv"
nom_fichier_pickle =
f"{reference_produit}_{reference_machine}_{id_parametre}_{sample_size}.pickle"
nom_fichier_text =
f"{reference_produit}_{reference_machine}_{id_parametre}_{sample_size}.text"

# Créer une instance de MeasureWindow avec les données du processus


measure_window = MeasureWindow(self, nom_fichier, nom_fichier_pickle,
nom_fichier_text,reference_produit, reference_machine, id_parametre,
sample_size, tolerance_inf, tolerance_sup, valeur_cible)

self.measure_windows.append(measure_window)
# Mettre à jour les informations du processus dans la fenêtre
MeasureWindow
measure_window = MeasureWindow(self, nom_fichier, nom_fichier_pickle,
nom_fichier_text, reference_produit, reference_machine, id_parametre,
sample_size, tolerance_inf, tolerance_sup, valeur_cible)
# 2 eme fenetre

class MeasureWindow:

def supprimer_mesure(self):
# Récupérer l'ID de la ligne sélectionnée dans le Treeview
selected_id = self.data_tree.selection()[0]
# Supprimer la ligne sélectionnée du Treeview
self.data_tree.delete(selected_id)

# Mettre à jour les courbes et l'histogramme


self.plot_curves()
self.show_histogram()

# Mettre à jour les valeurs de capacité


self.calculate_cp()
self.calculate_pp()
self.calculate_cpk()
self.calculate_Ppk()

def charger_mesures_depuis_csv(self):
# Obtenir le chemin complet du fichier CSV
file_path = self.nom_fichier_csv

try:
with open(file_path, newline='') as file:
reader = csv.reader(file)
# Lire les en-têtes
headers = next(reader)

# Ajouter les en-têtes au tableau


self.data_tree['columns'] = headers
for col in headers:
self.data_tree.heading(col, text=col)

# Lire les données et les ajouter au tableau


for row in reader:
self.data_tree.insert("", "end", values=row)
self.current_row_index = int(row[0]) + 1 # Mettre à jour
l'indice du compteur d'échantillons
except FileNotFoundError:
print("Le fichier CSV n'existe pas. Aucune mesure chargée.")

def sauvegarder_mesures_dans_csv(self):
# Récupérer les en-têtes des colonnes du tableau
# columns = self.data_tree['columns']
#headers = ['Echantillon', 'Date', 'Heure'] +
[self.data_tree.heading(column)['text'] for column in columns]
headers = ["Echantillon", "Date", "Heure", *range(1,
int(self.spc_app.sample_size.get()) + 1), "Moyenne", "Etendue"]

# Récupérer toutes les lignes du tableau


data = []
for item in self.data_tree.get_children():
values = self.data_tree.item(item, 'values')
data.append(values)

# Obtenir le chemin complet du fichier CSV


file_path = self.nom_fichier_csv

# Écrire les données dans le fichier CSV


with open(file_path, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(headers) # Écrire les en-têtes
for row in data:
writer.writerow(row) # Écrire chaque ligne de donnée
# Obtenir le chemin complet du fichier CSV
file_path = self.nom_fichier_text
# Sauvegarder l'indice du compteur d'échantillons dans un fichier
texte
with open(file_path, 'w') as counter_file:
counter_file.write(str(self.current_row_index))

def sauvegarder_mesures_dans_pickle(self):
# Obtenir le chemin complet du fichier pickle
file_path = self.nom_fichier_pickle

# Sauvegarder les données des cartes de contrôle dans le fichier


pickle
with open(file_path, 'wb') as curve_file:
curve_data = {
'averages': self.averages,
'ranges': self.ranges
}
pickle.dump(curve_data, curve_file)

def charger_mesures_depuis_pickle(self):
# Obtenir le chemin complet du fichier pickle
file_path = self.nom_fichier_pickle

try:
# Charger les données des courbes à partir du fichier pickle
with open(file_path, 'rb') as curve_file:
curve_data = pickle.load(curve_file)
self.averages = curve_data['averages']
self.ranges = curve_data['ranges']
except FileNotFoundError:
# Gérer le cas où le fichier n'existe pas encore
pass
#print("Le fichier pickle n'existe pas. Aucune mesure chargée.")

def __init__(self, spc_app, nom_fichier_csv, nom_fichier_pickle,


nom_fichier_text, reference_produit, reference_machine, id_parametre,
sample_size, tolerance_inf, tolerance_sup, target_value):

self.nom_fichier_pickle = nom_fichier_pickle
self.nom_fichier_csv = nom_fichier_csv
self.nom_fichier_text = nom_fichier_text
self.spc_app = spc_app
self.averages = [] # Liste pour stocker les moyennes
self.ranges = []
self.current_row_index = 1

# Créer la fenêtre de mesure


self.measure_window = tk.Toplevel()
self.measure_window.title("Mesures")
self.measure_window.geometry("1920x1080")

# frame pour les boutons


self.fr = tk.Frame(self.measure_window, bd=1, relief="sunken")
self.fr.pack(side=tk.TOP, anchor="nw")

# Labels pour afficher les informations du processus


self.product_label = tk.Label(self.fr, text=f"Produit:
{reference_produit}")
self.product_label.pack(side=tk.LEFT)

self.machine_label = tk.Label(self.fr, text=f"Machine:


{reference_machine}")
self.machine_label.pack(side=tk.LEFT)

self.parameter_label = tk.Label(self.fr, text=f"Paramètre:


{id_parametre}")
self.parameter_label.pack(side=tk.LEFT)

self.sample_size_label = tk.Label(self.fr, text=f"Taille de


l'échantillon: {sample_size}")
self.sample_size_label.pack(side=tk.LEFT)

self.tolerance_min_label = tk.Label(self.fr, text=f"Tolérance Min:


{tolerance_inf}")
self.tolerance_min_label.pack(side=tk.LEFT)

self.target_value_label = tk.Label(self.fr, text=f"Valeur Cible:


{target_value}")
self.target_value_label.pack(side=tk.LEFT)

self.tolerance_max_label = tk.Label(self.fr, text=f"Tolérance Max:


{tolerance_inf}")
self.tolerance_max_label.pack(side=tk.LEFT)

# Obtenir la date et l'heure actuelles


now = datetime.now()
current_date_time = now.strftime("%d/%m/%Y %H:%M:%S")
# Afficher la date et l'heure en haut de la fenêtre
self.date_time_label = tk.Label(self.measure_window,
text=current_date_time)
self.date_time_label.pack(side=tk.TOP)

# Créer le Treeview avec une barre de défilement vertical/ creation du


tableau

self.tree_frame = ttk.Frame(self.measure_window)
self.tree_frame.pack()

self.yscrollbar = ttk.Scrollbar(self.tree_frame, orient="vertical")


self.yscrollbar.pack(side="right", fill="y")

self.data_tree = ttk.Treeview(self.tree_frame,
columns=["Echantillon","Date", "Heure", *range(1,
int(self.spc_app.sample_size.get()) +1), "Moyenne", "Etendue"])

# tableau: nom des tetes

self.data_tree.heading("#1", text="Echantillon")
self.data_tree.heading("Date", text="Date")
self.data_tree.heading("Heure", text="Heure")
for i in range(1, int(self.spc_app.sample_size.get()) + 1):
self.data_tree.heading(f"{i}", text=f"Mesure {i}")
self.data_tree.heading("Moyenne", text="Moyenne")
self.data_tree.heading("Etendue", text="Etendue")

self.data_tree.pack(expand=True, fill="both")
self.yscrollbar.config(command=self.data_tree.yview)
self.data_tree.config(yscrollcommand=self.yscrollbar.set)

# frame pour les boutons


self.button_frame = tk.Frame(self.measure_window, bd=1,
relief="sunken")
self.button_frame.pack(side=tk.TOP, anchor="nw")

# Créez les labels Cp, Pp, Cpk et Ppk avec leurs noms et valeurs initiales
(vides)
self.cp_label = tk.Label(self.button_frame, text="Cp: ")
self.cp_label.pack(side=tk.LEFT)
self.cp_value = tk.StringVar()
self.cp_value.set("")

self.cp_value_label = tk.Label(self.button_frame,
textvariable=self.cp_value)
self.cp_value_label.pack(side=tk.LEFT)

self.pp_label = tk.Label(self.button_frame, text="Pp: ")


self.pp_label.pack(side=tk.LEFT)
self.pp_value = tk.StringVar()
self.pp_value.set("")

self.pp_value_label = tk.Label(self.button_frame,
textvariable=self.pp_value)
self.pp_value_label.pack(side=tk.LEFT)

self.cpk_label = tk.Label(self.button_frame, text="Cpk: ")


self.cpk_label.pack(side=tk.LEFT)
self.cpk_value = tk.StringVar()
self.cpk_value.set("")

self.cpk_value_label = tk.Label(self.button_frame,
textvariable=self.cpk_value)
self.cpk_value_label.pack(side=tk.LEFT)

self.ppk_label = tk.Label(self.button_frame, text="Ppk: ")


self.ppk_label.pack(side=tk.LEFT)
self.ppk_value = tk.StringVar()
self.ppk_value.set("")
self.ppk_value_label = tk.Label(self.button_frame,
textvariable=self.ppk_value)
self.ppk_value_label.pack(side=tk.LEFT)

# frame pour les limites


self.limites_frame = tk.Frame(self.measure_window, relief=tk.SOLID)
self.limites_frame.pack(side=tk.TOP, anchor="nw")

# Bouton pour calculer la limite de contrôle supérieure X


self.calculate_upper_control_limit_X_button =
tk.Button(self.limites_frame, text="LCS X",
command=self.calculate_upper_control_limit_X)
self.calculate_upper_control_limit_X_button.pack(side=tk.LEFT)

# Label pour afficher la limite de contrôle supérieure X


self.upper_control_limit_X_label = tk.Label(self.limites_frame,
text="")
self.upper_control_limit_X_label.pack(side=tk.LEFT)

# Bouton pour calculer la limite de contrôle inférieure X


self.calculate_lower_control_limit_X_button =
tk.Button(self.limites_frame, text="LCI X",
command=self.calculate_lower_control_limit_X)
self.calculate_lower_control_limit_X_button.pack(side=tk.LEFT)

# Label pour afficher la limite de contrôle inférieure X


self.lower_control_limit_X_label = tk.Label(self.limites_frame,
text="")
self.lower_control_limit_X_label.pack(side=tk.LEFT)

# Bouton pour calculer la limite supérieure de contrôle R


self.calculate_upper_control_limit_R_button =
tk.Button(self.limites_frame, text="LCS R",
command=self.calculate_upper_control_limit_R)
self.calculate_upper_control_limit_R_button.pack(side=tk.LEFT)

# Label pour afficher la limite supérieure de contrôle R


self.upper_control_limit_R_label = tk.Label(self.limites_frame,
text="")
self.upper_control_limit_R_label.pack(side=tk.LEFT)

# Bouton pour calculer la limite inférieure de contrôle R


self.calculate_lower_control_limit_R_button =
tk.Button(self.limites_frame, text="LCI R",
command=self.calculate_lower_control_limit_R)
self.calculate_lower_control_limit_R_button.pack(side=tk.LEFT)
# Label pour afficher la limite inférieure de contrôle R
self.lower_control_limit_R_label = tk.Label(self.limites_frame,
text="")
self.lower_control_limit_R_label.pack(side=tk.LEFT)

# Entrées pour saisir les mesures/ cases pour saisir les données
self.measure_entries = []
for i in range(int(self.spc_app.sample_size.get())):
measure_entry = tk.Entry(self.measure_window)
measure_entry.pack()
self.measure_entries.append(measure_entry)

# Bouton pour ajouter les mesures


tk.Button(self.measure_window, text="Ajouter des Mesures",
command=self.add_measures).pack()

# Créer un cadre pour l'histogramme


self.histogram_frame = tk.Frame(self.measure_window, bd=2,
relief=tk.SOLID, width=300,height=300)
self.histogram_frame.pack(side=tk.LEFT, anchor="ne", padx=10)

# Initialisez les axes et la figure Matplotlib pour l'histogramme


self.hist_fig, self.hist_ax = plt.subplots(figsize=(8, 6))

# Créer un canvas pour afficher l'histogramme dans le cadre


self.histogram_canvas = FigureCanvasTkAgg(self.hist_fig,
master=self.histogram_frame)
self.histogram_canvas.get_tk_widget().pack(expand=True,
fill=tk.BOTH)

#frame pour les courbes


self.curve_frame = tk.Frame(self.measure_window, bd=2,
relief=tk.SOLID)
self.curve_frame.pack(expand=True,anchor="nw")
# Créer un Canvas pour afficher les courbes dans le Frame
self.canvas = tk.Canvas(self.curve_frame)
self.canvas.pack(expand=True, fill=tk.BOTH)

# Initialiser les courbes des moyennes et des étendues


self.fig, (self.ax1, self.ax2) = plt.subplots(2, 1, figsize=(8, 6))
self.canvas_widget = FigureCanvasTkAgg(self.fig, master=self.canvas)
self.canvas_widget.get_tk_widget().pack(expand=True, fill=tk.BOTH)
self.plot_curves()

# Ajouter les labels pour les courbes dans le Frame


self.ax1_label = tk.Label(self.curve_frame, text="Carte X bar /R")
self.ax1_label.pack(side=tk.TOP, padx=10, pady=5)
self.ax2_label = tk.Label(self.curve_frame, text="Courbe des
Étendues")
self.ax2_label.pack(side=tk.TOP, padx=10, pady=5)

self.charger_mesures_depuis_csv()
self.charger_mesures_depuis_pickle()
# Tracer les courbes initiales
self.plot_curves()

# Afficher l'histogramme initial


self.show_histogram()

def update_process_info(self, product, machine, parameter, sample_size,


tolerance_min, target_value, tolerance_max):
# Mettre à jour les labels avec les informations du processus
self.product_label.config(text=f"Produit: {product}")
self.machine_label.config(text=f"Machine: {machine}")
self.parameter_label.config(text=f"Paramètre: {parameter}")
self.sample_size_label.config(text=f"Taille de l'échantillon:
{sample_size}")
self.tolerance_min_label.config(text=f"Tolérance Min:
{tolerance_min}")
self.target_value_label.config(text=f"Valeur Cible: {target_value}")
self.tolerance_max_label.config(text=f"Tolérance Max:
{tolerance_max}")

def add_measures(self):

# Récupérez la date et l'heure actuelles


current_datetime = datetime.now()
current_date = current_datetime.strftime("%d/%m/%Y")
current_time = current_datetime.strftime("%H:%M:%S")
# Ajouter les mesures dans le tableau de la fenêtre principale

measure_values = self.get_measure_values()
measures = [f"Mesure {i + 1}" for i in
range(int(self.spc_app.sample_size.get()))]

# Calculer la moyenne et l'étendue

average = sum(measure_values) / len(measure_values)


range_value = max(measure_values) - min(measure_values)
# Calculer la constante d2 en fonction de la taille de l'échantillon

n = int(self.spc_app.sample_size.get())
d2_constants = {
2: 1.128,
3: 1.693,
4: 2.059,
5: 2.326,
6: 2.534,
7: 2.704,
8: 2.847,
9: 2.970,
10: 3.078
}
d2_value = d2_constants.get(n, 0.0)
self.spc_app.d2_constant.set(d2_value)

# Afficher les valeurs dans le tableau


# self.spc_app.measure_windows[-1].data_tree.insert("", "end",
values=(self.current_row_index, current_date, current_time, *measure_values,
average, range_value))
# self.current_row_index += 1

self.data_tree.insert("", "end", values=(self.current_row_index,


current_date, current_time, *measure_values, average, range_value))
self.current_row_index += 1

# Maintenant, vous pouvez insérer les valeurs dans le data_tree de la


dernière fenêtre MeasureWindow

# Effacer les valeurs des cases de saisie


self.clear_measure_entries()

# Ajouter la moyenne à la liste


self.averages.append(average)
self.ranges.append(range_value)

#calculez automatiquement Cp, Pp, Cpk et Ppk


self.calculate_cp()
self.calculate_pp()
self.calculate_cpk()
self.calculate_Ppk()
self.plot_curves()
self.show_histogram()
# self.save_table_data_to_csv()
# Sauvegarder les données des courbes
self.sauvegarder_mesures_dans_csv()
self.sauvegarder_mesures_dans_pickle()

def calculate_cp(self):
# Récupérer toutes les valeurs des étendues pour calculer l'étendue
moyenne
range_values = []
for item in self.data_tree.get_children():
values = self.data_tree.item(item, 'values')
range_value = float(values[-1]) # Récupérer la dernière valeur qui
correspond à l'étendue
range_values.append(range_value)

# Calculer l'étendue moyenne


average_range = sum(range_values) / len(range_values)

# Calculer la tolérance
tolerance_sup = self.spc_app.tolerance_max.get()
tolerance_inf = self.spc_app.tolerance_min.get()

# Calculer la constante d2 en fonction de la taille de l'échantillon


n = int(self.spc_app.sample_size.get())
d2_constants = {
2: 1.128,
3: 1.693,
4: 2.059,
5: 2.326,
6: 2.534,
7: 2.704,
8: 2.847,
9: 2.970,
10: 3.078
}
d2_value = d2_constants.get(n, 0.0)

# Calculer Cp
cp_value = (tolerance_sup - tolerance_inf) * d2_value / (6 *
average_range)

# Afficher la valeur de Cp
self.cp_value.set(f"{cp_value:.2f}")

def calculate_pp(self):
# Récupérer les valeurs des mesures pour calculer l'écart type
measure_values = [float(self.data_tree.item(item, 'values')[i + 3]) for
item in self.data_tree.get_children() for i in
range(int(self.spc_app.sample_size.get()))]

# Calcul de l'écart type


sigma = np.std(measure_values)

# Récupérer les valeurs des tolérances supérieure et inférieure


# Calculer la tolérance
tolerance_sup = self.spc_app.tolerance_max.get()
tolerance_inf = self.spc_app.tolerance_min.get()

# Calcul de Pp
pp = (tolerance_sup - tolerance_inf) / (6 * sigma)

# Affichage de la valeur de Pp

self.pp_value.set(f"{pp:.2f}")

def calculate_Ppk(self):
# Récupérer les valeurs des mesures pour calculer l'écart type
measure_values = [float(self.data_tree.item(item, 'values')[i + 3]) for
item in self.data_tree.get_children() for i in
range(int(self.spc_app.sample_size.get()))]

# Calcul de l'écart type


sigma = np.std(measure_values)
process_mean= sum(measure_values)/len(measure_values)
# Récupérer les valeurs des tolérances supérieure et inférieure
# Calculer la tolérance
tolerance_sup = self.spc_app.tolerance_max.get()
tolerance_inf = self.spc_app.tolerance_min.get()

# Calcul de Pp
ppk = min((tolerance_sup - process_mean) / (3 * sigma), (process_mean -
tolerance_inf) / (3 * sigma))

# Affichage de la valeur de Pp

self.ppk_value.set(f"{ppk:.2f}")

def calculate_cpk(self):
# Récupérer toutes les valeurs des étendues pour calculer l'étendue
moyenne
average_values = []
for item in self.data_tree.get_children():
values = self.data_tree.item(item, 'values')
average_value = float(values[-2]) # Récupérer la dernière valeur qui
correspond à l'étendue
average_values.append(average_value)
# Calculer la moyenne du processus
process_mean = sum(average_values) / len(average_values)

# Récupérer toutes les valeurs des étendues pour calculer l'étendue


moyenne
range_values = []
for item in self.data_tree.get_children():
values = self.data_tree.item(item, 'values')
range_value = float(values[-1]) # Récupérer la dernière valeur qui
correspond à l'étendue
range_values.append(range_value)

# Calculer l'étendue moyenne


average_range = sum(range_values) / len(range_values)

# Calculer l'écart type des échantillons


n = int(self.spc_app.sample_size.get())
d2_constants = {
2: 1.128,
3: 1.693,
4: 2.059,
5: 2.326,
6: 2.534,
7: 2.704,
8: 2.847,
9: 2.970,
10: 3.078
}
d2_value = d2_constants.get(n, 0.0)
sample_std_dev = average_range / d2_value

# Calculer la tolérance
tolerance_sup = self.spc_app.tolerance_max.get()
tolerance_inf = self.spc_app.tolerance_min.get()

# Calculer Cpk
cpk_value = min(abs(tolerance_sup - process_mean) / (3 * sample_std_dev),
abs(process_mean - tolerance_inf) / (3 * sample_std_dev))

# Afficher la valeur de Cpk


self.cpk_value.set(f"{cpk_value:.2f}")

def calculate_upper_control_limit_X(self):
# Calculer la limite de contrôle supérieure pour la carte X
average_range = sum(self.ranges) / len(self.ranges)
x_double_bar = sum(self.averages) / len(self.averages)
n = int(self.spc_app.sample_size.get())
a2_values = {2: 1.880, 3: 1.023, 4: 0.729, 5: 0.577, 6: 0.483, 7: 0.419,
8: 0.373, 9: 0.337, 10: 0.308}
a2 = a2_values.get(n, 0)

upper_control_limit_X = x_double_bar + a2 * average_range


self.upper_control_limit_X_label.config(text=f"{upper_control_limit_X:.4f
}")

def calculate_lower_control_limit_X(self):
# Calculer la limite de contrôle inférieure pour la carte X
average_range = sum(self.ranges) / len(self.ranges)
x_double_bar = sum(self.averages) / len(self.averages)

n = int(self.spc_app.sample_size.get())
a2_values = {2: 1.880, 3: 1.023, 4: 0.729, 5: 0.577, 6: 0.483, 7: 0.419,
8: 0.373, 9: 0.337, 10: 0.308}
a2 = a2_values.get(n, 0)

lower_control_limit_X = x_double_bar - a2 * average_range


self.lower_control_limit_X_label.config(text=f"{lower_control_limit_X:.4f
}")

def calculate_lower_control_limit_R(self):
n = int(self.spc_app.sample_size.get())
d3_constants = {
7: 0.076,
8: 0.136,
9: 0.184,
10: 0.223
}
d3_value = d3_constants.get(n, 0.0)
average_range = sum(self.ranges) / len(self.ranges)
lower_control_limit_R = d3_value * average_range
self.lower_control_limit_R_label.config(text=f"{lower_control_limit_R:.4f
}")

def calculate_upper_control_limit_R(self):
n = int(self.spc_app.sample_size.get())
d4_constants = {
2: 3.267,
3: 2.574,
4: 2.282,
5: 2.114,
6: 2.004,
7: 1.924,
8: 1.864,
9: 1.816,
10: 1.777
}
d4_value = d4_constants.get(n, 0.0)
average_range = sum(self.ranges) / len(self.ranges)
upper_control_limit_R = d4_value * average_range
self.upper_control_limit_R_label.config(text=f"{upper_control_limit_R:.4f
}")

def plot_curves(self):
# Effacer les anciennes courbes
self.ax1.clear()
self.ax2.clear()

# Tracer les courbes des moyennes et des étendues


self.ax1.plot(range(len(self.averages)), self.averages, 'bo-')
self.ax2.plot(range(len(self.ranges)), self.ranges, 'bo-')

# Calculer les limites de contrôle pour la courbe des moyennes


if self.ranges:
average_range_X = sum(self.ranges) / len(self.ranges)
x_double_bar = sum(self.averages) / len(self.averages)
n = int(self.spc_app.sample_size.get())
a2_values = {2: 1.880, 3: 1.023, 4: 0.729, 5: 0.577, 6: 0.483, 7:
0.419, 8: 0.373, 9: 0.337, 10: 0.308}
a2 = a2_values.get(n, 0)
upper_control_limit_X = x_double_bar + a2 * average_range_X
lower_control_limit_X = x_double_bar - a2 * average_range_X
upper_surv_limit= x_double_bar +(2/3)* a2 * average_range_X
lower_surv_limit= x_double_bar -(2/3)* a2 * average_range_X

# Tracer les limites de contrôle pour la courbe des moyennes


self.ax1.axhline(y=upper_control_limit_X, color='r', linestyle='-',
label="LCS X")
self.ax1.axhline(y=lower_control_limit_X, color='r', linestyle='-',
label="LCI X")
self.ax1.axhline(y=upper_surv_limit, color='g', linestyle='-',
label="LSS X")
self.ax1.axhline(y=lower_surv_limit, color='g', linestyle='-',
label="LSI X")
self.ax1.axhline(y= x_double_bar, color='r', linestyle='--',
label="X//")

# Calculer les limites de contrôle pour la courbe des étendues


if self.ranges:

n = int(self.spc_app.sample_size.get())
d4_constants = {
2: 3.267,
3: 2.574,
4: 2.282,
5: 2.114,
6: 2.004,
7: 1.924,
8: 1.864,
9: 1.816,
10: 1.777
}
d4_value = d4_constants.get(n, 0.0)
average_range = sum(self.ranges) / len(self.ranges)
upper_control_limit_R = d4_value * average_range

average_range_R = sum(self.ranges) / len(self.ranges)


D3 = {7: 0.076, 8: 0.136, 9: 0.184, 10: 0.223}
D3_value = D3.get(self.spc_app.sample_size.get(), 0)
LCI_R = D3_value * average_range_R

# Tracer les limites de contrôle pour la courbe des étendues


self.ax2.axhline(y= upper_control_limit_R, color='r', linestyle='-',
label="LCS R")
self.ax2.axhline(y=LCI_R, color='r', linestyle='-', label="LCI R")

# tracer la medianne pour la carte R


mediane = upper_control_limit_R/2
self.ax2.axhline(y=mediane, color='g', linestyle='--',
label="mediane")

# Mettre à jour les titres et les étiquettes des axes


self.ax1.set_title('Courbe des Moyennes')
self.ax1.set_xlabel('Échantillon')
self.ax1.set_ylabel('Moyenne')
self.ax1.grid(True)

self.ax2.set_title('Courbe des Étendues')


self.ax2.set_xlabel('Échantillon')
self.ax2.set_ylabel('Étendue')
self.ax2.grid(True)

# Réafficher les courbes dans le Canvas


self.canvas_widget.draw()

def show_histogram(self):
# Récupérer les valeurs des mesures pour construire l'histogramme
all_measure_values = []
for item in self.data_tree.get_children():
measure_values = [float(self.data_tree.item(item, 'values')[i + 3])
for i in range(int(self.spc_app.sample_size.get()))]
all_measure_values.extend(measure_values)

# Créer une figure Matplotlib pour l'histogramme s'il n'existe pas


if not hasattr(self, 'hist_fig'):
self.hist_fig, self.hist_ax = plt.subplots(figsize=(8, 6))
else:
# Effacer l'histogramme existant pour mettre à jour
self.hist_ax.clear()

# Tracer l'histogramme avec toutes les valeurs des mesures


self.hist_ax.hist(all_measure_values, bins=10, density=True, alpha=0.7,
color='blue', edgecolor='black')

# Calculer la moyenne et l'écart type des mesures pour la forme de cloche


mu, sigma = np.mean(all_measure_values), np.std(all_measure_values)
x = np.linspace(min(all_measure_values), max(all_measure_values), 100)
y = 1/(sigma * np.sqrt(2 * np.pi)) * np.exp(- (x - mu)**2 / (2 *
sigma**2))
self.hist_ax.plot(x, y, 'r-', linewidth=3)

# Ajouter les droites des tolérances supérieure et inférieure


tolerance_sup = self.spc_app.tolerance_max.get()
tolerance_inf = self.spc_app.tolerance_min.get()
self.hist_ax.axvline(x=tolerance_sup, color='green', linestyle='-',
linewidth=2, label='Tolérance Supérieure')
self.hist_ax.axvline(x=tolerance_inf, color='green', linestyle='-',
linewidth=2, label='Tolérance Inférieure')

# Ajouter la ligne pour la valeur cible


target_value = self.spc_app.target_value.get()
self.hist_ax.axvline(x=target_value, color='purple', linestyle='-',
linewidth=2, label='Valeur Cible')

# Calculer les limites de contrôle


control_limit_sup = mu + 3 * sigma
control_limit_inf = mu - 3 * sigma

self.hist_ax.axvline(x=mu, color='black', linestyle='--', linewidth=2,


label='X bar')
self.hist_ax.axvline(x=control_limit_sup, color='black', linestyle='--',
linewidth=2, label='3sigma+')
self.hist_ax.axvline(x=control_limit_inf, color='black', linestyle='--',
linewidth=2, label='3sigma-')

# Configurer les titres et étiquettes des axes


self.hist_ax.set_title('Histogramme des Mesures')
self.hist_ax.set_xlabel('Valeurs')
self.hist_ax.set_ylabel('Fréquence')
# Afficher la légende
self.hist_ax.legend()

# Mettre à jour l'affichage du canevas


self.histogram_canvas.draw()

def clear_measure_entries(self):
for entry in self.measure_entries:
entry.delete(0, tk.END)

def get_measure_values(self):
measure_values = []
for entry in self.measure_entries:
value = entry.get().strip() # Supprime les espaces vides autour de la
valeur
if value: # Vérifie si la valeur n'est pas vide
try:
measure_values.append(float(value)) # Convertit la valeur en
float et l'ajoute à la liste
except ValueError:
# Gère le cas où la valeur ne peut pas être convertie en float
# Vous pouvez afficher un message d'erreur ici ou ignorer la
valeur incorrecte
print(f"La valeur '{value}' n'est pas un nombre valide.")
return measure_values

# def delete_selected_row(self):
# selected_item = self.data_tree.selection() # Récupère l'élément
sélectionné dans le treeview
# if selected_item: # Vérifie s'il y a un élément sélectionné
# self.data_tree.delete(selected_item) # Supprime l'élément
sélectionné du treeview
#else:
# Gère le cas où aucun élément n'est sélectionné
# print("Aucune ligne sélectionnée pour la suppression.")

if __name__ == "__main__":

Vous aimerez peut-être aussi