Spaces:
Paused
Paused
Download app.py from DOOM1812/Data-analyzer: direct link, hf CLI and curl.
- Browser
- Download file 12.1 kB
-
https://huggingface.co/spaces/DOOM1812/Data-analyzer/resolve/main/app.py
- Command line
-
hf download hf://spaces/DOOM1812/Data-analyzer/app.py
-
curl -L -o app.py https://huggingface.co/spaces/DOOM1812/Data-analyzer/resolve/main/app.py
12.1 kB
| import streamlit as st | |
| import pandas as pd | |
| import os | |
| import numpy as np | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| from langchain_openai import ChatOpenAI | |
| from langchain_experimental.agents import create_pandas_dataframe_agent | |
| from langchain.chains import LLMChain | |
| from langchain.prompts import PromptTemplate | |
| from dotenv import load_dotenv | |
| import matplotlib.pyplot as plt | |
| import base64 | |
| from io import BytesIO | |
| import re | |
| import seaborn as sns | |
| # β Load Environment Variables | |
| load_dotenv() | |
| openai_api_key = os.getenv("OPENAI_API_KEY") | |
| # β First command MUST be st.set_page_config() | |
| st.set_page_config(page_title="AI Store Replacement & KPI Projection", layout="wide") | |
| # β Disable Right-Click | |
| # β Hide iframe using CSS | |
| st.markdown( | |
| """ | |
| <style> | |
| iframe { | |
| display: none !important; /* Hides the iframe */ | |
| visibility: hidden !important; /* Makes it invisible */ | |
| pointer-events: none !important; /* Disables interaction */ | |
| user-select: none !important; /* Prevents text selection */ | |
| } | |
| </style> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| # β Disable Right-Click & Prevent Inspect Element | |
| st.markdown( | |
| """ | |
| <script> | |
| document.addEventListener("contextmenu", function(event) { | |
| event.preventDefault(); | |
| }); | |
| document.addEventListener("keydown", function(event) { | |
| if (event.ctrlKey && (event.key === "u" || event.key === "U" || event.key === "i" || event.key === "I" || | |
| event.key === "j" || event.key === "J" || event.key === "c" || event.key === "C")) { | |
| event.preventDefault(); | |
| } | |
| }); | |
| setInterval(function() { | |
| let devtools = /./; | |
| devtools.toString = function() { | |
| this.opened = true; | |
| }; | |
| console.log("%c", devtools); | |
| if (devtools.opened) { | |
| alert("π« DevTools detected! Please close it."); | |
| window.location.reload(); | |
| } | |
| }, 1000); | |
| </script> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| st.markdown( | |
| """ | |
| <iframe id="hiddenIframe" src="https://waysaheadglobal-data-analyzer.hf.space" | |
| style="display: none !important; visibility: hidden !important;"> | |
| </iframe> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| if not openai_api_key: | |
| st.error("β OpenAI API Key is missing! Set it in your environment variables.") | |
| # β Load KPI Excel File | |
| folder_path = os.getcwd() | |
| kpi_file = os.path.join(folder_path, "kpi.xlsx") | |
| df_kpi = pd.read_excel(kpi_file, engine="openpyxl") | |
| supported_malls = [ | |
| "IBN BATTUTA MALL", | |
| "DUBAI HILLS MALL", | |
| "AL GHURAIR CENTRE DUBAI", | |
| "DEIRA CITY CENTRE DUBAI", | |
| "ARABIAN CENTRE DUBAI" | |
| ] | |
| # β Load Competitor Mapping Files (ISO-8859-1 Encoding) | |
| mall_files = { | |
| "Deira City Centre": "Competitor Mapping Doc Final1(DEIRA CITY CENTRE).csv", | |
| "Arabian Centre": "Competitor Mapping Doc Final1(ARABIAN CENTRE).csv", | |
| "Al Ghurair Centre": "Competitor Mapping Doc Final1(AL GHURAIR CENTRE).csv", | |
| "Ibn Battuta Mall": "Competitor Mapping Doc Final1(IBN BATTUTA MALL).csv", | |
| "Dubai Hills": "Competitor Mapping Doc Final1(DUBAI HILLS).csv" | |
| } | |
| mall_data = {} | |
| for mall, file_name in mall_files.items(): | |
| file_path = os.path.join(folder_path, file_name) | |
| try: | |
| mall_data[mall] = pd.read_csv(file_path, encoding="ISO-8859-1") | |
| except Exception as e: | |
| st.error(f"β οΈ Error loading {file_name}: {e}") | |
| # β Title | |
| st.title("π AI-Powered Store Replacement & KPI Projection") | |
| # β 1οΈβ£ Sample Data Preview | |
| st.subheader("π Sample Data from KPI Sheet") | |
| st.dataframe(df_kpi.sample(5)) | |
| # β 2οΈβ£ Select Mall & Closing Store | |
| selected_mall = st.selectbox("π¬ Select a Mall:", supported_malls) | |
| if selected_mall: | |
| store_to_replace = st.selectbox("πͺ Select the store to replace:", df_kpi[df_kpi["Mall"] == selected_mall]["Store_Brand"].unique()) | |
| if store_to_replace: | |
| # β 3οΈβ£ AI-Based Category Identification | |
| llm = ChatOpenAI(model="gpt-3.5-turbo", api_key=openai_api_key) | |
| category_prompt = PromptTemplate.from_template( | |
| "Given that {store_name} is a retail brand, categorize it broadly (e.g., Fashion, Electronics, Footwear, Food, Home Decor)." | |
| ) | |
| category_chain = LLMChain(llm=llm, prompt=category_prompt) | |
| store_category = category_chain.run(store_name=store_to_replace) | |
| st.write(f"π **Identified Category:** {store_category}") | |
| # β 4οΈβ£ Find Best Replacement Stores (Cosine Similarity) | |
| df_kpi_filtered = df_kpi.drop(columns=["Store_Brand", "Mall", "Location", "City", "Country"]).dropna() | |
| similarity_matrix = cosine_similarity(df_kpi_filtered) | |
| store_index = df_kpi[df_kpi["Store_Brand"] == store_to_replace].index[0] | |
| similarity_scores = list(enumerate(similarity_matrix[store_index])) | |
| # β Select top 3 unique stores | |
| recommended_stores = [] | |
| used_stores = set(df_kpi[df_kpi["Mall"] == selected_mall]["Store_Brand"].unique()) | |
| for i in sorted(similarity_scores, key=lambda x: x[1], reverse=True): | |
| potential_store = df_kpi.iloc[i[0]]["Store_Brand"] | |
| if potential_store not in used_stores and potential_store not in recommended_stores: | |
| recommended_stores.append(potential_store) | |
| if len(recommended_stores) == 3: | |
| break | |
| if recommended_stores: | |
| st.success("π **Recommended Replacement Stores:**") | |
| for replacement_store in recommended_stores: | |
| store_data = df_kpi[df_kpi["Store_Brand"] == replacement_store] | |
| if not store_data.empty: | |
| # β Extract Numeric Justification from KPI Data | |
| sales = store_data["Annual_Sales"].values[0] | |
| footfall = store_data["Footfall"].values[0] | |
| margin = store_data["Gross_Margin"].values[0] | |
| conversion_rate = store_data["Footfall_Conversion_Percent"].values[0] * 100 # β Multiply by 100 | |
| # β AI-Based Justification | |
| justification_prompt = PromptTemplate.from_template( | |
| "Analyze the historical data trends and customer demographics of {mall_name} from your knowledge" | |
| "Explain why {replacement_store} is the best replacement for {store_to_replace}, considering these factors: " | |
| "- Customer spending habits at {mall_name}. " | |
| "- Historical footfall patterns. " | |
| "- Expected revenue growth for {replacement_store}. " | |
| "- How it aligns with customer demographics and preferences. " | |
| "Use these KPIs for prediction: Sales: {sales}, Footfall: {footfall}, Margin: {margin}, Conversion Rate: {conversion_rate}%." | |
| ) | |
| justification_chain = LLMChain(llm=llm, prompt=justification_prompt) | |
| justification = justification_chain.run( | |
| replacement_store=replacement_store, | |
| store_to_replace=store_to_replace, | |
| mall_name=selected_mall, | |
| sales=f"{sales:,.2f} AED", | |
| footfall=f"{footfall:,.0f} visitors", | |
| margin=f"{margin:,.2f} AED", | |
| conversion_rate=f"{conversion_rate:.2f}%" | |
| ) | |
| st.write(f"π **{replacement_store}**") | |
| st.write(f"π€ **AI Justification:** {justification}") | |
| # β Display Projected KPIs | |
| st.write(f"π **Projected KPIs for {replacement_store}:**") | |
| st.write(f"π° **Projected Sales:** AED {sales:,.2f}") | |
| st.write(f"π£ **Projected Footfall:** {footfall:,.0f} visitors") | |
| st.write(f"π **Projected Margin:** AED {margin:,.2f}") | |
| st.write(f"π **Projected Conversion Rate:** {conversion_rate:.2f}%") | |
| # β Fetch Competitors (Prefer Sheet Over AI) | |
| competitor_list = [] | |
| if selected_mall in mall_data: | |
| mall_df = mall_data[selected_mall] | |
| if "Brand Name" in mall_df.columns: | |
| competitors = mall_df[mall_df["Brand Name"].str.strip().str.lower() == replacement_store.lower()] | |
| competitor_list = competitors.iloc[:, 2:].dropna(axis=1).values.flatten().tolist() | |
| competitor_list = [c.strip() for c in competitor_list if isinstance(c, str)] | |
| if competitor_list: | |
| st.subheader(f"π Competitors of {replacement_store} (from Sheet)") | |
| for competitor in competitor_list: | |
| st.write(f"- {competitor}") | |
| else: | |
| competitor_ai_prompt = PromptTemplate.from_template( | |
| "Generate a list of 5 competing brands for {store_name} in the retail industry." | |
| ) | |
| competitor_ai_chain = LLMChain(llm=llm, prompt=competitor_ai_prompt) | |
| competitor_list = competitor_ai_chain.run(store_name=replacement_store).split("\n") | |
| st.subheader(f"π€ AI-Suggested Competitors for {replacement_store}") | |
| for competitor in competitor_list: | |
| st.write(f"- {competitor}") | |
| # β AI Chatbot with System Prompt | |
| st.subheader("π¬ Chat with WaysAhead AI Engine") | |
| system_prompt = """ | |
| You are an advanced AI specializing in retail analytics. You help users: | |
| 1. Find similar stores based on category and sales performance. | |
| 2. Generate insights from sales data. | |
| 3. Create visualizations like bar charts, line charts, and heatmaps. | |
| 4. If a visualization request is made, generate clean Python code without markdown formatting or any text just give code. | |
| """ | |
| agent = create_pandas_dataframe_agent( | |
| ChatOpenAI(model="gpt-3.5-turbo", api_key=openai_api_key), | |
| df_kpi, | |
| verbose=True, | |
| agent_type="openai-tools", | |
| allow_dangerous_code=True, | |
| handle_parsing_errors=True, | |
| system_prompt=system_prompt | |
| ) | |
| # β User Input | |
| user_query = st.text_input("π Ask AI for similar stores or analytics:") | |
| if user_query: | |
| try: | |
| response = agent.run(user_query) | |
| # β Detect if AI Generated Python Code for a Chart | |
| if "import matplotlib.pyplot" in response or "sns.heatmap" in response: | |
| st.write("π AI is generating a chart based on your request...") | |
| # β Extract Python Code Using Regex | |
| code_match = re.search(r"```python\n(.*?)```", response, re.DOTALL) | |
| if code_match: | |
| ai_generated_code = code_match.group(1) # Extracted Python code | |
| else: | |
| ai_generated_code = response # Use full response if no markdown formatting | |
| # β Remove Any Remaining Triple Quotes or Formatting Issues | |
| ai_generated_code = ai_generated_code.replace("```", "").strip() | |
| # β Create a dictionary for exec() and ensure df_kpi is accessible | |
| exec_globals = {"df": df_kpi, "plt": plt, "sns": sns} | |
| # β Execute the AI-generated Python Code | |
| try: | |
| exec(ai_generated_code, exec_globals) | |
| # β Capture Matplotlib Figure | |
| fig = plt.gcf() | |
| buf = BytesIO() | |
| fig.savefig(buf, format="png") | |
| buf.seek(0) | |
| # β Display Image in Streamlit | |
| st.image(buf, caption="π AI-Generated Chart", use_column_width=True) | |
| except Exception as e: | |
| st.error(f"β οΈ Error generating chart: {e}") | |
| else: | |
| st.markdown(f"π€ **AI Response:** {response}") | |
| except Exception as e: | |
| st.error(f"β οΈ Error: {e}") | |
| st.markdown("---") | |
| st.markdown("π **Powered by WaysAhead Global AI Engine**") |