import pandas as pd import plotly.express as px from datetime import datetime import os import time from PIL import Image # ================= LOAD FILE ================= def load_file(file_path): if file_path.endswith(".csv"): return pd.read_csv(file_path) else: return pd.read_excel(file_path) # ================= GET COLUMNS ================= def get_columns(file_path): try: df = load_file(file_path) return list(df.columns) except: return [] # ================= APPLY FILTERS ================= def apply_filters(df, filters): if not filters: return df try: for f in filters: col = f["column"] ftype = f["type"] val = f["value"] if col not in df.columns: continue # equals filter if ftype == "equals": df = df[df[col].isin(val)] # contains filter elif ftype == "contains": df = df[df[col].astype(str).str.contains(val[0], case=False, na=False)] # range filter elif ftype == "range": try: min_val, max_val = val df[col] = pd.to_numeric(df[col], errors='coerce') df = df[(df[col] >= min_val) & (df[col] <= max_val)] except: continue return df except: return df # ================= ANALYSIS ================= def sales_insights(df, chart_type, x_col, y_cols): if not x_col: raise ValueError("Select X-axis") if not y_cols: raise ValueError("Select Y-axis") # Convert numeric columns for col in y_cols: df[col] = pd.to_numeric(df[col], errors='coerce') df = df.dropna(subset=y_cols) # Aggregate data summary = df.groupby(x_col)[y_cols].sum().reset_index() # Create charts if chart_type == "Bar Chart": fig = px.bar(summary, x=x_col, y=y_cols, barmode="group") elif chart_type == "Line Chart": fig = px.line(summary, x=x_col, y=y_cols, markers=True) elif chart_type == "Pie Chart": fig = px.pie(summary, names=x_col, values=y_cols[0]) elif chart_type == "Box Plot": fig = px.box(df, x=x_col, y=y_cols[0], points="all") else: raise ValueError("Invalid chart type") fig.update_layout(template="plotly_white", height=600) # Save output files chart_path = "output_chart.png" data_path = "output_data.xlsx" try: fig.write_image(chart_path) except: Image.new('RGB', (1100, 650), color='#eeeeee').save(chart_path) summary.to_excel(data_path, index=False) return fig, chart_path, data_path # ================= FEEDBACK ================= def save_feedback(name, comment, stars): file = "feedback.xlsx" try: stars = max(1, min(5, int(stars))) except: stars = 3 entry = { "Time": datetime.now(), "Name": name or "Anonymous", "Comment": comment or "", "Stars": stars } for _ in range(3): try: if os.path.exists(file): df = pd.read_excel(file) else: df = pd.DataFrame(columns=entry.keys()) df = pd.concat([df, pd.DataFrame([entry])], ignore_index=True) df.to_excel(file, index=False) return "✅ Saved" except: time.sleep(0.3) return "❌ Error"