| import pandas as pd |
| import plotly.express as px |
| from datetime import datetime |
| import os |
| import time |
| from PIL import Image |
|
|
| |
| def load_file(file_path): |
| if file_path.endswith(".csv"): |
| return pd.read_csv(file_path) |
| else: |
| return pd.read_excel(file_path) |
|
|
| |
| def get_columns(file_path): |
| try: |
| df = load_file(file_path) |
| return list(df.columns) |
| except: |
| return [] |
|
|
| |
| 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 |
|
|
| |
| if ftype == "equals": |
| df = df[df[col].isin(val)] |
|
|
| |
| elif ftype == "contains": |
| df = df[df[col].astype(str).str.contains(val[0], case=False, na=False)] |
|
|
| |
| 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 |
|
|
| |
| 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") |
|
|
| |
| for col in y_cols: |
| df[col] = pd.to_numeric(df[col], errors='coerce') |
|
|
| df = df.dropna(subset=y_cols) |
|
|
| |
| summary = df.groupby(x_col)[y_cols].sum().reset_index() |
|
|
| |
| 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) |
|
|
| |
| 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 |
|
|
|
|
| |
| 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" |