Ültrapowerful Data Harmonizer Python GUI

👤 Sharing: AI
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
import pandas as pd
import os


class DataHarmonizer:
    def __init__(self, master):
        self.master = master
        master.title("?ltrapowerful Data Harmonizer")

        self.notebook = ttk.Notebook(master)
        self.notebook.pack(fill='both', expand=True)

        # Tab 1: CSV to Excel
        self.tab1 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab1, text='CSV to Excel')
        self.create_csv_to_excel_tab(self.tab1)

        # Tab 2: Data Cleaning
        self.tab2 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab2, text='Data Cleaning')
        self.create_data_cleaning_tab(self.tab2)

        # Tab 3:  Merge CSV Files
        self.tab3 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab3, text='Merge CSV Files')
        self.create_merge_csv_tab(self.tab3)

        # Details Button (Shared for all tabs)
        self.details_button = tk.Button(master, text="Details", command=self.show_details)
        self.details_button.pack(pady=10)

        self.details_window = None  # To store the details window

    def create_csv_to_excel_tab(self, tab):
        # File selection
        self.csv_file_path = tk.StringVar()
        tk.Label(tab, text="CSV File:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
        tk.Entry(tab, textvariable=self.csv_file_path, width=50).grid(row=0, column=1, padx=5, pady=5)
        tk.Button(tab, text="Browse", command=lambda: self.browse_file(self.csv_file_path)).grid(row=0, column=2, padx=5, pady=5)

        # Output path
        self.excel_file_path = tk.StringVar()
        tk.Label(tab, text="Excel File Name:").grid(row=1, column=0, padx=5, pady=5, sticky='w')
        tk.Entry(tab, textvariable=self.excel_file_path, width=50).grid(row=1, column=1, padx=5, pady=5)

        # Convert Button
        tk.Button(tab, text="Convert to Excel", command=self.convert_csv_to_excel).grid(row=2, column=1, padx=5, pady=5)

    def create_data_cleaning_tab(self, tab):
        # File selection
        self.cleaning_csv_file_path = tk.StringVar()
        tk.Label(tab, text="CSV File:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
        tk.Entry(tab, textvariable=self.cleaning_csv_file_path, width=50).grid(row=0, column=1, padx=5, pady=5)
        tk.Button(tab, text="Browse", command=lambda: self.browse_file(self.cleaning_csv_file_path)).grid(row=0, column=2, padx=5, pady=5)

        # Drop duplicates option
        self.drop_duplicates = tk.BooleanVar()
        tk.Checkbutton(tab, text="Drop Duplicate Rows", variable=self.drop_duplicates).grid(row=1, column=1, padx=5, pady=5, sticky='w')

        # Fill missing values option
        self.fill_missing = tk.BooleanVar()
        tk.Checkbutton(tab, text="Fill Missing Values (with mean)", variable=self.fill_missing).grid(row=2, column=1, padx=5, pady=5, sticky='w')

        # Clean Button
        tk.Button(tab, text="Clean Data", command=self.clean_data).grid(row=3, column=1, padx=5, pady=5)

    def create_merge_csv_tab(self, tab):
        # File selection 1
        self.merge_csv_file_path1 = tk.StringVar()
        tk.Label(tab, text="CSV File 1:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
        tk.Entry(tab, textvariable=self.merge_csv_file_path1, width=50).grid(row=0, column=1, padx=5, pady=5)
        tk.Button(tab, text="Browse", command=lambda: self.browse_file(self.merge_csv_file_path1)).grid(row=0, column=2, padx=5, pady=5)

        # File selection 2
        self.merge_csv_file_path2 = tk.StringVar()
        tk.Label(tab, text="CSV File 2:").grid(row=1, column=0, padx=5, pady=5, sticky='w')
        tk.Entry(tab, textvariable=self.merge_csv_file_path2, width=50).grid(row=1, column=1, padx=5, pady=5)
        tk.Button(tab, text="Browse", command=lambda: self.browse_file(self.merge_csv_file_path2)).grid(row=1, column=2, padx=5, pady=5)

        # Output file name
        self.merged_file_name = tk.StringVar()
        tk.Label(tab, text="Merged File Name:").grid(row=2, column=0, padx=5, pady=5, sticky='w')
        tk.Entry(tab, textvariable=self.merged_file_name, width=50).grid(row=2, column=1, padx=5, pady=5)

        # Merge Button
        tk.Button(tab, text="Merge CSVs", command=self.merge_csv_files).grid(row=3, column=1, padx=5, pady=5)


    def browse_file(self, file_path_var):
        filename = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
        file_path_var.set(filename)

    def convert_csv_to_excel(self):
        csv_file = self.csv_file_path.get()
        excel_file = self.excel_file_path.get()

        if not csv_file or not excel_file:
            self.show_error("Please select a CSV file and provide an Excel file name.")
            return

        try:
            df = pd.read_csv(csv_file)
            excel_file_path = os.path.splitext(excel_file)[0] + '.xlsx'
            df.to_excel(excel_file_path, index=False)
            self.show_message(f"CSV converted to Excel: {excel_file_path}")
        except Exception as e:
            self.show_error(f"Error converting: {e}")

    def clean_data(self):
        csv_file = self.cleaning_csv_file_path.get()

        if not csv_file:
            self.show_error("Please select a CSV file to clean.")
            return

        try:
            df = pd.read_csv(csv_file)

            if self.drop_duplicates.get():
                df.drop_duplicates(inplace=True)

            if self.fill_missing.get():
                df.fillna(df.mean(numeric_only=True), inplace=True)  # Fill numeric columns with the mean

            output_file = os.path.splitext(csv_file)[0] + "_cleaned.csv"
            df.to_csv(output_file, index=False)
            self.show_message(f"Data cleaned and saved to: {output_file}")

        except Exception as e:
            self.show_error(f"Error cleaning data: {e}")

    def merge_csv_files(self):
        file1 = self.merge_csv_file_path1.get()
        file2 = self.merge_csv_file_path2.get()
        output_file = self.merged_file_name.get()

        if not file1 or not file2 or not output_file:
            self.show_error("Please select two CSV files and provide an output file name.")
            return

        try:
            df1 = pd.read_csv(file1)
            df2 = pd.read_csv(file2)
            merged_df = pd.concat([df1, df2], ignore_index=True)
            output_file_path = os.path.splitext(output_file)[0] + '.csv'
            merged_df.to_csv(output_file_path, index=False)
            self.show_message(f"CSVs merged and saved to: {output_file_path}")
        except Exception as e:
            self.show_error(f"Error merging CSVs: {e}")

    def show_message(self, message):
        tk.messagebox.showinfo("Success", message)

    def show_error(self, message):
        tk.messagebox.showerror("Error", message)

    def show_details(self):
        if self.details_window is not None and self.details_window.winfo_exists():
            self.details_window.focus()
            return

        self.details_window = tk.Toplevel(self.master)
        self.details_window.title("Program Details")

        details_text = """The '?ltrapowerful Data Harmonizer' is a versatile tool designed to simplify common data manipulation tasks. It provides a user-friendly interface to:

        1.  **Convert CSV to Excel:** Easily convert CSV files into Excel format (.xlsx).
        2.  **Clean Data:**  Offers options to remove duplicate rows and fill missing numerical values with the mean of their respective columns. This improves data quality for analysis.
        3.  **Merge CSV Files:** Combines the contents of two CSV files into a single CSV file.

        This application leverages the 'pandas' library for efficient data handling and 'tkinter' for the graphical user interface. It is intended to be a practical and easy-to-use solution for anyone working with tabular data.
        """

        details_label = tk.Label(self.details_window, text=details_text, justify=tk.LEFT, padx=10, pady=10)
        details_label.pack()


root = tk.Tk()
app = DataHarmonizer(root)
root.mainloop()
👁️ Viewed: 7

Comments