Files changed (1) hide show
  1. app.py +373 -351
app.py CHANGED
@@ -1,351 +1,373 @@
1
- import os
2
- import pyaudio
3
- import pandas as pd
4
- from sentence_transformers import SentenceTransformer
5
- from sklearn.metrics.pairwise import cosine_similarity
6
- import numpy as np
7
- import time
8
- import speech_recognition as sr
9
- from textblob import TextBlob
10
- import streamlit as st
11
- import seaborn as sns
12
- import plotly.express as px
13
- from datetime import datetime, timedelta
14
- import gspread
15
- from google.oauth2.service_account import Credentials
16
-
17
- # Set up paths
18
- csv_file_path = r"C:\Users\Muthuraja\OneDrive\Attachments\Desktop\second\context.csv" # Path to your CSV file
19
- output_csv_path = r"C:\Users\Muthuraja\OneDrive\Attachments\Desktop\second\query_results.csv" # Path to save query results
20
-
21
- # Google Sheets setup
22
- SCOPE = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
23
- CREDS_PATH = r"C:\Users\Muthuraja\Downloads\modern-cycling-444916-g6-82c207d3eb47.json" # Provide your Google credentials path
24
-
25
- # Initialize Google Sheets connection
26
- def initialize_google_sheets():
27
- credentials = Credentials.from_service_account_file(CREDS_PATH, scopes=SCOPE)
28
- try:
29
- client = gspread.authorize(credentials)
30
- sheet = client.open("SalesStores").sheet1 # Change Google Sheet name to "SalesStores"
31
- return sheet
32
- except gspread.exceptions.APIError as e:
33
- st.error(f"Google Sheets API error: {e}")
34
- return None
35
-
36
- sheet = initialize_google_sheets()
37
-
38
- # Function to safely load the CSV dataset
39
- def load_csv_safely(file_path):
40
- try:
41
- # Attempt to read with error handling for bad lines
42
- df = pd.read_csv(file_path, on_bad_lines='skip') # Skips malformed lines
43
- # Check if the required columns exist
44
- required_columns = ['question', 'product', 'price', 'features', 'ratings', 'discount']
45
- for column in required_columns:
46
- if column not in df.columns:
47
- raise Exception(f"CSV does not contain the required column: '{column}'. Please check your CSV.")
48
-
49
- # If 'Timestamp' column doesn't exist, create it as NaN or empty
50
- if 'Timestamp' not in df.columns:
51
- df['Timestamp'] = pd.NaT # Set it to NaT (Not a Time) initially
52
-
53
- return df
54
- except pd.errors.ParserError as e:
55
- st.error(f"Error reading CSV file: {e}")
56
- return None
57
- except Exception as e:
58
- st.error(f"An error occurred: {e}")
59
- return None
60
-
61
- dataset = load_csv_safely(csv_file_path) # Load the dataset safely
62
- embedding_model = SentenceTransformer('all-MiniLM-L6-v2') # Pre-trained sentence transformer model
63
-
64
- # Function to filter data by date
65
- def filter_data_by_date(data, date_filter):
66
- if date_filter == "Today":
67
- start_date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
68
- data = data[data['Timestamp'] >= start_date]
69
- elif date_filter == "One Week":
70
- start_date = datetime.now() - timedelta(weeks=1)
71
- data = data[data['Timestamp'] >= start_date]
72
- return data
73
-
74
- # Function to recognize speech using SpeechRecognition and PyAudio in chunks
75
- def listen_to_speech():
76
- recognizer = sr.Recognizer()
77
-
78
- # Initialize PyAudio microphone stream
79
- with sr.Microphone() as source:
80
- recognizer.adjust_for_ambient_noise(source)
81
- st.write("Listening...") # Optional: Add a message to indicate listening state
82
-
83
- try:
84
- # Listen for the audio input
85
- audio = recognizer.listen(source, timeout=5, phrase_time_limit=10) # Listen for up to 10 seconds
86
- st.write("Recognizing...") # Optional: Add a message for recognition process
87
-
88
- # Use Google's speech recognition to convert audio to text
89
- text = recognizer.recognize_google(audio)
90
- st.write(f"Recognized: {text}")
91
- return text # Return the text detected from the audio
92
- except sr.UnknownValueError:
93
- st.error("Sorry, I could not understand the audio.") # Handle case when the audio is unclear
94
- return None
95
- except sr.RequestError:
96
- st.error("Could not request results from Google Speech Recognition service.") # Handle network issues
97
- return None
98
- except Exception as e:
99
- st.error(f"An error occurred: {e}")
100
- return None
101
-
102
- # Function to check if the text is a greeting
103
- def is_greeting(text):
104
- greetings = ["hello", "hi", "hey", "good morning", "good afternoon", "good evening", "hola"]
105
- return any(greeting in text.lower() for greeting in greetings)
106
-
107
- # Function to respond to greetings
108
- def respond_to_greeting():
109
- st.write("Hi there! How can I assist you today? 😊")
110
-
111
- # Function to extract the product name from the query
112
- def extract_product_name(query):
113
- # Ensure that all product names are strings and handle NaN values
114
- for product in dataset['product'].fillna('Unknown').astype(str):
115
- if product.lower() in query.lower():
116
- return product
117
- return None
118
-
119
- # Function to find the best matching answer using embeddings (Retrieve part of RAG)
120
- def find_answer(query):
121
- if dataset is None:
122
- return "Dataset not loaded properly."
123
-
124
- # Compute the embedding of the query
125
- query_embedding = embedding_model.encode([query])
126
-
127
- # Compute embeddings for all the dataset questions
128
- dataset_embeddings = embedding_model.encode(dataset['question'].tolist())
129
-
130
- # Find the closest match using cosine similarity
131
- similarities = cosine_similarity(query_embedding, dataset_embeddings)
132
-
133
- # Get the index of the most similar question
134
- closest_idx = np.argmax(similarities)
135
-
136
- # Retrieve the product info associated with the closest question
137
- closest_question = dataset.iloc[closest_idx]
138
- product_name = closest_question['product']
139
- price = closest_question['price']
140
- features = closest_question['features']
141
- ratings = closest_question['ratings']
142
- discount = closest_question['discount']
143
-
144
- # Ensure 'Timestamp' column exists before appending
145
- if 'Timestamp' not in closest_question.index:
146
- closest_question['Timestamp'] = datetime.now()
147
-
148
- # Append the query and answer to the CSV file
149
- new_entry = {
150
- 'question': query,
151
- 'product': product_name,
152
- 'price': price,
153
- 'features': features,
154
- 'ratings': ratings,
155
- 'discount': discount,
156
- 'Timestamp': datetime.now()
157
- }
158
- new_entry_df = pd.DataFrame([new_entry])
159
-
160
- # Save the new entry to the CSV file
161
- new_entry_df.to_csv(output_csv_path, mode='a', header=not os.path.exists(output_csv_path), index=False)
162
-
163
- # Return specific info based on query
164
- if "price" in query.lower():
165
- return f"The price of {product_name} is {price}"
166
- elif "features" in query.lower():
167
- return f"Features of {product_name}: {features}"
168
- elif "discount" in query.lower():
169
- return f"The discount on {product_name} is {discount}%"
170
- else:
171
- return f"Product: {product_name}\nPrice: {price}\nFeatures: {features}\nRatings: {ratings}\nDiscount: {discount}%"
172
-
173
- # Function for sentiment analysis using TextBlob with emojis
174
- def analyze_sentiment_with_emoji(text):
175
- # Create a TextBlob object
176
- blob = TextBlob(text)
177
-
178
- # Get the sentiment polarity (-1 to 1)
179
- sentiment_score = blob.sentiment.polarity
180
-
181
- # Determine sentiment and corresponding emoji based on the polarity score
182
- if sentiment_score > 0:
183
- sentiment = "Positive"
184
- emoji = "😊" # Happy emoji for positive sentiment
185
- elif sentiment_score < 0:
186
- sentiment = "Negative"
187
- emoji = "😞" # Sad emoji for negative sentiment
188
- else:
189
- sentiment = "Neutral"
190
- emoji = "😐" # Neutral emoji for neutral sentiment
191
-
192
- return sentiment, sentiment_score, emoji
193
-
194
- # Function to provide product recommendations (only product names) based on the query
195
- def recommend_products(query):
196
- if dataset is None:
197
- return "Dataset not loaded properly."
198
-
199
- # Ensure all product names are strings and handle missing data
200
- dataset['product'] = dataset['product'].fillna('Unknown').astype(str)
201
-
202
- # Compute the embedding of the query
203
- query_embedding = embedding_model.encode([query])
204
-
205
- # Compute embeddings for all the dataset product names
206
- dataset_embeddings = embedding_model.encode(dataset['product'].tolist())
207
-
208
- # Find the closest match using cosine similarity
209
- similarities = cosine_similarity(query_embedding, dataset_embeddings)
210
-
211
- # Get the indices of the top 3 recommendations
212
- top_indices = np.argsort(similarities[0])[-3:][::-1] # Get top 3 recommendations
213
-
214
- # Return at least 3 recommendations
215
- recommendations = []
216
- for idx in top_indices:
217
- product = dataset.iloc[idx]
218
- recommendations.append({
219
- 'product': product['product'],
220
- 'price': product['price'],
221
- 'features': product['features'],
222
- 'ratings': product['ratings'],
223
- 'discount': product['discount']
224
- }) # Append product details
225
-
226
- # If there are less than 3 recommendations, pad with default responses
227
- while len(recommendations) < 3:
228
- recommendations.append({
229
- 'product': 'No recommendation available',
230
- 'price': 'N/A',
231
- 'features': 'N/A',
232
- 'ratings': 'N/A',
233
- 'discount': 'N/A'
234
- })
235
-
236
- return recommendations
237
-
238
- # Function to handle the entire continuous interaction loop
239
- def continuous_interaction():
240
- st.title("Speech Recognition with Product Queries")
241
- if st.button("Start Speech Recognition"):
242
- while True: # Loop for continuous listening
243
- user_input = listen_to_speech()
244
- if user_input:
245
- # Check if the user is greeting
246
- if is_greeting(user_input):
247
- respond_to_greeting()
248
- continue # Skip the rest of the code and just greet
249
- # Extract product name if mentioned
250
- product_name = extract_product_name(user_input)
251
- if product_name:
252
- # If the user asks for a product like "iPhone price", respond with product details
253
- st.write(f"Let me check the details for {product_name}:")
254
- product_details = dataset[dataset['product'].str.lower() == product_name.lower()]
255
- if not product_details.empty:
256
- product_info = product_details.iloc[0]
257
- st.write(f"Product: {product_info['product']}")
258
- st.write(f"Price: {product_info['price']}")
259
- st.write(f"Features: {product_info['features']}")
260
- st.write(f"Ratings: {product_info['ratings']}")
261
- st.write(f"Discount: {product_info['discount']}%")
262
- else:
263
- st.write("Sorry, I couldn't find the product you're asking for.")
264
- else:
265
- # If no specific product is mentioned, perform normal question answering
266
- answer = find_answer(user_input)
267
- st.write(f"Answer: {answer}")
268
-
269
- # Sentiment Analysis with Emoji
270
- sentiment, sentiment_score, emoji = analyze_sentiment_with_emoji(user_input)
271
- st.write(f"Sentiment: {sentiment} (Score: {sentiment_score}) {emoji}")
272
-
273
- # Product Recommendations based on query
274
- st.write("Here are some product recommendations based on your query: ")
275
- recommendations = recommend_products(user_input)
276
- if recommendations:
277
- for idx, rec in enumerate(recommendations, 1):
278
- st.write(f"**Recommendation {idx}:**")
279
- st.write(f"**Product**: {rec['product']}")
280
- st.write(f"**Price**: {rec['price']}")
281
- st.write(f"**Features**: {rec['features']}")
282
- st.write(f"**Ratings**: {rec['ratings']}")
283
- st.write(f"**Discount**: {rec['discount']}%")
284
- st.write("---") # Separator between recommendations
285
-
286
- # Handle objections if any
287
- st.write("Do you like the recommendation or should I try again?")
288
- if listen_to_speech(): # Listen for user feedback
289
- pass
290
-
291
- # Dashboard function
292
- def display_dashboard():
293
- # Here you can display your dashboard content
294
- st.title("Product Dashboard")
295
- st.write("Welcome to the product query dashboard!")
296
-
297
- # Load query results from CSV
298
- query_results_df = pd.read_csv(output_csv_path, on_bad_lines='skip') # Skip bad lines when loading the CSV
299
-
300
- # Show a summary table of recent queries
301
- st.subheader("Recent Queries Summary")
302
- st.write(query_results_df.tail(10)) # Show the last 10 queries
303
-
304
- # Sentiment Analysis - Pie Chart for Positive, Negative, Neutral sentiment distribution
305
- sentiment_counts = query_results_df['question'].apply(lambda x: analyze_sentiment_with_emoji(x)[0]).value_counts()
306
- st.subheader("Sentiment Analysis Distribution")
307
- st.write(sentiment_counts)
308
-
309
- # Pie chart for sentiment distribution
310
- sentiment_fig = px.pie(
311
- sentiment_counts,
312
- names=sentiment_counts.index,
313
- values=sentiment_counts.values,
314
- title="Sentiment Distribution of Queries"
315
- )
316
- st.plotly_chart(sentiment_fig)
317
-
318
- # Line Chart - Sentiment score over time (based on Timestamp)
319
- query_results_df['Timestamp'] = pd.to_datetime(query_results_df['Timestamp'], errors='coerce')
320
- query_results_df['sentiment_score'] = query_results_df['question'].apply(lambda x: analyze_sentiment_with_emoji(x)[1])
321
-
322
- sentiment_time_fig = px.line(
323
- query_results_df,
324
- x='Timestamp',
325
- y='sentiment_score',
326
- title="Sentiment Score Over Time"
327
- )
328
- st.plotly_chart(sentiment_time_fig)
329
-
330
- # Product-based Analysis - Product popularity (based on number of queries)
331
- product_counts = query_results_df['product'].value_counts()
332
- st.subheader("Product Popularity")
333
- st.write(product_counts)
334
-
335
- # Pie chart for product popularity
336
- product_popularity_fig = px.pie(
337
- product_counts,
338
- names=product_counts.index,
339
- values=product_counts.values,
340
- title="Product Popularity"
341
- )
342
- st.plotly_chart(product_popularity_fig)
343
-
344
- # Main code logic for running the application
345
- if __name__ == "__main__":
346
- choice = st.sidebar.selectbox("Select Mode", ["Dashboard", "Speech Recognition"])
347
-
348
- if choice == "Dashboard":
349
- display_dashboard() # Display dashboard if selected
350
- else:
351
- continuous_interaction() # Speech recognition interaction
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pyaudio
3
+ import pandas as pd
4
+ from sentence_transformers import SentenceTransformer
5
+ from sklearn.metrics.pairwise import cosine_similarity
6
+ import numpy as np
7
+ import time
8
+ import speech_recognition as sr
9
+ from textblob import TextBlob
10
+ import streamlit as st
11
+ import seaborn as sns
12
+ import plotly.express as px
13
+ from datetime import datetime, timedelta
14
+ import gspread
15
+ from google.oauth2.service_account import Credentials
16
+
17
+ # Set up paths
18
+ csv_file_path = r"C:\Users\Muthuraja\OneDrive\Attachments\Desktop\second\context.csv" # Path to your CSV file
19
+ output_csv_path = r"C:\Users\Muthuraja\OneDrive\Attachments\Desktop\second\context.csv" # Path to save query results
20
+
21
+ # Google Sheets setup
22
+ SCOPE = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
23
+ CREDS_PATH = r"C:\Users\Muthuraja\Downloads\modern-cycling-444916-g6-82c207d3eb47.json" # Provide your Google credentials path
24
+
25
+ # Initialize Google Sheets connection
26
+ def initialize_google_sheets():
27
+ credentials = Credentials.from_service_account_file(CREDS_PATH, scopes=SCOPE)
28
+ try:
29
+ client = gspread.authorize(credentials)
30
+ sheet = client.open("infosys").sheet1 # Change Google Sheet name to "SalesStores"
31
+ return sheet
32
+ except gspread.exceptions.APIError as e:
33
+ st.error(f"Google Sheets API error: {e}")
34
+ return None
35
+
36
+ sheet = initialize_google_sheets()
37
+
38
+ # Function to safely load the CSV dataset
39
+ def load_csv_safely(file_path):
40
+ try:
41
+ # Attempt to read with error handling for bad lines
42
+ df = pd.read_csv(file_path, on_bad_lines='skip') # Skips malformed lines
43
+ # Check if the required columns exist
44
+ required_columns = ['question', 'product', 'price', 'features', 'ratings', 'discount']
45
+ for column in required_columns:
46
+ if column not in df.columns:
47
+ raise Exception(f"CSV does not contain the required column: '{column}'. Please check your CSV.")
48
+
49
+ # If 'Timestamp' column doesn't exist, create it as NaT or empty
50
+ if 'Timestamp' not in df.columns:
51
+ df['Timestamp'] = pd.NaT # Set it to NaT (Not a Time) initially
52
+
53
+ return df
54
+ except pd.errors.ParserError as e:
55
+ st.error(f"Error reading CSV file: {e}")
56
+ return None
57
+ except Exception as e:
58
+ st.error(f"An error occurred: {e}")
59
+ return None
60
+
61
+ dataset = load_csv_safely(csv_file_path) # Load the dataset safely
62
+ embedding_model = SentenceTransformer('all-MiniLM-L6-v2') # Pre-trained sentence transformer model
63
+
64
+ # Function to filter data by date
65
+ def filter_data_by_date(data, date_filter):
66
+ if date_filter == "Today":
67
+ start_date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
68
+ data = data[data['Timestamp'] >= start_date]
69
+ elif date_filter == "One Week":
70
+ start_date = datetime.now() - timedelta(weeks=1)
71
+ data = data[data['Timestamp'] >= start_date]
72
+ return data
73
+
74
+ # Function to recognize speech using SpeechRecognition and PyAudio in chunks
75
+ def listen_to_speech():
76
+ recognizer = sr.Recognizer()
77
+
78
+ # Initialize PyAudio microphone stream
79
+ with sr.Microphone() as source:
80
+ recognizer.adjust_for_ambient_noise(source)
81
+ st.write("Listening...") # Optional: Add a message to indicate listening state
82
+
83
+ try:
84
+ # Listen for the audio input
85
+ audio = recognizer.listen(source, timeout=5, phrase_time_limit=10) # Listen for up to 10 seconds
86
+ st.write("Recognizing...") # Optional: Add a message for recognition process
87
+
88
+ # Use Google's speech recognition to convert audio to text
89
+ text = recognizer.recognize_google(audio)
90
+ st.write(f"Recognized: {text}")
91
+ return text # Return the text detected from the audio
92
+ except sr.UnknownValueError:
93
+ st.error("Sorry, I could not understand the audio.") # Handle case when the audio is unclear
94
+ return None
95
+ except sr.RequestError:
96
+ st.error("Could not request results from Google Speech Recognition service.") # Handle network issues
97
+ return None
98
+ except Exception as e:
99
+ st.error(f"An error occurred: {e}")
100
+ return None
101
+
102
+ # Function to check if the text is a greeting
103
+ def is_greeting(text):
104
+ greetings = ["hello", "hi", "hey", "good morning", "good afternoon", "good evening", "hola"]
105
+ return any(greeting in text.lower() for greeting in greetings)
106
+
107
+ # Function to respond to greetings
108
+ def respond_to_greeting():
109
+ st.write("Hi there! How can I assist you today? 😊")
110
+
111
+ # Function to extract the product name from the query
112
+ def extract_product_name(query):
113
+ # Ensure that all product names are strings and handle NaN values
114
+ for product in dataset['product'].fillna('Unknown').astype(str):
115
+ if product.lower() in query.lower():
116
+ return product
117
+ return None
118
+
119
+ # Function to find the best matching answer using embeddings (Retrieve part of RAG)
120
+ def find_answer(query):
121
+ if dataset is None:
122
+ return "Dataset not loaded properly."
123
+
124
+ # Compute the embedding of the query
125
+ query_embedding = embedding_model.encode([query])
126
+
127
+ # Compute embeddings for all the dataset questions
128
+ dataset_embeddings = embedding_model.encode(dataset['question'].tolist())
129
+
130
+ # Find the closest match using cosine similarity
131
+ similarities = cosine_similarity(query_embedding, dataset_embeddings)
132
+
133
+ # Get the index of the most similar question
134
+ closest_idx = np.argmax(similarities)
135
+
136
+ # Retrieve the product info associated with the closest question
137
+ closest_question = dataset.iloc[closest_idx]
138
+ product_name = closest_question['product']
139
+ price = closest_question['price']
140
+ features = closest_question['features']
141
+ ratings = closest_question['ratings']
142
+ discount = closest_question['discount']
143
+
144
+ # Ensure 'Timestamp' column exists before appending
145
+ if 'Timestamp' not in closest_question.index:
146
+ closest_question['Timestamp'] = datetime.now()
147
+
148
+ # Save the query and response to CSV
149
+ save_query_to_csv(query, product_name, price, features, ratings, discount)
150
+
151
+ # Return specific info based on query
152
+ if "price" in query.lower():
153
+ return f"The price of {product_name} is {price}"
154
+ elif "features" in query.lower():
155
+ return f"Features of {product_name}: {features}"
156
+ elif "discount" in query.lower():
157
+ return f"The discount on {product_name} is {discount}%"
158
+ else:
159
+ return f"Product: {product_name}\nPrice: {price}\nFeatures: {features}\nRatings: {ratings}\nDiscount: {discount}%"
160
+
161
+ # Function to save the query and answer to 'context.csv'
162
+ def save_query_to_csv(query, product_name, price, features, ratings, discount):
163
+ new_entry = {
164
+ 'question': query,
165
+ 'product': product_name,
166
+ 'price': price,
167
+ 'features': features,
168
+ 'ratings': ratings,
169
+ 'discount': discount,
170
+ 'Timestamp': datetime.now() # Ensure the timestamp is correct
171
+ }
172
+ new_entry_df = pd.DataFrame([new_entry])
173
+
174
+ # Append to CSV (ensure header is only added for the first entry)
175
+ new_entry_df.to_csv(output_csv_path, mode='a', header=not os.path.exists(output_csv_path), index=False)
176
+
177
+ # Function for sentiment analysis using TextBlob with emojis
178
+ def analyze_sentiment_with_emoji(text):
179
+ # Create a TextBlob object
180
+ blob = TextBlob(text)
181
+
182
+ # Get the sentiment polarity (-1 to 1)
183
+ sentiment_score = blob.sentiment.polarity
184
+
185
+ # Determine sentiment and corresponding emoji based on the polarity score
186
+ if sentiment_score > 0:
187
+ sentiment = "Positive"
188
+ emoji = "😊" # Happy emoji for positive sentiment
189
+ elif sentiment_score < 0:
190
+ sentiment = "Negative"
191
+ emoji = "😞" # Sad emoji for negative sentiment
192
+ else:
193
+ sentiment = "Neutral"
194
+ emoji = "😐" # Neutral emoji for neutral sentiment
195
+
196
+ return sentiment, sentiment_score, emoji
197
+
198
+ # Function to provide product recommendations (only product names) based on the query
199
+ def recommend_products(query):
200
+ if dataset is None:
201
+ return "Dataset not loaded properly."
202
+
203
+ # Ensure all product names are strings and handle missing data
204
+ dataset['product'] = dataset['product'].fillna('Unknown').astype(str)
205
+
206
+ # Compute the embedding of the query
207
+ query_embedding = embedding_model.encode([query])
208
+
209
+ # Compute embeddings for all the dataset product names
210
+ dataset_embeddings = embedding_model.encode(dataset['product'].tolist())
211
+
212
+ # Find the closest match using cosine similarity
213
+ similarities = cosine_similarity(query_embedding, dataset_embeddings)
214
+
215
+ # Get the indices of the top 3 recommendations
216
+ top_indices = np.argsort(similarities[0])[-3:][::-1] # Get top 3 recommendations
217
+
218
+ # Return at least 3 recommendations
219
+ recommendations = []
220
+ for idx in top_indices:
221
+ product = dataset.iloc[idx]
222
+ recommendations.append({
223
+ 'product': product['product'],
224
+ 'price': product['price'],
225
+ 'features': product['features'],
226
+ 'ratings': product['ratings'],
227
+ 'discount': product['discount']
228
+ }) # Append product details
229
+
230
+ # If there are less than 3 recommendations, pad with default responses
231
+ while len(recommendations) < 3:
232
+ recommendations.append({
233
+ 'product': 'No recommendation available',
234
+ 'price': 'N/A',
235
+ 'features': 'N/A',
236
+ 'ratings': 'N/A',
237
+ 'discount': 'N/A'
238
+ })
239
+
240
+ return recommendations
241
+
242
+ # Function to handle the entire continuous interaction loop
243
+ def continuous_interaction():
244
+ st.title("Speech Recognition with Product Queries")
245
+ if st.button("Start Speech Recognition"):
246
+ while True: # Loop for continuous listening
247
+ user_input = listen_to_speech()
248
+ if user_input:
249
+ # Check if the user is greeting
250
+ if is_greeting(user_input):
251
+ respond_to_greeting()
252
+ continue # Skip the rest of the code and just greet
253
+ # Extract product name if mentioned
254
+ product_name = extract_product_name(user_input)
255
+ if product_name:
256
+ # If the user asks for a product like "iPhone price", respond with product details
257
+ st.write(f"Let me check the details for {product_name}:")
258
+ product_details = dataset[dataset['product'].str.lower() == product_name.lower()]
259
+ if not product_details.empty:
260
+ product_info = product_details.iloc[0]
261
+ st.write(f"Product: {product_info['product']}")
262
+ st.write(f"Price: {product_info['price']}")
263
+ st.write(f"Features: {product_info['features']}")
264
+ st.write(f"Ratings: {product_info['ratings']}")
265
+ st.write(f"Discount: {product_info['discount']}%")
266
+ else:
267
+ st.write("Sorry, I couldn't find the product you're asking for.")
268
+ else:
269
+ # If no specific product is mentioned, perform normal question answering
270
+ answer = find_answer(user_input)
271
+ st.write(f"Answer: {answer}")
272
+
273
+ # Sentiment Analysis with Emoji
274
+ sentiment, sentiment_score, emoji = analyze_sentiment_with_emoji(user_input)
275
+ st.write(f"Sentiment: {sentiment} (Score: {sentiment_score}) {emoji}")
276
+
277
+ # Product Recommendations based on query
278
+ st.write("Here are some product recommendations based on your query: ")
279
+ recommendations = recommend_products(user_input)
280
+ if recommendations:
281
+ for idx, rec in enumerate(recommendations, 1):
282
+ st.write(f"**Recommendation {idx}:**")
283
+ st.write(f"**Product**: {rec['product']}")
284
+ st.write(f"**Price**: {rec['price']}")
285
+ st.write(f"**Features**: {rec['features']}")
286
+ st.write(f"**Ratings**: {rec['ratings']}")
287
+ st.write(f"**Discount**: {rec['discount']}%")
288
+ st.write("---") # Separator between recommendations
289
+
290
+ # Handle objections if any
291
+ st.write("Do you like the recommendation or should I try again?")
292
+
293
+ # Dashboard function with time filtering
294
+ def display_dashboard():
295
+ st.title("Product Dashboard")
296
+ st.write("Welcome to the product query dashboard!")
297
+
298
+ # Sidebar time filter
299
+ time_filter = st.sidebar.selectbox(
300
+ "Select time period",
301
+ ["All Time", "Today", "One Week"]
302
+ )
303
+
304
+ query_results_df = pd.read_csv(output_csv_path, on_bad_lines='skip') # Load query results from 'context.csv'
305
+
306
+ # Check if 'Timestamp' column exists
307
+ if 'Timestamp' not in query_results_df.columns:
308
+ query_results_df['Timestamp'] = pd.to_datetime('now') # Add current timestamp if column is missing
309
+
310
+ # Filter data based on time selection
311
+ query_results_df = filter_data_by_date(query_results_df, time_filter)
312
+
313
+ st.subheader(f"Recent Queries Summary ({time_filter})")
314
+ st.write(query_results_df.tail(10)) # Show the last 10 queries
315
+
316
+ sentiment_counts = query_results_df['question'].apply(lambda x: analyze_sentiment_with_emoji(x)[0]).value_counts()
317
+ st.subheader(f"Sentiment Analysis Distribution ({time_filter})")
318
+ st.write(sentiment_counts)
319
+
320
+ sentiment_fig = px.pie(
321
+ sentiment_counts,
322
+ names=sentiment_counts.index,
323
+ values=sentiment_counts.values,
324
+ title=f"Sentiment Distribution of Queries ({time_filter})"
325
+ )
326
+ st.plotly_chart(sentiment_fig)
327
+
328
+ # Ensure 'Timestamp' is properly converted to datetime
329
+ query_results_df['Timestamp'] = pd.to_datetime(query_results_df['Timestamp'], errors='coerce')
330
+
331
+ query_results_df['sentiment_score'] = query_results_df['question'].apply(lambda x: analyze_sentiment_with_emoji(x)[1])
332
+
333
+ sentiment_time_fig = px.line(
334
+ query_results_df,
335
+ x='Timestamp',
336
+ y='sentiment_score',
337
+ title=f"Sentiment Score Over Time ({time_filter})"
338
+ )
339
+ st.plotly_chart(sentiment_time_fig)
340
+
341
+ product_counts = query_results_df['product'].value_counts()
342
+ st.subheader(f"Product Popularity ({time_filter})")
343
+ st.write(product_counts)
344
+
345
+ product_popularity_fig = px.pie(
346
+ product_counts,
347
+ names=product_counts.index,
348
+ values=product_counts.values,
349
+ title=f"Product Popularity ({time_filter})"
350
+ )
351
+ st.plotly_chart(product_popularity_fig)
352
+
353
+ # Most recommended products
354
+ recommended_products = query_results_df['product'].value_counts()
355
+ st.subheader(f"Most Recommended Products ({time_filter})")
356
+ st.write(recommended_products)
357
+
358
+ recommended_products_fig = px.bar(
359
+ recommended_products,
360
+ x=recommended_products.index,
361
+ y=recommended_products.values,
362
+ title=f"Top Recommended Products ({time_filter})"
363
+ )
364
+ st.plotly_chart(recommended_products_fig)
365
+
366
+ # Main code logic for running the application
367
+ if __name__ == "__main__":
368
+ choice = st.sidebar.selectbox("Select Mode", ["Dashboard", "Speech Recognition"])
369
+
370
+ if choice == "Dashboard":
371
+ display_dashboard() # Display dashboard if selected
372
+ else:
373
+ continuous_interaction() # Speech recognition interaction