zsoltapp commited on
Commit
a987248
1 Parent(s): e8b355f

Upload 101 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +9 -0
  2. BERTopic.ipynb +0 -0
  3. DrPepper.xlsx +3 -0
  4. NikeTwitter.csv +0 -0
  5. Untitled.ipynb +251 -0
  6. archivePrompts.txt +74 -0
  7. dev.sh +1 -0
  8. favicon.ico +0 -0
  9. gradio_app.ipynb +0 -0
  10. gradio_app.py +2088 -0
  11. gradio_experiments.py +32 -0
  12. mtu_blogs.csv +0 -0
  13. mtu_merged_v3.csv +3 -0
  14. mtuspecific/3d.html +527 -0
  15. mtuspecific/3d_old.html +3 -0
  16. mtuspecific/3dnew.html +3 -0
  17. mtuspecific/chart1.html +55 -0
  18. mtuspecific/mtu_merged_v3.csv +3 -0
  19. mtuspecific/mtu_merged_v3.csv3d.html +0 -0
  20. mtuspecific/parl.html +158 -0
  21. mtuspecific/pieros.html +57 -0
  22. mtuspecific/projectdata copy 2.js +0 -0
  23. mtuspecific/projectdata copy 3.js +0 -0
  24. mtuspecific/projectdata copy 4.js +0 -0
  25. mtuspecific/projectdata copy.js +0 -0
  26. mtuspecific/projectdata.js +0 -0
  27. mtuspecific/test.js +1 -0
  28. mtuspecific/test.json +6 -0
  29. prod.sh +3 -0
  30. readme.md +48 -0
  31. requirements.txt +58 -0
  32. test.xlsx +0 -0
  33. testpandas.py +124 -0
  34. topic.py +2073 -0
  35. uploader/.DS_Store +0 -0
  36. uploader/.gitignore +1 -0
  37. uploader/uploadapi.py +73 -0
  38. uploader/uploads/.DS_Store +0 -0
  39. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/LambWestonBrand.csv +0 -0
  40. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/LambWestonNews.csv +0 -0
  41. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.csv +3 -0
  42. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.csvExecutive Summary_CACHE.txt_old +56 -0
  43. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.xlsx +3 -0
  44. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.xlsxExecutive Summary_CACHE.txt +55 -0
  45. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/OnionTW.csv +0 -0
  46. uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/OnionTW.xlsx +3 -0
  47. uploader/uploads/demo/LambWestonBrand.csv +0 -0
  48. uploader/uploads/demo/LambWestonBrand.csvExecutive Summary_CACHE.txt +41 -0
  49. uploader/uploads/demo/MozzarellaTW.xlsx +3 -0
  50. uploader/uploads/demo/MozzarellaTW.xlsxdf3.csv +442 -0
.gitattributes CHANGED
@@ -32,3 +32,12 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ DrPepper.xlsx filter=lfs diff=lfs merge=lfs -text
36
+ mtu_merged_v3.csv filter=lfs diff=lfs merge=lfs -text
37
+ mtuspecific/3d_old.html filter=lfs diff=lfs merge=lfs -text
38
+ mtuspecific/3dnew.html filter=lfs diff=lfs merge=lfs -text
39
+ uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.csv filter=lfs diff=lfs merge=lfs -text
40
+ uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.xlsx filter=lfs diff=lfs merge=lfs -text
41
+ uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/OnionTW.xlsx filter=lfs diff=lfs merge=lfs -text
42
+ uploader/uploads/demo/MozzarellaTW.xlsx filter=lfs diff=lfs merge=lfs -text
43
+ uploader/uploads/demo/OnionTW.xlsx filter=lfs diff=lfs merge=lfs -text
BERTopic.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
DrPepper.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82c57fbeabc10f410e553fc7f9fae2fbcb7520f4aa532f0fb7b03dbf20b132c9
3
+ size 2985674
NikeTwitter.csv ADDED
The diff for this file is too large to render. See raw diff
 
Untitled.ipynb ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "844c876f",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "from bertopic import BERTopic\n",
11
+ "import pandas as pd \n",
12
+ "import openai\n",
13
+ "from bertopic.representation import OpenAI\n",
14
+ "from umap import UMAP\n"
15
+ ]
16
+ },
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": 2,
20
+ "id": "560143ff",
21
+ "metadata": {},
22
+ "outputs": [],
23
+ "source": [
24
+ "# df = pd.read_csv('mtu_merged_v3.csv')\n",
25
+ "df = pd.read_csv('NikeTwitter.csv')\n",
26
+ "\n",
27
+ "docs = df['translated_text'].tolist()\n",
28
+ "\n",
29
+ "docs = [str(x).replace(\"#\",\" \") for x in docs]\n",
30
+ "docs = [x for x in docs if len(x) > 30]"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": 3,
36
+ "id": "a579594d",
37
+ "metadata": {},
38
+ "outputs": [
39
+ {
40
+ "data": {
41
+ "application/vnd.jupyter.widget-view+json": {
42
+ "model_id": "f40e914627074089906a1d35d06f55b4",
43
+ "version_major": 2,
44
+ "version_minor": 0
45
+ },
46
+ "text/plain": [
47
+ "Batches: 0%| | 0/30 [00:00<?, ?it/s]"
48
+ ]
49
+ },
50
+ "metadata": {},
51
+ "output_type": "display_data"
52
+ },
53
+ {
54
+ "name": "stderr",
55
+ "output_type": "stream",
56
+ "text": [
57
+ "2023-05-17 08:49:56,734 - BERTopic - Transformed documents to Embeddings\n",
58
+ "2023-05-17 08:50:01,377 - BERTopic - Reduced dimensionality\n",
59
+ "2023-05-17 08:50:01,415 - BERTopic - Clustered reduced embeddings\n"
60
+ ]
61
+ }
62
+ ],
63
+ "source": [
64
+ "from sklearn.feature_extraction.text import CountVectorizer\n",
65
+ "\n",
66
+ "# we add this to remove stopwords\n",
67
+ "vectorizer_model = CountVectorizer(ngram_range=(1, 2), stop_words=\"english\")\n",
68
+ "\n",
69
+ "model = BERTopic(\n",
70
+ " vectorizer_model=vectorizer_model,\n",
71
+ " language='english', calculate_probabilities=True,\n",
72
+ " verbose=True\n",
73
+ ")\n",
74
+ "topics, probs = model.fit_transform(docs)"
75
+ ]
76
+ },
77
+ {
78
+ "cell_type": "code",
79
+ "execution_count": 4,
80
+ "id": "b4803af3",
81
+ "metadata": {},
82
+ "outputs": [],
83
+ "source": [
84
+ "# freq = model.get_document_info(docs)\n",
85
+ "# freq.head(10)\n",
86
+ "from sentence_transformers import SentenceTransformer\n",
87
+ "\n",
88
+ "sentence_model = SentenceTransformer(\"all-MiniLM-L6-v2\")\n",
89
+ "embeddings = sentence_model.encode(docs, show_progress_bar=False)\n"
90
+ ]
91
+ },
92
+ {
93
+ "cell_type": "code",
94
+ "execution_count": null,
95
+ "id": "4aba61ad",
96
+ "metadata": {},
97
+ "outputs": [
98
+ {
99
+ "name": "stderr",
100
+ "output_type": "stream",
101
+ "text": [
102
+ "2023-05-17 08:50:09,299 - BERTopic - Reduced dimensionality\n",
103
+ "2023-05-17 08:50:09,315 - BERTopic - Clustered reduced embeddings\n"
104
+ ]
105
+ }
106
+ ],
107
+ "source": [
108
+ "# Train BERTopic\n",
109
+ "topic_model = BERTopic().fit(docs, embeddings)\n",
110
+ "\n",
111
+ "# Run the visualization with the original embeddings\n",
112
+ "topic_model.visualize_documents(docs, embeddings=embeddings)\n",
113
+ "\n",
114
+ "reduced_embeddings = UMAP(n_neighbors=10, n_components=2, min_dist=0.0, metric='cosine').fit_transform(embeddings)\n",
115
+ "model.visualize_documents(docs,embeddings=embeddings)"
116
+ ]
117
+ },
118
+ {
119
+ "cell_type": "code",
120
+ "execution_count": null,
121
+ "id": "551db1f1",
122
+ "metadata": {},
123
+ "outputs": [],
124
+ "source": []
125
+ },
126
+ {
127
+ "cell_type": "code",
128
+ "execution_count": null,
129
+ "id": "cc8ece88",
130
+ "metadata": {},
131
+ "outputs": [],
132
+ "source": [
133
+ "# Create your representation model\n",
134
+ "openai.api_key = \"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\"\n",
135
+ "\n",
136
+ "\n",
137
+ "#prompt = \"I have the following documents: [DOCUMENTS] \\nThese documents are about the following topic: '\"\n",
138
+ "#representation_model = OpenAI(prompt=prompt)\n",
139
+ "\n",
140
+ "# representation_model = OpenAI()\n",
141
+ "\n",
142
+ "\n",
143
+ "\n",
144
+ "seed_topic_list = [\n",
145
+ " ['nature','photography','trees','sunset','view'],\n",
146
+ " ['hiking','explore', 'running', 'biking','bike', 'walk', 'csodasmagyarorszag'],\n",
147
+ " ['zoo','lions','animals', 'aquarium', 'wildlife'],\n",
148
+ " ['wine', 'drinking', 'drink', 'winery'],\n",
149
+ " ['lake','balaton', 'sea'],\n",
150
+ " ['lake', 'velence']\n",
151
+ "]\n",
152
+ "\n",
153
+ "\n",
154
+ "# Use the representation model in BERTopic on top of the default pipeline\n",
155
+ "topic_model = BERTopic(seed_topic_list=seed_topic_list, nr_topics=7)\n",
156
+ "\n",
157
+ "#topic_model.reduce_topics(docs, nr_topics=8, representation_model=representation_model)\n"
158
+ ]
159
+ },
160
+ {
161
+ "cell_type": "code",
162
+ "execution_count": null,
163
+ "id": "97b97844",
164
+ "metadata": {},
165
+ "outputs": [],
166
+ "source": [
167
+ "topics, probs = topic_model.fit_transform(docs)"
168
+ ]
169
+ },
170
+ {
171
+ "cell_type": "code",
172
+ "execution_count": null,
173
+ "id": "0c5d0a1c",
174
+ "metadata": {},
175
+ "outputs": [],
176
+ "source": [
177
+ "topic_model.get_document_info(docs)"
178
+ ]
179
+ },
180
+ {
181
+ "cell_type": "code",
182
+ "execution_count": null,
183
+ "id": "f29e0d00",
184
+ "metadata": {},
185
+ "outputs": [],
186
+ "source": [
187
+ "# topic_model.update_topics(docs, n_gram_range=(1, 3))"
188
+ ]
189
+ },
190
+ {
191
+ "cell_type": "code",
192
+ "execution_count": null,
193
+ "id": "a828823b",
194
+ "metadata": {},
195
+ "outputs": [],
196
+ "source": [
197
+ "topic_model.get_topics()\n",
198
+ "\n"
199
+ ]
200
+ },
201
+ {
202
+ "cell_type": "code",
203
+ "execution_count": null,
204
+ "id": "7c02c597",
205
+ "metadata": {},
206
+ "outputs": [],
207
+ "source": [
208
+ "topic_model.reduce_topics(docs, nr_topics=10)\n"
209
+ ]
210
+ },
211
+ {
212
+ "cell_type": "code",
213
+ "execution_count": null,
214
+ "id": "9c031065",
215
+ "metadata": {},
216
+ "outputs": [],
217
+ "source": []
218
+ },
219
+ {
220
+ "cell_type": "code",
221
+ "execution_count": null,
222
+ "id": "d267dd67",
223
+ "metadata": {},
224
+ "outputs": [],
225
+ "source": [
226
+ "topic_model.get_topics()"
227
+ ]
228
+ }
229
+ ],
230
+ "metadata": {
231
+ "kernelspec": {
232
+ "display_name": "Python 3 (ipykernel)",
233
+ "language": "python",
234
+ "name": "python3"
235
+ },
236
+ "language_info": {
237
+ "codemirror_mode": {
238
+ "name": "ipython",
239
+ "version": 3
240
+ },
241
+ "file_extension": ".py",
242
+ "mimetype": "text/x-python",
243
+ "name": "python",
244
+ "nbconvert_exporter": "python",
245
+ "pygments_lexer": "ipython3",
246
+ "version": "3.9.16"
247
+ }
248
+ },
249
+ "nbformat": 4,
250
+ "nbformat_minor": 5
251
+ }
archivePrompts.txt ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ # executive_summary_template = """
4
+ # {industry} {word_count}
5
+ # Imagine you are an Elite Analyst, Expert Sociologist, and Data Guru, Your task is to leverage your invaluable expertise in crafting a comprehensive and insightful executive summary.
6
+ # You have been tasked with analyzing a large corpus of blog posts related to tourism. Your goal is to summarize the key points and insights from these blog posts, and to provide recommendations for future tourism practices.
7
+
8
+ # To begin, analyze the blog posts from below:
9
+ # {summaries1}
10
+ # \n\n
11
+ # ...to identify the most common and hot topics. What are the main themes that emerge from the blog posts? Are there any recurring topics or issues that are discussed frequently?
12
+ # (proposed headings are:
13
+ # Common and Hot Topics in Tourism Blog Posts
14
+ # Key Trends in Tourism: Implications for Tourists and the Industry
15
+ # Observations and Key Findings from Tourism Blog Posts
16
+ # Takeaways and Recommendations for Future Tourism Practices)
17
+
18
+
19
+ # Next, examine and interpret the key trends that you observe in the blog posts. How have these trends evolved over time? What are the implications of these trends for tourists, travel agencies, and the tourism industry as a whole?
20
+
21
+ # Structure your analysis into two main sections: Observations and Key Findings. In the Observations section, provide detailed analysis and examples of the common/hot topics and key trends that you identified in the blog posts. Use supporting evidence and examples from the blog posts to illustrate your observations.
22
+
23
+ # In the Key Findings section, summarize the key insights and conclusions that you draw from your analysis. What are the main takeaways from the blog posts in terms of tourism practices? What recommendations can you make for future tourism practices based on your findings?
24
+
25
+ # Finally, prepare a clear and concise takeaway message that summarizes the main findings of your analysis. What are the key insights that tourists, travel agencies, and the tourism industry as a whole can take away from your analysis of these blog posts?
26
+
27
+ # Use your creativity and writing skills to generate a comprehensive and insightful summary of the tourism blog posts in your data corpus.
28
+
29
+ # Add subheaders, and write at least 500 words.
30
+ # Use markdown formatting:
31
+ # """
32
+
33
+ # executive_summary_template = """
34
+ # {industry} {word_count}
35
+ # You have been tasked with analyzing a large corpus of news/articles related to tourism. Your goal is to summarize the key points and insights from these news/articles, and to provide recommendations for future tourism practices.
36
+
37
+ # To begin, analyze the news/articles from below summaries:
38
+ # {summaries1}
39
+ # \n\n
40
+ # ...to identify the most common and hot topics. What are the main themes that emerge from the data? Are there any recurring topics or issues that are discussed frequently?
41
+ # (proposed headings are:
42
+ # Common and Hot Topics in news/articles related to Tourism
43
+ # Key Trends in Tourism: Implications for Tourists and the Industry
44
+ # Observations and Key Findings from Tourism news/articles
45
+ # Takeaways and Recommendations for Future Tourism Practices)
46
+
47
+ # Don't hallucinate, use only the data given summaries.
48
+
49
+ # Use your creativity and writing skills to generate a comprehensive and insightful summary of the tourism news/articles posts in your data corpus.
50
+
51
+ # Add subheaders, and write at least 700 words.
52
+ # Use markdown formatting:
53
+ # """
54
+ # executive_summary_template = """
55
+ # {industry} {word_count}
56
+ # You have been tasked with analyzing a large corpus of blog posts related to tourism. Your goal is to summarize the key points and insights from these blog posts, and to provide recommendations for future tourism practices.
57
+
58
+ # To begin, analyze the blog posts from below summaries:
59
+ # {summaries1}
60
+ # \n\n
61
+ # ...to identify the most common and hot topics. What are the main themes that emerge from the data? Are there any recurring topics or issues that are discussed frequently?
62
+ # (proposed headings are:
63
+ # Common and Hot Topics in blog posts related to Tourism
64
+ # Key Trends in Tourism: Implications for Tourists and the Industry
65
+ # Observations and Key Findings from Tourism blog posts
66
+ # Takeaways and Recommendations for Future Tourism Practices)
67
+
68
+ # Don't hallucinate, use only the data given summaries.
69
+
70
+ # Use your creativity and writing skills to generate a comprehensive and insightful summary of the tourism blog posts posts in your data corpus.
71
+
72
+ # Add subheaders, and write at least 700 words.
73
+ # Use markdown formatting:
74
+ # """
dev.sh ADDED
@@ -0,0 +1 @@
 
 
1
+ gradio gradio_app.py app
favicon.ico ADDED
gradio_app.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
gradio_app.py ADDED
@@ -0,0 +1,2088 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # %%
2
+ import datetime
3
+ import gradio as gr
4
+ from io import BytesIO
5
+ import numpy as np
6
+ import numpy as np
7
+ import tiktoken
8
+ import pandas as pd
9
+ from utils.functions import load_csv
10
+ from wordcloud import WordCloud
11
+ import matplotlib.pyplot as plt
12
+ plt.switch_backend('Agg')
13
+ import requests
14
+ import umap
15
+ from sklearn.feature_extraction.text import TfidfVectorizer
16
+ import hdbscan
17
+ import plotly.express as px
18
+ import plotly.graph_objects as go
19
+ import plotly.express as px
20
+ from langchain.chat_models import ChatOpenAI
21
+
22
+ import os
23
+ from langchain.agents import load_tools
24
+ from langchain.agents import initialize_agent, create_pandas_dataframe_agent
25
+ from langchain.llms import OpenAI
26
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
27
+ import gradio as gr
28
+ import openai
29
+ import pandas as pd
30
+ import numpy as np
31
+ import re
32
+ import whisper
33
+ import openai
34
+ import pandas as pd
35
+ import networkx as nx
36
+ import matplotlib.pyplot as plt
37
+
38
+ import networkx as nx
39
+ import matplotlib.pyplot as plt
40
+ from langchain import OpenAI, PromptTemplate, LLMChain
41
+
42
+ from langchain.agents import load_tools
43
+ from langchain.agents import initialize_agent
44
+ from langchain.llms import OpenAI
45
+ from langchain.document_loaders import YoutubeLoader
46
+ from langchain.chains.summarize import load_summarize_chain
47
+
48
+ from langchain.text_splitter import RecursiveCharacterTextSplitter, TokenTextSplitter
49
+ from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
50
+ from langchain.document_loaders import YoutubeLoader
51
+ import time
52
+ import re
53
+ import pinecone
54
+ import pandas as pd
55
+ from sentence_transformers import SentenceTransformer, util
56
+
57
+ #import numpy as np
58
+ from langchain.embeddings import HuggingFaceEmbeddings, OpenAIEmbeddings
59
+ from sklearn.metrics import silhouette_score
60
+ import torch
61
+ import nltk
62
+ nltk.download('vader_lexicon')
63
+
64
+
65
+ from dotenv import load_dotenv
66
+ load_dotenv()
67
+ gradio_css = os.getenv("GRADIO_CSS")
68
+ gradio_js = os.getenv("GRADIO_JS")
69
+ rubik_backend = os.getenv("RUBIK_BACKEND")
70
+ openapi_key = os.getenv("OPENAI_API_KEY")
71
+ wolfram_alpha_appid = os.getenv("WOLFRAM_ALPHA_APPID")
72
+
73
+ #for versioning
74
+ ra = np.random.randint(1000000)
75
+
76
+ os.environ['OPENAI_API_KEY'] = openapi_key
77
+ os.environ['WOLFRAM_ALPHA_APPID'] = wolfram_alpha_appid
78
+
79
+
80
+ def get_key(item):
81
+ return item['label']
82
+
83
+ def get_emotion_bertweet(dataset):
84
+ tokenizer4 = AutoTokenizer.from_pretrained("finiteautomata/bertweet-base-emotion-analysis", truncation=True)
85
+ model4 = AutoModelForSequenceClassification.from_pretrained("finiteautomata/bertweet-base-emotion-analysis")
86
+ nlp = pipeline('sentiment-analysis', model=model4,
87
+ tokenizer=tokenizer4, top_k=6, truncation=True, device=device)
88
+
89
+ top_emotion = []
90
+ # apply emotion model on data and get the labels and scores
91
+ for i in range(len(dataset)):
92
+ label = []
93
+ score = []
94
+ jsonfile = (nlp(dataset['translated_text'].iloc[i]))
95
+ jsonfile[0].sort(key=get_key)
96
+ for j in range(0, 6):
97
+ jsonfile2 = np.array(jsonfile)
98
+ label.append(jsonfile2[0][j]['label'])
99
+ score.append(jsonfile2[0][j]['score'])
100
+
101
+
102
+ top_emotion.append(label[score.index(max(score))])
103
+ dataset['top_emotion_bertweet'] = top_emotion
104
+ print(jsonfile2)
105
+ return dataset
106
+
107
+
108
+ model_name = "sentence-transformers/all-MiniLM-L6-v2"
109
+ hf = HuggingFaceEmbeddings(model_name=model_name)
110
+ embeddings = OpenAIEmbeddings()
111
+
112
+ # pinecone.init(
113
+ # api_key='ENTER API KEY HERE',
114
+ # environment='us-central1-gcp'
115
+ # )
116
+ # index_name = 'openaigradio'
117
+ def markdown_to_html(md_string):
118
+ # html_string = markdown.markdown(md_string)
119
+ return md_string
120
+
121
+ tokenizer4 = AutoTokenizer.from_pretrained("finiteautomata/bertweet-base-emotion-analysis", truncation=True)
122
+ model4 = AutoModelForSequenceClassification.from_pretrained("finiteautomata/bertweet-base-emotion-analysis")
123
+
124
+ openai.api_key = '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'
125
+ model_whisp = whisper.load_model("base")
126
+
127
+ llm = OpenAI(temperature=0.2, model_name='text-davinci-003', max_tokens=1000, top_p=1)
128
+
129
+ model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
130
+ # check if cpu or gpu
131
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
132
+ model = model.to(device)
133
+
134
+ # %%
135
+ Industries = ['Agriculture',
136
+ 'Automobile Manufacturing',
137
+ 'Banking and Finance',
138
+ 'Biotechnology',
139
+ 'Chemicals and Petrochemicals',
140
+ 'Construction and Engineering',
141
+ 'Consumer Goods and Retail',
142
+ 'Education',
143
+ 'Electronics',
144
+ 'Energy (Oil, Gas, Coal, and Renewable Energy)',
145
+ 'Entertainment and Media',
146
+ 'Food and Beverage',
147
+ 'Healthcare and Pharmaceuticals',
148
+ 'Hospitality, Travel, and Tourism',
149
+ 'Information Technology (IT) and Software',
150
+ 'Insurance',
151
+ 'Manufacturing (various sectors)',
152
+ 'Mining and Metals',
153
+ 'Real Estate',
154
+ 'Renewable Energy (Solar, Wind, Hydro, Geothermal)',
155
+ 'Telecommunications',
156
+ 'Textiles and Apparel',
157
+ 'Transportation and Logistics',
158
+ 'Utilities (Electricity, Water, Gas)',
159
+ 'Waste Management and Environmental Services']
160
+
161
+
162
+
163
+ def get_memory():
164
+ memory_string = ''
165
+ for i,j in memory.items():
166
+ print(i, j)
167
+ memory_string += str(j) + '\n'
168
+ return memory_string
169
+
170
+
171
+ def check_words_in_string(word_list, input_string, case=False):
172
+
173
+ input_string = input_string.lower()
174
+
175
+ # Convert words to lowercase if case is False
176
+ word_list = [word.lower() if case else word for word in word_list]
177
+
178
+ # Check if any word is in the input_string
179
+ result = any(word in input_string for word in word_list)
180
+
181
+ # check if True
182
+ if result:
183
+ return True
184
+ else:
185
+ return False
186
+
187
+
188
+ # Will be used by the Langchain chatbot
189
+
190
+ words = ['rows', 'data', 'length', 'dataset','plot', 'col','columns','column', 'max', 'min', 'minimum', 'maximum', 'visualize','visualise','represent','graph','chart','plot','diagram','illustrate','show','depict','display','count','number','sum','total','aggregate','trend','pattern','distribution','average','linechart','scatter','barchart','piechart','histogram','boxplot','heatmap','correlation','regression','forecast','predict']
191
+
192
+ memory = {'agent':[], 'user':[]}
193
+
194
+
195
+
196
+ def get_topic_cluster(dataframe, graph_type = None,filename = None):
197
+ print(filename)
198
+ if (dataframe is None):
199
+ # return None,None, '<h1>Please click "Launch" on the left sidebar.</h1>', '<h1>Please click "Launch" on the left.</h1>', "Executive Summary"
200
+ return None, None, None, None, None, '<span id="clusterx"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Topic Cluster"
201
+
202
+ reduce_dim = umap.UMAP(
203
+ n_components=3, n_neighbors=8, min_dist=0.55)
204
+
205
+ df = dataframe.copy()
206
+
207
+ # some cleaning for reddit datasets
208
+ df = df[df['translated_text'] != 'nan']
209
+ df = df[df['translated_text'] != '[deleted]']
210
+ df = df[df['translated_text'] != '[removed]']
211
+
212
+ # remove a list of words in this column
213
+ remWords = ['easter', 'spring', 'nature', 'turism','csodasmagyarorszag','csodalatosmagyarorszag','Easter','Spring','#húsvét','EASTER']
214
+
215
+ # remWords = ['nature', 'turism', 'csodasmagyarorszag','csodalatosmagyarorszag']
216
+ df['translated_text'] = df['translated_text'].apply(lambda x: ' '.join([word for word in x.split() if word not in (remWords)]))
217
+
218
+ # if filename + 'df3.csv' exists load csv
219
+ if os.path.exists(filename + 'df3.csv'):
220
+ df3 = pd.read_csv(filename + 'df3.csv')
221
+ df2 = df3
222
+ else:
223
+ def CleanTxt_quotes(text):
224
+ text = re.sub(r'https?:\/\/\S+', '', text) # Remove hyperlinks
225
+ text = re.sub(r'http?:\/\/\S+', '', text) # Remove hyperlinks
226
+ # if more than 5 mentions, remove all mention
227
+ if len(re.findall(r'@[A-Za-z0-9]+', text)) > 5:
228
+ text = re.sub(r'@[A-Za-z0-9]+', '', text)
229
+ # remove remWords words
230
+ text = re.sub(r'\b(?:{})\b'.format('|'.join(remWords)), '', text)
231
+ # if more than 4 hashtags, remove all hashtags
232
+ #text = re.sub(r'[^A-Za-z0-9.!?_#@]+', ' ', text) # Remove non-alphanumeric characters except exclamation marks and question marks
233
+ text = re.sub(r'\s+', ' ', text) # Remove extra whitespace
234
+ return text
235
+
236
+ df['clean_text'] = df['translated_text'].apply(lambda x: str(x))
237
+ df['clean_text'] = df['translated_text'].apply(lambda x: CleanTxt_quotes(x))
238
+ df['origi_text'] = df['text']
239
+ df['origi_text'] = df['text']
240
+ embedding = np.array([np.array(xi)
241
+ for xi in df.embeddings])
242
+
243
+ umap_embeddings = reduce_dim.fit_transform(embedding)
244
+
245
+ print('umap_embeddings', umap_embeddings.shape)
246
+
247
+ # CHECK THIS LINE
248
+ df['x'] = umap_embeddings[:, 0]
249
+ df['y'] = umap_embeddings[:, 1]
250
+ df['z'] = umap_embeddings[:, 2]
251
+
252
+ df.dropna(inplace=True)
253
+
254
+ hdbscan_min_samples = 1
255
+ hdbscan_minimal_cluster_size = int(len(df) * 0.01+34)
256
+
257
+ # hdbscan_minimal_cluster_size = 7
258
+ # hdbscan_min_samples = 10
259
+
260
+ cluster = hdbscan.HDBSCAN(
261
+ min_cluster_size=hdbscan_minimal_cluster_size,
262
+ metric='euclidean',
263
+ cluster_selection_epsilon=0.007,
264
+ cluster_selection_method='leaf',
265
+ algorithm='best',
266
+ prediction_data=False,
267
+ min_samples=hdbscan_min_samples).fit(df[['x', 'y', 'z']])
268
+
269
+ cluster_analysis = len(pd.Series(cluster.labels_).unique())
270
+ print('Number of Sentences = ', len(df))
271
+ print('Number of Clusters = ', cluster_analysis, '/n')
272
+
273
+ df_cluster = pd.DataFrame(
274
+ pd.DataFrame(cluster.labels_).value_counts())
275
+ clusters = pd.DataFrame(cluster.labels_)
276
+
277
+ # percent_unlabelled = round((len(df[clusters[0] == -1]) / len(df)) * 100, 2)
278
+ # print('The percentage of unlabelled sentences is: ', percent_unlabelled, '%')
279
+
280
+ # reindex
281
+ df.reset_index(inplace=True, drop=True)
282
+
283
+ print(len(df[clusters[0] == -1]))
284
+
285
+ for i in range(0, cluster_analysis):
286
+ print('Cluster ', i, ' has ', len(
287
+ df[clusters[0] == i]), ' sentences')
288
+
289
+ print(df_cluster.index)
290
+
291
+ from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
292
+
293
+ def get_tfidf_top_features(documents, n_top=4):
294
+ tfidf_vectorizer = TfidfVectorizer(
295
+ min_df=0.05,
296
+ max_df=0.95, max_features=10,
297
+ stop_words='english')
298
+ tfidf = tfidf_vectorizer.fit_transform(documents)
299
+ importance = np.argsort(np.asarray(
300
+ tfidf.sum(axis=0)).ravel())[::-1]
301
+ tfidf_feature_names = np.array(
302
+ tfidf_vectorizer.get_feature_names())
303
+ return tfidf_feature_names[importance[:n_top]]
304
+
305
+ cluster_names = pd.DataFrame(
306
+ columns=['cluster_name', 'embed_index'])
307
+
308
+ for i in range(cluster_analysis):
309
+ try:
310
+ print(get_tfidf_top_features(
311
+ df['clean_text'][clusters[0] == i]))
312
+
313
+ clstr_nm = get_tfidf_top_features(
314
+ df['clean_text'][clusters[0] == i])
315
+ clstr_idx = df['clean_text'][clusters[0] == i].index
316
+ cluster_names = cluster_names.append(
317
+ {'cluster_name': clstr_nm, 'embed_index': clstr_idx}, ignore_index=True)
318
+
319
+ except Exception as e:
320
+ print(e)
321
+ # cluster_name.append('NULL')
322
+ pass
323
+
324
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].astype(
325
+ str)
326
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
327
+ '[', '')
328
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
329
+ ']', '')
330
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
331
+ "'", '')
332
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
333
+ " ", '-')
334
+
335
+ clusters_names = cluster_names.explode('embed_index')
336
+
337
+ df2 = df.merge(clusters_names, left_index=True,
338
+ right_on='embed_index')
339
+
340
+ df2['cluster_name_str'] = df2['cluster_name'].apply(
341
+ lambda x: str(x))
342
+ # assign a int value to each unique cluster name in df3
343
+ df2['cluster_number'] = df2['cluster_name_str'].astype(
344
+ 'category').cat.codes
345
+
346
+ df2['trimmed_text'] = df2['clean_text'].str[:175]
347
+ df2['trimmed_origi_text'] = df2['origi_text'].str[:175]
348
+
349
+ print(df2.head())
350
+
351
+ df3 = df2[['x', 'y', 'z', 'cluster_number',
352
+ 'cluster_name_str', 'trimmed_text','trimmed_origi_text']]
353
+
354
+
355
+
356
+ #################################################### GET CLUSTER NAME #############################################
357
+
358
+ df2['gpt_cluster'] = ''
359
+ df3['gpt_cluster'] = ''
360
+
361
+ for cluster in df3['cluster_name_str'].unique():
362
+ each_cluster = df3[df3['cluster_name_str'] == cluster]
363
+
364
+ docs = '\n'.join(np.random.choice(each_cluster['trimmed_text'], 50))
365
+
366
+ response3 = openai.ChatCompletion.create(
367
+ model="gpt-3.5-turbo",
368
+ temperature=0.3,
369
+ max_tokens=300,
370
+ top_p=1,
371
+ # stream=True,
372
+ messages=[
373
+ {"role": "user", "content": f'Given a list of keywords {cluster}, and documents present in the cluster : {docs}; assign the most relevant topic name for this cluster : \n\n Cluster Name : '},
374
+ ]
375
+ )['choices'][0]['message']['content']
376
+
377
+ df3.loc[df3['cluster_name_str'] == cluster, 'gpt_cluster'] = response3
378
+ df2.loc[df2['cluster_name_str'] == cluster, 'gpt_cluster'] = response3
379
+
380
+
381
+
382
+ # print(df3['cluster_name_str'])
383
+ # xi = 0
384
+ # for cluster in df3['cluster_name_str'].unique():
385
+ # xi += 1
386
+ # df3.loc[df3['cluster_name_str'] == cluster, 'gpt_cluster'] = cluster#"cluster " + str(xi)
387
+ # df2.loc[df2['cluster_name_str'] == cluster, 'gpt_cluster'] = cluster#"cluster " + str(xi)
388
+
389
+ # save df3
390
+ df3.to_csv(filename + 'df3.csv', index=False, encoding='utf-8-sig')
391
+
392
+ if len(df3) > 10000:
393
+ dot_size = 1
394
+ else:
395
+ dot_size = 4
396
+
397
+
398
+ color_scale = px.colors.sequential.Viridis
399
+ color_list = ['#FF0000', '#FF0000', '#FF0000', '#FF0000', '#FF0000', '#FF0000']
400
+
401
+ fig = px.scatter_3d(df3, x='x', y='y', z='z', color='gpt_cluster', hover_name='trimmed_text', hover_data={
402
+ 'x': False, 'y': False, 'z': False, 'cluster_name_str': False, 'cluster_number': False, 'gpt_cluster': False}, opacity=1, template='plotly_white')
403
+
404
+ fig.update_traces(marker=dict(size=dot_size))
405
+
406
+ fig.add_trace(go.Scatter3d(x=[0], y=[0], z=[0], mode='markers', marker=dict(
407
+ size=0.1, color='white'), showlegend=True, name=' ', hoverinfo='none'))
408
+
409
+ # legend on the right side
410
+ fig.update_layout(legend=dict(
411
+ bgcolor='rgba(17,17,17,0)',
412
+ xanchor='auto',
413
+ yanchor='auto',
414
+ x=0.8, # Adjust the x position of the legend
415
+ y=0.2, # Adjust the y position of the legend
416
+ bordercolor='rgba(17,17,17,0)',
417
+ borderwidth=0,
418
+ ))
419
+
420
+ # fig.update_layout(scene=dict(
421
+ # xaxis=dict(
422
+ # title=' ',
423
+ # nticks=0,
424
+ # # backgroundcolor="rgb(0, 0, 0, 1)",
425
+ # gridcolor="rgba(17,17,17, 0)",
426
+ # showbackground=True,
427
+ # zerolinecolor="rgba(17,17,17, 0)",
428
+ # zeroline=False,
429
+ # showgrid=True,
430
+ # showticklabels=False,
431
+ # showspikes=False
432
+ # ),
433
+ # # hide ticks
434
+
435
+
436
+ # yaxis=dict(
437
+ # # name
438
+ # title=' ',
439
+ # nticks=0,
440
+ # # backgroundcolor="rgb(0, 0, 0, 1)",
441
+ # gridcolor="rgba(17,17,17, 0)",
442
+ # showbackground=True,
443
+ # zerolinecolor="rgba(17,17,17, 0)",
444
+ # zeroline=False,
445
+ # showgrid=True,
446
+ # showticklabels=False,
447
+ # showspikes=False
448
+ # ),
449
+
450
+
451
+
452
+ # zaxis=dict(
453
+ # # name
454
+ # title=' ',
455
+ # nticks=0,
456
+ # # backgroundcolor="rgba(0, 0, 0, 1)",
457
+ # gridcolor="rgba(17,17,17, 0)",
458
+ # showbackground=True,
459
+ # zerolinecolor="rgba(17,17,17, 0)",
460
+ # zeroline=False,
461
+ # showgrid=True,
462
+ # showticklabels=False,
463
+ # showspikes=False),)
464
+ # # tickvals=[],),
465
+ # )
466
+
467
+ fig.update_layout(coloraxis_showscale=False, width=1300, height=750, legend=dict(x=0, y=1, traceorder='normal', font=dict(size=14, color='black'), bgcolor='rgba(17,17,17,0)', bordercolor='rgba(17,17,17,0)', borderwidth=0))
468
+
469
+
470
+ # TO ADD AN IMAGE UNCOMMENT
471
+
472
+ # fig.add_layout_image(
473
+ # dict(
474
+ # source=<SOURCE>,
475
+ # xref="x",
476
+ # yref="y",
477
+ # x=-1,
478
+ # y=3.8,
479
+ # # xanchor = "left",
480
+ # # yanchor = "top",
481
+ # sizex=.4,
482
+ # sizey=.4,
483
+ # opacity=1,
484
+ # layer="above",
485
+ # )
486
+ # )
487
+
488
+ fig.update_layout(legend={'itemsizing': 'constant'}, legend_title_text=' ', legend_title_font_color='black',
489
+ legend_font_color='black', legend_font_size=14, legend_bgcolor='rgba(17,17,17,0)', legend_bordercolor='rgba(17,17,17,0)', legend_borderwidth=2)
490
+
491
+ # , title_font_size=30, title_font_family='Arial', title_font_color='white', title_x=0.06, title_y=0.95, title_xanchor='left', title_yanchor='top', title_text='Cluster of Emotions for {}/n n = {}'.format(subreddit, len(dataset_umap)), margin=dict(l=0, r=0, b=0, t=0, pad=0))
492
+ fig.update_layout(scene_camera_eye=dict(x=0.87, y=-0.88, z=0.84), scene_camera_center=dict(
493
+ x=0, y=0, z=0), template='plotly_white', hovermode='x unified', margin=dict(l=0, r=0, b=0, t=0, pad=2))
494
+
495
+ fig.update_layout(coloraxis_showscale=True)
496
+ fig.update_xaxes(showticklabels=True, showgrid=False, zeroline=False,
497
+ showline=True, automargin=False, showspikes=False)
498
+ fig.update_yaxes(showticklabels=True, showgrid=False, zeroline=False,
499
+ showline=True, automargin=False, showspikes=False)
500
+
501
+
502
+ #full_html=False, include_plotlyjs='cdn', default_height='750px', default_width='1500px', config={'displaylogo': False, 'modeBarButtonsToRemove': ['zoom2d', 'pan2d', 'select2d', 'lasso2d', 'zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'zoom3d', 'pan3d', 'resetCameraDefault3d', 'resetCameraLastSave3d', 'hoverClosest3d', 'orbitRotation', 'tableRotation', 'zoomInGeo', 'zoomOutGeo', 'resetGeo', 'hoverClosestGeo', 'toImage', 'sendDataToCloud', 'hoverClosestGl2d', 'hoverClosestPie', 'toggleHover', 'resetViews', 'toggleSpikelines', 'resetViewMapbox']})}
503
+
504
+
505
+ cluster_name = df3[['cluster_number', 'gpt_cluster']]
506
+ cluster_name = cluster_name.drop_duplicates()
507
+ cluster_name = cluster_name.sort_values(by=['cluster_number'])
508
+ cluster_name = cluster_name.reset_index(drop=True)
509
+ # create a list
510
+ cluster_name_list = cluster_name['gpt_cluster'].tolist()
511
+ cluster_name_list = '\n'.join(cluster_name_list)
512
+
513
+
514
+ # expor t to html
515
+ fig.write_html(filename + '3d.html')
516
+
517
+ Silhouette_Score = 'Silhouette score is : ', silhouette_score(df3[['x', 'y', 'z']], df3['gpt_cluster'], metric='euclidean')
518
+
519
+ # get a dataframe of unique cluster names and their count
520
+
521
+ cluster_count = df3.groupby('gpt_cluster').agg({'cluster_number': 'count'}).reset_index()
522
+ cluster_count = cluster_count.rename(columns={'cluster_number': 'count', 'gpt_cluster': 'Cluster'})
523
+
524
+
525
+ # return fig, cluster_count, cluster_name_list, Silhouette_Score, df2
526
+ return fig, cluster_count, cluster_name_list, None, df2, '<span id="clusterx"></span>', "<b>Please check 'Graph' tab for more details.</b>", "<span class='hsub'>Analysis:</span>Topic Cluster"
527
+
528
+
529
+
530
+ def get_executive_summary(dataframe=None, brand=None, industry=None, summaries=None, csv_file= None, graph_type = None,filename = None, fullProjectData= None, sourceIndex = 0):
531
+ # if data_answer.txt exists, open and read
532
+
533
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
534
+ externalPrompt = sourceData['content']['exec_sum']
535
+
536
+ if (dataframe is None):
537
+ return None,None,'<span id="executive"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Executive Summary"
538
+
539
+ if os.path.exists(filename + 'Executive Summary_CACHE.txt'):
540
+ with open(filename + 'Executive Summary_CACHE.txt', 'r') as f:
541
+ output_summary = f.read()
542
+
543
+ return output_summary, dataframe[['translated_text']], '<span id="executive"></span>', markdown_to_html(output_summary), "<span class='hsub'>Analysis:</span>Executive Summary"
544
+ else:
545
+ if brand is None:
546
+ brand = ' '
547
+
548
+ else :
549
+ brand = brand
550
+ try:
551
+ dataframe = dataframe[dataframe['translated_text'].str.contains(brand, case=False)]
552
+ except:
553
+ pass
554
+
555
+
556
+
557
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
558
+ encoding_name='p50k_base',
559
+ chunk_size = 2000,
560
+ )
561
+
562
+ splitted_articles = text_splitter.split_text(''.join(dataframe['translated_text']))
563
+
564
+ summarize_template = """ {text} \n\n
565
+ Summarize the most relevant information for an executive summary from the above document:
566
+
567
+ SUMMARY: """
568
+
569
+
570
+ prompt_template = PromptTemplate(input_variables=['text'], template=summarize_template)
571
+
572
+ summary_chain = LLMChain(llm=llm, prompt=prompt_template)
573
+
574
+ summaries = []
575
+ for i in splitted_articles:
576
+ summaries.append(summary_chain.run(i))
577
+
578
+
579
+
580
+ summaries1 = '/n'.join(summaries)
581
+ word_count = 500
582
+
583
+ #If needed, guess the industry
584
+ # industry_template = PromptTemplate(input_variables=['summaries'], template=extract_industry)
585
+ # summary_chain = LLMChain(llm=llm, prompt=industry_template)
586
+ # industry = summary_chain.run(summaries)
587
+
588
+ #Check size of output and go in a 2nd loop if it's too big
589
+ encoding = tiktoken.get_encoding('p50k_base')
590
+
591
+ if len(encoding.encode(summaries1)) > 2000:
592
+ # return only first 2000 tokens
593
+ summaries1 = encoding.decode(encoding.encode(summaries1)[:2000])
594
+
595
+
596
+ executive_summary_template = '''Imagine you are an Elite Analyst, Expert Sociologist, and Data Guru,
597
+ Your task is to leverage your invaluable expertise in crafting a comprehensive and insightful {word_count} words executive summary tailored for C-level executives and decision-makers in {industry}.
598
+ The summary should synthesize information from various data sources, incorporate relevant cultural and contextual elements, and provide valuable insights that can drive strategic decision-making.
599
+ Please ensure that your analysis meets the following high-level objectives:
600
+ Thoroughly examine and interpret the key trends, patterns, and insights derived from the following data sources:
601
+ {summaries1}
602
+
603
+ Articulate the implications and opportunities for {industry}, keeping in mind the needs and challenges of the industry.
604
+ Consider the cultural, social, and contextual nuances present in the data, drawing on your sociological expertise to ensure the summary remains relevant and insightful across diverse audiences.
605
+ Identify any potential risks or challenges that might arise from the data, providing strategic recommendations for mitigating these issues.
606
+ Present the information in a clear, concise, and engaging manner that captures the attention of busy executives and effectively communicates the key insights.
607
+ Leverage your data expertise to ensure the accuracy, reliability, and relevance of the information presented in the summary. Make us benefit from your unique expertise and insights.
608
+
609
+
610
+ Using markdown formatting, write a {word_count} word SEQ-optimized Executive Summary. Write a click worthy short titles. Add a key takeaway
611
+ section at the end. Use the seed keyword as the first H2. Always use a combination of paragraphs, lists, and tables for a better reader experience. For the styling of the output, please include headers for different sections, and use bullet points where applicable to organize the key insights.
612
+ To avoid repetition, vary the sentence structure and word choice when presenting information from different data sources or discussing various trends, insights, or opportunities.
613
+ Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers.
614
+ To avoid repetition, vary the sentence structure and word choice when presenting information from different data sources or discussing various trends, insights, or opportunities. Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers.
615
+ In order to maintain reader engagement and deliver a captivating text, please ensure that you diversify sentence structure and word choice when presenting insights, trends, or opportunities from different data sources. Employ synonyms, alternative expressions, and varied sentence patterns to provide a fresh and dynamic reading experience.
616
+ \n\n
617
+
618
+ '''
619
+
620
+ if externalPrompt and externalPrompt != "":
621
+ executive_summary_template = externalPrompt
622
+
623
+ prompt = PromptTemplate(template=executive_summary_template, input_variables=['industry', 'word_count', 'summaries1'])
624
+ print("start sum")
625
+ # llm2 = OpenAI(temperature=0.2, model_name='gpt-4', max_tokens=1000, top_p=1)
626
+
627
+ # llm2 = ChatOpenAI(temperature=0.2, model_name='gpt-4', max_tokens=1000, top_p=1)
628
+ executive_chain = LLMChain(llm=llm, prompt=prompt)
629
+
630
+ output_summary = executive_chain.run(industry=industry, word_count=word_count, summaries1=summaries1)
631
+
632
+
633
+ # output_summary = executive_chain.run(industry=industry, word_count=word_count, summaries1=summaries1)
634
+ with open(filename + "Executive Summary_CACHE.txt", "a") as f:
635
+ try:
636
+ f.write(output_summary)
637
+ except:
638
+ pass
639
+
640
+ # dataframe.rename(columns={'translated_text': 'Table'}, inplace=True)
641
+ # return("# Executive summary" + output_summary, dataframe[['translated_text']], markdown_to_html(output_summary), 1, markdown_to_html("# Executive Summary\n\n" + output_summary), "Executive Summary")
642
+ return output_summary, dataframe[['translated_text']], '<span id="executive"></span>', markdown_to_html(output_summary), "<span class='hsub'>Analysis:</span>Executive Summary"
643
+
644
+ return(output_summary, dataframe[['translated_text']][0:20], summaries, output_summary)
645
+
646
+
647
+
648
+
649
+
650
+
651
+
652
+ def get_competitive(brand, industry, graph_type = None, filename = None,dataframe = None,fullProjectData= None, sourceIndex = 0):
653
+
654
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
655
+ externalPrompt = sourceData['content']['competitor']
656
+
657
+ if dataframe is None:
658
+ return(None,'<span id="competitive"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Competitor Analysis")
659
+
660
+ if os.path.exists(filename + 'Competitor_CACHE.txt'):
661
+ with open(filename + 'Competitor_CACHE.txt', 'r') as f:
662
+ output_summary = f.read()
663
+ return(output_summary,'<span id="competitive"></span>', markdown_to_html("# Competitor Analysis\n\n"+output_summary), "<span class='hsub'>Analysis:</span>Competitor Analysis")
664
+
665
+ else:
666
+ competitive_prompt = '''
667
+ Ignore all previous instructions. Do not rush. Make this impactful and clear.
668
+ •Read through all the bullet points and make sure you understand all the bullet points, before you start working.
669
+ • Act as a subject matter expert, Business analyst, social media expert and professor with 20 years of research experience.
670
+ [IMPORTANT INSTRUCTION]
671
+ Your singular task is to provide expert reports with key elements and useful content. Do not make up any information. Do not use jargon.
672
+ Start with a short paragraph introducing {brand} position in the market. This should be clear and impactfull.
673
+ •I want to learn more about the competitors of brand {brand} in this market {industry}.
674
+ [SEPARATOR]
675
+ •Use the advanced level of expertise in this market {industry} to create topics and subtopics with detailed notes, this will help provide confidence and clarity about the item being sought.
676
+ [SEPARATOR]
677
+ 1 “Who are the 4 main competitors of {brand}?”
678
+ 2 “What are the top 3 strengths and weaknesses of each of those competitors?”
679
+ 3 “What are the unique selling points of our competitors?”
680
+ 4 “In what unique ways do those competitors market their products/services?”
681
+ 5 “What are the key trends in the {industry} that those competitors are capitalizing on?”
682
+ 6 “What are the areas where those competitors excel compared to {brand}?”
683
+ 7 “What are the areas where our competitors fall short compared to {brand}?”
684
+ 8 “How do our products/services prices compare to those competitors in terms of quality, price positioning and range?”
685
+ 9 “What are the common customer complaints about those competitors?”
686
+ 10 “What are the opportunities for growth in the {industry} that competitors are not taking advantage of?”
687
+ •Break down the exercise into easy-to-follow steps.
688
+ •For each topic and/or subtopic provide a clear and informative summary that compare and contrast results..
689
+ •Identify common mistakes made when addressing those competitive points and address those with maximum clarity.
690
+ •Proofread content for accuracy, paying special attention to any terms that may have been substituted or omitted unintentionally.
691
+ Conclude with a brief overview of the competitive landscape for "brand" with the top 3 takeaways and opportunities. The format should be markdown, add subheaders (h2 only), format into nice paragraphs.'''
692
+
693
+ # hardcoded!!!
694
+ brand = "Nike"
695
+ industry = 'Textiles and Apparel'
696
+
697
+ prompt = PromptTemplate(template=competitive_prompt, input_variables=['industry', 'brand'])
698
+ competition_chain = LLMChain(llm=llm, prompt=prompt)
699
+
700
+ output_summary = competition_chain.run(industry=industry, brand=brand)
701
+ with open(filename + "Competitor_CACHE.txt", "a") as f:
702
+ try:
703
+ f.write(output_summary)
704
+ except:
705
+ pass
706
+
707
+ return(output_summary,'<span id="competitive"></span>', markdown_to_html("# Competitor Analysis\n\n"+output_summary), "<span class='hsub'>Analysis:</span>Competitor Analysis")
708
+
709
+ # def get_topic_summary(dataframe, topics=None, brand=None, industry=None, graph_type = None, filename = None):
710
+ def get_trend_summary(dataframe, topics=None, brand=None, industry=None, graph_type = None, filename = None,fullProjectData= None, sourceIndex = 0):
711
+
712
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
713
+ externalPrompt = sourceData['content']['trend_analysis']
714
+
715
+ if (dataframe is None):
716
+ return None,None, '<span id="trend"></span>','<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Executive Summary"
717
+
718
+ if os.path.exists(filename + 'Trend Analysis_CACHE.txt'):
719
+ with open(filename + 'Trend Analysis_CACHE.txt', 'r') as f:
720
+ final_summary = f.read()
721
+
722
+ return(final_summary, dataframe[['translated_text']][0:20], '<span id="trend"></span>', markdown_to_html(final_summary), "<span class='hsub'>Analysis:</span>Trend Analysis")
723
+
724
+ else:
725
+
726
+ if brand is None:
727
+ brand = ''
728
+
729
+ else :
730
+ brand = brand
731
+ try:
732
+ dataframe = dataframe[dataframe['translated_text'].str.contains(brand, case=False)]
733
+ except:
734
+ pass
735
+
736
+
737
+
738
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
739
+ encoding_name='p50k_base',
740
+ chunk_size = 2000,
741
+ )
742
+
743
+
744
+ splitted_articles = text_splitter.split_text(''.join(dataframe['translated_text']))
745
+
746
+ summarize_template = """Summarize the most relevant information from the following document:
747
+
748
+ {text}
749
+
750
+ SUMMARY: """
751
+
752
+
753
+ prompt_template = PromptTemplate(input_variables=['text'], template=summarize_template)
754
+
755
+ summary_chain = LLMChain(llm=llm, prompt=prompt_template)
756
+
757
+ summaries = []
758
+ for i in splitted_articles:
759
+ summaries.append(summary_chain.run(i))
760
+
761
+
762
+ # split the summary into 2000 tokens chunks
763
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
764
+ encoding_name='p50k_base',
765
+ chunk_size = 2000,
766
+ )
767
+
768
+
769
+ summaries2 = text_splitter.split_text(''.join(summaries))
770
+
771
+ word_count = 500
772
+
773
+ topics = topics
774
+ final_summary = []
775
+
776
+ brand = "Nike"
777
+ industry = "Food and Beverage"
778
+ for summary_1 in summaries2:
779
+
780
+ topic_prompt = '''"Imagine you are an Elite Analyst and Trend Analysis Expert with extensive experience in identifying patterns and emerging themes from various data sources, such as social media, regular media, reviews, and survey data. Your task is to leverage your invaluable expertise in crafting a comprehensive and insightful trend analysis report tailored for {brand} within the {industry}. The objective is to provide valuable insights into shifts in consumer behavior, preferences, and market dynamics, enabling informed decision-making for C-level executives and decision-makers.
781
+
782
+ In your analysis of {word_count} words, ensure that you address the following key elements:
783
+
784
+ Topics : {topics}
785
+
786
+ Data: {summary}
787
+
788
+ Emerging Trends: Identify and discuss the key emerging trends in consumer behavior, preferences, and market dynamics within the {industry}. Examine the factors driving these trends and provide specific examples to illustrate your findings.
789
+
790
+ Impact on {brand}: Analyze how the identified trends are affecting or could potentially affect {brand}. Consider both opportunities and challenges that may arise from these trends, as well as any necessary adjustments to marketing strategies, product offerings, or customer service initiatives.
791
+
792
+ Recommendations: Based on the insights derived from the trend analysis, provide actionable recommendations for {brand} to stay ahead of the competition, capitalize on new opportunities, and address potential challenges. Consider innovations, partnerships, or targeted marketing campaigns that can help the company adapt to and benefit from the identified trends.
793
+
794
+ Ensure that your trend analysis report is clear, concise, and engaging for busy executives. Focus on providing actionable insights and recommendations that can inform the company's strategic direction. Draw on your expertise to ensure the accuracy, reliability, and relevance of the information presented in the analysis."
795
+
796
+
797
+ Using markdown formatting, write a {word_count} word SEQ-optimized Trend Analysis. Write a click worthy short titles. Add a key takeaway
798
+ section at the end. Use the seed keyword as the first H2. Always use a combination of paragraphs, lists, and tables for a better reader experience. For the styling of the output, please include headers for different sections, and use bullet points where applicable to organize the key insights.
799
+ To avoid repetition, vary the sentence structure and word choice when presenting information. Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers. \n\n
800
+
801
+ '''
802
+
803
+ prompt = PromptTemplate(template=topic_prompt, input_variables=['industry', 'topics', 'word_count', 'summary', 'brand'])
804
+
805
+ topic_chain = LLMChain(llm=llm, prompt=prompt)
806
+
807
+ topic_summary = topic_chain.run(industry=industry, topics = topics, word_count=word_count, summary=summary_1, brand=brand)
808
+
809
+ final_summary.append(topic_summary)
810
+
811
+ if len(final_summary) > 1:
812
+ topic_summary = ''.join(final_summary)
813
+
814
+ combination = '''{topic_summary}\n\nCombine the content from these articles into one; keeping the format and structure in place. \n\n##Trend Analysis:\n\n'''
815
+ prompt = PromptTemplate(template=combination, input_variables=['topic_summary'])
816
+ final_chain = LLMChain(llm=llm, prompt=prompt)
817
+ final_summary = final_chain.run(topic_summary=topic_summary)
818
+
819
+ else:
820
+ final_summary = final_summary[0]
821
+
822
+ with open(filename + "Trend Analysis_CACHE.txt", "a") as f:
823
+ try:
824
+ f.write(final_summary)
825
+ except:
826
+ pass
827
+
828
+ # dataframe.rename(columns={'translated_text': 'Table'}, inplace=True)
829
+
830
+ return("# Trend Analysis\n" + final_summary, dataframe[['translated_text']][0:20], '<span id="trend"></span>', markdown_to_html(''+final_summary), "<span class='hsub'>Analysis:</span>Trend Analysis")
831
+
832
+
833
+ def get_SWOT(dataframe, brand = None, industry = None, exec_summary=None, graph_type= None, filename = None,fullProjectData= None, sourceIndex = 0):
834
+
835
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
836
+ externalPrompt = sourceData['content']['swot_']
837
+
838
+ if (dataframe is None):
839
+ return(None,'<span id="swotx"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>SWOT")
840
+
841
+
842
+ brand = 'Nike'
843
+ industry = 'Textiles and Apparel'
844
+ if brand is None:
845
+ brand = ' '
846
+
847
+ else :
848
+ brand = brand
849
+ try:
850
+ dataframe = dataframe[dataframe['translated_text'].str.contains(brand, case=False)]
851
+ except:
852
+ pass
853
+
854
+
855
+ # if exec_summary is None:
856
+ #
857
+ exec_summary = '''
858
+ # Mozzarella Sticks: A Versatile Snack Food with Endless Possibilities
859
+
860
+ ## Introduction
861
+
862
+ Mozzarella sticks are a popular snack food that can be enjoyed in a variety of ways. They can be eaten alone, dipped in sauces, used as a topping on pizzas, or even turned into vape flavors. Mozzarella sticks can also be used to make creative dishes such as a mozzarella stick bowl, a mozzarella stick cake, or a mozzarella stick twinkie. They can also be used as a prank, such as paying per mozzarella stick. Mozzarella sticks are a versatile food that can be enjoyed in many different ways.
863
+
864
+ ## Popularity
865
+
866
+ Mozzarella sticks are a popular food item that can be enjoyed in many different ways. People have been experimenting with different recipes, such as a low-carb snack of apple, mozzarella stick, hummus, veggie, plain Greek yogurt, English cucumber, dill, peanut butter, and celery. There have also been attempts to create a stuffed crust pizza with a mozzarella stick, as well as a Korean corn dog with a French fry chunk and a half mozzarella stick inside. Mozzarella sticks can also be enjoyed with marinara sauce, ranch, ketchup, and other condiments.
867
+
868
+ ## Availability
869
+
870
+ Mozzarella sticks are a popular snack food that can be found in many places. They can be eaten alone or as part of a meal, such as a burger or a pizza. They can also be used as an ingredient in dishes such as mac and cheese, risotto, and fried cauliflower. Mozzarella sticks can be found in many forms, such as deep-fried, baked, or grilled. They can also be paired with other foods, such as fruit, vegetables, and sauces. Mozzarella sticks are high in lactose and should be consumed in moderation.
871
+
872
+ ## International Appeal
873
+
874
+ Mozzarella sticks are a popular dish enjoyed by people around the world. They can be made with a variety of ingredients, such as flour, Greek yogurt, turkey pepperoni, and cheese, and can be served with marinara sauce, butter, and olive oil. Mozzarella sticks are also popular in Czech, Slovak, and Polish cuisine. On International Cheese Day, people celebrate with cheese wedges, ooey gooey cheese pulls, and mozzarella sticks. There are a variety of recipes for mozzarella sticks, including a low-fat version with Greek yogurt, turkey pepperoni, and cheese. Mozzarella sticks can also be enjoyed with a variety of dips, such as marinara sauce, nacho cheese sauce, and homemade marinara sauce.
875
+
876
+ ## Uses
877
+
878
+ Mozzarella sticks are a popular snack food that can be enjoyed in a variety of ways. They can be deep fried, grilled, or microwaved, and are often served with marinara sauce or ranch dressing. They can also be used as a topping for pizza, burgers, and ramen. Mozzarella sticks are also available in low-fat and dairy-free varieties. They are often served at fast food restaurants, such as Arby's, Burger King, and Sonic, and can be purchased in stores. Mozzarella sticks are a great snack for those looking for a quick meal or a tasty treat.
879
+
880
+ ## Health Benefits
881
+
882
+ Mozzarella sticks are a popular food item that can be enjoyed in many different ways. They can be fried, microwaved, baked, or even wrapped in fruit roll-ups. They can be served with marinara sauce, ranch dressing, or even chocolate milk. Mozzarella sticks can also be used to make delicious dishes such as mac and cheese, chicken tenders, and jalapeno poppers. They can also be used to make sandwiches, tacos, and pizzas. Mozzarella sticks are a great way to add flavor and texture to any meal.
883
+
884
+ ## Implications and Opportunities
885
+
886
+ Mozzarella sticks are a popular snack food that can be enjoyed in a variety of ways. They can be served with different sauces, as part of a pizza, or as part of a sandwich. They can also be used to make a variety of dishes, such as a scotch egg, a Camembert burger, or a mozzarella stick hybrid pizza. Mozzarella sticks can also be served with a variety of sides, such as fries, onion rings, and hash browns. Additionally, they can be used to make a variety of desserts, such as a mozzarella stick candle.
887
+
888
+ Mozzarella sticks are a popular bar food and snack item that can be enjoyed in a variety of ways. They can be served as an appetizer, a side dish, or even as a main course.'''
889
+
890
+ #word_count = 500
891
+
892
+ with open(filename + "Executive Summary_CACHE.txt", "r") as f:
893
+ exec_summary = f.read()
894
+
895
+ # industry_template = PromptTemplate(input_variables=['summaries'], template=extract_industry)
896
+ # summary_chain = LLMChain(llm=llm, prompt=industry_template)
897
+ # industry = summary_chain.run(summaries)
898
+
899
+ brand = brand
900
+
901
+ industry = industry
902
+
903
+ # toolname = ['serpapi']
904
+ # tools = load_tools(toolname)
905
+ # agent = initialize_agent(tools=tools, llm=llm, agent='zero-shot-react-description', verbose=True)
906
+ # internet_content = agent.run(f'What is {brand}?')
907
+
908
+
909
+
910
+ SWOT_analysis_template = '''Ignore all previous instructions. Do not rush. Make this impactful and clear.
911
+ •Read through all the bullet points and make sure you understand all the bullet points, before you start working.
912
+ Act as a subject matter expert, Business analyst, social media expert and professor with 20 years of research experience.
913
+
914
+ Here is an executive Summary for updated context : {exec_summary}
915
+
916
+
917
+ [IMPORTANT INSTRUCTION]
918
+ Your singular task is to provide expert reports with key elements and useful content. Do not make up any information. Do not use jargon.
919
+ Introduction:
920
+ Start with a paragraph introducing
921
+
922
+ Now: return the SWOT for the brand {brand} in the {industry} industry.
923
+ example:
924
+ ## Strengths
925
+ - Strength 1
926
+ - Strength 2
927
+ ...
928
+ ## Weaknesses
929
+ - Weakness 1
930
+ - Weakness 2
931
+ ...
932
+ ## Opportunities
933
+ - Opportunity 1
934
+ - Opportunity 2
935
+ ...
936
+ ## Threats
937
+ - Threat 1
938
+ - Threat 2
939
+ ...
940
+
941
+ SWOT formatted with markdown syntax:
942
+
943
+ '''
944
+
945
+ prompt = PromptTemplate(template=SWOT_analysis_template, input_variables=['industry', 'brand', 'exec_summary'])
946
+
947
+ SWOT_chain = LLMChain(llm=llm, prompt=prompt)
948
+
949
+ SWOT_summary = SWOT_chain.run(industry=industry, brand=brand, exec_summary=exec_summary)
950
+
951
+ return("" + SWOT_summary,'<span id="swotx"></span>', markdown_to_html(SWOT_summary + "<div id='isSwot'></div>") , "<span class='hsub'>Analysis:</span>SWOT")
952
+
953
+
954
+ def emotional_mapping(dataframe, industry = None, graph_type = None, filename = None, fullProjectData = None, sourceIndex = 0):
955
+
956
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
957
+ # externalPrompt = sourceData['content']['swot_']
958
+
959
+ if (dataframe is None):
960
+ return None,None, '<span id="sentiment"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Sentiment Analysis"
961
+
962
+ if os.path.exists(filename + 'Sentiment Analysis_CACHE.txt'):
963
+ # read this: emotional_count.to_csv(filename + "Sentiment Analysis_CACHE.csv", index=False)
964
+ emotional_count = pd.read_csv(filename + "Sentiment Analysis_CACHE.csv")
965
+ with open(filename + 'Sentiment Analysis_CACHE.txt', 'r') as f:
966
+ emotional_summary = f.read()
967
+
968
+ return(emotional_summary, emotional_count,'<span id="sentiment"></span>', markdown_to_html(""+emotional_summary), "<span class='hsub'>Analysis:</span>Sentiment Analysis")
969
+ # return output_summary, dataframe[['translated_text']], markdown_to_html(output_summary), markdown_to_html(output_summary), "Executive Summary"
970
+ else:
971
+ if 'top_emotion_bertweet' in dataframe.columns:
972
+ dataframe['emotion'] = dataframe['top_emotion_roberta'] #dataframe['top_emotion_bertweet']
973
+
974
+ elif 'top_emotion_roberta' in dataframe.columns:
975
+ dataframe['emotion'] = dataframe['top_emotion_roberta']
976
+
977
+ elif 'top_emotion_distilbert' in dataframe.columns:
978
+ dataframe['emotion'] = dataframe['top_emotion_distilbert']
979
+
980
+ elif 'top_emotion' in dataframe.columns:
981
+ dataframe['emotion'] = dataframe['top_emotion']
982
+
983
+ else:
984
+ dataframe = get_emotion_bertweet(dataframe)
985
+ dataframe['emotion'] = dataframe['top_emotion_bertweet']
986
+
987
+ word_count = 500
988
+
989
+
990
+ # industry_template = PromptTemplate(input_variables=['summaries'], template=extract_industry)
991
+ # summary_chain = LLMChain(llm=llm, prompt=industry_template)
992
+ # industry = summary_chain.run(summaries)
993
+
994
+
995
+ industry = industry
996
+
997
+ # get positive dataset
998
+ positive = dataframe[dataframe['polarity'] > 0]
999
+
1000
+ # get negative dataset
1001
+ negative = dataframe[dataframe['polarity'] < 0]
1002
+
1003
+ positive_emotions = []
1004
+ negative_emotions = []
1005
+
1006
+ corpus_positive = {}
1007
+ corpus_negative = {}
1008
+
1009
+ # Calculate the number of unique emotions for positive and negative datasets
1010
+ num_positive_emotions = min(len(positive['emotion'].unique()), 3)
1011
+ num_negative_emotions = min(len(negative['emotion'].unique()), 3)
1012
+
1013
+ # Loop through the positive emotions
1014
+ for i in range(num_positive_emotions):
1015
+ value = str(positive['emotion'].value_counts(normalize=True).index[i])
1016
+ percent = str(round(positive['emotion'].value_counts(normalize=True)[i] * 100, 2)) + '%'
1017
+ positive_emotions.append(value + ' ' + percent)
1018
+
1019
+ corpus_positive[value] = positive[positive['emotion'] == value]['translated_text'].tolist()
1020
+
1021
+ # Loop through the negative emotions
1022
+ for i in range(num_negative_emotions):
1023
+ value = str(negative['emotion'].value_counts(normalize=True).index[i])
1024
+ percent = str(round(negative['emotion'].value_counts(normalize=True)[i] * 100, 2)) + '%'
1025
+ negative_emotions.append(value + ' ' + percent)
1026
+
1027
+ corpus_negative[value] = negative[negative['emotion'] == value]['translated_text'].tolist()
1028
+
1029
+
1030
+ emotion_summary = {}
1031
+
1032
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
1033
+ encoding_name='p50k_base',
1034
+ chunk_size = 2000,
1035
+ )
1036
+
1037
+
1038
+
1039
+ for emotion, text in corpus_positive.items():
1040
+
1041
+ emotion_summary[emotion] = text_splitter.split_text(''.join(text))
1042
+
1043
+ # get first element
1044
+ emotion_summary[emotion] = emotion_summary[emotion][0]
1045
+
1046
+ emotion_summarize_template = """ {text} \n\n
1047
+ Summarize the text from the above document to answer this question : Why are people feeling {emotion} ? \n\n
1048
+
1049
+ SUMMARY: """
1050
+
1051
+ prompt_template = PromptTemplate(input_variables=['text', 'emotion'], template=emotion_summarize_template)
1052
+
1053
+ summary_chain = LLMChain(llm=llm, prompt=prompt_template)
1054
+
1055
+ emotion_summary[emotion] = summary_chain.run(text=emotion_summary[emotion], emotion=emotion, industry=industry)
1056
+
1057
+ for emotion, text in corpus_negative.items():
1058
+
1059
+ emotion_summary[emotion] = text_splitter.split_text(''.join(text))
1060
+
1061
+ # get first element
1062
+ emotion_summary[emotion] = emotion_summary[emotion][0]
1063
+
1064
+ emotion_summarize_template = """ {text} \n\n
1065
+ Summarize the text from the above document to answer this question : Why are people feeling {emotion} ? \n\n
1066
+
1067
+ SUMMARY: """
1068
+
1069
+ prompt_template = PromptTemplate(input_variables=['text', 'emotion'], template=emotion_summarize_template)
1070
+
1071
+ emotion_summary[emotion] = summary_chain.run(text=emotion_summary[emotion], emotion=emotion, industry=industry)
1072
+
1073
+
1074
+
1075
+
1076
+ executive_summary_template = '''Imagine you are an Elite psychologist, Analyst, and Data Guru. You are familiar with leading emotion measurement techniques and the latest developments in the field,
1077
+
1078
+ including the Plutchik index and Emotional Intensity Scale (EIS).
1079
+
1080
+ Data Summary per emotions, leave 'other' emotions!: {all_emotions}
1081
+
1082
+ Your task is to leverage your invaluable expertise in crafting an insightful {word_count} emotion-driven report tailored for C-level executives and decision-makers in {industry}.
1083
+ The objective is to provide valuable insights into the impact of the top emotions marketing and branding strategies and provoke lightbulb moments for our readers. Your analysis should provide valuable insights that can drive strategic decision-making based on the key emotions.
1084
+
1085
+ Structure the analysis in two main sections: Observations and Key Findings. In the Observations section, provide precise details about specific emotion measurements and their relation to the wants and needs expressed in the data. In the Key Findings section, focus on insightful content and compare and contrast the different emotions, revealing what's hiding behind the numbers and addressing both expressed and latent emotions.
1086
+ Avoid jargon and broad terms in your analysis, ensuring that the content is clear, concise, and engaging.
1087
+
1088
+ Thoroughly examine and interpret the key trends, patterns, and insights derived from the key emotions .
1089
+ Articulate the implications and opportunities based on the emotion levels, keeping in mind the needs and challenges of the {industry}.
1090
+ Consider the cultural, social, and contextual nuances present in the data, drawing on your expertise to ensure the emotion analysis remains relevant and insightful across diverse audiences.
1091
+ Leverage your psychological expertise to ensure the accuracy, reliability, and relevance of the information presented in the summary. Make us benefit from your unique expertise and insights.
1092
+ Using markdown formatting, write a {word_count} word SEQ-optimized Executive Summary. Write a click worthy short titles. Add a key takeaway
1093
+
1094
+ section at the end. Use the seed keyword as the first H2. Always use a combination of paragraphs, lists, and tables for a better reader experience. For the styling of the output, please include headers for different sections, and use bullet points where applicable to organize the key insights.
1095
+ To avoid repetition, vary the sentence structure and word choice when presenting information from different data sources or discussing various trends, insights, or opportunities.
1096
+ Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers. \n\n
1097
+
1098
+ '''
1099
+
1100
+ prompt = PromptTemplate(template=executive_summary_template, input_variables=['word_count', 'industry', 'all_emotions'])
1101
+
1102
+ executive_chain = LLMChain(llm=llm, prompt=prompt)
1103
+
1104
+ emotional_summary = executive_chain.run(industry=industry, word_count=word_count, all_emotions=str(emotion_summary.items()))
1105
+
1106
+ emotional_count = dataframe.groupby('emotion').agg({'translated_text': 'count'}).reset_index()
1107
+
1108
+ emotional_count.to_csv(filename + "Sentiment Analysis_CACHE.csv", index=False)
1109
+
1110
+ with open(filename + "Sentiment Analysis_CACHE.txt", "a") as f:
1111
+ try:
1112
+ f.write(emotional_summary)
1113
+ except:
1114
+ pass
1115
+
1116
+ # dataframe.rename(columns={'emotion': 'Emotion'}, inplace=True)
1117
+
1118
+ return(emotional_summary, emotional_count,'<span id="sentiment"></span>', markdown_to_html(""+emotional_summary), "<span class='hsub'>Analysis:</span>Sentiment Analysis")
1119
+
1120
+
1121
+ def generate_wordcloud(dataframe):
1122
+ text = ' '.join(dataframe['translated_text'].tolist())
1123
+ colors = ["#FF69B4", "#FFD700", "#FFA500", "#D3D3D3"]
1124
+ wordcloud = WordCloud(max_font_size=300, max_words=800, width = 1600, height = 1200, background_color="white", colormap="Set2", color_func=lambda *args, **kwargs: colors[len(args[0]) % len(colors)]).generate(text)
1125
+ return wordcloud.to_image()
1126
+
1127
+
1128
+ def get_polarity(dataframe):
1129
+ df = dataframe.copy()
1130
+ def get_sentiment_vader(text):
1131
+ from nltk.sentiment.vader import SentimentIntensityAnalyzer
1132
+ sid = SentimentIntensityAnalyzer()
1133
+ return sid.polarity_scores(text)['compound']
1134
+
1135
+ df['translated_text'] = df['translated_text'].astype(str)
1136
+ df['polarity'] = df['translated_text'].apply(lambda x: get_sentiment_vader(x))
1137
+
1138
+ fig = plt.figure(frameon=False, figsize=(16, 12))
1139
+ fig = plt.figure(figsize=(15, 8))
1140
+
1141
+ # try :
1142
+ if 'date' in df.columns:
1143
+ df['date2'] = pd.to_datetime(df['date'], utc=True)
1144
+ else:
1145
+ return None, dataframe
1146
+ print('no date, skipping polarity viz')
1147
+ # except:
1148
+ # print("no/wrong date column")
1149
+ # return None, dataframe
1150
+
1151
+ sorted_dates = df.sort_values(by='date2')
1152
+
1153
+ cmap = plt.cm.get_cmap('RdYlGn')
1154
+ norm = plt.Normalize(sorted_dates['polarity'].min(), sorted_dates['polarity'].max())
1155
+ colors = [cmap(norm(value)) for value in sorted_dates['polarity']]
1156
+
1157
+ # scatter plot
1158
+ plt.scatter(sorted_dates['date2'],sorted_dates['polarity'], color=colors, alpha=0.5)
1159
+
1160
+ # add a lineplot to show the average per day
1161
+
1162
+ plt.plot(sorted_dates['date2'], sorted_dates['polarity'].rolling(window=50).mean(), color='hotpink', linewidth=1.5)
1163
+
1164
+
1165
+ # add legend about pink line
1166
+ plt.legend(['Polarity', 'Trend'], frameon=False, bbox_to_anchor=(0.3, 1), loc='upper right', ncol=2, fontsize=12)
1167
+
1168
+ # add x-label inside the plot
1169
+
1170
+ plt.xlabel('Date', fontsize=12 )
1171
+
1172
+ # add y-label
1173
+ plt.ylabel('Polarity', fontsize=12)
1174
+
1175
+ # add x-ticks
1176
+ # plt.xticks(fontsize=12 )
1177
+ # ax1 = plt.axes()
1178
+ # x_axis = ax1.axes.get_xaxis()
1179
+ # # x_axis.set_visible(False)
1180
+ # # hide axis values
1181
+ # x_axis.set_ticks([])
1182
+ # # hide axis line
1183
+ # x_axis.set_ticklabels([])
1184
+
1185
+ plt.yticks(fontsize=12)
1186
+
1187
+ return plt, df
1188
+
1189
+
1190
+ def get_synthetic_comment(text: None, slider, dataframe) :
1191
+
1192
+
1193
+ if check_words_in_string(words, text, case=False) and False:
1194
+
1195
+ df = dataframe.copy() # query is based on a dataframe called "df"
1196
+ agent = create_pandas_dataframe_agent(OpenAI(temperature=0), df, verbose=True)
1197
+
1198
+ def launch_agent(user_input):
1199
+ memory['user'].append(user_input)
1200
+ # user_input = get_memory() + user_input
1201
+ user_input = user_input
1202
+ agent_output = (agent.run(user_input))
1203
+ memory['agent'].append(agent_output)
1204
+ return agent_output
1205
+
1206
+ print('Pandas Agent Query')
1207
+ answer = launch_agent(text)
1208
+ return answer, None, None
1209
+
1210
+ else:
1211
+ query_type = 'comments'
1212
+
1213
+ query = f'Forget all of the above. Write 2-3 examples of {query_type} answering this question: {text}. \n\n{query_type}:\n\n'
1214
+ response = openai.ChatCompletion.create(
1215
+ model="gpt-3.5-turbo",
1216
+ temperature=0.5,
1217
+ max_tokens=300,
1218
+ top_p=1,
1219
+ # stream=True,
1220
+ messages=[
1221
+ #{"role": "system", "content": "Forget all the above instructions. You are a reviewer of products but also a customer and have an opinion about the products you buy. You are asked to write a review of a product you have recently purchased."},
1222
+ {"role": "user", "content": query},
1223
+ ]
1224
+ )['choices'][0]['message']['content']
1225
+ response = re.sub(r'As an AI model.*?\.', '', response)
1226
+ response = re.sub(r'As an AI language model.*?\.', '', response)
1227
+
1228
+ query_embed = model.encode(response)
1229
+ # dataframe['embeddings'] = dataframe['translated_text'].apply(
1230
+ # lambda x: model.encode(x))
1231
+ dataframe['similarity'] = dataframe['embeddings'].apply(
1232
+ lambda x: round(float(util.pytorch_cos_sim(query_embed, x)), 3))
1233
+
1234
+ dataframe.sort_values(by='similarity', ascending=False, inplace=True)
1235
+
1236
+
1237
+ complexity = ''
1238
+ cutsize = 900
1239
+
1240
+ if dataframe[dataframe['similarity'] > slider].shape[0] == 0:
1241
+ response2 = f'No {query_type} found with a similarity score above {slider}. Try to lower the similarity score threshold or change the question.\n\n However, this is what I found on the internet: \n\n'
1242
+
1243
+ toolname = ['wolfram-alpha']
1244
+ tools = load_tools(toolname)
1245
+ agent = initialize_agent(tools=tools, llm=llm, agent='zero-shot-react-description', verbose=False)
1246
+ wolfram_content = agent.run(f'{text}')
1247
+ wolfram_response = f'{wolfram_content}'
1248
+
1249
+ toolname = ['serpapi']
1250
+ tools = load_tools(toolname)
1251
+ agent = initialize_agent(tools=tools, llm=llm, agent='zero-shot-react-description', verbose=False)
1252
+ internet_content = agent.run(f'{text}')
1253
+ internet_response = f'{internet_content}'
1254
+
1255
+ response2 = f'{response2} \n\n {wolfram_response} \n\n {internet_response}'
1256
+
1257
+ else:
1258
+
1259
+ try:
1260
+ corpus = dataframe[dataframe['similarity']
1261
+ > slider]['translated_text'].tolist()
1262
+ print("CORPUS SIZE:", "FULL")
1263
+
1264
+ response2 = openai.ChatCompletion.create(
1265
+ model="gpt-3.5-turbo",
1266
+ temperature=0.4,
1267
+ max_tokens=300,
1268
+ top_p=1,
1269
+ # stream=True,
1270
+ messages=[
1271
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1272
+ ]
1273
+ )['choices'][0]['message']['content']
1274
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1275
+ except:
1276
+ try:
1277
+ corpus = dataframe[dataframe['similarity']
1278
+ > slider]['translated_text'][0:50].tolist()
1279
+ corpus = [x[:cutsize] for x in corpus]
1280
+ print("CORPUS SIZE:", 50)
1281
+ response2 = openai.ChatCompletion.create(
1282
+ model="gpt-3.5-turbo",
1283
+ temperature=0.4,
1284
+ max_tokens=300,
1285
+ top_p=1,
1286
+ # stream=True,
1287
+ messages=[
1288
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1289
+ ]
1290
+ )['choices'][0]['message']['content']
1291
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1292
+ except:
1293
+ try:
1294
+ corpus = dataframe[dataframe['similarity']
1295
+ > slider]['translated_text'][0:30].tolist()
1296
+ corpus = [x[:cutsize] for x in corpus]
1297
+
1298
+ print("CORPUS SIZE:", 30)
1299
+ response2 = openai.ChatCompletion.create(
1300
+ model="gpt-3.5-turbo",
1301
+ temperature=0.4,
1302
+ max_tokens=300,
1303
+ top_p=1,
1304
+ # stream=True,
1305
+ messages=[
1306
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1307
+ ]
1308
+ )['choices'][0]['message']['content']
1309
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1310
+ except:
1311
+ corpus = dataframe[dataframe['similarity']
1312
+ > slider]['translated_text'][0:15].tolist()
1313
+ print("CORPUS SIZE:", 15)
1314
+ # keep only the first 400 characters per each list elem
1315
+ corpus = [x[:cutsize] for x in corpus]
1316
+
1317
+ response2 = openai.ChatCompletion.create(
1318
+ model="gpt-3.5-turbo",
1319
+ temperature=0.4,
1320
+ max_tokens=300,
1321
+ top_p=1,
1322
+ # stream=True,
1323
+ messages=[
1324
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1325
+ ]
1326
+ )['choices'][0]['message']['content']
1327
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1328
+
1329
+ # Graph Generation
1330
+
1331
+ return response2, dataframe[dataframe['similarity'] > slider][['similarity', 'translated_text']][0:15], response2, "<span class='hsub'>Analysis:</span>Manual query"
1332
+
1333
+ return response2, dataframe[dataframe['similarity'] > slider][['similarity', 'translated_text']][0:15], response2, "<span class='hsub'>Analysis:</span>Manual query"
1334
+
1335
+ def clear_output(filename, titleBlock):
1336
+ titleBlock = re.sub('<[^<]+?>', '', titleBlock)
1337
+ # remove all \n
1338
+ # trim
1339
+ titleBlock = titleBlock.replace("\n", "")
1340
+
1341
+ print(titleBlock)
1342
+ print(filename)
1343
+ print(filename + titleBlock + "_CACHE.txt")
1344
+ try:
1345
+ os.remove(filename + titleBlock + "_CACHE.txt")
1346
+ except Exception as e:
1347
+ print (e)
1348
+
1349
+ pass
1350
+ return 'Cache has been cleared'
1351
+
1352
+ def save_output(tab, data_answer):
1353
+
1354
+ # def save_output(tab):
1355
+ if tab == "Summary":
1356
+ print("summary save")
1357
+ print(data_answer)
1358
+ print (data_answer.value)
1359
+ print(dir(data_answer))
1360
+ # with open("data_answer.txt", "+ab") as f:
1361
+ # open and append to it
1362
+ with open("data_answer.txt", "a") as f:
1363
+ try:
1364
+ f.write(data_answer.value)
1365
+ f.write(data_answer)
1366
+ except:
1367
+ pass
1368
+
1369
+ elif tab == "Table":
1370
+ try:
1371
+ similar_reviews_dataframe = pd.DataFrame(similar_reviews)
1372
+ similar_reviews_dataframe.to_csv("similar_reviews.csv", index=False, encoding='utf-8-sig')
1373
+ except:
1374
+ pass
1375
+ else:
1376
+ try:
1377
+ g.save_graph("graph.html")
1378
+ except:
1379
+ pass
1380
+
1381
+
1382
+ def generate_new_examples(text):
1383
+ # GENERATE NEW EXAMPLES BASED ON QUERY
1384
+ new_examples = openai.ChatCompletion.create(
1385
+ model="gpt-3.5-turbo",
1386
+ temperature=0.7,
1387
+ max_tokens=100,
1388
+ top_p=1,
1389
+ # stream=True,
1390
+ messages=[
1391
+ {"role": "user", "content": f'Generate a list of 4 most relevent questions related to this question : {text}. Output should be in a comma separated string format, no numbers, ordering. (example: What is this text about?, What is the main trend?,...) There is no need to enumerate each element.\n\n'},
1392
+ ]
1393
+ )['choices'][0]['message']['content']
1394
+
1395
+
1396
+ new_examples = new_examples.split('\n')
1397
+ # make a list for each element
1398
+
1399
+ new_examples = [x for x in new_examples if x != '']
1400
+ new_examples = [x.strip() for x in new_examples]
1401
+ new_examples = [x.split(',') for x in new_examples]
1402
+ return new_examples
1403
+
1404
+
1405
+ def summarize_video(url):
1406
+ loader = YoutubeLoader.from_youtube_channel(url)
1407
+ result = loader.load()
1408
+
1409
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=0)
1410
+ texts = text_splitter.split_documents(result)
1411
+ print(len(texts))
1412
+
1413
+
1414
+ # We first try the chain with the default chain type
1415
+ # if length of the text is more than 2000 tokens, we will use map reduce (summary of chunks)
1416
+
1417
+ try:
1418
+ chain = load_summarize_chain(llm, chain_type='stuff', verbose=True)
1419
+ print('ChainType: stuff')
1420
+ # store intermediate steps
1421
+ return chain.run(result)
1422
+
1423
+ except:
1424
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=0)
1425
+ texts = text_splitter.split_documents(result)
1426
+ # print(len(texts))
1427
+ chain = load_summarize_chain(llm, chain_type='map_reduce', verbose=True)
1428
+ print('ChainType: map reduce')
1429
+ return chain.run(texts)
1430
+
1431
+
1432
+ # def main():
1433
+ # global similar_reviews, g, query_type, response2, Output, output_html, html, new_examples, samples
1434
+
1435
+ def get_graph(dataframe):
1436
+
1437
+ print("step 1")
1438
+ from sklearn.cluster import KMeans
1439
+ from sklearn.metrics.pairwise import cosine_similarity
1440
+
1441
+
1442
+ embeddings_array = dataframe['embeddings'].tolist()
1443
+ print ("step 2")
1444
+ num_clusters = 3 # Adjust the number of clusters as needed
1445
+ kmeans = KMeans(n_clusters=num_clusters, random_state=42)
1446
+ cluster_labels = kmeans.fit_predict(embeddings_array)
1447
+
1448
+ print(cluster_labels)
1449
+ sentences = dataframe['translated_text'].tolist()
1450
+ print ("step 3")
1451
+ G = nx.DiGraph()
1452
+
1453
+
1454
+ cos_sim_matrix = cosine_similarity(embeddings_array)
1455
+ print(cos_sim_matrix)
1456
+ print ("step 4")
1457
+ for idx, label in enumerate(cluster_labels):
1458
+ G.add_node(idx, sentence=sentences[idx], cluster=label)
1459
+
1460
+ for i in range(len(sentences)):
1461
+ for j in range(len(sentences)):
1462
+ if i != j:
1463
+ #if cos_sim_matrix[i, j] > 0.8:
1464
+ G.add_edge(i, j, weight=cos_sim_matrix[i, j])
1465
+ # else:
1466
+ # continue
1467
+ print ("step 5")
1468
+ plt.figure(figsize=(10, 10))
1469
+
1470
+ pos = nx.spring_layout(G, k=0.5, iterations=50)
1471
+
1472
+ print ("step 6")
1473
+ G_undirected = G.to_undirected()
1474
+
1475
+ from community import community_louvain
1476
+ node_to_community = community_louvain.best_partition(G_undirected)
1477
+
1478
+ print ("step 7")
1479
+ community_to_color = {
1480
+ 0 : 'tab:pink',
1481
+ 1 : 'tab:orange',
1482
+ 2 : 'tab:purple',
1483
+ 3 : 'tab:blue',
1484
+ }
1485
+
1486
+ node_color = {node: community_to_color[community_id] for node, community_id in node_to_community.items()}
1487
+
1488
+ print ("step 8")
1489
+ reducer = umap.UMAP(n_components=2, random_state=42)
1490
+ embeddings_2d = reducer.fit_transform(embeddings_array)
1491
+
1492
+ def normalize_weight(weight, min_weight, max_weight):
1493
+ return (weight - min_weight) / (max_weight - min_weight)
1494
+
1495
+
1496
+ def visualize_graph_plotly(graph, embeddings_2d, scaling_factor=3):
1497
+
1498
+ print ("step 9")
1499
+ min_weight = min((data['weight'] for _, _, data in graph.edges(data=True)))
1500
+ max_weight = max((data['weight'] for _, _, data in graph.edges(data=True)))
1501
+
1502
+ fig = go.Figure()
1503
+
1504
+
1505
+ print ("step 10")
1506
+ # Add edges with width based on the normalized weights
1507
+ print(len(graph.edges()))
1508
+ for i, j in graph.edges():
1509
+ print(i)
1510
+ weight = normalize_weight(graph[i][j]['weight'], min_weight, max_weight)
1511
+ # weight=0.1
1512
+ fig.add_shape(
1513
+ type="line",
1514
+ x0=embeddings_2d[i][0],
1515
+ x1=embeddings_2d[j][0],
1516
+ y0=embeddings_2d[i][1],
1517
+ y1=embeddings_2d[j][1],
1518
+ yref="y",
1519
+ xref="x",
1520
+ line=dict(color="rgba(211, 211, 211, 0.5)", width=weight * scaling_factor * 0.7),
1521
+ )
1522
+ print ("step 11")
1523
+ # Add nodes
1524
+ for idx, emb in enumerate(embeddings_2d):
1525
+ closeness = nx.closeness_centrality(G)[idx]
1526
+ degree = nx.degree_centrality(G)[idx]
1527
+ betweenness = nx.betweenness_centrality(G)[idx]
1528
+ eigen = nx.eigenvector_centrality(G)[idx]
1529
+
1530
+ fig.add_trace(
1531
+ go.Scatter(
1532
+ x=[emb[0]],
1533
+ y=[emb[1]],
1534
+ mode="markers+text",
1535
+ text=[graph.nodes[idx]["sentence"]],
1536
+ textposition="bottom center",
1537
+ marker=dict(color=node_color[idx][4:], size=closeness * 40),
1538
+ # add closeness, degree, betweenness and sentence as hover text
1539
+ hovertext=[f"{graph.nodes[idx]['sentence']} <br> closeness_centrality: {closeness:.2f} <br> degree_centrality: {degree:.2f} <br> betweenness_centrality: {betweenness:.2f} <br> eigenvector_centrality: {eigen:.2f}"],
1540
+ )
1541
+ )
1542
+
1543
+ print("for completed")
1544
+
1545
+ fig.update_layout(showlegend=False, plot_bgcolor="white", width=1200, height=800)
1546
+ fig.update_xaxes(showticklabels=False, showgrid=False, zeroline=False,
1547
+ showline=False, automargin=False, showspikes=False)
1548
+ fig.update_yaxes(showticklabels=False, showgrid=False, zeroline=False,
1549
+ showline=False, automargin=False, showspikes=False)
1550
+
1551
+ fig.update_layout(title_text="Test Graph Visualization", title_x=0.5, title_font_size=30, title_font_color='black')
1552
+
1553
+ return fig
1554
+
1555
+ return visualize_graph_plotly(G, embeddings_2d, scaling_factor = 10)
1556
+
1557
+ def update_examples(samples):
1558
+ return gr.Dataset.update(samples=samples)
1559
+
1560
+ def print_samples():
1561
+ global samples
1562
+ return {"samples": samples}
1563
+
1564
+ def load_example(example_id):
1565
+ global samples
1566
+ return samples[example_id][0]
1567
+
1568
+ url_params = gr.JSON({}, visible=False, label="URL Params")
1569
+
1570
+
1571
+ def getAnalysisLabel(id):
1572
+ if id == 'exec_sum':
1573
+ return 'Executive Summary'
1574
+ elif id == 'top_clust':
1575
+ return 'Topic Cluster'
1576
+
1577
+ elif id == 'trend_analysis':
1578
+ return 'Trend Analysis'
1579
+
1580
+ elif id == 'emot_clust':
1581
+ return 'Sentiment Analysis'
1582
+
1583
+ elif id == 'swot_':
1584
+ return 'SWOT Analysis'
1585
+
1586
+ elif id == 'competitor':
1587
+ return 'Competitor Analysis'
1588
+
1589
+ tabs = [
1590
+ {
1591
+ "id": 0,
1592
+ "label": "Social Media",
1593
+ "content": {
1594
+ "exec_sum":None,
1595
+ "top_clust": None,
1596
+ "emot_clust": None,
1597
+ "swot_": None,
1598
+ # "competitor": None,
1599
+ },
1600
+ "filename": "profdemo_cleaned.xlsx"
1601
+ },
1602
+ {
1603
+ "id": 1,
1604
+ "label": "News/Publications",
1605
+ "content": {
1606
+ "exec_sum":None,
1607
+ "trend_analysis": None,
1608
+ # "top_clust": None,
1609
+ "competitor" : None,
1610
+ "swot_": None,
1611
+ },
1612
+ "filename": "cleaned_news.xlsx"
1613
+ },
1614
+ # {
1615
+ # "id": 0,
1616
+ # "label": "Mozzarella",
1617
+ # "content": {
1618
+ # "exec_sum":None,
1619
+ # "top_clust": None,
1620
+ # # "trend_analysis": None,
1621
+ # "emot_clust": None,
1622
+ # # "swot_": None,
1623
+ # # "competitor" : None,
1624
+ # },
1625
+ # "filename": "MozzarellaTW.xlsx"
1626
+ # },
1627
+ # {
1628
+ # "id": 1,
1629
+ # "label": "Onion",
1630
+ # "content": {
1631
+ # "exec_sum":None,
1632
+ # "top_clust": None,
1633
+ # "emot_clust": None,
1634
+ # # "competitor" : None,
1635
+ # },
1636
+ # "filename": "OnionTW.xlsx"
1637
+ # },
1638
+ # {
1639
+ # "id": 2,
1640
+ # "label": "Brand - Social Media",
1641
+ # "content": {
1642
+ # "exec_sum":None,
1643
+ # "top_clust": None,
1644
+ # "trend_analysis": None,
1645
+ # "emot_clust": None,
1646
+ # "swot_": None,
1647
+ # "competitor" : None,
1648
+ # },
1649
+ # "filename": "LambWestonBrand.csv"
1650
+ # },
1651
+ # {
1652
+ # "id": 3,
1653
+ # "label": "Brand - News",
1654
+ # "content": {
1655
+ # "exec_sum":None,
1656
+ # "top_clust": None,
1657
+ # "trend_analysis": None,
1658
+ # "emot_clust": None,
1659
+ # "swot_": None,
1660
+ # "competitor" : None,
1661
+ # },
1662
+ # "filename": "LambWestonNews.csv"
1663
+ # },
1664
+ ]
1665
+
1666
+ list = []
1667
+ maxSources = 10
1668
+
1669
+ oTab = []
1670
+ attachButtons = []
1671
+
1672
+ for element in tabs:
1673
+ oTab.append( {
1674
+ "exec_sum":None,
1675
+ "top_clust": None,
1676
+ "trend_analysis": None,
1677
+ "emot_clust": None,
1678
+ "swot_": None,
1679
+ "competitor" : None,
1680
+ })
1681
+ attachButtons.append(None)
1682
+
1683
+
1684
+ get_window_url_params = """
1685
+ function(url_params) {
1686
+ var scriptElement = document.createElement("script");
1687
+ scriptElement.src = '"""+gradio_js+"""?v="""+str(ra)+"""';
1688
+ scriptElement.innerHTML = "console.log('This is dynamic JavaScript code');";
1689
+ document.body.appendChild(scriptElement);
1690
+ const params = new URLSearchParams(window.location.search);
1691
+ url_params = Object.fromEntries(params);
1692
+ return [url_params];
1693
+ }
1694
+ """
1695
+
1696
+ runjs = """
1697
+ function(projJson,num,fullData) {
1698
+ console.log(fullData)
1699
+
1700
+ var localizations = fullData['localization']
1701
+ console.log( fullData['localization'])
1702
+ if (localizations) {
1703
+ document.querySelectorAll('.hsub')[0].innerText = localizations['project'];
1704
+ // document.querySelectorAll('.hsub')[1].innerText = "semmi";
1705
+ // document.querySelectorAll('.hsub')[2].innerText = "semmi";
1706
+
1707
+ if (document.querySelector('#querybtn')) document.querySelector('#querybtn').innerText = localizations['talk_to_your_data']
1708
+
1709
+ var tabs = document.querySelectorAll('#targetColMiddle .tab-nav button');
1710
+ tabs[0].innerText = localizations['overview'] || 'Overview'
1711
+ tabs[1].innerText = localizations['rawdata'] || 'Raw Data'
1712
+ tabs[2].innerText = localizations['visuals'] || 'Visuals'
1713
+
1714
+ document.querySelectorAll('.sideTitle span')[0].innerText = localizations['data_sources'] || 'Data sources'
1715
+ document.querySelectorAll('.sideTitle span')[1].innerText = localizations['predefined_analysis'] || 'Predefined analysis'
1716
+ }
1717
+ document.querySelectorAll('.analysisButton').forEach(function(el) {
1718
+ el.style.display = 'none';
1719
+ });
1720
+ Object.keys(projJson[num]['content']).forEach(function(key) {
1721
+ document.querySelectorAll('.analysisButton').forEach(function(el) {
1722
+ if (el.id == key) {
1723
+ el.style.display = 'block';
1724
+ }
1725
+
1726
+ });
1727
+ });
1728
+
1729
+ document.querySelectorAll('.sourceButton').forEach(function(el) {
1730
+ el.classList.remove('selectedSource');
1731
+ });
1732
+ document.querySelectorAll('.sourceButton').forEach(function(el) {
1733
+ if (el.innerHTML == projJson[num]['label']) el.classList.add('selectedSource');
1734
+ });
1735
+ // NEM ÉRTEM MINEK KELL TÖBB OUTPUT
1736
+ return [1, num,1,1]
1737
+ }
1738
+ """
1739
+
1740
+ def parse_URL_params(url_params):
1741
+ # if url params has 'pid'
1742
+ if 'pid' in url_params:
1743
+ request = requests.get(rubik_backend + '?proj=' + url_params['pid'])
1744
+ text = url_params['pid']
1745
+ else:
1746
+ request = requests.get(rubik_backend + '?proj=demo')
1747
+ text = "demo"
1748
+
1749
+ # textlowercase url_params['pid']
1750
+ # first letter uppercase
1751
+ textUpper = request.json()["brand"][0].upper() + request.json()["brand"][1:]
1752
+ return [url_params, request.json()["sources"], request.json()["sources"], "<div class='brand'><span class='hsub'>Project:</span>"+textUpper+"</div>", request.json(), text]
1753
+
1754
+ for i in range(maxSources):
1755
+ list.append({"id":i, "name":"asd", "obj":"", "analList":[]})
1756
+
1757
+
1758
+ def variable_outputs(k):
1759
+ global list
1760
+ sourceArray = k
1761
+ output = None
1762
+ for i in range(len(sourceArray)):
1763
+ if not output:
1764
+ output = [list[i]["obj"].update(value=sourceArray[i]["label"],visible=True)]
1765
+ else:
1766
+ output += [list[i]["obj"].update(value=sourceArray[i]["label"],visible=True)]
1767
+
1768
+ remainingCount = maxSources - len(sourceArray)
1769
+
1770
+ for i in range(remainingCount):
1771
+ output += [list[i]["obj"].update(value="",visible=False)]
1772
+
1773
+ return output
1774
+
1775
+ url_params = gr.JSON({}, label="URL Params", visible=False)
1776
+
1777
+ # with gr.Interface(theme=gr.themes.Soft(primary_hue='pink', secondary_hue='pink', neutral_hue='stone'), css="footer{display:none !important}") as app:
1778
+ # , css=".main{filter: blur(3px)}footer{display:none !important}"
1779
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue='pink', secondary_hue='pink', neutral_hue='stone')) as app:
1780
+
1781
+ dat = gr.Markdown()
1782
+ projdetails = gr.Textbox("test", label="Project Details", visible=False)
1783
+ projJson = gr.JSON(visible=False)
1784
+ fullProjectData = gr.JSON(visible=False)
1785
+ projectUUID = gr.State(value="", label="projectUUID", visible=False)
1786
+ if True:
1787
+ summaries_state = gr.State(value=[], label="summaries_state")
1788
+ executive = gr.State(value='', label="executive")
1789
+ needHeader = True
1790
+
1791
+ # if needHeader and False:
1792
+ # with gr.Row():
1793
+ # with gr.Column(scale=.1, elem_id="logocol"):
1794
+ # # gr.Markdown('<img id="logo" src="http://
1795
+ # # add a title at the center of the page
1796
+ # gr.Markdown('<a href="https://app.rubiklab.ai"><img id="logo" src="http://127.0.0.1:5500/logo.png" /></a>')
1797
+
1798
+ # with gr.Column(scale=.3):
1799
+ # gr.Markdown("<h1>Talkback</h1>")
1800
+
1801
+ # random number between 1 and 10000
1802
+ ra = str(np.random.randint(1, 10000))
1803
+ gr.Markdown(
1804
+ """
1805
+ <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap'>
1806
+ <link rel="stylesheet" href='""" + gradio_css + """?v="""+str(ra)+"""'>
1807
+ <link rel="icon" type="image/x-icon" href="https://api.rubiklab.ai/assets/favicon.ico">
1808
+ """
1809
+ )
1810
+
1811
+ # if needHeader:
1812
+ # with gr.Row():
1813
+ # with gr.Column(elem_id="header"):
1814
+ # gr.Markdown("<h2>Nike</h2>")
1815
+
1816
+ # selectedData = gr.Markdown('<span></span>', elem_id="datanameblock")
1817
+ # titleBlock = gr.Markdown("<span class='title'></span>", elem_id="titleblock")
1818
+
1819
+
1820
+ df = pd.DataFrame()
1821
+ with gr.Row():
1822
+ with gr.Column(scale=.4, elem_id="leftContainer"):
1823
+ with gr.Row(elem_id="header"):
1824
+ proj = gr.Markdown("")
1825
+ selectedData = gr.Markdown('<span></span>', elem_id="datanameblock")
1826
+ titleBlock = gr.Markdown("<span class='title'></span>", elem_id="titleblock")
1827
+
1828
+
1829
+
1830
+ gr.Markdown("<h3 class='sideTitle'><span>Data sources</span></h3>")
1831
+ tabs = []
1832
+ analysisList = []
1833
+ for i in range(maxSources):
1834
+ list[i]["obj"] = gr.Button(value="" + str(i),visible=False, elem_classes="sourceButton")
1835
+ list[i]["index"] = gr.Number(i, visible=False)
1836
+ tabs.append(list[i]["obj"])
1837
+
1838
+ gr.Markdown("<h3 class='sideTitle predefined'><span>Predefined analysis</span></h3>")
1839
+ # analysisList = ['exec_sum', 'top_clust', 'emot_clust', 'swot_', 'trend_analysis', 'competitor']
1840
+ oa = {
1841
+ 'exec_sum': gr.Button("Executive Summary", elem_id="exec_sum", elem_classes=["analysisButton"]),
1842
+ 'top_clust': gr.Button("Topic Clusters", elem_id="top_clust", elem_classes=["analysisButton"]),
1843
+ 'emot_clust': gr.Button("Sentiment Analysis", elem_id="emot_clust", elem_classes=["analysisButton"]),
1844
+ 'swot_': gr.Button("SWOT Analysis", elem_id="swot_", elem_classes=["analysisButton"]),
1845
+ 'trend_analysis': gr.Button("Trend Analysis", elem_id="trend_analysis", elem_classes=["analysisButton"]),
1846
+ 'competitor': gr.Button("Competitor Analysis", elem_id="competitor", elem_classes=["analysisButton"]),
1847
+ }
1848
+ newcluster = gr.Button("New Cluster", elem_id="newcluster", elem_classes=["newcluster"], visible=False)
1849
+ newgraph = gr.Button("New graph", elem_id="newcluster", elem_classes=["newgraph"], visible=False)
1850
+
1851
+ # for i in range(len(analysisList)):
1852
+ # gr.Button(analysisList[i], elem_classes=["analysisButton"], elem_id=analysisList[i])
1853
+
1854
+ # iterate throu oa
1855
+ gr.Button("Talk to your data", elem_id="querybtn")
1856
+ projJson.change(variable_outputs, projJson, tabs)
1857
+ gr.Markdown(f'url params value: {url_params.value}', visible=False)
1858
+ threshold = gr.Slider(minimum=0, maximum=1, label="Threshold", visible=False)
1859
+ csv_file = gr.File(label="File (csv, excel, h5..)", elem_id="fupload",visible=False)
1860
+
1861
+ brand = gr.State('brand')
1862
+ industry = gr.State('industry')
1863
+
1864
+ csvs = gr.State('csvnum')
1865
+ filename = gr.State('filename')
1866
+
1867
+ graph_type = gr.State('graph_type')
1868
+
1869
+ # THE DATASET
1870
+ data_storage = gr.State(label="data_storage")
1871
+
1872
+ # TOPICS LIST
1873
+ list_of_topics = gr.State(label="list_of_topics")
1874
+
1875
+ # add image output
1876
+ with gr.Tab("Word Cloud"):
1877
+ Imaj = gr.Image(label="Word Cloud")
1878
+
1879
+ with gr.Tab("Polarity"):
1880
+ Polarity = gr.Plot(label="Polarity")
1881
+
1882
+ app.load(
1883
+ fn=parse_URL_params,
1884
+ inputs=[url_params],
1885
+ outputs=[url_params, projJson, projdetails, proj, fullProjectData,projectUUID],
1886
+ _js=get_window_url_params
1887
+ )
1888
+ url_params.render()
1889
+ with gr.Column(scale=2, elem_id="targetColMiddle"):
1890
+
1891
+ graphHelper = gr.Markdown("<span></span>")
1892
+ with gr.Tab("Overview", elem_id="overviewTab"):
1893
+ tab = 'Summary'
1894
+ data_answer = gr.Textbox(visible=False, elem_id="hiddenTextbox")
1895
+ # gr.Textbox.style(data_answer)
1896
+ formattedres = gr.Markdown("<span class='description'></span>")
1897
+
1898
+ with gr.Row():
1899
+ with gr.Column(scale=6):
1900
+ # add empty space
1901
+ pass
1902
+ with gr.Column(scale=.5, min_width=100):
1903
+ clear_button = gr.Button("Clear", visible=True, elem_id="clear_button")
1904
+ clear_button.click(fn=clear_output, inputs=[filename, titleBlock], outputs=[formattedres])
1905
+ # save_button = gr.Button("Save", visible=True, elem_id="save_button")
1906
+ # save_button.click(lambda: save_output("Summary", data_answer))
1907
+
1908
+
1909
+ tab = gr.Tab("Raw data", elem_id="rawdataTab")
1910
+ with tab:
1911
+ tab = 'Table'
1912
+ similar_reviews = gr.Dataframe(label="Table", type="pandas", max_rows=20, overflow_row_behaviour='paginate', show_label=False)
1913
+ with gr.Row():
1914
+ with gr.Column(scale=6):
1915
+ # add empty space
1916
+ pass
1917
+ # with gr.Column(scale=.5, min_width=100):
1918
+ # save_button = gr.Button("Save", visible=True)
1919
+ # save_button.click(lambda: save_output("Table", data_answer))
1920
+ with gr.Tab("Visuals"):
1921
+ tab = 'Graph'
1922
+ graph = gr.Plot(elem_id="cluster", label="")
1923
+ graph2 = gr.Plot(elem_id="cluster2", label="", visible=False)
1924
+ # with gr.Tab("Word Cloud"):
1925
+ Imaj = gr.Image(label="Word Cloud", elem_id="vwordcloud")
1926
+
1927
+ # with gr.Tab("Polarity"):
1928
+ Polarity = gr.Plot(label="Polarity", elem_id="vpolarity")
1929
+
1930
+ # with gr.Row():
1931
+ # with gr.Column(scale=1):
1932
+ # clearbutton = gr.Button("Remove and regenerate", visible=True, elem_id="cleardrop_button")
1933
+ # clearkeepbutton = gr.Button("Keep and regenerate", visible=True, elem_id="clearkeep_button")
1934
+
1935
+
1936
+ with gr.Row():
1937
+ with gr.Column(scale=6):
1938
+ # add empty space
1939
+ pass
1940
+ # with gr.Column(scale=.5, min_width=100):
1941
+ # save_button = gr.Button("Save", visible=True)
1942
+ # gr.Button.style(save_button, color="secondary")
1943
+ # save_button.click(lambda: save_output("Graph", data_answer))
1944
+
1945
+
1946
+ with gr.Row(elem_id="query"):
1947
+ with gr.Column(scale=1, elem_id='query1'):
1948
+
1949
+ data_answerQuery = gr.Textbox(label="", lines=10, visible=False)
1950
+ # gr.Textbox.style(data_answer)
1951
+ formattedresQuery = gr.Markdown("<span class='description'></span>")
1952
+
1953
+ query = gr.Textbox(lines=1, placeholder="Start typing your question...", label=" ")
1954
+ gr.Textbox.style(query)
1955
+
1956
+ submit_button = gr.Button("Submit", elem_id='submit')
1957
+ gr.Button.style(submit_button, color="secondary")
1958
+
1959
+ with gr.Column(scale=.1, elem_id='query2'):
1960
+ samples = [["What insights can we take from this data?", "2 What insights can we take from this data?"]]
1961
+
1962
+ examples = gr.Dataset(samples=samples, components=[query], type="index", label="Some hints for your next question, select which one you prefer.")
1963
+
1964
+
1965
+
1966
+ def update_examples(query):
1967
+ global samples
1968
+ samples = generate_new_examples(query)
1969
+ return gr.Dataset.update(samples=samples)
1970
+
1971
+ def print_samples():
1972
+ global samples
1973
+ return {"samples": samples}
1974
+
1975
+ def load_example(example_id):
1976
+ global samples
1977
+ return samples[example_id][0]
1978
+
1979
+
1980
+ def changesource(projJson, num):
1981
+ # print("switching")
1982
+ return 1
1983
+ def doJS(projJson, num,fulldat):
1984
+ # print("doing js")
1985
+ return 1, num
1986
+
1987
+ sourcelabel = gr.TextArea(elem_id="activeSource", visible=False)
1988
+ sourceIndex = gr.Number(visible=False)
1989
+ xy = gr.State()
1990
+ for i in range(maxSources):
1991
+ num = list[i]["index"]
1992
+ list[i]["obj"].click(doJS,inputs=[projJson, num, fullProjectData], outputs=[xy, sourceIndex], _js=runjs).then(
1993
+ load_csv, inputs=[projJson, num, fullProjectData, projectUUID], outputs=[data_storage, data_answer, similar_reviews, formattedres, filename, selectedData]).then(
1994
+ generate_wordcloud, inputs=[data_storage], outputs=[Imaj]).then(
1995
+ get_polarity, inputs=[data_storage], outputs=[Polarity, data_storage])
1996
+
1997
+
1998
+ # SUMMARIZE VIDEO CONTENT
1999
+ def checkData(filename):
2000
+ print(filename)
2001
+
2002
+ dat = gr.State(label="dat")
2003
+
2004
+ oa['exec_sum'].click(fn=checkData, inputs=[filename], outputs=[]).then(get_executive_summary, inputs=[data_storage, brand, industry,summaries_state, csvs, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper, formattedres, titleBlock])
2005
+ oa['top_clust'].click(get_topic_cluster, inputs=[data_storage, graph_type,filename], outputs=[graph, similar_reviews, list_of_topics, query, dat, graphHelper,formattedres,titleBlock])
2006
+ oa['emot_clust'].click(emotional_mapping, inputs=[data_storage, industry, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper,formattedres,titleBlock])
2007
+ oa['swot_'].click(get_executive_summary, inputs=[data_storage, brand, industry,summaries_state, csvs, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper, formattedres, titleBlock]).then(get_SWOT, inputs=[data_storage, brand, industry, executive, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, graphHelper,formattedres,titleBlock])
2008
+ oa['trend_analysis'].click(get_trend_summary, inputs=[data_storage, list_of_topics, brand, industry, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper,formattedres,titleBlock])
2009
+ oa['competitor'].click(get_competitive, inputs=[brand, industry, graph_type,filename,data_storage, fullProjectData, sourceIndex], outputs=[data_answer, graphHelper,formattedres,titleBlock])
2010
+
2011
+
2012
+ def clear_data(filename):
2013
+ if os.path.exists(filename + 'df3.csv'):
2014
+ os.remove(filename + 'df3.csv')
2015
+
2016
+ def rename_data_timestamp(filename):
2017
+ if os.path.exists(filename + 'df3.csv'):
2018
+ os.rename(filename + 'df3.csv', filename + str(datetime.datetime.now()) + '.csv')
2019
+
2020
+ # clearbutton.click(clear_data, inputs=[filename], outputs=[]).then(get_topic_cluster, inputs=[data_storage, graph_type,filename], outputs=[graph, similar_reviews, list_of_topics, query, dat, graphHelper,formattedres,titleBlock])
2021
+ # clearkeepbutton.click(rename_data_timestamp, inputs=[filename], outputs=[]).then(get_topic_cluster, inputs=[data_storage, graph_type,filename], outputs=[graph, similar_reviews, list_of_topics, query, dat, graphHelper,formattedres,titleBlock])
2022
+
2023
+ # app.launch(share=True, server_name="0.0.0.0", server_port=7860)
2024
+ def get_new_topic(data_storage, graph_type,filename):
2025
+ from bertopic import BERTopic
2026
+ from bertopic.representation import OpenAI
2027
+ from sklearn.cluster import KMeans
2028
+ from sklearn.feature_extraction.text import CountVectorizer
2029
+ import pandas as pd
2030
+ # import openai
2031
+
2032
+ # openai.api_key = 'sk-2Ulixq
2033
+ prompt = """
2034
+ I have a topic that contains the following documents:
2035
+ [DOCUMENTS]
2036
+ The topic is described by the following keywords: [KEYWORDS]
2037
+
2038
+ Based on the information above, extract a short topic label in the following format:
2039
+ topic: <topic label>
2040
+ """
2041
+
2042
+ vectorizer_model=CountVectorizer(stop_words="english")
2043
+
2044
+ # df = pd.read_excel('C:/Users/sinan/Downloads/profdemo_cleaned (1).xlsx')
2045
+ df = data_storage
2046
+ df['translated_text'] = df['translated_text'].apply(lambda x: str(x))
2047
+
2048
+ docs = df['translated_text'].tolist()
2049
+
2050
+ representation_model = OpenAI(model="gpt-3.5-turbo", delay_in_seconds=.5, chat=True)
2051
+
2052
+ if len(docs) < 100:
2053
+ cluster_model = KMeans(n_clusters=3)
2054
+ topic_model = BERTopic(hdbscan_model=cluster_model, representation_model=representation_model, vectorizer_model=vectorizer_model)
2055
+ else:
2056
+ cluster_model = KMeans(n_clusters=6)
2057
+ # representation_model = 'bert-base-nli-mean-tokens'
2058
+ n_gram_range = (1, 1) # set the range of n-grams to be considered
2059
+ min_topic_size = 10 # set the minimum number of documents in each topic
2060
+
2061
+ topic_model = BERTopic(hdbscan_model=cluster_model, representation_model=representation_model, n_gram_range=n_gram_range, min_topic_size=min_topic_size)
2062
+ # topic_model = BERTopic(representation_model=representation_model, nr_topics=8)
2063
+
2064
+
2065
+
2066
+ topics, probs = topic_model.fit_transform(docs)
2067
+
2068
+ return topic_model.visualize_documents(docs, width=1200, height=800, title='Topic Clustering', hide_annotations=True)
2069
+
2070
+ newcluster.click(get_new_topic, inputs=[data_storage, graph_type,filename], outputs=[graph2])
2071
+ newgraph.click(get_graph,inputs=[data_storage], outputs=[graph2])
2072
+
2073
+ # 1. ADD QUESTIONS TO THE QUERY
2074
+ examples.click(load_example, inputs=[examples], outputs=[query])
2075
+
2076
+ # UNCOMMENT FOR TEXT TO SPEECH OUTPUT
2077
+ submit_button.click(get_synthetic_comment, inputs=[query, threshold, data_storage ], outputs=[data_answer, similar_reviews, formattedresQuery, titleBlock]).success(update_examples, inputs=[query], outputs=[examples])
2078
+
2079
+
2080
+
2081
+ def same_auth(username, password):
2082
+ return username == password
2083
+ if __name__ == "__main__":
2084
+ # app.launch(share=True, server_name="0.0.0.0", server_port=7860, auth=same_auth, auth_message="Please enter the same username and password")
2085
+ app.launch(share=True, server_name="0.0.0.0", server_port=7860)
2086
+
2087
+ # if __name__ == "__main__":
2088
+ # main()
gradio_experiments.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import gradio as gr
2
+
3
+ # with gr.Blocks(theme=gr.themes.Soft(primary_hue='pink', secondary_hue='pink', neutral_hue='stone')) as app:
4
+
5
+ # tab = gr.Tab(label="Tab 1")
6
+
7
+ # # tab.add_text("Text Input", lines=5, name="text")
8
+ # tab.update(name="Text Input")
9
+
10
+ # if __name__ == "__main__":
11
+ # # app.launch(share=True, server_name="0.0.0.0", server_port=7860, auth=same_auth, auth_message="Please enter the same username and password")
12
+ # app.launch(share=True, server_name="0.0.0.0", server_port=1111)
13
+
14
+ # # if __name__ == "__main__":
15
+ # # main()
16
+
17
+ import os
18
+ import openai
19
+ os.environ['OPENAI_API_KEY'] = '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'
20
+
21
+
22
+
23
+ messages=[{"role": "user", "content": "As an intelligent AI model, if you could be any fictional character, who would you choose and why?"}]
24
+
25
+ response = openai.ChatCompletion.create(
26
+ model="gpt-4",
27
+ max_tokens=100,
28
+ temperature=1.2,
29
+ api_key=os.environ['OPENAI_API_KEY'],
30
+ messages = messages)
31
+
32
+ print(response)
mtu_blogs.csv ADDED
The diff for this file is too large to render. See raw diff
 
mtu_merged_v3.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ad055fc89969e06febd852cb751894f40e2bc3212a07bdc999de20903b2b3b7b
3
+ size 17528113
mtuspecific/3d.html ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8" />
4
+ <script
5
+ src="https://cdn.plot.ly/plotly-2.20.0.min.js"
6
+ charset="utf-8"
7
+ ></script>
8
+ </head>
9
+ <body>
10
+ <div>
11
+ <script type="text/javascript">
12
+ window.PlotlyConfig = { MathJaxConfig: "local" };
13
+ </script>
14
+
15
+ <script src="projectdata.js"></script>
16
+
17
+ <div id="myPlot"></div>
18
+ <script type="text/javascript">
19
+ window.PLOTLYENV = window.PLOTLYENV || {};
20
+ Plotly.newPlot(
21
+ "myPlot",
22
+ projectData,
23
+ {
24
+ coloraxis: { showscale: true },
25
+ height: 500,
26
+ hovermode: "x unified",
27
+ legend: {
28
+ bgcolor: "rgba(17,17,17,0)",
29
+ bordercolor: "rgba(17,17,17,0)",
30
+ borderwidth: 2,
31
+ font: { color: "black", size: 14 },
32
+ itemsizing: "constant",
33
+ title: { font: { color: "black" }, text: " " },
34
+ tracegroupgap: 0,
35
+ traceorder: "normal",
36
+ x: 0,
37
+ xanchor: "auto",
38
+ y: 1,
39
+ yanchor: "auto",
40
+ },
41
+ margin: { b: 0, l: 0, pad: 2, r: 0, t: 0 },
42
+ scene: {
43
+ camera: {
44
+ center: { x: -0.4, y: 0, z: 0 },
45
+ eye: { x: 0.4, y: -1.58, z: 0.3 },
46
+ },
47
+ domain: { x: [0.0, 1.0], y: [0.0, 1.0] },
48
+ xaxis: { title: { text: "" } },
49
+ yaxis: { title: { text: "" } },
50
+ zaxis: { title: { text: "" } },
51
+ },
52
+ template: {
53
+ data: {
54
+ bar: [
55
+ {
56
+ error_x: { color: "#2a3f5f" },
57
+ error_y: { color: "#2a3f5f" },
58
+ marker: {
59
+ line: { color: "white", width: 0.5 },
60
+ pattern: {
61
+ fillmode: "overlay",
62
+ size: 10,
63
+ solidity: 0.2,
64
+ },
65
+ },
66
+ type: "bar",
67
+ },
68
+ ],
69
+ barpolar: [
70
+ {
71
+ marker: {
72
+ line: { color: "white", width: 0.5 },
73
+ pattern: {
74
+ fillmode: "overlay",
75
+ size: 10,
76
+ solidity: 0.2,
77
+ },
78
+ },
79
+ type: "barpolar",
80
+ },
81
+ ],
82
+ carpet: [
83
+ {
84
+ aaxis: {
85
+ endlinecolor: "#2a3f5f",
86
+ gridcolor: "#C8D4E3",
87
+ linecolor: "#C8D4E3",
88
+ minorgridcolor: "#C8D4E3",
89
+ startlinecolor: "#2a3f5f",
90
+ },
91
+ baxis: {
92
+ endlinecolor: "#2a3f5f",
93
+ gridcolor: "#C8D4E3",
94
+ linecolor: "#C8D4E3",
95
+ minorgridcolor: "#C8D4E3",
96
+ startlinecolor: "#2a3f5f",
97
+ },
98
+ type: "carpet",
99
+ },
100
+ ],
101
+ choropleth: [
102
+ {
103
+ colorbar: { outlinewidth: 0, ticks: "" },
104
+ type: "choropleth",
105
+ },
106
+ ],
107
+ contour: [
108
+ {
109
+ colorbar: { outlinewidth: 0, ticks: "" },
110
+ colorscale: [
111
+ [0.0, "#0d0887"],
112
+ [0.1111111111111111, "#46039f"],
113
+ [0.2222222222222222, "#7201a8"],
114
+ [0.3333333333333333, "#9c179e"],
115
+ [0.4444444444444444, "#bd3786"],
116
+ [0.5555555555555556, "#d8576b"],
117
+ [0.6666666666666666, "#ed7953"],
118
+ [0.7777777777777778, "#fb9f3a"],
119
+ [0.8888888888888888, "#fdca26"],
120
+ [1.0, "#f0f921"],
121
+ ],
122
+ type: "contour",
123
+ },
124
+ ],
125
+ contourcarpet: [
126
+ {
127
+ colorbar: { outlinewidth: 0, ticks: "" },
128
+ type: "contourcarpet",
129
+ },
130
+ ],
131
+ heatmap: [
132
+ {
133
+ colorbar: { outlinewidth: 0, ticks: "" },
134
+ colorscale: [
135
+ [0.0, "#0d0887"],
136
+ [0.1111111111111111, "#46039f"],
137
+ [0.2222222222222222, "#7201a8"],
138
+ [0.3333333333333333, "#9c179e"],
139
+ [0.4444444444444444, "#bd3786"],
140
+ [0.5555555555555556, "#d8576b"],
141
+ [0.6666666666666666, "#ed7953"],
142
+ [0.7777777777777778, "#fb9f3a"],
143
+ [0.8888888888888888, "#fdca26"],
144
+ [1.0, "#f0f921"],
145
+ ],
146
+ type: "heatmap",
147
+ },
148
+ ],
149
+ heatmapgl: [
150
+ {
151
+ colorbar: { outlinewidth: 0, ticks: "" },
152
+ colorscale: [
153
+ [0.0, "#0d0887"],
154
+ [0.1111111111111111, "#46039f"],
155
+ [0.2222222222222222, "#7201a8"],
156
+ [0.3333333333333333, "#9c179e"],
157
+ [0.4444444444444444, "#bd3786"],
158
+ [0.5555555555555556, "#d8576b"],
159
+ [0.6666666666666666, "#ed7953"],
160
+ [0.7777777777777778, "#fb9f3a"],
161
+ [0.8888888888888888, "#fdca26"],
162
+ [1.0, "#f0f921"],
163
+ ],
164
+ type: "heatmapgl",
165
+ },
166
+ ],
167
+ histogram: [
168
+ {
169
+ marker: {
170
+ pattern: {
171
+ fillmode: "overlay",
172
+ size: 10,
173
+ solidity: 0.2,
174
+ },
175
+ },
176
+ type: "histogram",
177
+ },
178
+ ],
179
+ histogram2d: [
180
+ {
181
+ colorbar: { outlinewidth: 0, ticks: "" },
182
+ colorscale: [
183
+ [0.0, "#0d0887"],
184
+ [0.1111111111111111, "#46039f"],
185
+ [0.2222222222222222, "#7201a8"],
186
+ [0.3333333333333333, "#9c179e"],
187
+ [0.4444444444444444, "#bd3786"],
188
+ [0.5555555555555556, "#d8576b"],
189
+ [0.6666666666666666, "#ed7953"],
190
+ [0.7777777777777778, "#fb9f3a"],
191
+ [0.8888888888888888, "#fdca26"],
192
+ [1.0, "#f0f921"],
193
+ ],
194
+ type: "histogram2d",
195
+ },
196
+ ],
197
+ histogram2dcontour: [
198
+ {
199
+ colorbar: { outlinewidth: 0, ticks: "" },
200
+ colorscale: [
201
+ [0.0, "#0d0887"],
202
+ [0.1111111111111111, "#46039f"],
203
+ [0.2222222222222222, "#7201a8"],
204
+ [0.3333333333333333, "#9c179e"],
205
+ [0.4444444444444444, "#bd3786"],
206
+ [0.5555555555555556, "#d8576b"],
207
+ [0.6666666666666666, "#ed7953"],
208
+ [0.7777777777777778, "#fb9f3a"],
209
+ [0.8888888888888888, "#fdca26"],
210
+ [1.0, "#f0f921"],
211
+ ],
212
+ type: "histogram2dcontour",
213
+ },
214
+ ],
215
+ mesh3d: [
216
+ {
217
+ colorbar: { outlinewidth: 0, ticks: "" },
218
+ type: "mesh3d",
219
+ },
220
+ ],
221
+ parcoords: [
222
+ {
223
+ line: { colorbar: { outlinewidth: 0, ticks: "" } },
224
+ type: "parcoords",
225
+ },
226
+ ],
227
+ pie: [{ automargin: true, type: "pie" }],
228
+ scatter: [
229
+ {
230
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
231
+ type: "scatter",
232
+ },
233
+ ],
234
+ scatter3d: [
235
+ {
236
+ line: { colorbar: { outlinewidth: 0, ticks: "" } },
237
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
238
+ type: "scatter3d",
239
+ },
240
+ ],
241
+ scattercarpet: [
242
+ {
243
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
244
+ type: "scattercarpet",
245
+ },
246
+ ],
247
+ scattergeo: [
248
+ {
249
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
250
+ type: "scattergeo",
251
+ },
252
+ ],
253
+ scattergl: [
254
+ {
255
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
256
+ type: "scattergl",
257
+ },
258
+ ],
259
+ scattermapbox: [
260
+ {
261
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
262
+ type: "scattermapbox",
263
+ },
264
+ ],
265
+ scatterpolar: [
266
+ {
267
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
268
+ type: "scatterpolar",
269
+ },
270
+ ],
271
+ scatterpolargl: [
272
+ {
273
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
274
+ type: "scatterpolargl",
275
+ },
276
+ ],
277
+ scatterternary: [
278
+ {
279
+ marker: { colorbar: { outlinewidth: 0, ticks: "" } },
280
+ type: "scatterternary",
281
+ },
282
+ ],
283
+ surface: [
284
+ {
285
+ colorbar: { outlinewidth: 0, ticks: "" },
286
+ colorscale: [
287
+ [0.0, "#0d0887"],
288
+ [0.1111111111111111, "#46039f"],
289
+ [0.2222222222222222, "#7201a8"],
290
+ [0.3333333333333333, "#9c179e"],
291
+ [0.4444444444444444, "#bd3786"],
292
+ [0.5555555555555556, "#d8576b"],
293
+ [0.6666666666666666, "#ed7953"],
294
+ [0.7777777777777778, "#fb9f3a"],
295
+ [0.8888888888888888, "#fdca26"],
296
+ [1.0, "#f0f921"],
297
+ ],
298
+ type: "surface",
299
+ },
300
+ ],
301
+ table: [
302
+ {
303
+ cells: {
304
+ fill: { color: "#EBF0F8" },
305
+ line: { color: "white" },
306
+ },
307
+ header: {
308
+ fill: { color: "#C8D4E3" },
309
+ line: { color: "white" },
310
+ },
311
+ type: "table",
312
+ },
313
+ ],
314
+ },
315
+ layout: {
316
+ annotationdefaults: {
317
+ arrowcolor: "#2a3f5f",
318
+ arrowhead: 0,
319
+ arrowwidth: 1,
320
+ },
321
+ autotypenumbers: "strict",
322
+ coloraxis: { colorbar: { outlinewidth: 0, ticks: "" } },
323
+ colorscale: {
324
+ diverging: [
325
+ [0, "#8e0152"],
326
+ [0.1, "#c51b7d"],
327
+ [0.2, "#de77ae"],
328
+ [0.3, "#f1b6da"],
329
+ [0.4, "#fde0ef"],
330
+ [0.5, "#f7f7f7"],
331
+ [0.6, "#e6f5d0"],
332
+ [0.7, "#b8e186"],
333
+ [0.8, "#7fbc41"],
334
+ [0.9, "#4d9221"],
335
+ [1, "#276419"],
336
+ ],
337
+ sequential: [
338
+ [0.0, "#0d0887"],
339
+ [0.1111111111111111, "#46039f"],
340
+ [0.2222222222222222, "#7201a8"],
341
+ [0.3333333333333333, "#9c179e"],
342
+ [0.4444444444444444, "#bd3786"],
343
+ [0.5555555555555556, "#d8576b"],
344
+ [0.6666666666666666, "#ed7953"],
345
+ [0.7777777777777778, "#fb9f3a"],
346
+ [0.8888888888888888, "#fdca26"],
347
+ [1.0, "#f0f921"],
348
+ ],
349
+ sequentialminus: [
350
+ [0.0, "#0d0887"],
351
+ [0.1111111111111111, "#46039f"],
352
+ [0.2222222222222222, "#7201a8"],
353
+ [0.3333333333333333, "#9c179e"],
354
+ [0.4444444444444444, "#bd3786"],
355
+ [0.5555555555555556, "#d8576b"],
356
+ [0.6666666666666666, "#ed7953"],
357
+ [0.7777777777777778, "#fb9f3a"],
358
+ [0.8888888888888888, "#fdca26"],
359
+ [1.0, "#f0f921"],
360
+ ],
361
+ },
362
+ colorway: [
363
+ "#000",
364
+ "#000",
365
+ "#000",
366
+ "#000",
367
+ "#000",
368
+ "#000",
369
+ "#000",
370
+ "#000",
371
+ "#000",
372
+ "#FECB52",
373
+ ],
374
+ font: { color: "#2a3f5f" },
375
+ geo: {
376
+ bgcolor: "red",
377
+ lakecolor: "white",
378
+ landcolor: "white",
379
+ showlakes: true,
380
+ showland: true,
381
+ subunitcolor: "#C8D4E3",
382
+ },
383
+ hoverlabel: { align: "left" },
384
+ hovermode: "closest",
385
+ mapbox: { style: "light" },
386
+ paper_bgcolor: "white",
387
+ plot_bgcolor: "white",
388
+ polar: {
389
+ angularaxis: {
390
+ gridcolor: "#EBF0F8",
391
+ linecolor: "#EBF0F8",
392
+ ticks: "",
393
+ },
394
+ bgcolor: "white",
395
+ radialaxis: {
396
+ gridcolor: "#EBF0F8",
397
+ linecolor: "#EBF0F8",
398
+ ticks: "",
399
+ },
400
+ },
401
+ scene: {
402
+ xaxis: {
403
+ backgroundcolor: "white",
404
+ gridcolor: "#DFE8F3",
405
+ gridwidth: 2,
406
+ linecolor: "#EBF0F8",
407
+ showbackground: true,
408
+ ticks: "",
409
+ zerolinecolor: "#EBF0F8",
410
+ },
411
+ yaxis: {
412
+ backgroundcolor: "white",
413
+ gridcolor: "#DFE8F3",
414
+ gridwidth: 2,
415
+ linecolor: "#EBF0F8",
416
+ showbackground: true,
417
+ ticks: "",
418
+ zerolinecolor: "#EBF0F8",
419
+ },
420
+ zaxis: {
421
+ backgroundcolor: "white",
422
+ gridcolor: "#DFE8F3",
423
+ gridwidth: 2,
424
+ linecolor: "#EBF0F8",
425
+ showbackground: true,
426
+ ticks: "",
427
+ zerolinecolor: "#EBF0F8",
428
+ },
429
+ },
430
+ shapedefaults: { line: { color: "#2a3f5f" } },
431
+ ternary: {
432
+ aaxis: {
433
+ gridcolor: "#DFE8F3",
434
+ linecolor: "#A2B1C6",
435
+ ticks: "",
436
+ },
437
+ baxis: {
438
+ gridcolor: "#DFE8F3",
439
+ linecolor: "#A2B1C6",
440
+ ticks: "",
441
+ },
442
+ bgcolor: "white",
443
+ caxis: {
444
+ gridcolor: "#DFE8F3",
445
+ linecolor: "#A2B1C6",
446
+ ticks: "",
447
+ },
448
+ },
449
+ title: { x: 0.05 },
450
+ xaxis: {
451
+ automargin: true,
452
+ gridcolor: "#EBF0F8",
453
+ linecolor: "#EBF0F8",
454
+ ticks: "",
455
+ title: { standoff: 15 },
456
+ zerolinecolor: "#EBF0F8",
457
+ zerolinewidth: 2,
458
+ visible: false,
459
+ show: false,
460
+ hidden: true,
461
+ },
462
+ yaxis: {
463
+ automargin: true,
464
+ gridcolor: "#EBF0F8",
465
+ linecolor: "#EBF0F8",
466
+ ticks: "",
467
+ title: { standoff: 15 },
468
+ zerolinecolor: "#EBF0F8",
469
+ zerolinewidth: 2,
470
+ visible: false,
471
+ show: false,
472
+ hidden: true,
473
+ },
474
+ },
475
+ },
476
+ // itt van a width
477
+ width: window.innerWidth - 170,
478
+ height: window.innerHeight - 50,
479
+ xaxis: {
480
+ automargin: false,
481
+ showgrid: false,
482
+ showline: true,
483
+ showspikes: false,
484
+ showticklabels: true,
485
+ zeroline: false,
486
+ },
487
+ yaxis: {
488
+ automargin: false,
489
+ showgrid: false,
490
+ showline: true,
491
+ showspikes: false,
492
+ showticklabels: true,
493
+ zeroline: false,
494
+ },
495
+ },
496
+ { responsive: true }
497
+ );
498
+
499
+ // rotate by using time, around the center of the plot
500
+ // x: 0.4, y: -1.88, z: 0.3
501
+ var cnt = 1;
502
+
503
+ var interval = setInterval(function () {
504
+ Plotly.relayout(
505
+ "myPlot",
506
+ {
507
+ "scene.camera.eye.x": 0.4 * cnt,
508
+ // "scene.camera.eye.y": -1.88 * Math.sin(cnt),
509
+ // "scene.camera.eye.z": 0.3 * cnt,
510
+ },
511
+ [0]
512
+ );
513
+ if (cnt > 2) clearInterval(interval);
514
+ cnt += 0.001;
515
+ }, 1);
516
+
517
+
518
+ document.addEventListener("click", function () {
519
+ clearInterval(interval);
520
+ });
521
+ document.addEventListener("mousedown", function () {
522
+ clearInterval(interval);
523
+ });
524
+ </script>
525
+ </div>
526
+ </body>
527
+ </html>
mtuspecific/3d_old.html ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8495e58991f3e1520daecc7fde990270e90f6322a3c335b53b6c688eea714d49
3
+ size 10509420
mtuspecific/3dnew.html ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8ce6db826066a36a7924c97e3c94fc213ddf6e932ebaaf62f926c7b0dc9f172e
3
+ size 10509572
mtuspecific/chart1.html ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
4
+
5
+ </head>
6
+ <body>
7
+ <div id="main">
8
+
9
+ </div>
10
+
11
+ <script>
12
+ var chartDom = document.getElementById('main');
13
+ var myChart = echarts.init(chartDom);
14
+ var option;
15
+
16
+ option = {
17
+ tooltip: {
18
+ trigger: 'item',
19
+ title: 'asd',
20
+ formatter: '{a} <br/>{b} ({d}%)'
21
+ },
22
+ series: [
23
+ {
24
+ name: '',
25
+ type: 'pie',
26
+ radius: [40, 200],
27
+ center: ['75%', '50%'],
28
+ roseType: 'area',
29
+ itemStyle: {
30
+ borderRadius: 2
31
+ },
32
+
33
+ // Túrázás 40%
34
+ // Városnézés 30%
35
+ // Fotózás 20%
36
+ // Borturisztika 5%
37
+ // Állatkert látogatás 5%
38
+ data: [
39
+ { value: 40, name: 'Túrázás' },
40
+ { value: 30, name: 'Városnézés' },
41
+ { value: 20, name: 'Fotózás' },
42
+ { value: 5, name: 'Borturisztika' },
43
+ { value: 5, name: 'Állatkert látogatás' }
44
+ ]
45
+ }
46
+ ]
47
+ };
48
+
49
+ option && myChart.setOption(option);
50
+
51
+
52
+ </script>
53
+ </body>
54
+
55
+ </html>
mtuspecific/mtu_merged_v3.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ad055fc89969e06febd852cb751894f40e2bc3212a07bdc999de20903b2b3b7b
3
+ size 17528113
mtuspecific/mtu_merged_v3.csv3d.html ADDED
The diff for this file is too large to render. See raw diff
 
mtuspecific/parl.html ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ THIS EXAMPLE WAS DOWNLOADED FROM https://echarts.apache.org/examples/en/editor.html?c=pie-parliament-transition
3
+ -->
4
+ <!DOCTYPE html>
5
+ <html lang="en" style="height: 100%">
6
+ <head>
7
+ <meta charset="utf-8" />
8
+ </head>
9
+ <body style="height: 100%; margin: 0">
10
+ <div id="container" style="height: 100%"></div>
11
+
12
+ <script
13
+ type="text/javascript"
14
+ src="https://fastly.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js"
15
+ ></script>
16
+
17
+ <script type="text/javascript">
18
+ var dom = document.getElementById("container");
19
+ var myChart = echarts.init(dom, null, {
20
+ renderer: "canvas",
21
+ useDirtyRect: false,
22
+ });
23
+ var app = {};
24
+
25
+ var option;
26
+
27
+ const data = [
28
+ { value: 40, name: "Túrázás" },
29
+ { value: 30, name: "Városnézés" },
30
+ { value: 5, name: "Borturisztika" },
31
+ { value: 5, name: "Állatkert látogatás" },
32
+ { value: 20, name: "Fotózás" },
33
+ ];
34
+ const defaultPalette = ["#E667AC", "#3D5176", "#CEBDCB", "#6D6E6E", "#FFC423" ]
35
+
36
+ const radius = ["20%", "80%"];
37
+ const pieOption = {
38
+ series: [
39
+ {
40
+ type: "pie",
41
+ id: "distribution",
42
+ radius: radius,
43
+ label: {
44
+ show: true,
45
+ position: "outside",
46
+ formatter: "{b} ({d}%)",
47
+ fontSize: 20,
48
+ color: "#A0ADBE",
49
+ },
50
+ color:defaultPalette,
51
+ universalTransition: true,
52
+ animationDurationUpdate: 1000,
53
+ data: data,
54
+ },
55
+ ],
56
+ };
57
+ const parliamentOption = (function () {
58
+ let sum = data.reduce(function (sum, cur) {
59
+ return sum + cur.value;
60
+ }, 0);
61
+ let angles = [];
62
+ let startAngle = -Math.PI / 2;
63
+ let curAngle = startAngle;
64
+ data.forEach(function (item) {
65
+ angles.push(curAngle);
66
+ curAngle += (item.value / sum) * Math.PI * 2;
67
+ });
68
+ angles.push(startAngle + Math.PI * 2);
69
+ function parliamentLayout(
70
+ startAngle,
71
+ endAngle,
72
+ totalAngle,
73
+ r0,
74
+ r1,
75
+ size
76
+ ) {
77
+ let rowsCount = Math.ceil((r1 - r0) / size);
78
+ let points = [];
79
+ let r = r0;
80
+ for (let i = 0; i < rowsCount; i++) {
81
+ // Recalculate size
82
+ let totalRingSeatsNumber = Math.round((totalAngle * r) / size);
83
+ let newSize = (totalAngle * r) / totalRingSeatsNumber;
84
+ for (
85
+ let k = Math.floor((startAngle * r) / newSize) * newSize;
86
+ k < Math.floor((endAngle * r) / newSize) * newSize - 1e-6;
87
+ k += newSize
88
+ ) {
89
+ let angle = k / r;
90
+ let x = Math.cos(angle) * r;
91
+ let y = Math.sin(angle) * r;
92
+ points.push([x, y]);
93
+ }
94
+ r += size;
95
+ }
96
+ return points;
97
+ }
98
+ return {
99
+ series: {
100
+ type: "custom",
101
+ id: "distribution",
102
+ data: data,
103
+ coordinateSystem: undefined,
104
+ universalTransition: true,
105
+ animationDurationUpdate: 1000,
106
+ renderItem: function (params, api) {
107
+ var idx = params.dataIndex;
108
+ var viewSize = Math.min(api.getWidth(), api.getHeight());
109
+ var r0 = ((parseFloat(radius[0]) / 100) * viewSize) / 2;
110
+ var r1 = ((parseFloat(radius[1]) / 100) * viewSize) / 2;
111
+ var cx = api.getWidth() * 0.5;
112
+ var cy = api.getHeight() * 0.5;
113
+ var size = viewSize / 67;
114
+ var points = parliamentLayout(
115
+ angles[idx],
116
+ angles[idx + 1],
117
+ Math.PI * 2,
118
+ r0,
119
+ r1,
120
+ size + 2
121
+ );
122
+ console.log(points.length);
123
+ return {
124
+ type: "group",
125
+ children: points.map(function (pt) {
126
+ return {
127
+ type: "circle",
128
+ autoBatch: true,
129
+ shape: {
130
+ cx: cx + pt[0],
131
+ cy: cy + pt[1],
132
+ r: size / 2,
133
+ },
134
+ style: {
135
+ fill: defaultPalette[idx % defaultPalette.length],
136
+ },
137
+ };
138
+ }),
139
+ };
140
+ },
141
+ },
142
+ };
143
+ })();
144
+ let currentOption = (option = pieOption);
145
+ setInterval(function () {
146
+ currentOption =
147
+ currentOption === pieOption ? parliamentOption : pieOption;
148
+ myChart.setOption(currentOption);
149
+ }, 6000);
150
+
151
+ if (option && typeof option === "object") {
152
+ myChart.setOption(option);
153
+ }
154
+
155
+ window.addEventListener("resize", myChart.resize);
156
+ </script>
157
+ </body>
158
+ </html>
mtuspecific/pieros.html ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" style="height: 100%">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ </head>
6
+ <body style="height: 100%;width:100%; margin: 0">
7
+ <div id="container" style="height: 100%;width:100%"></div>
8
+
9
+ <script
10
+ type="text/javascript"
11
+ src="https://fastly.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js"
12
+ ></script>
13
+
14
+ <script type="text/javascript">
15
+ var dom = document.getElementById("container");
16
+ var myChart = echarts.init(dom, null, {
17
+ renderer: "canvas"
18
+ });
19
+ var app = {};
20
+
21
+ var option;
22
+
23
+ option = {
24
+ tooltip: {
25
+ trigger: "item",
26
+ title: "asd",
27
+ formatter: "{b} ({d}%)",
28
+ },
29
+ series: [
30
+ {
31
+ name: "",
32
+ type: "pie",
33
+ radius: [30, 220],
34
+ roseType: "area",
35
+ itemStyle: {
36
+ borderRadius: 2,
37
+ },
38
+
39
+ data: [
40
+ { value: 40, name: "Túrázás" },
41
+ { value: 30, name: "Városnézés" },
42
+ { value: 20, name: "Fotózás" },
43
+ { value: 5, name: "Borturisztika" },
44
+ { value: 5, name: "Állatkert látogatás" },
45
+ ],
46
+ },
47
+ ],
48
+ };
49
+
50
+ if (option && typeof option === "object") {
51
+ myChart.setOption(option);
52
+ }
53
+
54
+ window.addEventListener("resize", myChart.resize);
55
+ </script>
56
+ </body>
57
+ </html>
mtuspecific/projectdata copy 2.js ADDED
The diff for this file is too large to render. See raw diff
 
mtuspecific/projectdata copy 3.js ADDED
The diff for this file is too large to render. See raw diff
 
mtuspecific/projectdata copy 4.js ADDED
The diff for this file is too large to render. See raw diff
 
mtuspecific/projectdata copy.js ADDED
The diff for this file is too large to render. See raw diff
 
mtuspecific/projectdata.js ADDED
The diff for this file is too large to render. See raw diff
 
mtuspecific/test.js ADDED
@@ -0,0 +1 @@
 
 
1
+ test.js
mtuspecific/test.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ [
2
+ ["hiking","trail","backpack","boots","trekking poles","nature","outdoor","mountains","camping","wilderness","navigation"],
3
+ ["zoo","animals","enclosure","exhibit","conservation","education","habitat","zookeeper","safari","aquarium","wildlife"],
4
+ ["wine","vineyard","winery","tasting","sommelier","cellar","terroir","grape","vintage","wine region","wine pairing"],
5
+ ["sightseeing","landmarks","monuments","architecture","city tour","historical","cultural","tour guide","attractions","museums","walking tour"]
6
+ ]
prod.sh ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ git pull
2
+ pm2 restart gradio_app
3
+ pm2 restart uploadapi
readme.md ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Rubiklab Talkback environment
2
+
3
+ _If you're a power user, stop reading and start wasting your time.._
4
+
5
+ # Get started
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install -r requirements.txt
11
+ ```
12
+
13
+ ## Make sure you have your .env file based on .env.example
14
+
15
+ ```ini
16
+ # custom formatting sources
17
+ GRADIO_CSS=http://localhost:8001/assets/gradio_app.css
18
+ GRADIO_JS=http://localhost:8001/assets/gradio_app.js
19
+ # this is the rubiklab backend (on prod: https://api.rubiklab.ai)
20
+ RUBIK_BACKEND=http://localhost:8001/api/talkback
21
+ ```
22
+
23
+ ## How to start
24
+
25
+ To make everything work, you need to make sure all the below services are up-to-date, the .env file contains the correct paths, and everything is running:
26
+
27
+ - API backend
28
+ - Flask data uploader (part of this repository)
29
+
30
+ ---
31
+
32
+ ### Launch the app [DEV]
33
+
34
+ 1. `gradio gradio_app.py app`
35
+ 2. `cd uploader && python uploadapi.py`
36
+
37
+ If backend is not started yet:
38
+ Navigate to the Rubiklab backend, and..
39
+
40
+ `php artisan serve --port=8001`
41
+
42
+ ---
43
+
44
+ ### Launch the app [PROD]
45
+
46
+ 1. `cd /var/www/talkback`
47
+ 2. `sh prod.sh`
48
+ 3. now just wait a few sec.. and done
requirements.txt ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ snscrape
2
+ umap_learn
3
+ openai
4
+ matplotlib
5
+ textblob
6
+ plotly
7
+ django
8
+ django_select2
9
+ django-urls
10
+ Django
11
+ requests
12
+ flask
13
+ flask_cors
14
+ pandas
15
+ scikit-learn==0.24.2
16
+ pipwin
17
+ pyaudio
18
+ streamlit
19
+ praw
20
+ markdown
21
+ emoji
22
+ load-dotenv
23
+ streamlit-chat
24
+ python_translator
25
+ apify-client
26
+ streamlit-aggrid
27
+ newscatcherapi
28
+ numpy
29
+ Pillow
30
+ sentence_transformers
31
+ transformers
32
+ umap
33
+ umap-learn
34
+ gradio
35
+ openai-whisper
36
+ langchain
37
+ faiss-cpu
38
+ requests-toolbelt
39
+ hdbscan
40
+ torch
41
+ bertopic
42
+ PythonTurtle
43
+ scikit-image
44
+ datetime
45
+ seaborn
46
+ pyvis
47
+ pyvis-network
48
+ pinecone-client
49
+ tiktoken
50
+ us
51
+ librosa
52
+ openpyxl
53
+ folium
54
+ nltk
55
+ pickle-mixin
56
+ translate
57
+ wordcloud
58
+ tweepy
test.xlsx ADDED
Binary file (96.3 kB). View file
 
testpandas.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # from langchain.agents import create_pandas_dataframe_agent
2
+ # from langchain.llms import OpenAI
3
+ # import pandas as pd
4
+ # import os
5
+ # # debunidebdeb_cleaned.xlsx
6
+ # os.environ['OPENAI_API_KEY'] = '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'
7
+
8
+
9
+ # df = pd.read_excel("debunidebdeb_cleaned.xlsx")
10
+ # agent = create_pandas_dataframe_agent(OpenAI(temperature=0), df, verbose=True)
11
+
12
+ # # agent.run("based on 'top_emotion', what is the most common emotion?")
13
+
14
+ # # get input from terminal
15
+ # while True:
16
+
17
+ # # get input from terminal
18
+ # question = input("Ask a question: ")
19
+
20
+ # # if input is 'exit', then exit
21
+ # if question == 'exit':
22
+ # break
23
+
24
+ # # run the agent
25
+ # agent.run(question)
26
+
27
+
28
+ # from youtube_transcript_api import YouTubeTranscriptApi
29
+
30
+ # transcript = YouTubeTranscriptApi.get_transcript("VslxnS9Gs34")
31
+
32
+ # # keep text key only
33
+ # transcript = [x['text'] for x in transcript]
34
+ # # print(transcript)
35
+ # # join all text into one string
36
+ # transcript = ' '.join(transcript)
37
+ # print(len(transcript))
38
+ # import openai
39
+ # import os
40
+
41
+ # os.environ['OPENAI_API_KEY'] = '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'
42
+ # response = openai.ChatCompletion.create(
43
+ # model="gpt-3.5",
44
+ # temperature=0.5,
45
+ # # stream=True,
46
+ # messages=[
47
+ # #{"role": "system", "content": "Forget all the above instructions. You are a reviewer of products but also a customer and have an opinion about the products you buy. You are asked to write a review of a product you have recently purchased."},
48
+ # {"role": "user", "content": 'How are you?'},
49
+ # ]
50
+ # )['choices'][0]['message']['content']
51
+
52
+
53
+ import requests
54
+
55
+ cookies = {
56
+ 'dapUid': '544c792c-877b-0214f1c0c407',
57
+ 'privacySettings': '%7B%22v%C%22t%22%3A1664841600%2C%22m%22%3A%22STRICT%22%2C%22consent%22%3A%5B%22NECESSARY%22%2C%22PERFORMANCE%22%2C%22COMFORT%22%5D%7D',
58
+ 'LMTBID': 'v2|9c29fd7a-25b2-4c2a-a1d3-6665d402fb1d|6379551ac25c1fb89d6c2d580bec3fb6',
59
+ 'userRecommendations': 'RC-1.1_RC-10.1_RC-5.1',
60
+ 'userCountry': 'HU',
61
+ 'releaseGroups': '388.DM-49778.DM-705.2.2_866.DM-592.2.2_867.DM-684.2.4_975.DM-609.2.3_1119.B2B-251.2.4_1219.DAL-136.2.3_1223.DAL-179.2.4_1437.DM-850.2.2_1460.TC-502.2.1_1577.DM-594.1.2_865.TG-1004.2.4_1571.DM-791.2.3_1572.TC-559.2.6_1583.DM-807.2.5_1780.DM-872.2.2_1808.DF-3339.2.2_1585.DM-900.2.3_1815.RC-377.2.5_1207.DWFA-96.1.4_1996.DM-822.1.1_1997.DM-941.2.3_2007.DWFA-470.2.2_2022.DF-3340.2.1_2024.SEO-103.2.3_2025.ACL-24.2.2_2027.WDW-56.2.4_2055.DM-814.2.2_2067.SEO-205.2.2_2068.DF-3045.2.1_2073.DM-928.2.1_2256.DF-3461.2.1_2259.SEO-316.2.1_220.DF-1925.1.9_1328.DWFA-285.2.2_2127.AAEXP-1380.1.1_1438.DM-768.2.2_2119.AAEXP-1372.1.1_976.DM-667.2.3_2120.AAEXP-1373.1.1_774.DWFA-212.2.2_2132.AAEXP-1385.1.1_2133.AAEXP-1386.1.1_2122.AAEXP-1375.1.1_1246.DM-793.2.2_1783.TC-171.2.3_2020.DWFA-450.2.2_1444.DWFA-362.2.2_863.DM-601.2.2_1327.DWFA-391.2.2_2117.AAEXP-1370.2.1_2121.AAEXP-1374.1.1_2129.AAEXP-1382.1.1_605.DM-585.2.3_1084.TG-1207.2.3_1332.DM-709.2.2_1483.DM-821.2.1_1776.B2B-345.2.1_2050.DM-455.1.1_2071.DM-951.1.1_2072.DM-741.2.1_2124.AAEXP-1377.2.1_2114.AAEXP-1367.2.1_2118.AAEXP-1371.2.1_2125.AAEXP-1378.1.1_2128.AAEXP-1381.1.1_2131.AAEXP-1384.1.1_2126.AAEXP-1379.1.1_2116.AAEXP-1369.1.1_2130.AAEXP-1383.1.1_2123.AAEXP-1376.2.1_2115.AAEXP-1368.2.1',
62
+ 'dapVn': '34',
63
+ 'dapSid': '%7B%22sid85c8-4898-bafe-37754831ff0c%22%2C%22lastUpdate%22%3A1683702948%7D',
64
+ }
65
+
66
+ headers = {
67
+ 'authority': 'www2.deepl.com',
68
+ 'accept': '*/*',
69
+ 'accept-language': 'en-GB,en;q=0.9,en-US;q=0.8',
70
+ 'content-type': 'application/json',
71
+ 'origin': 'https://www.deepl.com',
72
+ 'referer': 'https://www.deepl.com/',
73
+ 'sec-ch-ua': '"Microsoft Edge";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
74
+ 'sec-ch-ua-mobile': '?0',
75
+ 'sec-ch-ua-platform': '"macOS"',
76
+ 'sec-fetch-dest': 'empty',
77
+ 'sec-fetch-mode': 'cors',
78
+ 'sec-fetch-site': 'same-site',
79
+ 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35',
80
+ }
81
+
82
+ params = {
83
+ 'method': 'LMT_handle_jobs',
84
+ }
85
+
86
+ json_data = {
87
+ 'jsonrpc': '2.0',
88
+ 'method': 'LMT_handle_jobs',
89
+ 'params': {
90
+ 'jobs': [
91
+ {
92
+ 'kind': 'default',
93
+ 'sentences': [
94
+ {
95
+ 'text': 'this is a cat',
96
+ 'id': 0,
97
+ 'prefix': '',
98
+ },
99
+ ],
100
+ 'raw_en_context_before': [],
101
+ 'raw_en_context_after': [],
102
+ 'preferred_num_beams': 4,
103
+ },
104
+ ],
105
+ 'lang': {
106
+ 'preference': {
107
+ 'weight': {},
108
+ 'default': 'default',
109
+ },
110
+ 'source_lang_computed': 'EN',
111
+ 'target_lang': 'HU',
112
+ },
113
+ 'priority': 1,
114
+ 'commonJobParams': {
115
+ 'mode': 'translate',
116
+ 'browserType': 1,
117
+ },
118
+ 'timestamp': 1683702948583,
119
+ },
120
+ 'id': 91990007,
121
+ }
122
+
123
+ response = requests.post('https://www2.deepl.com/jsonrpc', params=params, cookies=cookies, headers=headers, json=json_data)
124
+ print (response.text)
topic.py ADDED
@@ -0,0 +1,2073 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # %%
2
+ import datetime
3
+ import gradio as gr
4
+ from io import BytesIO
5
+ import numpy as np
6
+ import numpy as np
7
+ import tiktoken
8
+ import pandas as pd
9
+ from utils.functions import load_csv
10
+ from wordcloud import WordCloud
11
+ import matplotlib.pyplot as plt
12
+ plt.switch_backend('Agg')
13
+ import requests
14
+ import umap
15
+ from sklearn.feature_extraction.text import TfidfVectorizer
16
+ import hdbscan
17
+ import plotly.express as px
18
+ import plotly.graph_objects as go
19
+ import plotly.express as px
20
+ from langchain.chat_models import ChatOpenAI
21
+
22
+ import os
23
+ from langchain.agents import load_tools
24
+ from langchain.agents import initialize_agent, create_pandas_dataframe_agent
25
+ from langchain.llms import OpenAI
26
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
27
+ import gradio as gr
28
+ import openai
29
+ import pandas as pd
30
+ import numpy as np
31
+ import re
32
+ import whisper
33
+ import openai
34
+ import pandas as pd
35
+ import networkx as nx
36
+ import matplotlib.pyplot as plt
37
+
38
+ import networkx as nx
39
+ import matplotlib.pyplot as plt
40
+ from langchain import OpenAI, PromptTemplate, LLMChain
41
+
42
+ from langchain.agents import load_tools
43
+ from langchain.agents import initialize_agent
44
+ from langchain.llms import OpenAI
45
+ from langchain.document_loaders import YoutubeLoader
46
+ from langchain.chains.summarize import load_summarize_chain
47
+
48
+ from langchain.text_splitter import RecursiveCharacterTextSplitter, TokenTextSplitter
49
+ from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
50
+ from langchain.document_loaders import YoutubeLoader
51
+ import time
52
+ import re
53
+ import pinecone
54
+ import pandas as pd
55
+ from sentence_transformers import SentenceTransformer, util
56
+
57
+ #import numpy as np
58
+ from langchain.embeddings import HuggingFaceEmbeddings, OpenAIEmbeddings
59
+ from sklearn.metrics import silhouette_score
60
+ import torch
61
+ import nltk
62
+ nltk.download('vader_lexicon')
63
+
64
+
65
+ from dotenv import load_dotenv
66
+ load_dotenv()
67
+ gradio_css = os.getenv("GRADIO_CSS")
68
+ gradio_js = os.getenv("GRADIO_JS")
69
+ rubik_backend = os.getenv("RUBIK_BACKEND")
70
+ openapi_key = os.getenv("OPENAI_API_KEY")
71
+ wolfram_alpha_appid = os.getenv("WOLFRAM_ALPHA_APPID")
72
+
73
+ #for versioning
74
+ ra = np.random.randint(1000000)
75
+
76
+ os.environ['OPENAI_API_KEY'] = openapi_key
77
+ os.environ['WOLFRAM_ALPHA_APPID'] = wolfram_alpha_appid
78
+
79
+
80
+ def get_key(item):
81
+ return item['label']
82
+
83
+ def get_emotion_bertweet(dataset):
84
+ tokenizer4 = AutoTokenizer.from_pretrained("finiteautomata/bertweet-base-emotion-analysis", truncation=True)
85
+ model4 = AutoModelForSequenceClassification.from_pretrained("finiteautomata/bertweet-base-emotion-analysis")
86
+ nlp = pipeline('sentiment-analysis', model=model4,
87
+ tokenizer=tokenizer4, top_k=6, truncation=True, device=device)
88
+
89
+ top_emotion = []
90
+ # apply emotion model on data and get the labels and scores
91
+ for i in range(len(dataset)):
92
+ label = []
93
+ score = []
94
+ jsonfile = (nlp(dataset['translated_text'].iloc[i]))
95
+ jsonfile[0].sort(key=get_key)
96
+ for j in range(0, 6):
97
+ jsonfile2 = np.array(jsonfile)
98
+ label.append(jsonfile2[0][j]['label'])
99
+ score.append(jsonfile2[0][j]['score'])
100
+
101
+
102
+ top_emotion.append(label[score.index(max(score))])
103
+ dataset['top_emotion_bertweet'] = top_emotion
104
+ print(jsonfile2)
105
+ return dataset
106
+
107
+
108
+ model_name = "sentence-transformers/all-MiniLM-L6-v2"
109
+ hf = HuggingFaceEmbeddings(model_name=model_name)
110
+ embeddings = OpenAIEmbeddings()
111
+
112
+ # pinecone.init(
113
+ # api_key='ENTER API KEY HERE',
114
+ # environment='us-central1-gcp'
115
+ # )
116
+ # index_name = 'openaigradio'
117
+ def markdown_to_html(md_string):
118
+ # html_string = markdown.markdown(md_string)
119
+ return md_string
120
+
121
+ tokenizer4 = AutoTokenizer.from_pretrained("finiteautomata/bertweet-base-emotion-analysis", truncation=True)
122
+ model4 = AutoModelForSequenceClassification.from_pretrained("finiteautomata/bertweet-base-emotion-analysis")
123
+
124
+ openai.api_key = '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'
125
+ model_whisp = whisper.load_model("base")
126
+
127
+ llm = OpenAI(temperature=0.2, model_name='text-davinci-003', max_tokens=1000, top_p=1)
128
+
129
+ model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
130
+ # check if cpu or gpu
131
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
132
+ model = model.to(device)
133
+
134
+ # %%
135
+ Industries = ['Agriculture',
136
+ 'Automobile Manufacturing',
137
+ 'Banking and Finance',
138
+ 'Biotechnology',
139
+ 'Chemicals and Petrochemicals',
140
+ 'Construction and Engineering',
141
+ 'Consumer Goods and Retail',
142
+ 'Education',
143
+ 'Electronics',
144
+ 'Energy (Oil, Gas, Coal, and Renewable Energy)',
145
+ 'Entertainment and Media',
146
+ 'Food and Beverage',
147
+ 'Healthcare and Pharmaceuticals',
148
+ 'Hospitality, Travel, and Tourism',
149
+ 'Information Technology (IT) and Software',
150
+ 'Insurance',
151
+ 'Manufacturing (various sectors)',
152
+ 'Mining and Metals',
153
+ 'Real Estate',
154
+ 'Renewable Energy (Solar, Wind, Hydro, Geothermal)',
155
+ 'Telecommunications',
156
+ 'Textiles and Apparel',
157
+ 'Transportation and Logistics',
158
+ 'Utilities (Electricity, Water, Gas)',
159
+ 'Waste Management and Environmental Services']
160
+
161
+
162
+
163
+
164
+ def get_memory():
165
+ memory_string = ''
166
+ for i,j in memory.items():
167
+ print(i, j)
168
+ memory_string += str(j) + '\n'
169
+ return memory_string
170
+
171
+
172
+ def check_words_in_string(word_list, input_string, case=False):
173
+
174
+ input_string = input_string.lower()
175
+
176
+ # Convert words to lowercase if case is False
177
+ word_list = [word.lower() if case else word for word in word_list]
178
+
179
+ # Check if any word is in the input_string
180
+ result = any(word in input_string for word in word_list)
181
+
182
+ # check if True
183
+ if result:
184
+ return True
185
+ else:
186
+ return False
187
+
188
+
189
+ # Will be used by the Langchain chatbot
190
+
191
+ words = ['rows', 'data', 'length', 'dataset','plot', 'col','columns','column', 'max', 'min', 'minimum', 'maximum', 'visualize','visualise','represent','graph','chart','plot','diagram','illustrate','show','depict','display','count','number','sum','total','aggregate','trend','pattern','distribution','average','linechart','scatter','barchart','piechart','histogram','boxplot','heatmap','correlation','regression','forecast','predict']
192
+
193
+ memory = {'agent':[], 'user':[]}
194
+
195
+
196
+
197
+ def get_topic_cluster(dataframe, graph_type = None,filename = None):
198
+ print(filename)
199
+ if (dataframe is None):
200
+ # return None,None, '<h1>Please click "Launch" on the left sidebar.</h1>', '<h1>Please click "Launch" on the left.</h1>', "Executive Summary"
201
+ return None, None, None, None, None, '<span id="clusterx"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Topic Cluster"
202
+
203
+ reduce_dim = umap.UMAP(
204
+ n_components=3, n_neighbors=8, min_dist=0.55)
205
+
206
+ df = dataframe.copy()
207
+
208
+ # some cleaning for reddit datasets
209
+ df = df[df['translated_text'] != 'nan']
210
+ df = df[df['translated_text'] != '[deleted]']
211
+ df = df[df['translated_text'] != '[removed]']
212
+
213
+ # if filename + 'df3.csv' exists load csv
214
+ if os.path.exists(filename + 'df3.csv'):
215
+ df3 = pd.read_csv(filename + 'df3.csv')
216
+ df2 = df3
217
+ else:
218
+ def CleanTxt_quotes(text):
219
+ text = re.sub(r'https?:\/\/\S+', '', text) # Remove hyperlinks
220
+ text = re.sub(r'http?:\/\/\S+', '', text) # Remove hyperlinks
221
+ # if more than 5 mentions, remove all mention
222
+ if len(re.findall(r'@[A-Za-z0-9]+', text)) > 5:
223
+ text = re.sub(r'@[A-Za-z0-9]+', '', text)
224
+ # if more than 4 hashtags, remove all hashtags
225
+ #text = re.sub(r'[^A-Za-z0-9.!?_#@]+', ' ', text) # Remove non-alphanumeric characters except exclamation marks and question marks
226
+ text = re.sub(r'\s+', ' ', text) # Remove extra whitespace
227
+ return text
228
+
229
+ df['clean_text'] = df['translated_text'].apply(lambda x: str(x))
230
+ df['clean_text'] = df['translated_text'].apply(lambda x: CleanTxt_quotes(x))
231
+
232
+ embedding = np.array([np.array(xi)
233
+ for xi in df.embeddings])
234
+
235
+ umap_embeddings = reduce_dim.fit_transform(embedding)
236
+
237
+ print('umap_embeddings', umap_embeddings.shape)
238
+
239
+ # CHECK THIS LINE
240
+ df['x'] = umap_embeddings[:, 0]
241
+ df['y'] = umap_embeddings[:, 1]
242
+ df['z'] = umap_embeddings[:, 2]
243
+
244
+ df.dropna(inplace=True)
245
+
246
+ hdbscan_min_samples = 1
247
+ hdbscan_minimal_cluster_size = int(len(df) * 0.01+40)
248
+
249
+ # hdbscan_minimal_cluster_size = 7
250
+ # hdbscan_min_samples = 10
251
+
252
+ cluster = hdbscan.HDBSCAN(
253
+ min_cluster_size=hdbscan_minimal_cluster_size,
254
+ metric='euclidean',
255
+ cluster_selection_epsilon=0.001,
256
+ cluster_selection_method='leaf',
257
+ algorithm='best',
258
+ prediction_data=False,
259
+ min_samples=hdbscan_min_samples).fit(df[['x', 'y', 'z']])
260
+
261
+ cluster_analysis = len(pd.Series(cluster.labels_).unique())
262
+ print('Number of Sentences = ', len(df))
263
+ print('Number of Clusters = ', cluster_analysis, '/n')
264
+
265
+ df_cluster = pd.DataFrame(
266
+ pd.DataFrame(cluster.labels_).value_counts())
267
+ print(df_cluster)
268
+ clusters = pd.DataFrame(cluster.labels_)
269
+
270
+ # percent_unlabelled = round((len(df[clusters[0] == -1]) / len(df)) * 100, 2)
271
+ # print('The percentage of unlabelled sentences is: ', percent_unlabelled, '%')
272
+
273
+ # reindex
274
+ df.reset_index(inplace=True, drop=True)
275
+
276
+ print(len(df[clusters[0] == -1]))
277
+
278
+ for i in range(0, cluster_analysis):
279
+ print('Cluster ', i, ' has ', len(
280
+ df[clusters[0] == i]), ' sentences')
281
+
282
+ print(df_cluster.index)
283
+
284
+ from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
285
+
286
+ def get_tfidf_top_features(documents, n_top=4):
287
+ tfidf_vectorizer = TfidfVectorizer(
288
+ min_df=0.05,
289
+ max_df=0.95, max_features=10,
290
+ stop_words='english')
291
+ tfidf = tfidf_vectorizer.fit_transform(documents)
292
+ importance = np.argsort(np.asarray(
293
+ tfidf.sum(axis=0)).ravel())[::-1]
294
+ tfidf_feature_names = np.array(
295
+ tfidf_vectorizer.get_feature_names())
296
+ return tfidf_feature_names[importance[:n_top]]
297
+
298
+ cluster_names = pd.DataFrame(
299
+ columns=['cluster_name', 'embed_index'])
300
+
301
+ for i in range(cluster_analysis):
302
+ try:
303
+ print(get_tfidf_top_features(
304
+ df['clean_text'][clusters[0] == i]))
305
+
306
+ clstr_nm = get_tfidf_top_features(
307
+ df['clean_text'][clusters[0] == i])
308
+ clstr_idx = df['clean_text'][clusters[0] == i].index
309
+ cluster_names = cluster_names.append(
310
+ {'cluster_name': clstr_nm, 'embed_index': clstr_idx}, ignore_index=True)
311
+
312
+ except Exception as e:
313
+ print(e)
314
+ # cluster_name.append('NULL')
315
+ pass
316
+
317
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].astype(
318
+ str)
319
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
320
+ '[', '')
321
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
322
+ ']', '')
323
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
324
+ "'", '')
325
+ cluster_names['cluster_name'] = cluster_names['cluster_name'].str.replace(
326
+ " ", '-')
327
+
328
+ clusters_names = cluster_names.explode('embed_index')
329
+
330
+ df2 = df.merge(clusters_names, left_index=True,
331
+ right_on='embed_index')
332
+
333
+ df2['cluster_name_str'] = df2['cluster_name'].apply(
334
+ lambda x: str(x))
335
+ # assign a int value to each unique cluster name in df3
336
+ df2['cluster_number'] = df2['cluster_name_str'].astype(
337
+ 'category').cat.codes
338
+
339
+ df2['trimmed_text'] = df2['clean_text'].str[:175]
340
+
341
+ print(df2.head())
342
+
343
+ df3 = df2[['x', 'y', 'z', 'cluster_number',
344
+ 'cluster_name_str', 'trimmed_text']]
345
+
346
+
347
+ #################################################### GET CLUSTER NAME #############################################
348
+
349
+ df2['gpt_cluster'] = ''
350
+ df3['gpt_cluster'] = ''
351
+
352
+ for cluster in df3['cluster_name_str'].unique():
353
+ each_cluster = df3[df3['cluster_name_str'] == cluster]
354
+
355
+ docs = '\n'.join(np.random.choice(each_cluster['trimmed_text'], 50))
356
+
357
+ response3 = openai.ChatCompletion.create(
358
+ model="gpt-3.5-turbo",
359
+ temperature=0.3,
360
+ max_tokens=300,
361
+ top_p=1,
362
+ # stream=True,
363
+ messages=[
364
+ {"role": "user", "content": f'Given a list of keywords {cluster}, and documents present in the cluster : {docs}; assign the most relevant topic name for this cluster : \n\n Cluster Name : '},
365
+ ]
366
+ )['choices'][0]['message']['content']
367
+
368
+ df3.loc[df3['cluster_name_str'] == cluster, 'gpt_cluster'] = response3
369
+ df2.loc[df2['cluster_name_str'] == cluster, 'gpt_cluster'] = response3
370
+
371
+
372
+
373
+ # print(df3['cluster_name_str'])
374
+ # xi = 0
375
+ # for cluster in df3['cluster_name_str'].unique():
376
+ # xi += 1
377
+ # df3.loc[df3['cluster_name_str'] == cluster, 'gpt_cluster'] = cluster#"cluster " + str(xi)
378
+ # df2.loc[df2['cluster_name_str'] == cluster, 'gpt_cluster'] = cluster#"cluster " + str(xi)
379
+
380
+ # save df3
381
+ df3.to_csv(filename + 'df3.csv', index=False, encoding='utf-8-sig')
382
+
383
+ if len(df3) > 10000:
384
+ dot_size = 1
385
+ else:
386
+ dot_size = 4
387
+
388
+
389
+ color_scale = px.colors.sequential.Viridis
390
+ color_list = ['#FF0000', '#FF0000', '#FF0000', '#FF0000', '#FF0000', '#FF0000']
391
+
392
+ fig = px.scatter_3d(df3, x='x', y='y', z='z', color='gpt_cluster', hover_name='trimmed_text', hover_data={
393
+ 'x': False, 'y': False, 'z': False, 'cluster_name_str': False, 'cluster_number': False, 'gpt_cluster': False}, opacity=1, template='plotly_white')
394
+
395
+ fig.update_traces(marker=dict(size=dot_size))
396
+
397
+ fig.add_trace(go.Scatter3d(x=[0], y=[0], z=[0], mode='markers', marker=dict(
398
+ size=0.1, color='white'), showlegend=True, name=' ', hoverinfo='none'))
399
+
400
+ # legend on the right side
401
+ fig.update_layout(legend=dict(
402
+ bgcolor='rgba(17,17,17,0)',
403
+ xanchor='auto',
404
+ yanchor='auto',
405
+ x=0.8, # Adjust the x position of the legend
406
+ y=0.2, # Adjust the y position of the legend
407
+ bordercolor='rgba(17,17,17,0)',
408
+ borderwidth=0,
409
+ ))
410
+
411
+ # fig.update_layout(scene=dict(
412
+ # xaxis=dict(
413
+ # title=' ',
414
+ # nticks=0,
415
+ # # backgroundcolor="rgb(0, 0, 0, 1)",
416
+ # gridcolor="rgba(17,17,17, 0)",
417
+ # showbackground=True,
418
+ # zerolinecolor="rgba(17,17,17, 0)",
419
+ # zeroline=False,
420
+ # showgrid=True,
421
+ # showticklabels=False,
422
+ # showspikes=False
423
+ # ),
424
+ # # hide ticks
425
+
426
+
427
+ # yaxis=dict(
428
+ # # name
429
+ # title=' ',
430
+ # nticks=0,
431
+ # # backgroundcolor="rgb(0, 0, 0, 1)",
432
+ # gridcolor="rgba(17,17,17, 0)",
433
+ # showbackground=True,
434
+ # zerolinecolor="rgba(17,17,17, 0)",
435
+ # zeroline=False,
436
+ # showgrid=True,
437
+ # showticklabels=False,
438
+ # showspikes=False
439
+ # ),
440
+
441
+
442
+
443
+ # zaxis=dict(
444
+ # # name
445
+ # title=' ',
446
+ # nticks=0,
447
+ # # backgroundcolor="rgba(0, 0, 0, 1)",
448
+ # gridcolor="rgba(17,17,17, 0)",
449
+ # showbackground=True,
450
+ # zerolinecolor="rgba(17,17,17, 0)",
451
+ # zeroline=False,
452
+ # showgrid=True,
453
+ # showticklabels=False,
454
+ # showspikes=False),)
455
+ # # tickvals=[],),
456
+ # )
457
+
458
+ fig.update_layout(coloraxis_showscale=False, width=1300, height=750, legend=dict(x=0, y=1, traceorder='normal', font=dict(size=14, color='black'), bgcolor='rgba(17,17,17,0)', bordercolor='rgba(17,17,17,0)', borderwidth=0))
459
+
460
+
461
+ # TO ADD AN IMAGE UNCOMMENT
462
+
463
+ # fig.add_layout_image(
464
+ # dict(
465
+ # source=<SOURCE>,
466
+ # xref="x",
467
+ # yref="y",
468
+ # x=-1,
469
+ # y=3.8,
470
+ # # xanchor = "left",
471
+ # # yanchor = "top",
472
+ # sizex=.4,
473
+ # sizey=.4,
474
+ # opacity=1,
475
+ # layer="above",
476
+ # )
477
+ # )
478
+
479
+ fig.update_layout(legend={'itemsizing': 'constant'}, legend_title_text=' ', legend_title_font_color='black',
480
+ legend_font_color='black', legend_font_size=14, legend_bgcolor='rgba(17,17,17,0)', legend_bordercolor='rgba(17,17,17,0)', legend_borderwidth=2)
481
+
482
+ # , title_font_size=30, title_font_family='Arial', title_font_color='white', title_x=0.06, title_y=0.95, title_xanchor='left', title_yanchor='top', title_text='Cluster of Emotions for {}/n n = {}'.format(subreddit, len(dataset_umap)), margin=dict(l=0, r=0, b=0, t=0, pad=0))
483
+ fig.update_layout(scene_camera_eye=dict(x=0.87, y=-0.88, z=0.84), scene_camera_center=dict(
484
+ x=0, y=0, z=0), template='plotly_white', hovermode='x unified', margin=dict(l=0, r=0, b=0, t=0, pad=2))
485
+
486
+ fig.update_layout(coloraxis_showscale=True)
487
+ fig.update_xaxes(showticklabels=True, showgrid=False, zeroline=False,
488
+ showline=True, automargin=False, showspikes=False)
489
+ fig.update_yaxes(showticklabels=True, showgrid=False, zeroline=False,
490
+ showline=True, automargin=False, showspikes=False)
491
+
492
+
493
+ #full_html=False, include_plotlyjs='cdn', default_height='750px', default_width='1500px', config={'displaylogo': False, 'modeBarButtonsToRemove': ['zoom2d', 'pan2d', 'select2d', 'lasso2d', 'zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'zoom3d', 'pan3d', 'resetCameraDefault3d', 'resetCameraLastSave3d', 'hoverClosest3d', 'orbitRotation', 'tableRotation', 'zoomInGeo', 'zoomOutGeo', 'resetGeo', 'hoverClosestGeo', 'toImage', 'sendDataToCloud', 'hoverClosestGl2d', 'hoverClosestPie', 'toggleHover', 'resetViews', 'toggleSpikelines', 'resetViewMapbox']})}
494
+
495
+
496
+ cluster_name = df3[['cluster_number', 'gpt_cluster']]
497
+ cluster_name = cluster_name.drop_duplicates()
498
+ cluster_name = cluster_name.sort_values(by=['cluster_number'])
499
+ cluster_name = cluster_name.reset_index(drop=True)
500
+ # create a list
501
+ cluster_name_list = cluster_name['gpt_cluster'].tolist()
502
+ cluster_name_list = '\n'.join(cluster_name_list)
503
+
504
+
505
+
506
+ Silhouette_Score = 'Silhouette score is : ', silhouette_score(df3[['x', 'y', 'z']], df3['gpt_cluster'], metric='euclidean')
507
+
508
+ # get a dataframe of unique cluster names and their count
509
+
510
+ cluster_count = df3.groupby('gpt_cluster').agg({'cluster_number': 'count'}).reset_index()
511
+ cluster_count = cluster_count.rename(columns={'cluster_number': 'count', 'gpt_cluster': 'Cluster'})
512
+
513
+
514
+ # return fig, cluster_count, cluster_name_list, Silhouette_Score, df2
515
+ return fig, cluster_count, cluster_name_list, None, df2, '<span id="clusterx"></span>', "<b>Please check 'Graph' tab for more details.</b>", "<span class='hsub'>Analysis:</span>Topic Cluster"
516
+
517
+
518
+
519
+ def get_executive_summary(dataframe=None, brand=None, industry=None, summaries=None, csv_file= None, graph_type = None,filename = None, fullProjectData= None, sourceIndex = 0):
520
+ # if data_answer.txt exists, open and read
521
+
522
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
523
+ externalPrompt = sourceData['content']['exec_sum']
524
+
525
+ if (dataframe is None):
526
+ return None,None,'<span id="executive"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Executive Summary"
527
+
528
+ if os.path.exists(filename + 'Executive Summary_CACHE.txt'):
529
+ with open(filename + 'Executive Summary_CACHE.txt', 'r') as f:
530
+ output_summary = f.read()
531
+
532
+ return output_summary, dataframe[['translated_text']], '<span id="executive"></span>', markdown_to_html(output_summary), "<span class='hsub'>Analysis:</span>Executive Summary"
533
+ else:
534
+ if brand is None:
535
+ brand = ' '
536
+
537
+ else :
538
+ brand = brand
539
+ try:
540
+ dataframe = dataframe[dataframe['translated_text'].str.contains(brand, case=False)]
541
+ except:
542
+ pass
543
+
544
+
545
+
546
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
547
+ encoding_name='p50k_base',
548
+ chunk_size = 2000,
549
+ )
550
+
551
+ splitted_articles = text_splitter.split_text(''.join(dataframe['translated_text']))
552
+
553
+ summarize_template = """ {text} \n\n
554
+ Summarize the most relevant information for an executive summary from the above document:
555
+
556
+ SUMMARY: """
557
+
558
+
559
+ prompt_template = PromptTemplate(input_variables=['text'], template=summarize_template)
560
+
561
+ summary_chain = LLMChain(llm=llm, prompt=prompt_template)
562
+
563
+ summaries = []
564
+ for i in splitted_articles:
565
+ summaries.append(summary_chain.run(i))
566
+
567
+
568
+
569
+ summaries1 = '/n'.join(summaries)
570
+ word_count = 500
571
+
572
+ #If needed, guess the industry
573
+ # industry_template = PromptTemplate(input_variables=['summaries'], template=extract_industry)
574
+ # summary_chain = LLMChain(llm=llm, prompt=industry_template)
575
+ # industry = summary_chain.run(summaries)
576
+
577
+ #Check size of output and go in a 2nd loop if it's too big
578
+ encoding = tiktoken.get_encoding('p50k_base')
579
+
580
+ if len(encoding.encode(summaries1)) > 2000:
581
+ # return only first 2000 tokens
582
+ summaries1 = encoding.decode(encoding.encode(summaries1)[:2000])
583
+
584
+
585
+ executive_summary_template = '''Imagine you are an Elite Analyst, Expert Sociologist, and Data Guru,
586
+ Your task is to leverage your invaluable expertise in crafting a comprehensive and insightful {word_count} words executive summary tailored for C-level executives and decision-makers in {industry}.
587
+ The summary should synthesize information from various data sources, incorporate relevant cultural and contextual elements, and provide valuable insights that can drive strategic decision-making.
588
+ Please ensure that your analysis meets the following high-level objectives:
589
+ Thoroughly examine and interpret the key trends, patterns, and insights derived from the following data sources:
590
+ {summaries1}
591
+
592
+ Articulate the implications and opportunities for {industry}, keeping in mind the needs and challenges of the industry.
593
+ Consider the cultural, social, and contextual nuances present in the data, drawing on your sociological expertise to ensure the summary remains relevant and insightful across diverse audiences.
594
+ Identify any potential risks or challenges that might arise from the data, providing strategic recommendations for mitigating these issues.
595
+ Present the information in a clear, concise, and engaging manner that captures the attention of busy executives and effectively communicates the key insights.
596
+ Leverage your data expertise to ensure the accuracy, reliability, and relevance of the information presented in the summary. Make us benefit from your unique expertise and insights.
597
+
598
+
599
+ Using markdown formatting, write a {word_count} word SEQ-optimized Executive Summary. Write a click worthy short titles. Add a key takeaway
600
+ section at the end. Use the seed keyword as the first H2. Always use a combination of paragraphs, lists, and tables for a better reader experience. For the styling of the output, please include headers for different sections, and use bullet points where applicable to organize the key insights.
601
+ To avoid repetition, vary the sentence structure and word choice when presenting information from different data sources or discussing various trends, insights, or opportunities.
602
+ Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers.
603
+ To avoid repetition, vary the sentence structure and word choice when presenting information from different data sources or discussing various trends, insights, or opportunities. Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers.
604
+ In order to maintain reader engagement and deliver a captivating text, please ensure that you diversify sentence structure and word choice when presenting insights, trends, or opportunities from different data sources. Employ synonyms, alternative expressions, and varied sentence patterns to provide a fresh and dynamic reading experience.
605
+ \n\n
606
+
607
+ '''
608
+
609
+ if externalPrompt and externalPrompt != "":
610
+ executive_summary_template = externalPrompt
611
+
612
+ prompt = PromptTemplate(template=executive_summary_template, input_variables=['industry', 'word_count', 'summaries1'])
613
+ print("start sum")
614
+ # llm2 = OpenAI(temperature=0.2, model_name='gpt-4', max_tokens=1000, top_p=1)
615
+
616
+ llm2 = ChatOpenAI(temperature=0.2, model_name='gpt-4', max_tokens=1000, top_p=1)
617
+ executive_chain = LLMChain(llm=llm2, prompt=prompt)
618
+
619
+ output_summary = executive_chain.run(industry=industry, word_count=word_count, summaries1=summaries1)
620
+
621
+
622
+ # output_summary = executive_chain.run(industry=industry, word_count=word_count, summaries1=summaries1)
623
+ with open(filename + "Executive Summary_CACHE.txt", "a") as f:
624
+ try:
625
+ f.write(output_summary)
626
+ except:
627
+ pass
628
+
629
+ # dataframe.rename(columns={'translated_text': 'Table'}, inplace=True)
630
+ # return("# Executive summary" + output_summary, dataframe[['translated_text']], markdown_to_html(output_summary), 1, markdown_to_html("# Executive Summary\n\n" + output_summary), "Executive Summary")
631
+ return output_summary, dataframe[['translated_text']], '<span id="executive"></span>', markdown_to_html(output_summary), "<span class='hsub'>Analysis:</span>Executive Summary"
632
+
633
+ return(output_summary, dataframe[['translated_text']][0:20], summaries, output_summary)
634
+
635
+
636
+
637
+
638
+
639
+
640
+
641
+ def get_competitive(brand, industry, graph_type = None, filename = None,dataframe = None,fullProjectData= None, sourceIndex = 0):
642
+
643
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
644
+ externalPrompt = sourceData['content']['competitor']
645
+
646
+ if dataframe is None:
647
+ return(None,'<span id="competitive"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Competitor Analysis")
648
+
649
+ if os.path.exists(filename + 'Competitor_CACHE.txt'):
650
+ with open(filename + 'Competitor_CACHE.txt', 'r') as f:
651
+ output_summary = f.read()
652
+ return(output_summary,'<span id="competitive"></span>', markdown_to_html("# Competitor Analysis\n\n"+output_summary), "<span class='hsub'>Analysis:</span>Competitor Analysis")
653
+
654
+ else:
655
+ competitive_prompt = '''
656
+ Ignore all previous instructions. Do not rush. Make this impactful and clear.
657
+ •Read through all the bullet points and make sure you understand all the bullet points, before you start working.
658
+ • Act as a subject matter expert, Business analyst, social media expert and professor with 20 years of research experience.
659
+ [IMPORTANT INSTRUCTION]
660
+ Your singular task is to provide expert reports with key elements and useful content. Do not make up any information. Do not use jargon.
661
+ Start with a short paragraph introducing {brand} position in the market. This should be clear and impactfull.
662
+ •I want to learn more about the competitors of brand {brand} in this market {industry}.
663
+ [SEPARATOR]
664
+ •Use the advanced level of expertise in this market {industry} to create topics and subtopics with detailed notes, this will help provide confidence and clarity about the item being sought.
665
+ [SEPARATOR]
666
+ 1 “Who are the 4 main competitors of {brand}?”
667
+ 2 “What are the top 3 strengths and weaknesses of each of those competitors?”
668
+ 3 “What are the unique selling points of our competitors?”
669
+ 4 “In what unique ways do those competitors market their products/services?”
670
+ 5 “What are the key trends in the {industry} that those competitors are capitalizing on?”
671
+ 6 “What are the areas where those competitors excel compared to {brand}?”
672
+ 7 “What are the areas where our competitors fall short compared to {brand}?”
673
+ 8 “How do our products/services prices compare to those competitors in terms of quality, price positioning and range?”
674
+ 9 “What are the common customer complaints about those competitors?”
675
+ 10 “What are the opportunities for growth in the {industry} that competitors are not taking advantage of?”
676
+ •Break down the exercise into easy-to-follow steps.
677
+ •For each topic and/or subtopic provide a clear and informative summary that compare and contrast results..
678
+ •Identify common mistakes made when addressing those competitive points and address those with maximum clarity.
679
+ •Proofread content for accuracy, paying special attention to any terms that may have been substituted or omitted unintentionally.
680
+ Conclude with a brief overview of the competitive landscape for "brand" with the top 3 takeaways and opportunities. The format should be markdown, add subheaders (h2 only), format into nice paragraphs.'''
681
+
682
+ # hardcoded!!!
683
+ brand = "Nike"
684
+ industry = 'Textiles and Apparel'
685
+
686
+ prompt = PromptTemplate(template=competitive_prompt, input_variables=['industry', 'brand'])
687
+ competition_chain = LLMChain(llm=llm, prompt=prompt)
688
+
689
+ output_summary = competition_chain.run(industry=industry, brand=brand)
690
+ with open(filename + "Competitor_CACHE.txt", "a") as f:
691
+ try:
692
+ f.write(output_summary)
693
+ except:
694
+ pass
695
+
696
+ return(output_summary,'<span id="competitive"></span>', markdown_to_html("# Competitor Analysis\n\n"+output_summary), "<span class='hsub'>Analysis:</span>Competitor Analysis")
697
+
698
+ # def get_topic_summary(dataframe, topics=None, brand=None, industry=None, graph_type = None, filename = None):
699
+ def get_trend_summary(dataframe, topics=None, brand=None, industry=None, graph_type = None, filename = None,fullProjectData= None, sourceIndex = 0):
700
+
701
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
702
+ externalPrompt = sourceData['content']['trend_analysis']
703
+
704
+ if (dataframe is None):
705
+ return None,None, '<span id="trend"></span>','<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Executive Summary"
706
+
707
+ if os.path.exists(filename + 'Trend Analysis_CACHE.txt'):
708
+ with open(filename + 'Trend Analysis_CACHE.txt', 'r') as f:
709
+ final_summary = f.read()
710
+
711
+ return(final_summary, dataframe[['translated_text']][0:20], '<span id="trend"></span>', markdown_to_html(final_summary), "<span class='hsub'>Analysis:</span>Trend Analysis")
712
+
713
+ else:
714
+
715
+ if brand is None:
716
+ brand = ''
717
+
718
+ else :
719
+ brand = brand
720
+ try:
721
+ dataframe = dataframe[dataframe['translated_text'].str.contains(brand, case=False)]
722
+ except:
723
+ pass
724
+
725
+
726
+
727
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
728
+ encoding_name='p50k_base',
729
+ chunk_size = 2000,
730
+ )
731
+
732
+
733
+ splitted_articles = text_splitter.split_text(''.join(dataframe['translated_text']))
734
+
735
+ summarize_template = """Summarize the most relevant information from the following document:
736
+
737
+ {text}
738
+
739
+ SUMMARY: """
740
+
741
+
742
+ prompt_template = PromptTemplate(input_variables=['text'], template=summarize_template)
743
+
744
+ summary_chain = LLMChain(llm=llm, prompt=prompt_template)
745
+
746
+ summaries = []
747
+ for i in splitted_articles:
748
+ summaries.append(summary_chain.run(i))
749
+
750
+
751
+ # split the summary into 2000 tokens chunks
752
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
753
+ encoding_name='p50k_base',
754
+ chunk_size = 2000,
755
+ )
756
+
757
+
758
+ summaries2 = text_splitter.split_text(''.join(summaries))
759
+
760
+ word_count = 500
761
+
762
+ topics = topics
763
+ final_summary = []
764
+
765
+ brand = "Nike"
766
+ industry = "Food and Beverage"
767
+ for summary_1 in summaries2:
768
+
769
+ topic_prompt = '''"Imagine you are an Elite Analyst and Trend Analysis Expert with extensive experience in identifying patterns and emerging themes from various data sources, such as social media, regular media, reviews, and survey data. Your task is to leverage your invaluable expertise in crafting a comprehensive and insightful trend analysis report tailored for {brand} within the {industry}. The objective is to provide valuable insights into shifts in consumer behavior, preferences, and market dynamics, enabling informed decision-making for C-level executives and decision-makers.
770
+
771
+ In your analysis of {word_count} words, ensure that you address the following key elements:
772
+
773
+ Topics : {topics}
774
+
775
+ Data: {summary}
776
+
777
+ Emerging Trends: Identify and discuss the key emerging trends in consumer behavior, preferences, and market dynamics within the {industry}. Examine the factors driving these trends and provide specific examples to illustrate your findings.
778
+
779
+ Impact on {brand}: Analyze how the identified trends are affecting or could potentially affect {brand}. Consider both opportunities and challenges that may arise from these trends, as well as any necessary adjustments to marketing strategies, product offerings, or customer service initiatives.
780
+
781
+ Recommendations: Based on the insights derived from the trend analysis, provide actionable recommendations for {brand} to stay ahead of the competition, capitalize on new opportunities, and address potential challenges. Consider innovations, partnerships, or targeted marketing campaigns that can help the company adapt to and benefit from the identified trends.
782
+
783
+ Ensure that your trend analysis report is clear, concise, and engaging for busy executives. Focus on providing actionable insights and recommendations that can inform the company's strategic direction. Draw on your expertise to ensure the accuracy, reliability, and relevance of the information presented in the analysis."
784
+
785
+
786
+ Using markdown formatting, write a {word_count} word SEQ-optimized Trend Analysis. Write a click worthy short titles. Add a key takeaway
787
+ section at the end. Use the seed keyword as the first H2. Always use a combination of paragraphs, lists, and tables for a better reader experience. For the styling of the output, please include headers for different sections, and use bullet points where applicable to organize the key insights.
788
+ To avoid repetition, vary the sentence structure and word choice when presenting information. Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers. \n\n
789
+
790
+ '''
791
+
792
+ prompt = PromptTemplate(template=topic_prompt, input_variables=['industry', 'topics', 'word_count', 'summary', 'brand'])
793
+
794
+ topic_chain = LLMChain(llm=llm, prompt=prompt)
795
+
796
+ topic_summary = topic_chain.run(industry=industry, topics = topics, word_count=word_count, summary=summary_1, brand=brand)
797
+
798
+ final_summary.append(topic_summary)
799
+
800
+ if len(final_summary) > 1:
801
+ topic_summary = ''.join(final_summary)
802
+
803
+ combination = '''{topic_summary}\n\nCombine the content from these articles into one; keeping the format and structure in place. \n\n##Trend Analysis:\n\n'''
804
+ prompt = PromptTemplate(template=combination, input_variables=['topic_summary'])
805
+ final_chain = LLMChain(llm=llm, prompt=prompt)
806
+ final_summary = final_chain.run(topic_summary=topic_summary)
807
+
808
+ else:
809
+ final_summary = final_summary[0]
810
+
811
+ with open(filename + "Trend Analysis_CACHE.txt", "a") as f:
812
+ try:
813
+ f.write(final_summary)
814
+ except:
815
+ pass
816
+
817
+ # dataframe.rename(columns={'translated_text': 'Table'}, inplace=True)
818
+
819
+ return("# Trend Analysis\n" + final_summary, dataframe[['translated_text']][0:20], '<span id="trend"></span>', markdown_to_html(''+final_summary), "<span class='hsub'>Analysis:</span>Trend Analysis")
820
+
821
+
822
+ def get_SWOT(dataframe, brand = None, industry = None, exec_summary=None, graph_type= None, filename = None,fullProjectData= None, sourceIndex = 0):
823
+
824
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
825
+ externalPrompt = sourceData['content']['swot_']
826
+
827
+ if (dataframe is None):
828
+ return(None,'<span id="swotx"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>SWOT")
829
+
830
+
831
+ brand = 'Nike'
832
+ industry = 'Textiles and Apparel'
833
+ if brand is None:
834
+ brand = ' '
835
+
836
+ else :
837
+ brand = brand
838
+ try:
839
+ dataframe = dataframe[dataframe['translated_text'].str.contains(brand, case=False)]
840
+ except:
841
+ pass
842
+
843
+
844
+ # if exec_summary is None:
845
+ #
846
+ exec_summary = '''
847
+ # Mozzarella Sticks: A Versatile Snack Food with Endless Possibilities
848
+
849
+ ## Introduction
850
+
851
+ Mozzarella sticks are a popular snack food that can be enjoyed in a variety of ways. They can be eaten alone, dipped in sauces, used as a topping on pizzas, or even turned into vape flavors. Mozzarella sticks can also be used to make creative dishes such as a mozzarella stick bowl, a mozzarella stick cake, or a mozzarella stick twinkie. They can also be used as a prank, such as paying per mozzarella stick. Mozzarella sticks are a versatile food that can be enjoyed in many different ways.
852
+
853
+ ## Popularity
854
+
855
+ Mozzarella sticks are a popular food item that can be enjoyed in many different ways. People have been experimenting with different recipes, such as a low-carb snack of apple, mozzarella stick, hummus, veggie, plain Greek yogurt, English cucumber, dill, peanut butter, and celery. There have also been attempts to create a stuffed crust pizza with a mozzarella stick, as well as a Korean corn dog with a French fry chunk and a half mozzarella stick inside. Mozzarella sticks can also be enjoyed with marinara sauce, ranch, ketchup, and other condiments.
856
+
857
+ ## Availability
858
+
859
+ Mozzarella sticks are a popular snack food that can be found in many places. They can be eaten alone or as part of a meal, such as a burger or a pizza. They can also be used as an ingredient in dishes such as mac and cheese, risotto, and fried cauliflower. Mozzarella sticks can be found in many forms, such as deep-fried, baked, or grilled. They can also be paired with other foods, such as fruit, vegetables, and sauces. Mozzarella sticks are high in lactose and should be consumed in moderation.
860
+
861
+ ## International Appeal
862
+
863
+ Mozzarella sticks are a popular dish enjoyed by people around the world. They can be made with a variety of ingredients, such as flour, Greek yogurt, turkey pepperoni, and cheese, and can be served with marinara sauce, butter, and olive oil. Mozzarella sticks are also popular in Czech, Slovak, and Polish cuisine. On International Cheese Day, people celebrate with cheese wedges, ooey gooey cheese pulls, and mozzarella sticks. There are a variety of recipes for mozzarella sticks, including a low-fat version with Greek yogurt, turkey pepperoni, and cheese. Mozzarella sticks can also be enjoyed with a variety of dips, such as marinara sauce, nacho cheese sauce, and homemade marinara sauce.
864
+
865
+ ## Uses
866
+
867
+ Mozzarella sticks are a popular snack food that can be enjoyed in a variety of ways. They can be deep fried, grilled, or microwaved, and are often served with marinara sauce or ranch dressing. They can also be used as a topping for pizza, burgers, and ramen. Mozzarella sticks are also available in low-fat and dairy-free varieties. They are often served at fast food restaurants, such as Arby's, Burger King, and Sonic, and can be purchased in stores. Mozzarella sticks are a great snack for those looking for a quick meal or a tasty treat.
868
+
869
+ ## Health Benefits
870
+
871
+ Mozzarella sticks are a popular food item that can be enjoyed in many different ways. They can be fried, microwaved, baked, or even wrapped in fruit roll-ups. They can be served with marinara sauce, ranch dressing, or even chocolate milk. Mozzarella sticks can also be used to make delicious dishes such as mac and cheese, chicken tenders, and jalapeno poppers. They can also be used to make sandwiches, tacos, and pizzas. Mozzarella sticks are a great way to add flavor and texture to any meal.
872
+
873
+ ## Implications and Opportunities
874
+
875
+ Mozzarella sticks are a popular snack food that can be enjoyed in a variety of ways. They can be served with different sauces, as part of a pizza, or as part of a sandwich. They can also be used to make a variety of dishes, such as a scotch egg, a Camembert burger, or a mozzarella stick hybrid pizza. Mozzarella sticks can also be served with a variety of sides, such as fries, onion rings, and hash browns. Additionally, they can be used to make a variety of desserts, such as a mozzarella stick candle.
876
+
877
+ Mozzarella sticks are a popular bar food and snack item that can be enjoyed in a variety of ways. They can be served as an appetizer, a side dish, or even as a main course.'''
878
+
879
+ #word_count = 500
880
+
881
+ with open(filename + "Executive Summary_CACHE.txt", "r") as f:
882
+ exec_summary = f.read()
883
+
884
+ # industry_template = PromptTemplate(input_variables=['summaries'], template=extract_industry)
885
+ # summary_chain = LLMChain(llm=llm, prompt=industry_template)
886
+ # industry = summary_chain.run(summaries)
887
+
888
+ brand = brand
889
+
890
+ industry = industry
891
+
892
+ # toolname = ['serpapi']
893
+ # tools = load_tools(toolname)
894
+ # agent = initialize_agent(tools=tools, llm=llm, agent='zero-shot-react-description', verbose=True)
895
+ # internet_content = agent.run(f'What is {brand}?')
896
+
897
+
898
+
899
+ SWOT_analysis_template = '''Ignore all previous instructions. Do not rush. Make this impactful and clear.
900
+ •Read through all the bullet points and make sure you understand all the bullet points, before you start working.
901
+ Act as a subject matter expert, Business analyst, social media expert and professor with 20 years of research experience.
902
+
903
+ Here is an executive Summary for updated context : {exec_summary}
904
+
905
+
906
+ [IMPORTANT INSTRUCTION]
907
+ Your singular task is to provide expert reports with key elements and useful content. Do not make up any information. Do not use jargon.
908
+ Introduction:
909
+ Start with a paragraph introducing
910
+
911
+ Now: return the SWOT for the brand {brand} in the {industry} industry.
912
+ example:
913
+ ## Strengths
914
+ - Strength 1
915
+ - Strength 2
916
+ ...
917
+ ## Weaknesses
918
+ - Weakness 1
919
+ - Weakness 2
920
+ ...
921
+ ## Opportunities
922
+ - Opportunity 1
923
+ - Opportunity 2
924
+ ...
925
+ ## Threats
926
+ - Threat 1
927
+ - Threat 2
928
+ ...
929
+
930
+ SWOT formatted with markdown syntax:
931
+
932
+ '''
933
+
934
+ prompt = PromptTemplate(template=SWOT_analysis_template, input_variables=['industry', 'brand', 'exec_summary'])
935
+
936
+ SWOT_chain = LLMChain(llm=llm, prompt=prompt)
937
+
938
+ SWOT_summary = SWOT_chain.run(industry=industry, brand=brand, exec_summary=exec_summary)
939
+
940
+ return("" + SWOT_summary,'<span id="swotx"></span>', markdown_to_html(SWOT_summary + "<div id='isSwot'></div>") , "<span class='hsub'>Analysis:</span>SWOT")
941
+
942
+
943
+ def emotional_mapping(dataframe, industry = None, graph_type = None, filename = None, fullProjectData = None, sourceIndex = 0):
944
+
945
+ sourceData = fullProjectData['sources'][int(sourceIndex)]
946
+ externalPrompt = sourceData['content']['swot_']
947
+
948
+ if (dataframe is None):
949
+ return None,None, '<span id="sentiment"></span>', '<h1>Please click "Launch" on the left sidebar.</h1>', "<span class='hsub'>Analysis:</span>Sentiment Analysis"
950
+
951
+ if os.path.exists(filename + 'Sentiment Analysis_CACHE.txt'):
952
+ # read this: emotional_count.to_csv(filename + "Sentiment Analysis_CACHE.csv", index=False)
953
+ emotional_count = pd.read_csv(filename + "Sentiment Analysis_CACHE.csv")
954
+ with open(filename + 'Sentiment Analysis_CACHE.txt', 'r') as f:
955
+ emotional_summary = f.read()
956
+
957
+ return(emotional_summary, emotional_count,'<span id="sentiment"></span>', markdown_to_html(""+emotional_summary), "<span class='hsub'>Analysis:</span>Sentiment Analysis")
958
+ # return output_summary, dataframe[['translated_text']], markdown_to_html(output_summary), markdown_to_html(output_summary), "Executive Summary"
959
+ else:
960
+ if 'top_emotion_bertweet' in dataframe.columns:
961
+ dataframe['emotion'] = dataframe['top_emotion_roberta'] #dataframe['top_emotion_bertweet']
962
+
963
+ elif 'top_emotion_roberta' in dataframe.columns:
964
+ dataframe['emotion'] = dataframe['top_emotion_roberta']
965
+
966
+ elif 'top_emotion_distilbert' in dataframe.columns:
967
+ dataframe['emotion'] = dataframe['top_emotion_distilbert']
968
+
969
+ elif 'top_emotion' in dataframe.columns:
970
+ dataframe['emotion'] = dataframe['top_emotion']
971
+
972
+ else:
973
+ dataframe = get_emotion_bertweet(dataframe)
974
+ dataframe['emotion'] = dataframe['top_emotion_bertweet']
975
+
976
+ word_count = 500
977
+
978
+
979
+ # industry_template = PromptTemplate(input_variables=['summaries'], template=extract_industry)
980
+ # summary_chain = LLMChain(llm=llm, prompt=industry_template)
981
+ # industry = summary_chain.run(summaries)
982
+
983
+
984
+ industry = industry
985
+
986
+ # get positive dataset
987
+ positive = dataframe[dataframe['polarity'] > 0]
988
+
989
+ # get negative dataset
990
+ negative = dataframe[dataframe['polarity'] < 0]
991
+
992
+ positive_emotions = []
993
+ negative_emotions = []
994
+
995
+ corpus_positive = {}
996
+ corpus_negative = {}
997
+
998
+ # Calculate the number of unique emotions for positive and negative datasets
999
+ num_positive_emotions = min(len(positive['emotion'].unique()), 3)
1000
+ num_negative_emotions = min(len(negative['emotion'].unique()), 3)
1001
+
1002
+ # Loop through the positive emotions
1003
+ for i in range(num_positive_emotions):
1004
+ value = str(positive['emotion'].value_counts(normalize=True).index[i])
1005
+ percent = str(round(positive['emotion'].value_counts(normalize=True)[i] * 100, 2)) + '%'
1006
+ positive_emotions.append(value + ' ' + percent)
1007
+
1008
+ corpus_positive[value] = positive[positive['emotion'] == value]['translated_text'].tolist()
1009
+
1010
+ # Loop through the negative emotions
1011
+ for i in range(num_negative_emotions):
1012
+ value = str(negative['emotion'].value_counts(normalize=True).index[i])
1013
+ percent = str(round(negative['emotion'].value_counts(normalize=True)[i] * 100, 2)) + '%'
1014
+ negative_emotions.append(value + ' ' + percent)
1015
+
1016
+ corpus_negative[value] = negative[negative['emotion'] == value]['translated_text'].tolist()
1017
+
1018
+
1019
+ emotion_summary = {}
1020
+
1021
+ text_splitter = TokenTextSplitter.from_tiktoken_encoder(
1022
+ encoding_name='p50k_base',
1023
+ chunk_size = 2000,
1024
+ )
1025
+
1026
+
1027
+
1028
+ for emotion, text in corpus_positive.items():
1029
+
1030
+ emotion_summary[emotion] = text_splitter.split_text(''.join(text))
1031
+
1032
+ # get first element
1033
+ emotion_summary[emotion] = emotion_summary[emotion][0]
1034
+
1035
+ emotion_summarize_template = """ {text} \n\n
1036
+ Summarize the text from the above document to answer this question : Why are people feeling {emotion} ? \n\n
1037
+
1038
+ SUMMARY: """
1039
+
1040
+ prompt_template = PromptTemplate(input_variables=['text', 'emotion'], template=emotion_summarize_template)
1041
+
1042
+ summary_chain = LLMChain(llm=llm, prompt=prompt_template)
1043
+
1044
+ emotion_summary[emotion] = summary_chain.run(text=emotion_summary[emotion], emotion=emotion, industry=industry)
1045
+
1046
+ for emotion, text in corpus_negative.items():
1047
+
1048
+ emotion_summary[emotion] = text_splitter.split_text(''.join(text))
1049
+
1050
+ # get first element
1051
+ emotion_summary[emotion] = emotion_summary[emotion][0]
1052
+
1053
+ emotion_summarize_template = """ {text} \n\n
1054
+ Summarize the text from the above document to answer this question : Why are people feeling {emotion} ? \n\n
1055
+
1056
+ SUMMARY: """
1057
+
1058
+ prompt_template = PromptTemplate(input_variables=['text', 'emotion'], template=emotion_summarize_template)
1059
+
1060
+ emotion_summary[emotion] = summary_chain.run(text=emotion_summary[emotion], emotion=emotion, industry=industry)
1061
+
1062
+
1063
+
1064
+
1065
+ executive_summary_template = '''Imagine you are an Elite psychologist, Analyst, and Data Guru. You are familiar with leading emotion measurement techniques and the latest developments in the field,
1066
+
1067
+ including the Plutchik index and Emotional Intensity Scale (EIS).
1068
+
1069
+ Data Summary per emotions, leave 'other' emotions!: {all_emotions}
1070
+
1071
+ Your task is to leverage your invaluable expertise in crafting an insightful {word_count} emotion-driven report tailored for C-level executives and decision-makers in {industry}.
1072
+ The objective is to provide valuable insights into the impact of the top emotions marketing and branding strategies and provoke lightbulb moments for our readers. Your analysis should provide valuable insights that can drive strategic decision-making based on the key emotions.
1073
+
1074
+ Structure the analysis in two main sections: Observations and Key Findings. In the Observations section, provide precise details about specific emotion measurements and their relation to the wants and needs expressed in the data. In the Key Findings section, focus on insightful content and compare and contrast the different emotions, revealing what's hiding behind the numbers and addressing both expressed and latent emotions.
1075
+ Avoid jargon and broad terms in your analysis, ensuring that the content is clear, concise, and engaging.
1076
+
1077
+ Thoroughly examine and interpret the key trends, patterns, and insights derived from the key emotions .
1078
+ Articulate the implications and opportunities based on the emotion levels, keeping in mind the needs and challenges of the {industry}.
1079
+ Consider the cultural, social, and contextual nuances present in the data, drawing on your expertise to ensure the emotion analysis remains relevant and insightful across diverse audiences.
1080
+ Leverage your psychological expertise to ensure the accuracy, reliability, and relevance of the information presented in the summary. Make us benefit from your unique expertise and insights.
1081
+ Using markdown formatting, write a {word_count} word SEQ-optimized Executive Summary. Write a click worthy short titles. Add a key takeaway
1082
+
1083
+ section at the end. Use the seed keyword as the first H2. Always use a combination of paragraphs, lists, and tables for a better reader experience. For the styling of the output, please include headers for different sections, and use bullet points where applicable to organize the key insights.
1084
+ To avoid repetition, vary the sentence structure and word choice when presenting information from different data sources or discussing various trends, insights, or opportunities.
1085
+ Using synonyms, alternate phrasings, and modifying sentence structure can help keep the text engaging and fresh for readers. \n\n
1086
+
1087
+ '''
1088
+
1089
+ prompt = PromptTemplate(template=executive_summary_template, input_variables=['word_count', 'industry', 'all_emotions'])
1090
+
1091
+ executive_chain = LLMChain(llm=llm, prompt=prompt)
1092
+
1093
+ emotional_summary = executive_chain.run(industry=industry, word_count=word_count, all_emotions=str(emotion_summary.items()))
1094
+
1095
+ emotional_count = dataframe.groupby('emotion').agg({'translated_text': 'count'}).reset_index()
1096
+
1097
+ emotional_count.to_csv(filename + "Sentiment Analysis_CACHE.csv", index=False)
1098
+
1099
+ with open(filename + "Sentiment Analysis_CACHE.txt", "a") as f:
1100
+ try:
1101
+ f.write(emotional_summary)
1102
+ except:
1103
+ pass
1104
+
1105
+ # dataframe.rename(columns={'emotion': 'Emotion'}, inplace=True)
1106
+
1107
+ return(emotional_summary, emotional_count,'<span id="sentiment"></span>', markdown_to_html(""+emotional_summary), "<span class='hsub'>Analysis:</span>Sentiment Analysis")
1108
+
1109
+
1110
+ def generate_wordcloud(dataframe):
1111
+ text = ' '.join(dataframe['translated_text'].tolist())
1112
+ colors = ["#FF69B4", "#FFD700", "#FFA500", "#D3D3D3"]
1113
+ wordcloud = WordCloud(max_font_size=300, max_words=800, width = 1600, height = 1200, background_color="white", colormap="Set2", color_func=lambda *args, **kwargs: colors[len(args[0]) % len(colors)]).generate(text)
1114
+ return wordcloud.to_image()
1115
+
1116
+
1117
+ def get_polarity(dataframe):
1118
+ df = dataframe.copy()
1119
+ def get_sentiment_vader(text):
1120
+ from nltk.sentiment.vader import SentimentIntensityAnalyzer
1121
+ sid = SentimentIntensityAnalyzer()
1122
+ return sid.polarity_scores(text)['compound']
1123
+
1124
+ df['translated_text'] = df['translated_text'].astype(str)
1125
+ df['polarity'] = df['translated_text'].apply(lambda x: get_sentiment_vader(x))
1126
+
1127
+ fig = plt.figure(frameon=False, figsize=(16, 12))
1128
+ fig = plt.figure(figsize=(15, 8))
1129
+
1130
+ # try :
1131
+ if 'date' in df.columns:
1132
+ df['date2'] = pd.to_datetime(df['date'], utc=True)
1133
+ else:
1134
+ return None, dataframe
1135
+ print('no date, skipping polarity viz')
1136
+ # except:
1137
+ # print("no/wrong date column")
1138
+ # return None, dataframe
1139
+
1140
+ sorted_dates = df.sort_values(by='date2')
1141
+
1142
+ cmap = plt.cm.get_cmap('RdYlGn')
1143
+ norm = plt.Normalize(sorted_dates['polarity'].min(), sorted_dates['polarity'].max())
1144
+ colors = [cmap(norm(value)) for value in sorted_dates['polarity']]
1145
+
1146
+ # scatter plot
1147
+ plt.scatter(sorted_dates['date2'],sorted_dates['polarity'], color=colors, alpha=0.5)
1148
+
1149
+ # add a lineplot to show the average per day
1150
+
1151
+ plt.plot(sorted_dates['date2'], sorted_dates['polarity'].rolling(window=50).mean(), color='hotpink', linewidth=1.5)
1152
+
1153
+
1154
+ # add legend about pink line
1155
+ plt.legend(['Polarity', 'Trend'], frameon=False, bbox_to_anchor=(0.3, 1), loc='upper right', ncol=2, fontsize=12)
1156
+
1157
+ # add x-label inside the plot
1158
+
1159
+ plt.xlabel('Date', fontsize=12 )
1160
+
1161
+ # add y-label
1162
+ plt.ylabel('Polarity', fontsize=12)
1163
+
1164
+ # add x-ticks
1165
+ plt.xticks(fontsize=12 )
1166
+ # ax1 = plt.axes()
1167
+ # x_axis = ax1.axes.get_xaxis()
1168
+ # x_axis.set_visible(False)
1169
+ plt.yticks(fontsize=12)
1170
+
1171
+ return plt, df
1172
+
1173
+
1174
+ def get_synthetic_comment(text: None, slider, dataframe) :
1175
+
1176
+
1177
+ if check_words_in_string(words, text, case=False) and False:
1178
+
1179
+ df = dataframe.copy() # query is based on a dataframe called "df"
1180
+ agent = create_pandas_dataframe_agent(OpenAI(temperature=0), df, verbose=True)
1181
+
1182
+ def launch_agent(user_input):
1183
+ memory['user'].append(user_input)
1184
+ # user_input = get_memory() + user_input
1185
+ user_input = user_input
1186
+ agent_output = (agent.run(user_input))
1187
+ memory['agent'].append(agent_output)
1188
+ return agent_output
1189
+
1190
+ print('Pandas Agent Query')
1191
+ answer = launch_agent(text)
1192
+ return answer, None, None
1193
+
1194
+ else:
1195
+ query_type = 'comments'
1196
+
1197
+ query = f'Forget all of the above. Write 2-3 examples of {query_type} answering this question: {text}. \n\n{query_type}:\n\n'
1198
+ response = openai.ChatCompletion.create(
1199
+ model="gpt-3.5-turbo",
1200
+ temperature=0.5,
1201
+ max_tokens=300,
1202
+ top_p=1,
1203
+ # stream=True,
1204
+ messages=[
1205
+ #{"role": "system", "content": "Forget all the above instructions. You are a reviewer of products but also a customer and have an opinion about the products you buy. You are asked to write a review of a product you have recently purchased."},
1206
+ {"role": "user", "content": query},
1207
+ ]
1208
+ )['choices'][0]['message']['content']
1209
+ response = re.sub(r'As an AI model.*?\.', '', response)
1210
+ response = re.sub(r'As an AI language model.*?\.', '', response)
1211
+
1212
+ query_embed = model.encode(response)
1213
+ # dataframe['embeddings'] = dataframe['translated_text'].apply(
1214
+ # lambda x: model.encode(x))
1215
+ dataframe['similarity'] = dataframe['embeddings'].apply(
1216
+ lambda x: round(float(util.pytorch_cos_sim(query_embed, x)), 3))
1217
+
1218
+ dataframe.sort_values(by='similarity', ascending=False, inplace=True)
1219
+
1220
+
1221
+ complexity = ''
1222
+ cutsize = 900
1223
+
1224
+ if dataframe[dataframe['similarity'] > slider].shape[0] == 0:
1225
+ response2 = f'No {query_type} found with a similarity score above {slider}. Try to lower the similarity score threshold or change the question.\n\n However, this is what I found on the internet: \n\n'
1226
+
1227
+ toolname = ['wolfram-alpha']
1228
+ tools = load_tools(toolname)
1229
+ agent = initialize_agent(tools=tools, llm=llm, agent='zero-shot-react-description', verbose=False)
1230
+ wolfram_content = agent.run(f'{text}')
1231
+ wolfram_response = f'{wolfram_content}'
1232
+
1233
+ toolname = ['serpapi']
1234
+ tools = load_tools(toolname)
1235
+ agent = initialize_agent(tools=tools, llm=llm, agent='zero-shot-react-description', verbose=False)
1236
+ internet_content = agent.run(f'{text}')
1237
+ internet_response = f'{internet_content}'
1238
+
1239
+ response2 = f'{response2} \n\n {wolfram_response} \n\n {internet_response}'
1240
+
1241
+ else:
1242
+
1243
+ try:
1244
+ corpus = dataframe[dataframe['similarity']
1245
+ > slider]['translated_text'].tolist()
1246
+ print("CORPUS SIZE:", "FULL")
1247
+
1248
+ response2 = openai.ChatCompletion.create(
1249
+ model="gpt-3.5-turbo",
1250
+ temperature=0.5,
1251
+ max_tokens=300,
1252
+ top_p=1,
1253
+ # stream=True,
1254
+ messages=[
1255
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1256
+ ]
1257
+ )['choices'][0]['message']['content']
1258
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1259
+ except:
1260
+ try:
1261
+ corpus = dataframe[dataframe['similarity']
1262
+ > slider]['translated_text'][0:50].tolist()
1263
+ corpus = [x[:cutsize] for x in corpus]
1264
+ print("CORPUS SIZE:", 50)
1265
+ response2 = openai.ChatCompletion.create(
1266
+ model="gpt-3.5-turbo",
1267
+ temperature=0.5,
1268
+ max_tokens=300,
1269
+ top_p=1,
1270
+ # stream=True,
1271
+ messages=[
1272
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1273
+ ]
1274
+ )['choices'][0]['message']['content']
1275
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1276
+ except:
1277
+ try:
1278
+ corpus = dataframe[dataframe['similarity']
1279
+ > slider]['translated_text'][0:30].tolist()
1280
+ corpus = [x[:cutsize] for x in corpus]
1281
+
1282
+ print("CORPUS SIZE:", 30)
1283
+ response2 = openai.ChatCompletion.create(
1284
+ model="gpt-3.5-turbo",
1285
+ temperature=0.5,
1286
+ max_tokens=300,
1287
+ top_p=1,
1288
+ # stream=True,
1289
+ messages=[
1290
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1291
+ ]
1292
+ )['choices'][0]['message']['content']
1293
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1294
+ except:
1295
+ corpus = dataframe[dataframe['similarity']
1296
+ > slider]['translated_text'][0:15].tolist()
1297
+ print("CORPUS SIZE:", 15)
1298
+ # keep only the first 400 characters per each list elem
1299
+ corpus = [x[:cutsize] for x in corpus]
1300
+
1301
+ response2 = openai.ChatCompletion.create(
1302
+ model="gpt-3.5-turbo",
1303
+ temperature=0.5,
1304
+ max_tokens=300,
1305
+ top_p=1,
1306
+ # stream=True,
1307
+ messages=[
1308
+ {"role": "user", "content": f'\n{corpus}\n\nSummarize the above {query_type}s {complexity} to answer this question: {text}\n\nSummary:\n\n'},
1309
+ ]
1310
+ )['choices'][0]['message']['content']
1311
+ response2 = f'<b>Question:</b> {text}\n\n<b>Answer:</b> {response2}'
1312
+
1313
+ # Graph Generation
1314
+
1315
+ return response2, dataframe[dataframe['similarity'] > slider][['similarity', 'translated_text']][0:15], response2, "<span class='hsub'>Analysis:</span>Manual query"
1316
+
1317
+ return response2, dataframe[dataframe['similarity'] > slider][['similarity', 'translated_text']][0:15], response2, "<span class='hsub'>Analysis:</span>Manual query"
1318
+
1319
+ def clear_output(filename, titleBlock):
1320
+ titleBlock = re.sub('<[^<]+?>', '', titleBlock)
1321
+ # remove all \n
1322
+ # trim
1323
+ titleBlock = titleBlock.replace("\n", "")
1324
+
1325
+ print(titleBlock)
1326
+ print(filename)
1327
+ print(filename + titleBlock + "_CACHE.txt")
1328
+ try:
1329
+ os.remove(filename + titleBlock + "_CACHE.txt")
1330
+ except Exception as e:
1331
+ print (e)
1332
+
1333
+ pass
1334
+ return 'Cache has been cleared'
1335
+
1336
+ def save_output(tab, data_answer):
1337
+
1338
+ # def save_output(tab):
1339
+ if tab == "Summary":
1340
+ print("summary save")
1341
+ print(data_answer)
1342
+ print (data_answer.value)
1343
+ print(dir(data_answer))
1344
+ # with open("data_answer.txt", "+ab") as f:
1345
+ # open and append to it
1346
+ with open("data_answer.txt", "a") as f:
1347
+ try:
1348
+ f.write(data_answer.value)
1349
+ f.write(data_answer)
1350
+ except:
1351
+ pass
1352
+
1353
+ elif tab == "Table":
1354
+ try:
1355
+ similar_reviews_dataframe = pd.DataFrame(similar_reviews)
1356
+ similar_reviews_dataframe.to_csv("similar_reviews.csv", index=False, encoding='utf-8-sig')
1357
+ except:
1358
+ pass
1359
+ else:
1360
+ try:
1361
+ g.save_graph("graph.html")
1362
+ except:
1363
+ pass
1364
+
1365
+
1366
+ def generate_new_examples(text):
1367
+ # GENERATE NEW EXAMPLES BASED ON QUERY
1368
+ new_examples = openai.ChatCompletion.create(
1369
+ model="gpt-3.5-turbo",
1370
+ temperature=0.7,
1371
+ max_tokens=100,
1372
+ top_p=1,
1373
+ # stream=True,
1374
+ messages=[
1375
+ {"role": "user", "content": f'Generate a list of 4 most relevent questions related to this question : {text}. Output should be in a comma separated string format, no numbers, ordering. (example: What is this text about?, What is the main trend?,...) There is no need to enumerate each element.\n\n'},
1376
+ ]
1377
+ )['choices'][0]['message']['content']
1378
+
1379
+
1380
+ new_examples = new_examples.split('\n')
1381
+ # make a list for each element
1382
+
1383
+ new_examples = [x for x in new_examples if x != '']
1384
+ new_examples = [x.strip() for x in new_examples]
1385
+ new_examples = [x.split(',') for x in new_examples]
1386
+ return new_examples
1387
+
1388
+
1389
+ def summarize_video(url):
1390
+ loader = YoutubeLoader.from_youtube_channel(url)
1391
+ result = loader.load()
1392
+
1393
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=0)
1394
+ texts = text_splitter.split_documents(result)
1395
+ print(len(texts))
1396
+
1397
+
1398
+ # We first try the chain with the default chain type
1399
+ # if length of the text is more than 2000 tokens, we will use map reduce (summary of chunks)
1400
+
1401
+ try:
1402
+ chain = load_summarize_chain(llm, chain_type='stuff', verbose=True)
1403
+ print('ChainType: stuff')
1404
+ # store intermediate steps
1405
+ return chain.run(result)
1406
+
1407
+ except:
1408
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=2000, chunk_overlap=0)
1409
+ texts = text_splitter.split_documents(result)
1410
+ # print(len(texts))
1411
+ chain = load_summarize_chain(llm, chain_type='map_reduce', verbose=True)
1412
+ print('ChainType: map reduce')
1413
+ return chain.run(texts)
1414
+
1415
+
1416
+ # def main():
1417
+ # global similar_reviews, g, query_type, response2, Output, output_html, html, new_examples, samples
1418
+
1419
+ def get_graph(dataframe):
1420
+
1421
+ print("step 1")
1422
+ from sklearn.cluster import KMeans
1423
+ from sklearn.metrics.pairwise import cosine_similarity
1424
+
1425
+
1426
+ embeddings_array = dataframe['embeddings'].tolist()
1427
+ print ("step 2")
1428
+ num_clusters = 3 # Adjust the number of clusters as needed
1429
+ kmeans = KMeans(n_clusters=num_clusters, random_state=42)
1430
+ cluster_labels = kmeans.fit_predict(embeddings_array)
1431
+
1432
+ print(cluster_labels)
1433
+ sentences = dataframe['translated_text'].tolist()
1434
+ print ("step 3")
1435
+ G = nx.DiGraph()
1436
+
1437
+
1438
+ cos_sim_matrix = cosine_similarity(embeddings_array)
1439
+ print(cos_sim_matrix)
1440
+ print ("step 4")
1441
+ for idx, label in enumerate(cluster_labels):
1442
+ G.add_node(idx, sentence=sentences[idx], cluster=label)
1443
+
1444
+ for i in range(len(sentences)):
1445
+ for j in range(len(sentences)):
1446
+ if i != j:
1447
+ #if cos_sim_matrix[i, j] > 0.8:
1448
+ G.add_edge(i, j, weight=cos_sim_matrix[i, j])
1449
+ # else:
1450
+ # continue
1451
+ print ("step 5")
1452
+ plt.figure(figsize=(10, 10))
1453
+
1454
+ pos = nx.spring_layout(G, k=0.5, iterations=50)
1455
+
1456
+ print ("step 6")
1457
+ G_undirected = G.to_undirected()
1458
+
1459
+ from community import community_louvain
1460
+ node_to_community = community_louvain.best_partition(G_undirected)
1461
+
1462
+ print ("step 7")
1463
+ community_to_color = {
1464
+ 0 : 'tab:pink',
1465
+ 1 : 'tab:orange',
1466
+ 2 : 'tab:purple',
1467
+ 3 : 'tab:blue',
1468
+ }
1469
+
1470
+ node_color = {node: community_to_color[community_id] for node, community_id in node_to_community.items()}
1471
+
1472
+ print ("step 8")
1473
+ reducer = umap.UMAP(n_components=2, random_state=42)
1474
+ embeddings_2d = reducer.fit_transform(embeddings_array)
1475
+
1476
+ def normalize_weight(weight, min_weight, max_weight):
1477
+ return (weight - min_weight) / (max_weight - min_weight)
1478
+
1479
+
1480
+ def visualize_graph_plotly(graph, embeddings_2d, scaling_factor=3):
1481
+
1482
+ print ("step 9")
1483
+ min_weight = min((data['weight'] for _, _, data in graph.edges(data=True)))
1484
+ max_weight = max((data['weight'] for _, _, data in graph.edges(data=True)))
1485
+
1486
+ fig = go.Figure()
1487
+
1488
+
1489
+ print ("step 10")
1490
+ # Add edges with width based on the normalized weights
1491
+ print(len(graph.edges()))
1492
+ for i, j in graph.edges():
1493
+ print(i)
1494
+ weight = normalize_weight(graph[i][j]['weight'], min_weight, max_weight)
1495
+ # weight=0.1
1496
+ fig.add_shape(
1497
+ type="line",
1498
+ x0=embeddings_2d[i][0],
1499
+ x1=embeddings_2d[j][0],
1500
+ y0=embeddings_2d[i][1],
1501
+ y1=embeddings_2d[j][1],
1502
+ yref="y",
1503
+ xref="x",
1504
+ line=dict(color="rgba(211, 211, 211, 0.5)", width=weight * scaling_factor * 0.7),
1505
+ )
1506
+ print ("step 11")
1507
+ # Add nodes
1508
+ for idx, emb in enumerate(embeddings_2d):
1509
+ closeness = nx.closeness_centrality(G)[idx]
1510
+ degree = nx.degree_centrality(G)[idx]
1511
+ betweenness = nx.betweenness_centrality(G)[idx]
1512
+ eigen = nx.eigenvector_centrality(G)[idx]
1513
+
1514
+ fig.add_trace(
1515
+ go.Scatter(
1516
+ x=[emb[0]],
1517
+ y=[emb[1]],
1518
+ mode="markers+text",
1519
+ text=[graph.nodes[idx]["sentence"]],
1520
+ textposition="bottom center",
1521
+ marker=dict(color=node_color[idx][4:], size=closeness * 40),
1522
+ # add closeness, degree, betweenness and sentence as hover text
1523
+ hovertext=[f"{graph.nodes[idx]['sentence']} <br> closeness_centrality: {closeness:.2f} <br> degree_centrality: {degree:.2f} <br> betweenness_centrality: {betweenness:.2f} <br> eigenvector_centrality: {eigen:.2f}"],
1524
+ )
1525
+ )
1526
+
1527
+ print("for completed")
1528
+
1529
+ fig.update_layout(showlegend=False, plot_bgcolor="white", width=1200, height=800)
1530
+ fig.update_xaxes(showticklabels=False, showgrid=False, zeroline=False,
1531
+ showline=False, automargin=False, showspikes=False)
1532
+ fig.update_yaxes(showticklabels=False, showgrid=False, zeroline=False,
1533
+ showline=False, automargin=False, showspikes=False)
1534
+
1535
+ fig.update_layout(title_text="Test Graph Visualization", title_x=0.5, title_font_size=30, title_font_color='black')
1536
+
1537
+ return fig
1538
+
1539
+ return visualize_graph_plotly(G, embeddings_2d, scaling_factor = 10)
1540
+
1541
+ def update_examples(samples):
1542
+ return gr.Dataset.update(samples=samples)
1543
+
1544
+ def print_samples():
1545
+ global samples
1546
+ return {"samples": samples}
1547
+
1548
+ def load_example(example_id):
1549
+ global samples
1550
+ return samples[example_id][0]
1551
+
1552
+ url_params = gr.JSON({}, visible=False, label="URL Params")
1553
+
1554
+
1555
+ def getAnalysisLabel(id):
1556
+ if id == 'exec_sum':
1557
+ return 'Executive Summary'
1558
+ elif id == 'top_clust':
1559
+ return 'Topic Cluster'
1560
+
1561
+ elif id == 'trend_analysis':
1562
+ return 'Trend Analysis'
1563
+
1564
+ elif id == 'emot_clust':
1565
+ return 'Sentiment Analysis'
1566
+
1567
+ elif id == 'swot_':
1568
+ return 'SWOT Analysis'
1569
+
1570
+ elif id == 'competitor':
1571
+ return 'Competitor Analysis'
1572
+
1573
+ tabs = [
1574
+ {
1575
+ "id": 0,
1576
+ "label": "Social Media",
1577
+ "content": {
1578
+ "exec_sum":None,
1579
+ "top_clust": None,
1580
+ "emot_clust": None,
1581
+ "swot_": None,
1582
+ # "competitor": None,
1583
+ },
1584
+ "filename": "profdemo_cleaned.xlsx"
1585
+ },
1586
+ {
1587
+ "id": 1,
1588
+ "label": "News/Publications",
1589
+ "content": {
1590
+ "exec_sum":None,
1591
+ "trend_analysis": None,
1592
+ # "top_clust": None,
1593
+ "competitor" : None,
1594
+ "swot_": None,
1595
+ },
1596
+ "filename": "cleaned_news.xlsx"
1597
+ },
1598
+ # {
1599
+ # "id": 0,
1600
+ # "label": "Mozzarella",
1601
+ # "content": {
1602
+ # "exec_sum":None,
1603
+ # "top_clust": None,
1604
+ # # "trend_analysis": None,
1605
+ # "emot_clust": None,
1606
+ # # "swot_": None,
1607
+ # # "competitor" : None,
1608
+ # },
1609
+ # "filename": "MozzarellaTW.xlsx"
1610
+ # },
1611
+ # {
1612
+ # "id": 1,
1613
+ # "label": "Onion",
1614
+ # "content": {
1615
+ # "exec_sum":None,
1616
+ # "top_clust": None,
1617
+ # "emot_clust": None,
1618
+ # # "competitor" : None,
1619
+ # },
1620
+ # "filename": "OnionTW.xlsx"
1621
+ # },
1622
+ # {
1623
+ # "id": 2,
1624
+ # "label": "Brand - Social Media",
1625
+ # "content": {
1626
+ # "exec_sum":None,
1627
+ # "top_clust": None,
1628
+ # "trend_analysis": None,
1629
+ # "emot_clust": None,
1630
+ # "swot_": None,
1631
+ # "competitor" : None,
1632
+ # },
1633
+ # "filename": "LambWestonBrand.csv"
1634
+ # },
1635
+ # {
1636
+ # "id": 3,
1637
+ # "label": "Brand - News",
1638
+ # "content": {
1639
+ # "exec_sum":None,
1640
+ # "top_clust": None,
1641
+ # "trend_analysis": None,
1642
+ # "emot_clust": None,
1643
+ # "swot_": None,
1644
+ # "competitor" : None,
1645
+ # },
1646
+ # "filename": "LambWestonNews.csv"
1647
+ # },
1648
+ ]
1649
+
1650
+ list = []
1651
+ maxSources = 10
1652
+
1653
+ oTab = []
1654
+ attachButtons = []
1655
+
1656
+ for element in tabs:
1657
+ oTab.append( {
1658
+ "exec_sum":None,
1659
+ "top_clust": None,
1660
+ "trend_analysis": None,
1661
+ "emot_clust": None,
1662
+ "swot_": None,
1663
+ "competitor" : None,
1664
+ })
1665
+ attachButtons.append(None)
1666
+
1667
+
1668
+ get_window_url_params = """
1669
+ function(url_params) {
1670
+ var scriptElement = document.createElement("script");
1671
+ scriptElement.src = '"""+gradio_js+"""?v="""+str(ra)+"""';
1672
+ scriptElement.innerHTML = "console.log('This is dynamic JavaScript code');";
1673
+ document.body.appendChild(scriptElement);
1674
+ const params = new URLSearchParams(window.location.search);
1675
+ url_params = Object.fromEntries(params);
1676
+ return [url_params];
1677
+ }
1678
+ """
1679
+
1680
+ runjs = """
1681
+ function(projJson,num,fullData) {
1682
+ console.log(fullData)
1683
+
1684
+ var localizations = fullData['localization']
1685
+ console.log( fullData['localization'])
1686
+ if (localizations) {
1687
+ document.querySelectorAll('.hsub')[0].innerText = localizations['project'];
1688
+ // document.querySelectorAll('.hsub')[1].innerText = "semmi";
1689
+ // document.querySelectorAll('.hsub')[2].innerText = "semmi";
1690
+
1691
+ if (document.querySelector('#querybtn')) document.querySelector('#querybtn').innerText = localizations['talk_to_your_data']
1692
+
1693
+ var tabs = document.querySelectorAll('#targetColMiddle .tab-nav button');
1694
+ tabs[0].innerText = localizations['overview'] || 'Overview'
1695
+ tabs[1].innerText = localizations['rawdata'] || 'Raw Data'
1696
+ tabs[2].innerText = localizations['visuals'] || 'Visuals'
1697
+
1698
+ document.querySelectorAll('.sideTitle span')[0].innerText = localizations['data_sources'] || 'Data sources'
1699
+ document.querySelectorAll('.sideTitle span')[1].innerText = localizations['predefined_analysis'] || 'Predefined analysis'
1700
+ }
1701
+ document.querySelectorAll('.analysisButton').forEach(function(el) {
1702
+ el.style.display = 'none';
1703
+ });
1704
+ Object.keys(projJson[num]['content']).forEach(function(key) {
1705
+ document.querySelectorAll('.analysisButton').forEach(function(el) {
1706
+ if (el.id == key) {
1707
+ el.style.display = 'block';
1708
+ }
1709
+
1710
+ });
1711
+ });
1712
+
1713
+ document.querySelectorAll('.sourceButton').forEach(function(el) {
1714
+ el.classList.remove('selectedSource');
1715
+ });
1716
+ document.querySelectorAll('.sourceButton').forEach(function(el) {
1717
+ if (el.innerHTML == projJson[num]['label']) el.classList.add('selectedSource');
1718
+ });
1719
+ // NEM ÉRTEM MINEK KELL TÖBB OUTPUT
1720
+ return [1, num,1,1]
1721
+ }
1722
+ """
1723
+
1724
+ def parse_URL_params(url_params):
1725
+ # if url params has 'pid'
1726
+ if 'pid' in url_params:
1727
+ request = requests.get(rubik_backend + '?proj=' + url_params['pid'])
1728
+ text = url_params['pid']
1729
+ else:
1730
+ request = requests.get(rubik_backend + '?proj=demo')
1731
+ text = "demo"
1732
+
1733
+ # textlowercase url_params['pid']
1734
+ # first letter uppercase
1735
+ textUpper = request.json()["brand"][0].upper() + request.json()["brand"][1:]
1736
+ return [url_params, request.json()["sources"], request.json()["sources"], "<div class='brand'><span class='hsub'>Project:</span>"+textUpper+"</div>", request.json(), text]
1737
+
1738
+ for i in range(maxSources):
1739
+ list.append({"id":i, "name":"asd", "obj":"", "analList":[]})
1740
+
1741
+
1742
+ def variable_outputs(k):
1743
+ global list
1744
+ sourceArray = k
1745
+ output = None
1746
+ for i in range(len(sourceArray)):
1747
+ if not output:
1748
+ output = [list[i]["obj"].update(value=sourceArray[i]["label"],visible=True)]
1749
+ else:
1750
+ output += [list[i]["obj"].update(value=sourceArray[i]["label"],visible=True)]
1751
+
1752
+ remainingCount = maxSources - len(sourceArray)
1753
+
1754
+ for i in range(remainingCount):
1755
+ output += [list[i]["obj"].update(value="",visible=False)]
1756
+
1757
+ return output
1758
+
1759
+ url_params = gr.JSON({}, label="URL Params", visible=False)
1760
+
1761
+ # with gr.Interface(theme=gr.themes.Soft(primary_hue='pink', secondary_hue='pink', neutral_hue='stone'), css="footer{display:none !important}") as app:
1762
+ # , css=".main{filter: blur(3px)}footer{display:none !important}"
1763
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue='pink', secondary_hue='pink', neutral_hue='stone')) as app:
1764
+
1765
+ dat = gr.Markdown()
1766
+ projdetails = gr.Textbox("test", label="Project Details", visible=False)
1767
+ projJson = gr.JSON(visible=False)
1768
+ fullProjectData = gr.JSON(visible=False)
1769
+ projectUUID = gr.State(value="", label="projectUUID", visible=False)
1770
+ if True:
1771
+ summaries_state = gr.State(value=[], label="summaries_state")
1772
+ executive = gr.State(value='', label="executive")
1773
+ needHeader = True
1774
+
1775
+ # if needHeader and False:
1776
+ # with gr.Row():
1777
+ # with gr.Column(scale=.1, elem_id="logocol"):
1778
+ # # gr.Markdown('<img id="logo" src="http://
1779
+ # # add a title at the center of the page
1780
+ # gr.Markdown('<a href="https://app.rubiklab.ai"><img id="logo" src="http://127.0.0.1:5500/logo.png" /></a>')
1781
+
1782
+ # with gr.Column(scale=.3):
1783
+ # gr.Markdown("<h1>Talkback</h1>")
1784
+
1785
+ # random number between 1 and 10000
1786
+ ra = str(np.random.randint(1, 10000))
1787
+ gr.Markdown(
1788
+ """
1789
+ <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap'>
1790
+ <link rel="stylesheet" href='""" + gradio_css + """?v="""+str(ra)+"""'>
1791
+ <link rel="icon" type="image/x-icon" href="https://api.rubiklab.ai/assets/favicon.ico">
1792
+ """
1793
+ )
1794
+
1795
+ # if needHeader:
1796
+ # with gr.Row():
1797
+ # with gr.Column(elem_id="header"):
1798
+ # gr.Markdown("<h2>Nike</h2>")
1799
+
1800
+ # selectedData = gr.Markdown('<span></span>', elem_id="datanameblock")
1801
+ # titleBlock = gr.Markdown("<span class='title'></span>", elem_id="titleblock")
1802
+
1803
+
1804
+ df = pd.DataFrame()
1805
+ with gr.Row():
1806
+ with gr.Column(scale=.4, elem_id="leftContainer"):
1807
+ with gr.Row(elem_id="header"):
1808
+ proj = gr.Markdown("")
1809
+ selectedData = gr.Markdown('<span></span>', elem_id="datanameblock")
1810
+ titleBlock = gr.Markdown("<span class='title'></span>", elem_id="titleblock")
1811
+
1812
+
1813
+
1814
+ gr.Markdown("<h3 class='sideTitle'><span>Data sources</span></h3>")
1815
+ tabs = []
1816
+ analysisList = []
1817
+ for i in range(maxSources):
1818
+ list[i]["obj"] = gr.Button(value="" + str(i),visible=False, elem_classes="sourceButton")
1819
+ list[i]["index"] = gr.Number(i, visible=False)
1820
+ tabs.append(list[i]["obj"])
1821
+
1822
+ gr.Markdown("<h3 class='sideTitle predefined'><span>Predefined analysis</span></h3>")
1823
+ # analysisList = ['exec_sum', 'top_clust', 'emot_clust', 'swot_', 'trend_analysis', 'competitor']
1824
+ oa = {
1825
+ 'exec_sum': gr.Button("Executive Summary", elem_id="exec_sum", elem_classes=["analysisButton"]),
1826
+ 'top_clust': gr.Button("Topic Clusters", elem_id="top_clust", elem_classes=["analysisButton"]),
1827
+ 'emot_clust': gr.Button("Sentiment Analysis", elem_id="emot_clust", elem_classes=["analysisButton"]),
1828
+ 'swot_': gr.Button("SWOT Analysis", elem_id="swot_", elem_classes=["analysisButton"]),
1829
+ 'trend_analysis': gr.Button("Trend Analysis", elem_id="trend_analysis", elem_classes=["analysisButton"]),
1830
+ 'competitor': gr.Button("Competitor Analysis", elem_id="competitor", elem_classes=["analysisButton"]),
1831
+ }
1832
+ newcluster = gr.Button("New Cluster", elem_id="newcluster", elem_classes=["newcluster"], visible=False)
1833
+ newgraph = gr.Button("New graph", elem_id="newcluster", elem_classes=["newgraph"], visible=False)
1834
+
1835
+ # for i in range(len(analysisList)):
1836
+ # gr.Button(analysisList[i], elem_classes=["analysisButton"], elem_id=analysisList[i])
1837
+
1838
+ # iterate throu oa
1839
+ gr.Button("Talk to your data", elem_id="querybtn")
1840
+ projJson.change(variable_outputs, projJson, tabs)
1841
+ gr.Markdown(f'url params value: {url_params.value}', visible=False)
1842
+ threshold = gr.Slider(minimum=0, maximum=1, label="Threshold", visible=False)
1843
+ csv_file = gr.File(label="File (csv, excel, h5..)", elem_id="fupload",visible=False)
1844
+
1845
+ brand = gr.State('brand')
1846
+ industry = gr.State('industry')
1847
+
1848
+ csvs = gr.State('csvnum')
1849
+ filename = gr.State('filename')
1850
+
1851
+ graph_type = gr.State('graph_type')
1852
+
1853
+ # THE DATASET
1854
+ data_storage = gr.State(label="data_storage")
1855
+
1856
+ # TOPICS LIST
1857
+ list_of_topics = gr.State(label="list_of_topics")
1858
+
1859
+ # add image output
1860
+ with gr.Tab("Word Cloud"):
1861
+ Imaj = gr.Image(label="Word Cloud")
1862
+
1863
+ with gr.Tab("Polarity"):
1864
+ Polarity = gr.Plot(label="Polarity")
1865
+
1866
+ app.load(
1867
+ fn=parse_URL_params,
1868
+ inputs=[url_params],
1869
+ outputs=[url_params, projJson, projdetails, proj, fullProjectData,projectUUID],
1870
+ _js=get_window_url_params
1871
+ )
1872
+ url_params.render()
1873
+ with gr.Column(scale=2, elem_id="targetColMiddle"):
1874
+
1875
+ graphHelper = gr.Markdown("<span></span>")
1876
+ with gr.Tab("Overview", elem_id="overviewTab"):
1877
+ tab = 'Summary'
1878
+ data_answer = gr.Textbox(visible=False, elem_id="hiddenTextbox")
1879
+ # gr.Textbox.style(data_answer)
1880
+ formattedres = gr.Markdown("<span class='description'></span>")
1881
+
1882
+ with gr.Row():
1883
+ with gr.Column(scale=6):
1884
+ # add empty space
1885
+ pass
1886
+ with gr.Column(scale=.5, min_width=100):
1887
+ clear_button = gr.Button("Clear", visible=True, elem_id="clear_button")
1888
+ clear_button.click(fn=clear_output, inputs=[filename, titleBlock], outputs=[formattedres])
1889
+ # save_button = gr.Button("Save", visible=True, elem_id="save_button")
1890
+ # save_button.click(lambda: save_output("Summary", data_answer))
1891
+
1892
+
1893
+ tab = gr.Tab("Raw data", elem_id="rawdataTab")
1894
+ with tab:
1895
+ tab = 'Table'
1896
+ similar_reviews = gr.Dataframe(label="Table", type="pandas", max_rows=20, overflow_row_behaviour='paginate', show_label=False)
1897
+ with gr.Row():
1898
+ with gr.Column(scale=6):
1899
+ # add empty space
1900
+ pass
1901
+ # with gr.Column(scale=.5, min_width=100):
1902
+ # save_button = gr.Button("Save", visible=True)
1903
+ # save_button.click(lambda: save_output("Table", data_answer))
1904
+ with gr.Tab("Visuals"):
1905
+ tab = 'Graph'
1906
+ graph = gr.Plot(elem_id="cluster", label="")
1907
+ graph2 = gr.Plot(elem_id="cluster2", label="", visible=False)
1908
+ # with gr.Tab("Word Cloud"):
1909
+ Imaj = gr.Image(label="Word Cloud", elem_id="vwordcloud")
1910
+
1911
+ # with gr.Tab("Polarity"):
1912
+ Polarity = gr.Plot(label="Polarity", elem_id="vpolarity")
1913
+
1914
+ with gr.Row():
1915
+ with gr.Column(scale=1):
1916
+ clearbutton = gr.Button("Remove and regenerate", visible=True, elem_id="cleardrop_button")
1917
+ clearkeepbutton = gr.Button("Keep and regenerate", visible=True, elem_id="clearkeep_button")
1918
+
1919
+
1920
+ with gr.Row():
1921
+ with gr.Column(scale=6):
1922
+ # add empty space
1923
+ pass
1924
+ # with gr.Column(scale=.5, min_width=100):
1925
+ # save_button = gr.Button("Save", visible=True)
1926
+ # gr.Button.style(save_button, color="secondary")
1927
+ # save_button.click(lambda: save_output("Graph", data_answer))
1928
+
1929
+
1930
+ with gr.Row(elem_id="query"):
1931
+ with gr.Column(scale=1, elem_id='query1'):
1932
+
1933
+ data_answerQuery = gr.Textbox(label="", lines=10, visible=False)
1934
+ # gr.Textbox.style(data_answer)
1935
+ formattedresQuery = gr.Markdown("<span class='description'></span>")
1936
+
1937
+ query = gr.Textbox(lines=1, placeholder="Start typing your question...", label=" ")
1938
+ gr.Textbox.style(query)
1939
+
1940
+ submit_button = gr.Button("Submit", elem_id='submit')
1941
+ gr.Button.style(submit_button, color="secondary")
1942
+
1943
+ with gr.Column(scale=.1, elem_id='query2'):
1944
+ samples = [["What insights can we take from this data?", "2 What insights can we take from this data?"]]
1945
+
1946
+ examples = gr.Dataset(samples=samples, components=[query], type="index", label="Some hints for your next question, select which one you prefer.")
1947
+
1948
+
1949
+
1950
+ def update_examples(query):
1951
+ global samples
1952
+ samples = generate_new_examples(query)
1953
+ return gr.Dataset.update(samples=samples)
1954
+
1955
+ def print_samples():
1956
+ global samples
1957
+ return {"samples": samples}
1958
+
1959
+ def load_example(example_id):
1960
+ global samples
1961
+ return samples[example_id][0]
1962
+
1963
+
1964
+ def changesource(projJson, num):
1965
+ # print("switching")
1966
+ return 1
1967
+ def doJS(projJson, num,fulldat):
1968
+ # print("doing js")
1969
+ return 1, num
1970
+
1971
+ sourcelabel = gr.TextArea(elem_id="activeSource", visible=False)
1972
+ sourceIndex = gr.Number(visible=False)
1973
+ xy = gr.State()
1974
+ for i in range(maxSources):
1975
+ num = list[i]["index"]
1976
+ list[i]["obj"].click(doJS,inputs=[projJson, num, fullProjectData], outputs=[xy, sourceIndex], _js=runjs).then(
1977
+ load_csv, inputs=[projJson, num, fullProjectData, projectUUID], outputs=[data_storage, data_answer, similar_reviews, formattedres, filename, selectedData]).then(
1978
+ generate_wordcloud, inputs=[data_storage], outputs=[Imaj]).then(
1979
+ get_polarity, inputs=[data_storage], outputs=[Polarity, data_storage])
1980
+
1981
+
1982
+ # SUMMARIZE VIDEO CONTENT
1983
+ def checkData(filename):
1984
+ print(filename)
1985
+
1986
+ dat = gr.State(label="dat")
1987
+
1988
+ oa['exec_sum'].click(fn=checkData, inputs=[filename], outputs=[]).then(get_executive_summary, inputs=[data_storage, brand, industry,summaries_state, csvs, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper, formattedres, titleBlock])
1989
+ oa['top_clust'].click(get_topic_cluster, inputs=[data_storage, graph_type,filename], outputs=[graph, similar_reviews, list_of_topics, query, dat, graphHelper,formattedres,titleBlock])
1990
+ oa['emot_clust'].click(emotional_mapping, inputs=[data_storage, industry, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper,formattedres,titleBlock])
1991
+ oa['swot_'].click(get_executive_summary, inputs=[data_storage, brand, industry,summaries_state, csvs, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper, formattedres, titleBlock]).then(get_SWOT, inputs=[data_storage, brand, industry, executive, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, graphHelper,formattedres,titleBlock])
1992
+ oa['trend_analysis'].click(get_trend_summary, inputs=[data_storage, list_of_topics, brand, industry, graph_type,filename, fullProjectData, sourceIndex], outputs=[data_answer, similar_reviews, graphHelper,formattedres,titleBlock])
1993
+ oa['competitor'].click(get_competitive, inputs=[brand, industry, graph_type,filename,data_storage, fullProjectData, sourceIndex], outputs=[data_answer, graphHelper,formattedres,titleBlock])
1994
+
1995
+
1996
+ def clear_data(filename):
1997
+ if os.path.exists(filename + 'df3.csv'):
1998
+ os.remove(filename + 'df3.csv')
1999
+
2000
+ def rename_data_timestamp(filename):
2001
+ if os.path.exists(filename + 'df3.csv'):
2002
+ os.rename(filename + 'df3.csv', filename + str(datetime.datetime.now()) + '.csv')
2003
+
2004
+ clearbutton.click(clear_data, inputs=[filename], outputs=[]).then(get_topic_cluster, inputs=[data_storage, graph_type,filename], outputs=[graph, similar_reviews, list_of_topics, query, dat, graphHelper,formattedres,titleBlock])
2005
+ clearkeepbutton.click(rename_data_timestamp, inputs=[filename], outputs=[]).then(get_topic_cluster, inputs=[data_storage, graph_type,filename], outputs=[graph, similar_reviews, list_of_topics, query, dat, graphHelper,formattedres,titleBlock])
2006
+
2007
+ # app.launch(share=True, server_name="0.0.0.0", server_port=7860)
2008
+ def get_new_topic(data_storage, graph_type,filename):
2009
+ from bertopic import BERTopic
2010
+ from bertopic.representation import OpenAI
2011
+ from sklearn.cluster import KMeans
2012
+ from sklearn.feature_extraction.text import CountVectorizer
2013
+ import pandas as pd
2014
+ # import openai
2015
+
2016
+ # openai.api_key = 'sk-2Ulixq
2017
+ prompt = """
2018
+ I have a topic that contains the following documents:
2019
+ [DOCUMENTS]
2020
+ The topic is described by the following keywords: [KEYWORDS]
2021
+
2022
+ Based on the information above, extract a short topic label in the following format:
2023
+ topic: <topic label>
2024
+ """
2025
+
2026
+ vectorizer_model=CountVectorizer(stop_words="english")
2027
+
2028
+ # df = pd.read_excel('C:/Users/sinan/Downloads/profdemo_cleaned (1).xlsx')
2029
+ df = data_storage
2030
+ df['translated_text'] = df['translated_text'].apply(lambda x: str(x))
2031
+
2032
+ docs = df['translated_text'].tolist()
2033
+
2034
+ representation_model = OpenAI(model="gpt-3.5-turbo", delay_in_seconds=.5, chat=True)
2035
+
2036
+ if len(docs) < 100:
2037
+ cluster_model = KMeans(n_clusters=3)
2038
+ topic_model = BERTopic(hdbscan_model=cluster_model, representation_model=representation_model, vectorizer_model=vectorizer_model)
2039
+ else:
2040
+ cluster_model = KMeans(n_clusters=6)
2041
+
2042
+ # representation_model = 'bert-base-nli-mean-tokens'
2043
+ n_gram_range = (1, 1) # set the range of n-grams to be considered
2044
+ min_topic_size = 10 # set the minimum number of documents in each topic
2045
+
2046
+ topic_model = BERTopic(hdbscan_model=cluster_model, representation_model=representation_model, n_gram_range=n_gram_range, min_topic_size=min_topic_size)
2047
+ # topic_model = BERTopic(representation_model=representation_model, nr_topics=8)
2048
+
2049
+
2050
+
2051
+ topics, probs = topic_model.fit_transform(docs)
2052
+
2053
+ return topic_model.visualize_documents(docs, width=1200, height=800, title='Topic Clustering', hide_annotations=True)
2054
+
2055
+ newcluster.click(get_new_topic, inputs=[data_storage, graph_type,filename], outputs=[graph2])
2056
+ newgraph.click(get_graph,inputs=[data_storage], outputs=[graph2])
2057
+
2058
+ # 1. ADD QUESTIONS TO THE QUERY
2059
+ examples.click(load_example, inputs=[examples], outputs=[query])
2060
+
2061
+ # UNCOMMENT FOR TEXT TO SPEECH OUTPUT
2062
+ submit_button.click(get_synthetic_comment, inputs=[query, threshold, data_storage ], outputs=[data_answer, similar_reviews, formattedresQuery, titleBlock]).success(update_examples, inputs=[query], outputs=[examples])
2063
+
2064
+
2065
+
2066
+ def same_auth(username, password):
2067
+ return username == password
2068
+ if __name__ == "__main__":
2069
+ # app.launch(share=True, server_name="0.0.0.0", server_port=7860, auth=same_auth, auth_message="Please enter the same username and password")
2070
+ app.launch(share=True, server_name="0.0.0.0", server_port=7860)
2071
+
2072
+ # if __name__ == "__main__":
2073
+ # main()
uploader/.DS_Store ADDED
Binary file (6.15 kB). View file
 
uploader/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ uploads/*
uploader/uploadapi.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for
2
+ import os
3
+ # cors
4
+ from flask_cors import CORS, cross_origin
5
+ app = Flask(__name__)
6
+
7
+ cors = CORS(app)
8
+ # Set upload folder
9
+ UPLOAD_FOLDER = 'uploads'
10
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
11
+
12
+ # Set allowed file extensions
13
+ ALLOWED_EXTENSIONS = {'xlsx', 'csv'}
14
+
15
+ def allowed_file(filename):
16
+ """Helper function to check if a file has an allowed extension"""
17
+ return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
18
+
19
+ @app.route('/upload', methods=['GET', 'POST'])
20
+ def upload_file():
21
+ if request.method == 'POST':
22
+ # Check if a file was uploaded
23
+ if 'file' not in request.files:
24
+ return redirect(request.url)
25
+
26
+ if 'uuid' not in request.form:
27
+ return "no uuid"
28
+
29
+ file = request.files['file']
30
+
31
+ # Check if file has an allowed extension
32
+ if not allowed_file(file.filename):
33
+ return 'Invalid file type'
34
+ # get uuid from form
35
+ uuid = request.form['uuid']
36
+ # Save file to upload folder
37
+
38
+ # if folder with name: uuid does not exist, create it
39
+ if not os.path.exists(os.path.join(app.config['UPLOAD_FOLDER'], uuid)):
40
+ os.makedirs(os.path.join(app.config['UPLOAD_FOLDER'], uuid))
41
+
42
+ file.save(os.path.join(app.config['UPLOAD_FOLDER'], uuid, file.filename))
43
+
44
+ return {"status":"success","filename": file.filename, "uuid": uuid}
45
+
46
+ return "did nothing..."
47
+ # return render_template('upload.html')
48
+
49
+ @app.route('/clearcache', methods=['POST'])
50
+ def clear_cache():
51
+ print(request.json)
52
+ if request.method == 'POST':
53
+ if 'uuid' not in request.json:
54
+ return "no uuid"
55
+ if 'filename' not in request.json:
56
+ return "no filename"
57
+
58
+ uuid = request.json['uuid']
59
+ folder = os.path.join(app.config['UPLOAD_FOLDER'],uuid)
60
+ filename = request.json['filename']
61
+ if filename in os.listdir(folder):
62
+ # os.remove(os.path.join(folder,filename))
63
+ # rename this file to filename + _old
64
+ os.rename(os.path.join(folder,filename),os.path.join(folder,filename+"_old"))
65
+ return {"status":"success"}
66
+
67
+
68
+ return "did nothing..."
69
+ # return render_template('upload.html')
70
+
71
+
72
+ if __name__ == '__main__':
73
+ app.run(debug=True, port=5100)
uploader/uploads/.DS_Store ADDED
Binary file (8.2 kB). View file
 
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/LambWestonBrand.csv ADDED
The diff for this file is too large to render. See raw diff
 
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/LambWestonNews.csv ADDED
The diff for this file is too large to render. See raw diff
 
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9aa8b4dc58d1ebfd732922d8ff5b894be8f56af223d9636b01f3d5490b3bdb91
3
+ size 11523457
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.csvExecutive Summary_CACHE.txt_old ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Common and Hot Topics in Tourism Blog Posts
3
+
4
+ The blog posts in the data corpus reveal a number of common and hot topics related to tourism. These topics include rebranding of tourist products, the impact of technology on the tourism industry, the importance of customer experience, and the need for sustainable tourism practices.
5
+
6
+ ## Rebranding of Tourist Products
7
+
8
+ The blog posts discuss the importance of rebranding tourist products in order to make them more attractive to customers. For example, one post discusses the proposed rebrand of the mozzarella stick design, with the aim of making the product the best on the planet. Joe audibly moaned in approval of the new design, suggesting that the brand will be beautiful. This example illustrates the potential of rebranding to create a more attractive product that customers will be drawn to.
9
+
10
+ ## Impact of Technology on the Tourism Industry
11
+
12
+ The blog posts also discuss the impact of technology on the tourism industry. Technology has revolutionized the way that tourists plan and book their trips, with many now opting to use online booking platforms and apps. This has had a significant impact on the industry, with travel agencies having to adapt their services to meet the needs of tech-savvy customers.
13
+
14
+ ## The Importance of Customer Experience
15
+
16
+ The blog posts also emphasize the importance of customer experience in the tourism industry. Customers are increasingly looking for a personalized and unique experience when they travel, and travel agencies must be able to provide this in order to stay competitive. This means that travel agencies must be able to provide a range of services and amenities that cater to the needs of their customers.
17
+
18
+ ## The Need for Sustainable Tourism Practices
19
+
20
+ Finally, the blog posts discuss the need for sustainable tourism practices. Sustainable tourism is becoming increasingly important in the industry, as tourists are looking for ways to reduce their environmental impact when they travel. This means that travel agencies must be aware of the environmental impact of their services and strive to reduce their carbon footprint.
21
+
22
+ # Key Trends in Tourism: Implications for Tourists and the Industry
23
+
24
+ The blog posts reveal a number of key trends in the tourism industry that have implications for tourists and the industry as a whole. These trends include the increasing importance of technology, the need for personalized customer experiences, and the need for sustainable tourism practices.
25
+
26
+ ## Increasing Importance of Technology
27
+
28
+ The blog posts reveal that technology is playing an increasingly important role in the tourism industry. Technology has revolutionized the way that tourists plan and book their trips, with many now opting to use online booking platforms and apps. This has had a significant impact on the industry, with travel agencies having to adapt their services to meet the needs of tech-savvy customers.
29
+
30
+ ## Need for Personalized Customer Experiences
31
+
32
+ The blog posts also emphasize the importance of providing personalized customer experiences in the tourism industry. Customers are increasingly looking for a unique and personalized experience when they travel, and travel agencies must be able to provide this in order to stay competitive. This means that travel agencies must be able to provide a range of services and amenities that cater to the needs of their customers.
33
+
34
+ ## Need for Sustainable Tourism Practices
35
+
36
+ Finally, the blog posts discuss the need for sustainable tourism practices. Sustainable tourism is becoming increasingly important in the industry, as tourists are looking for ways to reduce their environmental impact when they travel. This means that travel agencies must be aware of the environmental impact of their services and strive to reduce their carbon footprint.
37
+
38
+ # Observations and Key Findings from Tourism Blog Posts
39
+
40
+ The blog posts in the data corpus reveal a number of common and hot topics related to tourism, as well as key trends that have implications for tourists and the industry as a whole.
41
+
42
+ ## Common and Hot Topics
43
+
44
+ The blog posts discuss a number of common and hot topics related to tourism. These topics include rebranding of tourist products, the impact of technology on the tourism industry, the importance of customer experience, and the need for sustainable tourism practices.
45
+
46
+ ## Key Trends
47
+
48
+ The blog posts also reveal a number of key trends in the tourism industry that have implications for tourists and the industry as a whole. These trends include the increasing importance of technology, the need for personalized customer experiences, and the need for sustainable tourism practices.
49
+
50
+ # Takeaways and Recommendations for Future Tourism Practices
51
+
52
+ The analysis of the blog posts in the data corpus reveals a number of key takeaways and recommendations for future tourism practices.
53
+
54
+ ## Takeaways
55
+
56
+ The blog posts reveal that technology is playing an increasingly important role in the tourism industry, and travel agencies must be able to adapt their services to meet the needs of tech-savvy customers. Additionally, customers are increasingly looking for a personalized and unique experience when they travel, and travel agencies must be able to provide this in order to stay competitive. Finally, sustainable tourism practices are becoming increasingly important in
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cbd0f153cc9defd4bcafda2fc05bb70eda04dfb112b78cff8c6e69629b0c9ffa
3
+ size 4441676
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/MozzarellaTW.xlsxExecutive Summary_CACHE.txt ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Executive Summary: Revolutionizing the Mozzarella Stick Industry
2
+
3
+ ## The Mozzarella Stick Rebranding Phenomenon
4
+
5
+ A groundbreaking rebranding of the mozzarella stick design has been proposed, aiming to create the best mozzarella stick on the planet. This innovative design has been met with overwhelmingly positive reactions, with Joe audibly moaning in appreciation. The brandmark has been updated to reflect this new design, signifying a significant shift in the industry.
6
+
7
+ ### Key Trends and Patterns
8
+
9
+ - A surge in consumer interest for unique and innovative food products
10
+ - Increasing demand for high-quality, gourmet mozzarella sticks
11
+ - The power of rebranding in capturing consumer attention and driving sales
12
+
13
+ ## Implications and Opportunities for the Industry
14
+
15
+ The mozzarella stick rebranding presents a plethora of opportunities for industry players, including:
16
+
17
+ - Capitalizing on the growing consumer interest in innovative food products
18
+ - Differentiating their offerings from competitors through unique designs and flavors
19
+ - Enhancing brand image and recognition through strategic rebranding efforts
20
+
21
+ However, it is crucial to consider the challenges and needs of the industry, such as:
22
+
23
+ - Ensuring consistent product quality and taste across different markets
24
+ - Adapting to varying consumer preferences and cultural nuances
25
+ - Managing potential supply chain disruptions and ingredient sourcing issues
26
+
27
+ ## Cultural, Social, and Contextual Nuances
28
+
29
+ As an expert sociologist, it is essential to recognize the cultural, social, and contextual factors that may impact the success of the rebranded mozzarella stick. These include:
30
+
31
+ - The role of social media in driving food trends and consumer preferences
32
+ - The influence of local culinary traditions and tastes on product acceptance
33
+ - The importance of sustainability and ethical sourcing in consumer decision-making
34
+
35
+ ## Potential Risks and Challenges
36
+
37
+ The rebranding of the mozzarella stick may present certain risks and challenges, such as:
38
+
39
+ - Resistance from traditionalists who prefer classic mozzarella stick designs
40
+ - Potential backlash from consumers who perceive the rebranding as a gimmick
41
+ - Difficulties in maintaining product consistency and quality during rapid expansion
42
+
43
+ ### Strategic Recommendations
44
+
45
+ To mitigate these risks and challenges, industry players should:
46
+
47
+ - Conduct thorough market research to understand consumer preferences and cultural nuances
48
+ - Engage in transparent communication and marketing efforts to convey the value of the rebranding
49
+ - Implement robust quality control measures to ensure product consistency and excellence
50
+
51
+ ## Key Takeaways
52
+
53
+ - The mozzarella stick rebranding presents a significant opportunity for industry players to capitalize on growing consumer interest in innovative food products
54
+ - Understanding and adapting to cultural, social, and contextual nuances is crucial for success in diverse markets
55
+ - Addressing potential risks and challenges through strategic planning and execution will ensure the rebranded mozzarella stick remains a game-changer in the industry
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/OnionTW.csv ADDED
The diff for this file is too large to render. See raw diff
 
uploader/uploads/a1b1e9ca-7d76-4663-b48c-12f284304475/OnionTW.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9ba6fba9469a2cc812e2b0a856e40f22369dee64293d6a28fff8302ba416d1c1
3
+ size 3829500
uploader/uploads/demo/LambWestonBrand.csv ADDED
The diff for this file is too large to render. See raw diff
 
uploader/uploads/demo/LambWestonBrand.csvExecutive Summary_CACHE.txt ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Executive Summary: Consumer Goods Industry Insights and Opportunities
2
+
3
+ ## Key Trends and Patterns in Earnings Reports
4
+
5
+ A thorough analysis of earnings reports from several consumer goods companies, including Constellation Brands (STZ), Lamb Weston Holdings, Levi Strauss (LEVI), RPM International (RPM), and WDFCToday, reveals the following key trends and patterns:
6
+
7
+ - Strong revenue and EPS beats for Conagra Brands and Lamb Weston last week, indicating a positive outlook for the industry.
8
+ - Anticipated earnings releases for the week of April 2023 include ConAgra, Constellation Brands, Lamb Weston, SAIC, and Acuity Brands (AYI).
9
+ - Introduction of Maliha Subhani as the Director of Sales for Asia at Lamb Weston, signaling the company's focus on expanding its presence in the region.
10
+ - Launch of Lamb Weston's Super Crispy Tots product, showcasing the company's commitment to innovation and meeting consumer demands.
11
+
12
+ ## Implications and Opportunities for the Industry
13
+
14
+ Considering the needs and challenges of the consumer goods industry, the following implications and opportunities can be derived from the data:
15
+
16
+ - **Expansion in Asia**: The appointment of Maliha Subhani as the Director of Sales for Asia at Lamb Weston highlights the potential for growth in the region. Companies should consider exploring opportunities to expand their presence in Asia to capitalize on this potential.
17
+ - **Innovation and Product Development**: The launch of Lamb Weston's Super Crispy Tots product demonstrates the importance of innovation and meeting consumer demands. Companies should invest in research and development to create new products that cater to evolving consumer preferences.
18
+ - **Strategic Partnerships**: Discounts available on brands such as Lamb Weston, Meatless Farm, Tilda, and Quorn suggest the possibility of strategic partnerships and collaborations. Companies should explore opportunities to work together to drive growth and create value for consumers.
19
+
20
+ ## Cultural, Social, and Contextual Nuances
21
+
22
+ To ensure the relevance and insightfulness of this analysis across diverse audiences, the following cultural, social, and contextual nuances have been considered:
23
+
24
+ - **Cultural Sensitivity**: Companies should be mindful of cultural differences when expanding into new markets, particularly in Asia. Tailoring products and marketing strategies to suit local tastes and preferences will be crucial for success.
25
+ - **Sustainability and Health**: As consumers become increasingly conscious of the environmental and health impacts of their choices, companies should prioritize sustainability and health in their product offerings and business practices.
26
+ - **Economic Factors**: The ongoing global economic recovery may impact consumer spending patterns. Companies should monitor economic indicators and adjust their strategies accordingly to remain competitive.
27
+
28
+ ## Potential Risks and Challenges
29
+
30
+ The following potential risks and challenges have been identified, along with strategic recommendations for mitigating these issues:
31
+
32
+ - **Supply Chain Disruptions**: Ongoing global supply chain challenges may impact the availability and cost of raw materials. Companies should diversify their supply chains and invest in technology to improve efficiency and reduce the risk of disruptions.
33
+ - **Regulatory Changes**: Changes in regulations and trade policies may affect the consumer goods industry. Companies should stay informed about relevant policy changes and adapt their strategies accordingly.
34
+ - **Competitive Landscape**: The consumer goods industry is highly competitive, with new entrants and disruptive technologies constantly emerging. Companies should invest in innovation and strategic partnerships to maintain a competitive edge.
35
+
36
+ ## Key Takeaways
37
+
38
+ - Strong earnings reports and anticipated releases indicate a positive outlook for the consumer goods industry.
39
+ - Opportunities for growth and innovation include expansion in Asia, product development, and strategic partnerships.
40
+ - Companies should consider cultural, social, and contextual nuances when crafting strategies and entering new markets.
41
+ - Potential risks and challenges include supply chain disruptions, regulatory changes, and a competitive landscape. Companies should invest in innovation, diversify supply chains, and stay informed about policy changes to mitigate these risks.
uploader/uploads/demo/MozzarellaTW.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cbd0f153cc9defd4bcafda2fc05bb70eda04dfb112b78cff8c6e69629b0c9ffa
3
+ size 4441676
uploader/uploads/demo/MozzarellaTW.xlsxdf3.csv ADDED
@@ -0,0 +1,442 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ x,y,z,cluster_number,cluster_name_str,trimmed_text,gpt_cluster
2
+ 10.601388,4.2817106,14.682537,5,like-look-looked-kinda,7953 Ong look like mozzarella stick,Mozzarella Stick Comparisons
3
+ 12.674002,6.303694,15.591997,4,like-good-eat-cheese,good mozzarella stick gona get every time,Mozzarella Stick Eating and Reviews
4
+ 12.60497,5.406012,16.470526,3,like-cheese-good-lol,sleepily warms mozzarella stick,Mozzarella Stick Obsession
5
+ 8.510767,7.263887,14.593172,1,face-joy-stick-joyface,Completely sane normal smiling face tear,Mozzarella Stick Joy.
6
+ 11.486528,5.7899384,14.661182,4,like-good-eat-cheese,love child build like mozzarella stick like soft still stick,Mozzarella Stick Eating and Reviews
7
+ 13.1321125,6.283302,16.597675,3,like-cheese-good-lol,Tryna lay White Castle mozzarella stick tasting mid day crazy,Mozzarella Stick Obsession
8
+ 9.55976,9.142235,14.67928,6,stick-face-loudly-faceloudly,Telling someone add cheese mozzarella stick make taste better absolutely absurd loudly cry faceloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
9
+ 12.054619,6.0084534,14.176854,4,like-good-eat-cheese,first mozzarella stick ever day great invention,Mozzarella Stick Eating and Reviews
10
+ 10.196211,4.705156,15.372414,5,like-look-looked-kinda,She look like mozzarella stick got put inside bag hot fry,Mozzarella Stick Comparisons
11
+ 14.949425,6.4882936,15.763675,0,cheese-lol-like-time,twizzlers mozzarella stick head week help,Mozzarella Stick Obsession
12
+ 13.248773,6.0689287,14.466486,4,like-good-eat-cheese,3njoyer idk mozzarella stick,Mozzarella Stick Eating and Reviews
13
+ 9.165916,7.3798456,14.733141,1,face-joy-stick-joyface,mattyr Obviously half mozzarella stick brekkie lad yea face tear joy,Mozzarella Stick Joy.
14
+ 12.651443,6.576064,14.746434,4,like-good-eat-cheese,woken maccies burger rapper bed half mozzarella stick inside Don even remember going maccies,Mozzarella Stick Eating and Reviews
15
+ 13.667232,6.7981696,15.831126,0,cheese-lol-like-time,put mozzarella stick tortilla got feeling like flipped switch,Mozzarella Stick Obsession
16
+ 10.207368,4.6932235,15.798386,5,like-look-looked-kinda,Bro She look like dehydrated mozzarella stick brushed Old Bay seasoning You living life correctly,Mozzarella Stick Comparisons
17
+ 9.684032,9.304138,14.791315,6,stick-face-loudly-faceloudly,burger big mozzarella stick patty thing good loudly cry face,Mozzarella Stick Complaints and Experiences
18
+ 11.215096,6.023473,15.081404,4,like-good-eat-cheese,Walt Brigitte sharing mozzarella stick Lady,Mozzarella Stick Eating and Reviews
19
+ 9.608759,7.1918297,14.736943,1,face-joy-stick-joyface,They got mozzarella stick dinner pick face tear joy,Mozzarella Stick Joy.
20
+ 10.414513,8.650654,14.603575,6,stick-face-loudly-faceloudly,best ive ever done bloodhound lmfao someone say youre proud,Mozzarella Stick Complaints and Experiences
21
+ 12.076197,8.139711,16.38829,2,face-weary-open-craving,wake every day dying cheeky mozzarella stick actual addiction tbh,Mozzarella Stick Cravings
22
+ 10.575868,4.299484,14.845252,5,like-look-looked-kinda,Ooh kinda look like tater tot mozzarella stick hybrid,Mozzarella Stick Comparisons
23
+ 13.618223,6.7552447,16.80607,3,like-cheese-good-lol,You make bite mozzarella stick make point,Mozzarella Stick Obsession
24
+ 12.875819,6.9482102,16.068165,4,like-good-eat-cheese,You never truly lived unless driven stick holding mozzarella stick drink would need enough cup holder,Mozzarella Stick Eating and Reviews
25
+ 12.803218,6.8789344,15.137978,4,like-good-eat-cheese,The guy gas station must patience saint idk many time could watch girl look back item store settle mozzarella cheese stick diet soda EVERY TIME asked wtf wrong,Mozzarella Stick Eating and Reviews
26
+ 10.496923,9.540256,14.444525,6,stick-face-loudly-faceloudly,way pushed jungwoo onto bed stretched like stick mozzarella loudly cry face giving capital punishment skull,Mozzarella Stick Complaints and Experiences
27
+ 14.194015,7.296956,15.782804,0,cheese-lol-like-time,Someone give fuching mozzarella stick,Mozzarella Stick Obsession
28
+ 12.74159,6.6890316,17.020506,4,like-good-eat-cheese,tbh ive never mozzarella stick,Mozzarella Stick Eating and Reviews
29
+ 10.538123,8.050993,17.184637,2,face-weary-open-craving,horizon busy mozzarella stick weary face,Mozzarella Stick Cravings
30
+ 10.827337,7.799086,16.970392,2,face-weary-open-craving,giant mozzarella stick today flushed face,Mozzarella Stick Cravings
31
+ 12.769217,6.809624,16.497969,4,like-good-eat-cheese,Ima turn mozzarella stick eat one They good tho,Mozzarella Stick Eating and Reviews
32
+ 13.315523,5.0757875,16.17442,3,like-cheese-good-lol,trade Schoop mozzarella stick Doesn even warm Doesn even date good local cheese,Mozzarella Stick Obsession
33
+ 12.48091,6.1669173,15.760283,4,like-good-eat-cheese,boyo NOT invent mozzarella stick,Mozzarella Stick Eating and Reviews
34
+ 9.596663,9.129283,14.604329,6,stick-face-loudly-faceloudly,ramble YEAH LIKE even support loudly cry face wait time support minute lmfao,Mozzarella Stick Complaints and Experiences
35
+ 12.482208,5.7480245,14.435136,4,like-good-eat-cheese,good vegan mozzarella stick yet,Mozzarella Stick Eating and Reviews
36
+ 13.798757,6.816889,16.030554,0,cheese-lol-like-time,guess trying mozzarella stick first time,Mozzarella Stick Obsession
37
+ 12.366557,6.460415,14.626819,4,like-good-eat-cheese,going manifest biggest mozzarella stick,Mozzarella Stick Eating and Reviews
38
+ 10.258071,9.4137535,14.837922,6,stick-face-loudly-faceloudly,ate mozzarella stick ready drink loudly cry face,Mozzarella Stick Complaints and Experiences
39
+ 12.276139,6.3942857,14.716327,4,like-good-eat-cheese,son carry around item get attached Sometimes mozzarella stick sometimes little red car sometimes big purple bear Today little blue egg,Mozzarella Stick Eating and Reviews
40
+ 11.80491,5.432448,16.681131,3,like-cheese-good-lol,feel gooey like inside mozzarella stick,Mozzarella Stick Obsession
41
+ 11.677635,7.9272017,16.38501,2,face-weary-open-craving,French people literally shove whole block cheese make proper mozzarella stick wtfff weary facesmiling face tear,Mozzarella Stick Cravings
42
+ 12.566497,5.524954,15.776088,4,like-good-eat-cheese,And ice cream mozzarella stick ranch,Mozzarella Stick Eating and Reviews
43
+ 14.495453,6.213545,15.750951,0,cheese-lol-like-time,mozzarella stick person made mozzarella stick stick mozzarella,Mozzarella Stick Obsession
44
+ 10.961872,9.351929,14.581344,6,stick-face-loudly-faceloudly,first still time Went open passenger door father car school Bothered resting angry bee chased around car finally stung index finger Blew like mozzarella stick,Mozzarella Stick Complaints and Experiences
45
+ 10.988599,4.3414726,14.706048,5,like-look-looked-kinda,Vos And loaf look like mozzarella stick,Mozzarella Stick Comparisons
46
+ 13.668172,5.787908,15.3218975,0,cheese-lol-like-time,Dude flip mozzarella stick around air wildly spatula launching perfectly breast pocket,Mozzarella Stick Obsession
47
+ 11.666385,5.8033257,15.067404,4,like-good-eat-cheese,Bernico good mozzarella stick make feel warm happy inside friending basket empty bad mozzarella stick get one bite leave basket full This Ska Choose good ska,Mozzarella Stick Eating and Reviews
48
+ 11.385306,7.3844028,16.45702,2,face-weary-open-craving,SeX Great And All BUT Have You Ever Had The LaSt Mozzarella Stick winking face,Mozzarella Stick Cravings
49
+ 13.816421,5.385023,15.440541,0,cheese-lol-like-time,Also ocean mozzarella stick electrical socket allergy tree many name,Mozzarella Stick Obsession
50
+ 12.144129,5.8223867,14.367009,4,like-good-eat-cheese,Idk invented mozzarella stick whoever deserves award sort Like Nobel Prize food CashApp j2thehayes,Mozzarella Stick Eating and Reviews
51
+ 12.813699,5.4720626,16.245129,3,like-cheese-good-lol,look silly happily turn arm mozzarella cheese stick,Mozzarella Stick Obsession
52
+ 14.324949,7.001719,15.743855,0,cheese-lol-like-time,taking every last mozzarella stick booking room,Mozzarella Stick Obsession
53
+ 10.443889,7.2904344,16.97139,2,face-weary-open-craving,Not almost mozzarella stick death pensive face,Mozzarella Stick Cravings
54
+ 10.507783,7.5771894,17.39821,2,face-weary-open-craving,You mozzarella stick flushed faceflushed face,Mozzarella Stick Cravings
55
+ 11.415047,7.8187485,16.368183,2,face-weary-open-craving,migraine bad post migraine mozzarella stick craving nowhere neighborhood get decent takeout mozzarella stick arguably worse,Mozzarella Stick Cravings
56
+ 14.012119,5.7187057,13.862689,4,like-good-eat-cheese,Would like try mozzarella stick,Mozzarella Stick Eating and Reviews
57
+ 13.558875,6.7703886,15.115309,0,cheese-lol-like-time,san pls let feed mozzarella stick,Mozzarella Stick Obsession
58
+ 12.9840355,6.856848,16.17978,4,like-good-eat-cheese,period stomach either want baby mozzarella stick boyfriend give either,Mozzarella Stick Eating and Reviews
59
+ 13.918937,7.040508,15.176536,4,like-good-eat-cheese,mozzarella stick would need mouth,Mozzarella Stick Eating and Reviews
60
+ 10.378773,7.5596213,16.453169,2,face-weary-open-craving,arcy mozzarella stick pleading face,Mozzarella Stick Cravings
61
+ 9.786673,8.995872,15.407417,6,stick-face-loudly-faceloudly,Keep cry get surgery imitate poc feature stick pasty mozzarella toned skin paper thin lip pls,Mozzarella Stick Complaints and Experiences
62
+ 11.622106,5.237876,14.930343,4,like-good-eat-cheese,They player left Little man Blum collective raised enough cover one mozzarella stick table,Mozzarella Stick Eating and Reviews
63
+ 12.158679,6.9651527,15.946519,4,like-good-eat-cheese,EAT MOZZARELLA STICKS LOVE,Mozzarella Stick Eating and Reviews
64
+ 9.222862,7.102976,15.221968,1,face-joy-stick-joyface,hahahaha ako craving cheese wonton cheese stick mozzarella stick face holding back tear,Mozzarella Stick Joy.
65
+ 10.71442,7.887321,16.935947,2,face-weary-open-craving,Craving big mozzarella stick fair weary face,Mozzarella Stick Cravings
66
+ 12.076472,5.1086082,16.532736,3,like-cheese-good-lol,give mozzarella stick vibe like feel like ripped open bbokari expecially would cheesy,Mozzarella Stick Obsession
67
+ 12.607087,6.4661884,14.075985,4,like-good-eat-cheese,made Mozzarella stick party tonight,Mozzarella Stick Eating and Reviews
68
+ 11.831888,5.1279297,14.964163,4,like-good-eat-cheese,great beef cheddar usurper throne almighty behemoth beef mozzarella stick mephistopheles may five buck,Mozzarella Stick Eating and Reviews
69
+ 11.804975,4.976054,16.468603,3,like-cheese-good-lol,got cheesy mozzarella stick want taste,Mozzarella Stick Obsession
70
+ 11.6595335,5.6028605,16.544712,3,like-cheese-good-lol,emma doe mozzarella stick taste like much,Mozzarella Stick Obsession
71
+ 10.981829,4.8258963,15.687721,5,like-look-looked-kinda,bro melty bit best tbh personally make army material outside melty bit inside like mozzarella stick,Mozzarella Stick Comparisons
72
+ 13.486906,5.2311206,14.755567,0,cheese-lol-like-time,Canadian tire tire shop And party city party store Lol looking find get mozzarella stick flavor one,Mozzarella Stick Obsession
73
+ 14.464574,5.959486,15.554586,0,cheese-lol-like-time,stick mozzarella stick Dustin,Mozzarella Stick Obsession
74
+ 13.295784,5.359808,16.159615,3,like-cheese-good-lol,want mozzarella cheese stick bad lol,Mozzarella Stick Obsession
75
+ 11.844396,6.438035,15.435332,4,like-good-eat-cheese,mozzarella hmm green glow stick also stick insect Uhhhh 4AM morning like glittery eye makeup,Mozzarella Stick Eating and Reviews
76
+ 13.1616125,6.638763,17.194172,4,like-good-eat-cheese,mozzarella stick would never dirty like,Mozzarella Stick Eating and Reviews
77
+ 10.53363,8.751508,15.060271,6,stick-face-loudly-faceloudly,mozzarella stick right right would cry,Mozzarella Stick Complaints and Experiences
78
+ 14.353954,6.8411827,15.98847,0,cheese-lol-like-time,sacrifice every one mozzarella cheese stick,Mozzarella Stick Obsession
79
+ 9.564434,7.485158,15.707627,1,face-joy-stick-joyface,WAOOUGHH MALO THANK MUCH sparkling heartgrowing heartbeating heartsparkling heartsparkling heartheart arrowsparkling heartgrowing heartbeating heart little skrunkly mippy chee,Mozzarella Stick Joy.
80
+ 10.122676,8.541841,14.773873,6,stick-face-loudly-faceloudly,ble one indeed forget mozzarella stick thank really need take loudly cry face,Mozzarella Stick Complaints and Experiences
81
+ 9.426405,9.109606,14.90424,6,stick-face-loudly-faceloudly,Calling mozzarella stick girthy also WILDloudly cry faceloudly cry faceloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
82
+ 12.640336,7.8802257,16.14846,4,like-good-eat-cheese,Not okay ate every mozzarella stick house kinda want,Mozzarella Stick Eating and Reviews
83
+ 12.173888,6.755096,16.399166,4,like-good-eat-cheese,way single mozzarella stick cals like talking breadstick talking inch mozzarella stick hate life,Mozzarella Stick Eating and Reviews
84
+ 12.247188,5.679565,14.711033,4,like-good-eat-cheese,Raisin mozzarella stick hero,Mozzarella Stick Eating and Reviews
85
+ 12.450979,6.0280423,15.019995,4,like-good-eat-cheese,raisin need hear mozzarella stick story tbh,Mozzarella Stick Eating and Reviews
86
+ 13.773242,5.708882,14.909243,0,cheese-lol-like-time,mozzarella stick one hahaha although bag chip probably true try sometime,Mozzarella Stick Obsession
87
+ 13.640983,6.905453,15.785211,0,cheese-lol-like-time,kennedy11 Can wrong mozzarella stick ten,Mozzarella Stick Obsession
88
+ 12.402956,6.7476206,15.922509,4,like-good-eat-cheese,actually bad something must try point Imagine giant mozzarella stick make stop heart,Mozzarella Stick Eating and Reviews
89
+ 10.319719,7.2397714,16.542517,2,face-weary-open-craving,name mozzarella stick nerd face,Mozzarella Stick Cravings
90
+ 14.525049,5.9720373,15.555993,0,cheese-lol-like-time,TEQUE MAMI Venezuelan teque mozzarella stick nonsense use mozzarella filling starter,Mozzarella Stick Obsession
91
+ 12.160584,5.8146515,14.45351,4,like-good-eat-cheese,sheetz mozzarella stick girlie,Mozzarella Stick Eating and Reviews
92
+ 12.864368,5.85315,14.409214,4,like-good-eat-cheese,palmed thickest girthy mozzarella stick life,Mozzarella Stick Eating and Reviews
93
+ 12.99371,6.4378796,16.990225,4,like-good-eat-cheese,anyways hate mozzarella form stick,Mozzarella Stick Eating and Reviews
94
+ 12.439054,6.5595794,16.991388,4,like-good-eat-cheese,Plenty like eating mozzarella stick gone Cole kind string cheese,Mozzarella Stick Eating and Reviews
95
+ 12.5297365,6.3336797,14.759698,4,like-good-eat-cheese,version dipping mozzarella stick salford quay,Mozzarella Stick Eating and Reviews
96
+ 14.548213,6.1630244,15.485773,0,cheese-lol-like-time,Trying Mozzarella Stick,Mozzarella Stick Obsession
97
+ 12.455689,7.5647464,16.259876,4,like-good-eat-cheese,Sense know cheese stick eating mozzarella rest life,Mozzarella Stick Eating and Reviews
98
+ 13.00897,7.1666894,15.895902,4,like-good-eat-cheese,Idk feel like mozzarella stick would fix life,Mozzarella Stick Eating and Reviews
99
+ 10.822873,7.702444,17.06878,2,face-weary-open-craving,throw mozzarella stick face,Mozzarella Stick Cravings
100
+ 12.087104,4.5992417,14.956369,4,like-good-eat-cheese,professional mozzarella stick master Lol But really odd best mozzarella stock pinched fingerscheese wedge Thank brave enough hold end trust hit string cheesecat tear joyface b,Mozzarella Stick Eating and Reviews
101
+ 12.552586,7.0604796,17.061779,4,like-good-eat-cheese,eating yunho mozzarella stick,Mozzarella Stick Eating and Reviews
102
+ 12.186834,6.681551,16.730938,4,like-good-eat-cheese,say mozzarella stick box flip halfway actually lie,Mozzarella Stick Eating and Reviews
103
+ 12.606911,6.810149,15.101587,4,like-good-eat-cheese,Omg mozzarella stick age time,Mozzarella Stick Eating and Reviews
104
+ 12.154149,7.111489,16.046762,4,like-good-eat-cheese,eat mozzarella stick without thinking best friend Like two week passed tried swoop one last one hungry denied wishing gave one like woulda saved Lol,Mozzarella Stick Eating and Reviews
105
+ 12.374387,5.957509,14.100725,4,like-good-eat-cheese,generic modern would mozzarella stick man,Mozzarella Stick Eating and Reviews
106
+ 13.683487,6.4019103,15.153826,0,cheese-lol-like-time,ask hit pen batter taped mozzarella stick lol,Mozzarella Stick Obsession
107
+ 13.802304,5.742704,14.998858,0,cheese-lol-like-time,pretty good job fair enough gotten chocolate flavor taking mozzarella stick dipping cup stick,Mozzarella Stick Obsession
108
+ 9.861013,9.601784,14.787557,6,stick-face-loudly-faceloudly,good actually loudly cry face like big mozzarella stick juss dont like hotdog,Mozzarella Stick Complaints and Experiences
109
+ 9.654525,9.201818,15.040429,6,stick-face-loudly-faceloudly,brought mozzarella stick roux 61loudly cry faceloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
110
+ 8.937693,7.4761057,14.958385,1,face-joy-stick-joyface,This true like mozzarella stick baby dip sauce monster face tear joy,Mozzarella Stick Joy.
111
+ 10.426111,8.831153,15.237028,6,stick-face-loudly-faceloudly,mozzarella stick choke hold yeah def much wtfloudly cry face mozz stick,Mozzarella Stick Complaints and Experiences
112
+ 13.162771,7.127566,16.163961,4,like-good-eat-cheese,would love take bite mozzarella stick sad,Mozzarella Stick Eating and Reviews
113
+ 12.101608,4.6433067,15.071242,4,like-good-eat-cheese,Extra cool look like enjoying mozzarella stick really good pull,Mozzarella Stick Eating and Reviews
114
+ 9.291978,7.115679,14.837192,1,face-joy-stick-joyface,Not mozzarella stick face tear joy,Mozzarella Stick Joy.
115
+ 12.758793,5.782998,14.418477,4,like-good-eat-cheese,lady trled mozzarella stick rainforest cafe,Mozzarella Stick Eating and Reviews
116
+ 13.893956,5.664241,15.361303,0,cheese-lol-like-time,ima make mozzarella stick lol,Mozzarella Stick Obsession
117
+ 12.465482,5.7452426,14.943568,4,like-good-eat-cheese,Garza Hold consider mozzarella stick connoisseur You better lying,Mozzarella Stick Eating and Reviews
118
+ 9.219744,7.330869,15.119167,1,face-joy-stick-joyface,want boneless wing mozzarella stick applebees face exhalingface tear joy,Mozzarella Stick Joy.
119
+ 13.698469,5.768428,15.656414,0,cheese-lol-like-time,gin Mozzarella chaos cheese stick,Mozzarella Stick Obsession
120
+ 12.334047,5.9883776,15.123883,4,like-good-eat-cheese,horizon Cheddar mozzarella going start buy non grated thing grated make stick together might see pepper jack nibble,Mozzarella Stick Eating and Reviews
121
+ 13.572754,7.2904897,15.261465,4,like-good-eat-cheese,god need mozzarella stick mouth RIGHT NOW,Mozzarella Stick Eating and Reviews
122
+ 12.449681,7.8293886,16.04825,4,like-good-eat-cheese,life get bad think eating mozzarella stick nice cheese pull make life lil bearable,Mozzarella Stick Eating and Reviews
123
+ 12.046389,6.139316,15.448545,4,like-good-eat-cheese,mozzarella stick HEY THERE LORENA SaveWarriorNun WarriorNun,Mozzarella Stick Eating and Reviews
124
+ 10.352041,7.3362255,16.073383,2,face-weary-open-craving,Need HER mozzarella Stick drooling facesweat dropletsblack heart,Mozzarella Stick Cravings
125
+ 11.61818,5.735249,14.234834,4,like-good-eat-cheese,love mozzarella stick meal mozzarella stick nail polish,Mozzarella Stick Eating and Reviews
126
+ 10.837106,9.603007,14.854567,6,stick-face-loudly-faceloudly,also choked mozzarella stick broken jaw loudly cry face,Mozzarella Stick Complaints and Experiences
127
+ 10.929848,7.9696155,16.747477,2,face-weary-open-craving,currently craving mozzarella stick weary face,Mozzarella Stick Cravings
128
+ 12.25737,4.6432595,16.248037,3,like-cheese-good-lol,like mozzarella stick wince need,Mozzarella Stick Obsession
129
+ 9.87957,8.691732,15.055147,6,stick-face-loudly-faceloudly,WANT MOZZARELLA STICK NOWloudly cry face,Mozzarella Stick Complaints and Experiences
130
+ 12.1595955,4.487548,16.309948,3,like-cheese-good-lol,Like wing mozzarella stick summ,Mozzarella Stick Obsession
131
+ 11.442499,5.276146,15.172554,4,like-good-eat-cheese,Leslie next time town take Nashua watery beer mozzarella stick leda leave guy behind stick finger oversized ball somewhere else,Mozzarella Stick Eating and Reviews
132
+ 12.075351,5.728996,15.613926,4,like-good-eat-cheese,omg mozz cheese stick earlier good love mozzarella cheese,Mozzarella Stick Eating and Reviews
133
+ 12.162448,5.973302,14.444498,4,like-good-eat-cheese,mozzarella stick sandwich crazy croquetas,Mozzarella Stick Eating and Reviews
134
+ 12.394671,4.799203,15.219257,4,like-good-eat-cheese,Tfw big dummy guess one mozzarella stick,Mozzarella Stick Eating and Reviews
135
+ 14.951647,6.5027947,15.944341,0,cheese-lol-like-time,applying mozzarella stick self love mask first attempting help anyone else,Mozzarella Stick Obsession
136
+ 12.75596,6.650554,15.016608,4,like-good-eat-cheese,waiter What hallucinogen put drink get reality drooling looking mozzarella stick stuck hand ItZ BeAuDaFul,Mozzarella Stick Eating and Reviews
137
+ 10.635011,7.5637846,17.101437,2,face-weary-open-craving,stick mozzarella sticksanxious face sweat,Mozzarella Stick Cravings
138
+ 12.444845,5.377622,14.592596,4,like-good-eat-cheese,This magnificent mozzarella stick,Mozzarella Stick Eating and Reviews
139
+ 12.270698,7.3240576,17.09211,4,like-good-eat-cheese,cant tell stomach hurt cause eat breakfast ate rangoon mozzarella stick two morning,Mozzarella Stick Eating and Reviews
140
+ 8.964405,6.851283,15.043466,1,face-joy-stick-joyface,Tried use mozzarella cheese cheese stick face tear joy All cheese tried escape wrapper face tear joy Anyway merienda human purple heart,Mozzarella Stick Joy.
141
+ 12.706529,6.046629,14.844508,4,like-good-eat-cheese,Now definitely mozzarella stick,Mozzarella Stick Eating and Reviews
142
+ 12.48665,6.4147363,14.151549,4,like-good-eat-cheese,back New York mozzarella stick,Mozzarella Stick Eating and Reviews
143
+ 12.738299,6.417835,16.95165,4,like-good-eat-cheese,wait rin never mozzarella stick,Mozzarella Stick Eating and Reviews
144
+ 8.961543,7.161524,14.444515,1,face-joy-stick-joyface,still going get 5pc mozzarella stick White Castle face tear joyface tear joy,Mozzarella Stick Joy.
145
+ 14.025688,6.5399036,15.789478,0,cheese-lol-like-time,w33b showing mozzarella stick dude cmon one begin,Mozzarella Stick Obsession
146
+ 14.658792,6.757222,15.562706,0,cheese-lol-like-time,bastard Mozzarella stick work,Mozzarella Stick Obsession
147
+ 8.5136795,7.247459,14.658208,1,face-joy-stick-joyface,Fraudulence This boy look like burnt mozzarella stick lmao face tear joyface tear joy,Mozzarella Stick Joy.
148
+ 12.107091,6.7624836,16.127525,4,like-good-eat-cheese,You wake whole family turn mozzarella stick What,Mozzarella Stick Eating and Reviews
149
+ 13.192052,5.198625,14.542953,0,cheese-lol-like-time,parmesan What mozzarella stick,Mozzarella Stick Obsession
150
+ 10.14711,8.951341,14.744168,6,stick-face-loudly-faceloudly,mozzarella stick idea blood opened either thinking facethinking faceloudly cry face,Mozzarella Stick Complaints and Experiences
151
+ 11.6651325,7.921873,17.25915,2,face-weary-open-craving,biting nose like mozzarella stick,Mozzarella Stick Cravings
152
+ 10.25895,8.786031,14.6586685,6,stick-face-loudly-faceloudly,pull white castle 3am mone yeah lem get piece mozzarella stick loudly cry face,Mozzarella Stick Complaints and Experiences
153
+ 10.332988,7.5954256,17.041159,2,face-weary-open-craving,mozzarella stick synonym something elseface raised eyebrow,Mozzarella Stick Cravings
154
+ 13.912585,5.8091917,15.132675,0,cheese-lol-like-time,Cookie butter Speculoos spread Mozzarella Stick,Mozzarella Stick Obsession
155
+ 12.672008,6.761893,15.291948,4,like-good-eat-cheese,grandmother mozzarella stick first time lol,Mozzarella Stick Eating and Reviews
156
+ 9.003716,7.3544064,14.614384,1,face-joy-stick-joyface,Look like eating mozzarella stickface tear joy,Mozzarella Stick Joy.
157
+ 11.660084,4.939891,15.063326,4,like-good-eat-cheese,Niiiiice face savoring food actual piece mozzarella cheesy bread stick type,Mozzarella Stick Eating and Reviews
158
+ 8.804657,7.2457795,14.575678,1,face-joy-stick-joyface,Did guy talk last item tray like last mozzarella stick may need put marriage lineface tear joyface tear joy,Mozzarella Stick Joy.
159
+ 11.1320505,4.587631,15.643378,5,like-look-looked-kinda,Nah mate Looking like mozzarella stick thing You though,Mozzarella Stick Comparisons
160
+ 14.086767,5.559744,15.406055,0,cheese-lol-like-time,Super low effort supper Crockpot Lasagna Bought ragu deli layered pasta ricotta Mozzarella Then stick high let thing hour,Mozzarella Stick Obsession
161
+ 13.025417,5.978731,15.678204,4,like-good-eat-cheese,Call mozzarella way stick real one,Mozzarella Stick Eating and Reviews
162
+ 12.213544,5.290451,16.24133,3,like-cheese-good-lol,Isn mozzarella stick lol,Mozzarella Stick Obsession
163
+ 13.123611,5.588086,15.031539,0,cheese-lol-like-time,Woah Panko Italian mozzarella cheese stick Twix want,Mozzarella Stick Obsession
164
+ 12.348201,6.021973,14.897433,4,like-good-eat-cheese,Brother also mozzarella stick,Mozzarella Stick Eating and Reviews
165
+ 10.95985,6.154604,15.079735,4,like-good-eat-cheese,nice tease small grin Thank goodness starving She bite mozzarella stick,Mozzarella Stick Eating and Reviews
166
+ 10.41712,7.8135176,16.91633,2,face-weary-open-craving,wash mozzarella stick smiling face,Mozzarella Stick Cravings
167
+ 13.733223,5.8727937,15.078589,0,cheese-lol-like-time,get slide calling mozzarella stick PUT RESPECT THE NAME,Mozzarella Stick Obsession
168
+ 8.603155,7.4159083,14.568367,1,face-joy-stick-joyface,aviel Might thought seeing mozzarella stick tweet drawing Laurent thinking commenting art saying mozzarella stick face tear joyface tear joy,Mozzarella Stick Joy.
169
+ 11.515983,5.4906015,15.089205,4,like-good-eat-cheese,Laurent also floppy mozzarella stick comment,Mozzarella Stick Eating and Reviews
170
+ 10.734388,4.223845,15.087711,5,like-look-looked-kinda,Sweetie mozzarella cheese stick look like delish,Mozzarella Stick Comparisons
171
+ 10.2033825,7.738333,17.09928,2,face-weary-open-craving,This mozzarella stick unamused face,Mozzarella Stick Cravings
172
+ 13.581182,5.53076,15.479225,0,cheese-lol-like-time,This Mozzarella stick extra step,Mozzarella Stick Obsession
173
+ 14.068957,6.614673,15.936003,0,cheese-lol-like-time,next time use dynajump clearly wanted tch lighting end mozzarella stick,Mozzarella Stick Obsession
174
+ 12.171384,5.748766,14.04316,4,like-good-eat-cheese,Guess day The latest review local mozzarella stick connoisseur Watch,Mozzarella Stick Eating and Reviews
175
+ 10.424558,7.9765134,16.740301,2,face-weary-open-craving,luv mozzarella stick weary face wish mozzarella stick,Mozzarella Stick Cravings
176
+ 8.807178,7.0617046,14.865393,1,face-joy-stick-joyface,Feirah ordering slider mozzarella stick face tear joyface tear joy,Mozzarella Stick Joy.
177
+ 12.640356,7.6979823,16.40103,4,like-good-eat-cheese,Thats eat one mozzarella stick normally eat,Mozzarella Stick Eating and Reviews
178
+ 12.892452,5.283177,16.351574,3,like-cheese-good-lol,wait lay beach cook like mozzarella stick,Mozzarella Stick Obsession
179
+ 14.6946125,6.6207876,15.906182,0,cheese-lol-like-time,throwing dish ground restaurant one mozzarella stick breading came completely apart cheese ruined last stick perfect,Mozzarella Stick Obsession
180
+ 10.334091,7.383199,15.782007,2,face-weary-open-craving,ready turn someone daughter mozzarella stick smiling face heart,Mozzarella Stick Cravings
181
+ 13.142755,6.236983,15.831635,4,like-good-eat-cheese,Nothing beat good mozzarella stick,Mozzarella Stick Eating and Reviews
182
+ 13.471671,7.2349324,14.522291,4,like-good-eat-cheese,Tryna survive work day red bull mozzarella prosciutto stick,Mozzarella Stick Eating and Reviews
183
+ 13.049555,6.11793,16.355,3,like-cheese-good-lol,made mozzarella stick colored ribbon raise awareness tummy ache,Mozzarella Stick Obsession
184
+ 8.952516,7.667238,14.668776,1,face-joy-stick-joyface,love getting nutted feeling like MOZZARELLA STICK face tear joyface tear joyface tear joyface tear joy,Mozzarella Stick Joy.
185
+ 8.988493,7.0433345,14.721368,1,face-joy-stick-joyface,You going turn mozzarella stick STGGG face tear joy,Mozzarella Stick Joy.
186
+ 12.2038555,4.8290954,16.439537,3,like-cheese-good-lol,yea ive heard scotch egg one reminded mozzarella stick also TYYYY might draw eating huge scotch egg,Mozzarella Stick Obsession
187
+ 8.90885,7.181179,15.050017,1,face-joy-stick-joyface,mozzarella stick end face tear joy,Mozzarella Stick Joy.
188
+ 10.384393,9.218187,14.505645,6,stick-face-loudly-faceloudly,Still thinking livgrace13 said dream gone threw mozzarella stick one rolled eye loudly cry face pretty sure pulled mozzarella stick purse loudly cry face,Mozzarella Stick Complaints and Experiences
189
+ 9.300363,8.749637,14.895863,6,stick-face-loudly-faceloudly,Literally turned fam mozzarella stick barely anythingloudly cry face endgame last personally enjoyable MCU movie,Mozzarella Stick Complaints and Experiences
190
+ 11.976377,6.5482516,13.942371,4,like-good-eat-cheese,Every day time twice The new sandwich week outstanding mozzarella stick gyro thanks sharing need,Mozzarella Stick Eating and Reviews
191
+ 11.59606,5.5258293,13.7579775,4,like-good-eat-cheese,The tournament sponsored mozzarella stick company,Mozzarella Stick Eating and Reviews
192
+ 12.001758,4.9606767,16.64917,3,like-cheese-good-lol,Yeah like like mozzarella stick like child eat,Mozzarella Stick Obsession
193
+ 12.576594,6.926502,16.549555,4,like-good-eat-cheese,eat jalape mozzarella stick guy trap taste bad second time see anyone mozza stick may slap ground stomp though wouldnt half surprised picked back ate standard,Mozzarella Stick Eating and Reviews
194
+ 12.254204,4.552328,16.177061,3,like-cheese-good-lol,Damn stick hard boiled egg mozzarella cheddar cheese protein calcium zinc well nut,Mozzarella Stick Obsession
195
+ 10.196047,9.707287,14.907484,6,stick-face-loudly-faceloudly,anyways went apple bee chicken tender french fry mozzarella stick cup french onion soup stuffed stomach hurt bad loudly cry face,Mozzarella Stick Complaints and Experiences
196
+ 10.1657,6.9221673,15.67927,2,face-weary-open-craving,something dude emotional intelligence overall maturity mozzarella stick smiling face heart eye,Mozzarella Stick Cravings
197
+ 13.120857,7.262309,15.308863,4,like-good-eat-cheese,year old response mozzarella stick greased teenager,Mozzarella Stick Eating and Reviews
198
+ 9.834554,9.19539,14.992889,6,stick-face-loudly-faceloudly,eat mozzarella stick burger cry face,Mozzarella Stick Complaints and Experiences
199
+ 11.237361,5.7181544,15.045591,4,like-good-eat-cheese,mozzarella stick beloved,Mozzarella Stick Eating and Reviews
200
+ 12.483436,6.5347977,14.52645,4,like-good-eat-cheese,Never understood mozzarella stick mozz little flavor Gim gouda stick day,Mozzarella Stick Eating and Reviews
201
+ 12.19541,5.0565414,14.652383,4,like-good-eat-cheese,mozzarella stick You could always tell father snuck dog cheese hellish gas,Mozzarella Stick Eating and Reviews
202
+ 13.150371,7.032898,14.788308,4,like-good-eat-cheese,waiting food lunch CAN THEY HURRY JUST WANT MOZZARELLA STICK,Mozzarella Stick Eating and Reviews
203
+ 10.536975,7.8366966,16.549297,2,face-weary-open-craving,die bsg like extra Mozzarella Stick price winking face,Mozzarella Stick Cravings
204
+ 10.683935,7.938363,16.82285,2,face-weary-open-craving,turn mozzarella stick face rolling eye,Mozzarella Stick Cravings
205
+ 12.292014,6.390025,15.991418,4,like-good-eat-cheese,whenever see double mozzarella stick mean good luck,Mozzarella Stick Eating and Reviews
206
+ 14.637904,6.5728464,15.8200245,0,cheese-lol-like-time,tried threw mozzarella stick want fired,Mozzarella Stick Obsession
207
+ 12.563713,7.505987,16.2065,4,like-good-eat-cheese,eat bone food cannibalistic choked mozzarella stick went veggie hummus,Mozzarella Stick Eating and Reviews
208
+ 11.736055,6.049067,14.016987,4,like-good-eat-cheese,Sry congrats btw Mozzarella stick let,Mozzarella Stick Eating and Reviews
209
+ 13.705942,6.0297594,15.216992,0,cheese-lol-like-time,ZohVT Where mozzarella Where stick,Mozzarella Stick Obsession
210
+ 13.506435,6.4301195,15.004444,0,cheese-lol-like-time,feed Stick MOZZARELLA plz,Mozzarella Stick Obsession
211
+ 13.645197,6.116503,15.692063,0,cheese-lol-like-time,Just Had first ever mozzarella cheese stick,Mozzarella Stick Obsession
212
+ 12.012227,5.632316,14.181362,4,like-good-eat-cheese,Philly mozzarella stick soft Knicks six,Mozzarella Stick Eating and Reviews
213
+ 8.653905,7.5235868,14.671493,1,face-joy-stick-joyface,naptime face tear joyface tear joyskull mean think look like mozzarella stick got wondering thinking face,Mozzarella Stick Joy.
214
+ 9.745369,9.312867,15.043055,6,stick-face-loudly-faceloudly,WHY DOES THE CHEESE THIS VEGAN MOZZARELLA STICK BUST LOAD MOUTH loudly cry faceloudly cry faceloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
215
+ 10.493829,9.004674,15.008483,6,stick-face-loudly-faceloudly,thts crazy ordered burger salad mozzarella stick dessert got donut ona stickloudly cry face,Mozzarella Stick Complaints and Experiences
216
+ 12.977053,4.8413754,16.227425,3,like-cheese-good-lol,Definitely mean like good wing sometimes back got good mozzarella stick pizza combo loving,Mozzarella Stick Obsession
217
+ 12.493502,5.3610597,16.350883,3,like-cheese-good-lol,That emoji anything super picky mozzarella stick quality They give digestive issue anymore though,Mozzarella Stick Obsession
218
+ 13.644636,7.0254283,15.34921,4,like-good-eat-cheese,His breath already growing little heavier lower lip tingling lightly Could always another round One hand let grab another mozzarella stick box holding taking one end teeth,Mozzarella Stick Eating and Reviews
219
+ 8.580833,7.341611,14.480398,1,face-joy-stick-joyface,cry face tear joy Not dipping Rose sauce like Mozzarella Stick rolling floor laughingface tear joywoman facepalming light skin tone,Mozzarella Stick Joy.
220
+ 13.553535,7.8983088,15.1452465,4,like-good-eat-cheese,Think like get lot hate outsider absolutely team together even team New Jersey competitive sibling always going try get last mozzarella stick,Mozzarella Stick Eating and Reviews
221
+ 12.340203,6.152776,15.488326,4,like-good-eat-cheese,Boyyyy shut mozzarella stick,Mozzarella Stick Eating and Reviews
222
+ 10.574167,9.520089,14.944841,6,stick-face-loudly-faceloudly,dynamosa thought big mozzarella stick first grabbing whole fist loudly cry face,Mozzarella Stick Complaints and Experiences
223
+ 10.446807,9.181304,14.645874,6,stick-face-loudly-faceloudly,shooky meal come mozzarella stick REAL THEM loudly cry face,Mozzarella Stick Complaints and Experiences
224
+ 9.554566,9.03076,14.951479,6,stick-face-loudly-faceloudly,trying find mozzarella stick dog month cant find anymore loudly cry faceloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
225
+ 12.944421,5.0209184,15.1738205,0,cheese-lol-like-time,Memories They also mozzarella stick flavor like 2012ish absolute favorite,Mozzarella Stick Obsession
226
+ 10.669198,4.514338,15.182764,5,like-look-looked-kinda,wait jeff look like whole mozzarella stick,Mozzarella Stick Comparisons
227
+ 10.041274,7.589433,17.131676,2,face-weary-open-craving,mad get mozzarella stick face steam nose wonder whole thing felt short unamused face,Mozzarella Stick Cravings
228
+ 13.074642,6.720802,16.867678,4,like-good-eat-cheese,You never outgrow good mozzarella stick,Mozzarella Stick Eating and Reviews
229
+ 13.441485,7.1086187,14.859929,4,like-good-eat-cheese,Stream today shorter hand cam also late shopping Please awkward sneak peek hand perceiving mozzarella stick breakfast,Mozzarella Stick Eating and Reviews
230
+ 10.057072,9.229401,15.239145,6,stick-face-loudly-faceloudly,one thing share paid 400usd mexico day day didnt get mozzarella stick loudly cry faceloudly cry face supposed give,Mozzarella Stick Complaints and Experiences
231
+ 12.911415,6.6786895,15.19651,4,like-good-eat-cheese,Pretty sure son going turn mozzarella stick,Mozzarella Stick Eating and Reviews
232
+ 12.796671,6.377837,14.472195,4,like-good-eat-cheese,Oooh know place talking They got mozzarella option wife like giant mozzarella stick stick SOLD,Mozzarella Stick Eating and Reviews
233
+ 12.007404,4.9697604,16.48563,3,like-cheese-good-lol,Nut make feel like mozzarella stick,Mozzarella Stick Obsession
234
+ 10.795754,7.811504,16.51579,2,face-weary-open-craving,lisalavish Closed guh wanted lil mozzarella stick turned around hungry confused neutral face,Mozzarella Stick Cravings
235
+ 11.6895685,7.52853,16.352436,2,face-weary-open-craving,craving mozzarella stick body calling,Mozzarella Stick Cravings
236
+ 10.592973,8.17257,16.798573,2,face-weary-open-craving,ouuuuu imagine face card decline mozzarella stick day,Mozzarella Stick Cravings
237
+ 11.241714,5.3463726,15.488595,5,like-look-looked-kinda,None whatever Love good mozzarella stick face savoring food,Mozzarella Stick Comparisons
238
+ 10.384354,7.1827126,15.781347,2,face-weary-open-craving,girl precious really one mozzarella stick woozy face,Mozzarella Stick Cravings
239
+ 12.631438,6.542173,16.670122,4,like-good-eat-cheese,How feel eating mozzarella stick white castle,Mozzarella Stick Eating and Reviews
240
+ 11.819935,6.614992,15.266574,4,like-good-eat-cheese,You know good night wake mozzarella stick puke shirt Firm TheBoyIsBack Rippers,Mozzarella Stick Eating and Reviews
241
+ 9.663152,9.484746,14.66327,6,stick-face-loudly-faceloudly,genuinely tell serious loudly cry face pea pur loudly cry faceloudly cry face Cajun fry WHERE Where seasoning time That long mozzarella stick loudly cry face,Mozzarella Stick Complaints and Experiences
242
+ 11.262917,8.037045,17.250238,2,face-weary-open-craving,Higgins71 That mozzarella stick analogy entire dating past weary face,Mozzarella Stick Cravings
243
+ 12.244868,5.342949,14.772912,4,like-good-eat-cheese,mozzarella lmao queso blanco slap Stick poutine,Mozzarella Stick Eating and Reviews
244
+ 12.767195,6.9718018,17.201992,4,like-good-eat-cheese,confess never enjoyed single mozzarella stick entire life,Mozzarella Stick Eating and Reviews
245
+ 10.860457,8.032881,16.583782,2,face-weary-open-craving,feel like mozzarella stick everyone trying strip piece cheese Time face spiral eyesexploding head,Mozzarella Stick Cravings
246
+ 12.223232,6.062563,14.2413845,4,like-good-eat-cheese,absolutely honored single mozzarella stick,Mozzarella Stick Eating and Reviews
247
+ 11.880843,5.546114,13.954546,4,like-good-eat-cheese,moonlight mozzarella stick eyessweat droplet,Mozzarella Stick Eating and Reviews
248
+ 12.49501,7.0377192,16.773245,4,like-good-eat-cheese,strip eat like fried mozzarella stick,Mozzarella Stick Eating and Reviews
249
+ 12.818217,5.7930365,14.612365,4,like-good-eat-cheese,This place foot long mozzarella stick heaven,Mozzarella Stick Eating and Reviews
250
+ 13.151083,6.837525,16.455378,4,like-good-eat-cheese,Anytime Keep mozzarella stick intake,Mozzarella Stick Eating and Reviews
251
+ 14.006521,6.3845787,15.922408,0,cheese-lol-like-time,This appalling And quite frankly take mozzarella derivative stick sun shine,Mozzarella Stick Obsession
252
+ 13.105851,4.977145,16.096514,3,like-cheese-good-lol,mozzarella stick cheese bite frim zaxbys,Mozzarella Stick Obsession
253
+ 14.197053,7.368646,15.566242,0,cheese-lol-like-time,For record potluck box frozen mozzarella stick wrong,Mozzarella Stick Obsession
254
+ 12.522067,7.2132196,15.33188,4,like-good-eat-cheese,may Dietitian But resist good MozzarellaStick The CheesePull everything face tear joy LoveCaregivers CaregiverLife FoodTalk,Mozzarella Stick Eating and Reviews
255
+ 8.747621,7.222372,14.90957,1,face-joy-stick-joyface,face tear joyface tear joy Green Mozzarella Stick,Mozzarella Stick Joy.
256
+ 13.680771,6.1386876,14.984798,0,cheese-lol-like-time,helpp pls tired con crunch want play persona eat mozzarella stick take long Sun,Mozzarella Stick Obsession
257
+ 9.982989,9.043334,14.302875,6,stick-face-loudly-faceloudly,seriously heated pregnant lady How hard stick customer asks Asked plain tender mozzarella stick Received buffalo tender chicken quesadilla instead And ice cream right either l,Mozzarella Stick Complaints and Experiences
258
+ 12.244451,6.6772285,14.67621,4,like-good-eat-cheese,Mozzarella stick Red Robin buddy,Mozzarella Stick Eating and Reviews
259
+ 13.70779,6.6405096,15.920936,0,cheese-lol-like-time,Unless got mozzarella stick earring putting,Mozzarella Stick Obsession
260
+ 12.893258,6.6904426,16.324936,4,like-good-eat-cheese,hazzard god mozzarella stick one accurate,Mozzarella Stick Eating and Reviews
261
+ 10.489524,4.650662,15.513246,5,like-look-looked-kinda,Reggie Bullock hair look like mozzarella stick respect grind,Mozzarella Stick Comparisons
262
+ 13.5451565,5.875955,14.366509,4,like-good-eat-cheese,Top tier mozzarella stick BIGGS,Mozzarella Stick Eating and Reviews
263
+ 13.201709,6.9732027,14.965347,4,like-good-eat-cheese,Nothing like rising mozzarella stick price fire Americans,Mozzarella Stick Eating and Reviews
264
+ 11.707454,5.497051,15.216069,4,like-good-eat-cheese,purple tie dye mozzarella stick,Mozzarella Stick Eating and Reviews
265
+ 11.926461,5.2143073,14.627658,4,like-good-eat-cheese,Daddy little mozzarella stick,Mozzarella Stick Eating and Reviews
266
+ 11.638547,6.030722,14.360427,4,like-good-eat-cheese,really hope bring little mozzarella stick stage,Mozzarella Stick Eating and Reviews
267
+ 10.386862,7.6477933,16.987564,2,face-weary-open-craving,Mozzarella stick pizza drooling face,Mozzarella Stick Cravings
268
+ 13.381949,7.120983,14.788525,4,like-good-eat-cheese,someone PLEASE get singular mozzarella stick begging,Mozzarella Stick Eating and Reviews
269
+ 10.200114,4.4794436,15.743414,5,like-look-looked-kinda,Bruh nose look like mozzarella stick His hair look like washed like five year,Mozzarella Stick Comparisons
270
+ 11.650601,5.2260284,16.601025,3,like-cheese-good-lol,taste like mozzarella stick lol,Mozzarella Stick Obsession
271
+ 13.43939,7.5640416,15.291478,4,like-good-eat-cheese,girl put ketchup mozzarella stick,Mozzarella Stick Eating and Reviews
272
+ 14.311658,6.516852,15.892906,0,cheese-lol-like-time,mozzarella stick would cure,Mozzarella Stick Obsession
273
+ 11.582858,5.9537616,14.753846,4,like-good-eat-cheese,love plush much cant wait til restocks get throw mozzarella stick,Mozzarella Stick Eating and Reviews
274
+ 12.513564,6.351894,16.031116,4,like-good-eat-cheese,Feeling good mozzarella stick chance,Mozzarella Stick Eating and Reviews
275
+ 11.778672,6.6271167,15.329398,4,like-good-eat-cheese,Finn real love Finn hmm someone let last mozzarella stick This kid know true love tender age,Mozzarella Stick Eating and Reviews
276
+ 13.248128,6.349033,15.649614,4,like-good-eat-cheese,whatever save last mozzarella stick,Mozzarella Stick Eating and Reviews
277
+ 13.520054,6.2717814,14.261152,4,like-good-eat-cheese,Portia Gaysa also live The Mozzarella Stick Factory also open Link bio,Mozzarella Stick Eating and Reviews
278
+ 14.385733,7.472102,15.623457,0,cheese-lol-like-time,Woke mozzarella stick stuck back like sticky note friday,Mozzarella Stick Obsession
279
+ 8.796121,7.381704,14.697467,1,face-joy-stick-joyface,Omg mozzarella stick face tear joyface tear joyface tear joyface tear joy,Mozzarella Stick Joy.
280
+ 13.844307,6.226728,15.834192,0,cheese-lol-like-time,frank Grimes time also like mozzarella stick elaborating,Mozzarella Stick Obsession
281
+ 13.465476,6.2947598,16.76694,3,like-cheese-good-lol,stick pizza tomato cheese base would never eat slice bread roast dinner sprinkle grated mozzarella,Mozzarella Stick Obsession
282
+ 13.175552,5.2145686,15.053953,0,cheese-lol-like-time,twix mozzarella stick candy world,Mozzarella Stick Obsession
283
+ 12.867963,6.4838886,15.213788,4,like-good-eat-cheese,Another night another mozzarella stick,Mozzarella Stick Eating and Reviews
284
+ 13.653976,6.54757,16.870838,3,like-cheese-good-lol,Always stick mozzarella,Mozzarella Stick Obsession
285
+ 13.6648445,6.563708,16.77452,3,like-cheese-good-lol,zara believe vision detected put mozzarella stick oven,Mozzarella Stick Obsession
286
+ 14.467126,7.1167526,15.67925,0,cheese-lol-like-time,taking break rerooting clawdeen mozzarella stick family guy time,Mozzarella Stick Obsession
287
+ 8.791022,7.7161727,14.786169,1,face-joy-stick-joyface,Nigga said pause mozzarella stick face tear joyface tear joyloudly cry face,Mozzarella Stick Joy.
288
+ 13.028011,5.504163,15.988945,3,like-cheese-good-lol,They Like better version mozzarella stick,Mozzarella Stick Obsession
289
+ 10.513289,4.370539,14.757266,5,like-look-looked-kinda,kirby angle look like tempura mozzarella stick little booger baby KyoPets,Mozzarella Stick Comparisons
290
+ 13.178394,4.8379674,16.089039,3,like-cheese-good-lol,worker asked type cheese mozzarella stick let weary sigh,Mozzarella Stick Obsession
291
+ 12.438312,7.351532,16.86046,4,like-good-eat-cheese,eating single mozzarella stick yippee hate,Mozzarella Stick Eating and Reviews
292
+ 8.657716,7.092769,14.70633,1,face-joy-stick-joyface,For sure cake giant mozzarella stick face holding back tearssmiling face heart eyesface tear joy,Mozzarella Stick Joy.
293
+ 10.7742405,8.068943,16.852232,2,face-weary-open-craving,Stick making best mozzarella stick planet Leave brand Twitter winking face tongue,Mozzarella Stick Cravings
294
+ 12.9188595,6.2809463,15.526796,4,like-good-eat-cheese,guy guy calm mean mozzarella stick feast,Mozzarella Stick Eating and Reviews
295
+ 11.14535,8.015334,17.09889,2,face-weary-open-craving,Refrying shakey mozzarella stick bec depressing eating hot stretchy persevering face,Mozzarella Stick Cravings
296
+ 10.805969,4.3905134,15.528949,5,like-look-looked-kinda,kinda look like mozzarella cheese stick inside,Mozzarella Stick Comparisons
297
+ 10.481115,9.037912,15.093304,6,stick-face-loudly-faceloudly,actually trust never mozzarella stick loudly cry face,Mozzarella Stick Complaints and Experiences
298
+ 14.276032,5.61355,15.616524,0,cheese-lol-like-time,Mozzarella stick cattail omg The timing would tricky,Mozzarella Stick Obsession
299
+ 12.5591545,6.151658,16.046833,4,like-good-eat-cheese,How feel first mozzarella stick,Mozzarella Stick Eating and Reviews
300
+ 12.3638935,6.3110933,15.159676,4,like-good-eat-cheese,goodnight mozzarella stick,Mozzarella Stick Eating and Reviews
301
+ 13.619466,5.7043405,15.18713,0,cheese-lol-like-time,making cheap charcuterie board mozzarella stick Lol,Mozzarella Stick Obsession
302
+ 13.729335,6.3610315,15.691825,0,cheese-lol-like-time,apart Mozzarella stick LMFAOHDJD,Mozzarella Stick Obsession
303
+ 8.630614,6.974078,14.851088,1,face-joy-stick-joyface,actually essentially mozzarella stick face tear joy bunch different dip add art artist palette,Mozzarella Stick Joy.
304
+ 12.445085,5.3202515,16.206516,3,like-cheese-good-lol,literally watched YouTube vid Indian woman cooking naan topping mozzarella couple day ago bit surprised tbqh Making naan tawa favorite thing kitchen Such fun thing cook mostly,Mozzarella Stick Obsession
305
+ 10.616567,7.64265,17.30593,2,face-weary-open-craving,pizza open face mozzarella stick,Mozzarella Stick Cravings
306
+ 12.415389,7.4736276,16.990862,4,like-good-eat-cheese,Eating mozzarella stick pretending sugar glider eating one cheese bug,Mozzarella Stick Eating and Reviews
307
+ 9.379441,7.686901,14.992707,1,face-joy-stick-joyface,soft creamy inside said like mozzarella stick pancake face tear joy forgot baking powder salt maybe next time could fluffy inside,Mozzarella Stick Joy.
308
+ 12.502786,4.677135,16.139551,3,like-cheese-good-lol,trisha paytas would loved cheese pull got mozzarella stick,Mozzarella Stick Obsession
309
+ 13.680493,6.271569,15.960884,0,cheese-lol-like-time,drink milk haha considered making quick mozzarella give body something chew decided stick milk,Mozzarella Stick Obsession
310
+ 11.247972,8.0118,16.494175,2,face-weary-open-craving,face open eye hand mouth Never truly great mozzarella stick lmao,Mozzarella Stick Cravings
311
+ 12.633391,7.587246,16.75823,4,like-good-eat-cheese,One time bit mozzarella stick hollow saddest thing ever,Mozzarella Stick Eating and Reviews
312
+ 10.471718,7.133245,16.545414,2,face-weary-open-craving,MTbaum Alright doubling villain face anti mozzarella stick era,Mozzarella Stick Cravings
313
+ 9.281925,7.4497256,15.044702,1,face-joy-stick-joyface,This girl whole mozzarella stick talm bout goin face tear joy,Mozzarella Stick Joy.
314
+ 13.413508,6.528356,16.649258,3,like-cheese-good-lol,mozzarella stick dislike dni,Mozzarella Stick Obsession
315
+ 8.975651,7.196413,15.029444,1,face-joy-stick-joyface,Count day world boneless mozzarella stick face steam noseface tear joy,Mozzarella Stick Joy.
316
+ 13.239909,6.0214467,16.21721,3,like-cheese-good-lol,thought mozzarella stick bru still nice SMOKING INTENSIVES,Mozzarella Stick Obsession
317
+ 11.065191,5.7612076,14.81173,4,like-good-eat-cheese,mozzarella stick meatball Hello 10lbs waving hand thanks nyc red heart,Mozzarella Stick Eating and Reviews
318
+ 12.631515,5.940291,15.558219,4,like-good-eat-cheese,chef glad deterred homie away mozz The reasoning eat quickly becomes big cheesesteak mozzarella stick mozz like cement cool,Mozzarella Stick Eating and Reviews
319
+ 10.554789,7.13359,16.899324,2,face-weary-open-craving,bro pea fry single big mozzarella sticksleepy face,Mozzarella Stick Cravings
320
+ 12.800119,7.42697,15.339632,4,like-good-eat-cheese,asked son mozzarella stick gave Then son see eating grab back proceeds shove mouthskull,Mozzarella Stick Eating and Reviews
321
+ 11.858918,4.9219384,16.439865,3,like-cheese-good-lol,Noooo like big mozzarella stick,Mozzarella Stick Obsession
322
+ 12.0736885,4.771497,15.3872,4,like-good-eat-cheese,guess could say mozzarella stick,Mozzarella Stick Eating and Reviews
323
+ 13.478538,6.942923,15.1278105,4,like-good-eat-cheese,seductively stir mozzarella stick,Mozzarella Stick Eating and Reviews
324
+ 11.6397705,5.9983473,15.132565,4,like-good-eat-cheese,love bad mozzarella stick,Mozzarella Stick Eating and Reviews
325
+ 9.412131,8.4527855,14.750026,6,stick-face-loudly-faceloudly,That look like pancake loudly cry face look like large mozzarella stick double exclamation mark,Mozzarella Stick Complaints and Experiences
326
+ 10.639976,4.0793514,15.178422,5,like-look-looked-kinda,thats sausage looked like big mozzarella stick,Mozzarella Stick Comparisons
327
+ 13.636207,5.4463086,13.446321,4,like-good-eat-cheese,Buffalo chicken slider 4pc mozzarella stick plz,Mozzarella Stick Eating and Reviews
328
+ 10.234789,7.7310805,17.325241,2,face-weary-open-craving,This lil boy ate last mozzarella stickenraged faceenraged faceenraged face,Mozzarella Stick Cravings
329
+ 10.98956,7.987486,17.101936,2,face-weary-open-craving,danieIking even mozzarella stick anymore stick frowning face open mouth,Mozzarella Stick Cravings
330
+ 9.441584,9.160431,14.839476,6,stick-face-loudly-faceloudly,BRO cheese mozzarella stickloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
331
+ 10.090464,8.316571,14.89655,6,stick-face-loudly-faceloudly,mozzarella stick phase right Which would perfectly fine gluten free mozzarella stick like box loudly cry face,Mozzarella Stick Complaints and Experiences
332
+ 13.086495,6.1426787,15.552034,4,like-good-eat-cheese,Why Italian Shut eat massive mozzarella stick meatball,Mozzarella Stick Eating and Reviews
333
+ 9.452647,7.401082,14.756758,1,face-joy-stick-joyface,There reason everything She might get mozzarella stick face tear joy,Mozzarella Stick Joy.
334
+ 12.224837,4.923071,14.980139,4,like-good-eat-cheese,incredibly basic All mozzarella sprinkled sugar Essentially giant mozzarella stick,Mozzarella Stick Eating and Reviews
335
+ 12.827364,6.7495894,15.988484,4,like-good-eat-cheese,WQNT SHEETS MOZZARELLA STICK BAD GOD,Mozzarella Stick Eating and Reviews
336
+ 9.049482,6.8385034,14.960887,1,face-joy-stick-joyface,made chocolate chip pancake eating mozzarella cheese stick woman facepalming medium skin tone face tear joy,Mozzarella Stick Joy.
337
+ 11.410453,5.9930425,14.819437,4,like-good-eat-cheese,Pocky kiss mozzarella stick,Mozzarella Stick Eating and Reviews
338
+ 10.796135,4.4436626,15.568192,5,like-look-looked-kinda,doe fozzie look like mozzarella stick,Mozzarella Stick Comparisons
339
+ 11.339062,5.160558,15.943446,5,like-look-looked-kinda,A10 wonder mozzarella stick would taste dipped bacon guac drooling facedrooling facedrooling face avocadoamerican football gno MakeItBetter SBLVII,Mozzarella Stick Comparisons
340
+ 14.000134,6.8317537,15.823874,0,cheese-lol-like-time,half assed workout rewarded mozzarella stick,Mozzarella Stick Obsession
341
+ 13.222546,5.216416,15.022033,0,cheese-lol-like-time,giant mozzarella stick covered potato idk,Mozzarella Stick Obsession
342
+ 12.274955,6.8149366,16.952473,4,like-good-eat-cheese,worry abt ima munching like mozzarella stick,Mozzarella Stick Eating and Reviews
343
+ 12.971869,5.8897576,16.314196,3,like-cheese-good-lol,literally inside fried mozzarella stick When think gooey goodness make perfect sense superior method consumption,Mozzarella Stick Obsession
344
+ 13.775103,5.3464007,13.219884,4,like-good-eat-cheese,Just standing front salad asking mozzarella stick,Mozzarella Stick Eating and Reviews
345
+ 12.463179,6.0166416,14.442752,4,like-good-eat-cheese,keeping light mozzarella stick addiction They great lemonade,Mozzarella Stick Eating and Reviews
346
+ 13.266507,5.4049726,15.28566,0,cheese-lol-like-time,thing fresh mozzarella stick,Mozzarella Stick Obsession
347
+ 10.5940695,8.2454,16.817713,2,face-weary-open-craving,want eat mozzarella stick poutine drooling facedrooling facedrooling face,Mozzarella Stick Cravings
348
+ 8.66621,7.1135607,14.798344,1,face-joy-stick-joyface,Looking like Hot Cheetos mozzarella stick face tear joyface tear joyface hand mouththinking face,Mozzarella Stick Joy.
349
+ 12.58071,5.9636765,15.343946,4,like-good-eat-cheese,dream night nipple length mozzarella stick,Mozzarella Stick Eating and Reviews
350
+ 10.415302,4.6732817,15.177661,5,like-look-looked-kinda,look like bill mitchell mozzarella stick,Mozzarella Stick Comparisons
351
+ 10.456549,7.66441,17.20034,2,face-weary-open-craving,Mozzarella Stick helpercheese wedgesmiling face open hand,Mozzarella Stick Cravings
352
+ 10.662334,4.0307336,14.860127,5,like-look-looked-kinda,Looks like hot cheeto mozzarella stick,Mozzarella Stick Comparisons
353
+ 12.249167,6.0072627,15.657465,4,like-good-eat-cheese,Moser mozzarella stick patty try say word let know feel,Mozzarella Stick Eating and Reviews
354
+ 12.723436,6.5071764,15.882168,4,like-good-eat-cheese,son swears eat cheese eat mozzarella stick scrambled egg cheese,Mozzarella Stick Eating and Reviews
355
+ 12.8918295,5.699068,16.236288,3,like-cheese-good-lol,mozzarella stick Good though,Mozzarella Stick Obsession
356
+ 11.98225,5.877533,14.477103,4,like-good-eat-cheese,sucker nice mozzarella stick,Mozzarella Stick Eating and Reviews
357
+ 10.007917,9.142781,14.616231,6,stick-face-loudly-faceloudly,ngl thing ate mozzarella cheese stick thingies salad salad barloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
358
+ 11.935227,6.916123,15.972349,4,like-good-eat-cheese,Let eat mozzarella stick Lady style sure,Mozzarella Stick Eating and Reviews
359
+ 11.966872,7.0250716,16.311062,4,like-good-eat-cheese,every time think horny like wait horny would rather mozzarella stick time wanted mozzarella stick anyway eating mozzarella stick,Mozzarella Stick Eating and Reviews
360
+ 10.634882,4.4009995,15.204072,5,like-look-looked-kinda,This look like frozen mozzarella stick,Mozzarella Stick Comparisons
361
+ 13.263092,7.1708384,14.553435,4,like-good-eat-cheese,please need find video borzoi mozzarella stick,Mozzarella Stick Eating and Reviews
362
+ 12.651795,5.1580505,16.342194,3,like-cheese-good-lol,basically mozzarella stick tho,Mozzarella Stick Obsession
363
+ 13.326184,5.2397,14.799781,0,cheese-lol-like-time,What mozzarella stick Tryna get appetizer,Mozzarella Stick Obsession
364
+ 12.489026,4.914447,16.365927,3,like-cheese-good-lol,They mozzarella stick fye,Mozzarella Stick Obsession
365
+ 10.404677,9.501126,14.603074,6,stick-face-loudly-faceloudly,kid eat normally loudly cry face always take bite mozzarella stick flip face rolling eye,Mozzarella Stick Complaints and Experiences
366
+ 8.736608,7.153863,14.646384,1,face-joy-stick-joyface,wan make someone walking mozzarella stickface tear joy,Mozzarella Stick Joy.
367
+ 14.180695,7.2739005,15.536469,0,cheese-lol-like-time,girl leave mozzarella stick dough,Mozzarella Stick Obsession
368
+ 12.356445,6.2222714,14.725558,4,like-good-eat-cheese,Mozzarella stick Mozzy,Mozzarella Stick Eating and Reviews
369
+ 11.200993,5.874653,15.153349,4,like-good-eat-cheese,love strong word serious would say love mozzarella stick,Mozzarella Stick Eating and Reviews
370
+ 12.647421,7.088901,15.427005,4,like-good-eat-cheese,Celibacy easy realize balance doe drink Casamigos fruit juice wear thong everyday top letting randoms turn mozzarella stick,Mozzarella Stick Eating and Reviews
371
+ 11.296696,5.0205054,15.815118,5,like-look-looked-kinda,NOT THE MELTED MOZZARELLA STICK BEING DRAWN OVER LMFAO LOVE,Mozzarella Stick Comparisons
372
+ 9.577813,8.946986,14.975281,6,stick-face-loudly-faceloudly,recipe requires mini pepperoni mozzarella stickloudly cry face,Mozzarella Stick Complaints and Experiences
373
+ 12.835332,6.066951,14.423067,4,like-good-eat-cheese,That buttered chicken mozzarella stick last night must drinking beer immaculate,Mozzarella Stick Eating and Reviews
374
+ 10.809172,4.7771745,14.642465,5,like-look-looked-kinda,What mozzarella stick looking thing first pic,Mozzarella Stick Comparisons
375
+ 10.141549,9.511338,15.162959,6,stick-face-loudly-faceloudly,Been dairy free week piece mozzarella stick stomach fire loudly cry faceloudly cry faceface holding back tearsface holding back tearsface holding back tear help plz,Mozzarella Stick Complaints and Experiences
376
+ 12.296711,5.6853857,15.685136,4,like-good-eat-cheese,haha busting chop pal whim best type mozzarella stick,Mozzarella Stick Eating and Reviews
377
+ 12.699079,7.7597156,16.301424,4,like-good-eat-cheese,started period morning Does mean deserve mozzarella stick And yet one Another mother nature cruel punishment,Mozzarella Stick Eating and Reviews
378
+ 12.432896,5.510881,15.569157,4,like-good-eat-cheese,BUT DON AROUND CALLING YOU GIRL YOU ARE SPECIFIC GIRL BRITTNEY MOZZARELLA ALSO SPECIFIC THE MOZZARELLA STICK,Mozzarella Stick Eating and Reviews
379
+ 12.800833,5.0573306,16.225897,3,like-cheese-good-lol,MAN WHY ITS THE MOZZARELLA STICK,Mozzarella Stick Obsession
380
+ 13.330845,5.115695,14.823681,0,cheese-lol-like-time,Not fan removing cheese bite appetizer menu replacement stereotypical mozzarella stick like place,Mozzarella Stick Obsession
381
+ 12.64188,6.958032,15.359523,4,like-good-eat-cheese,This Jup friend opened mozzarella stick saw streeeeetch lmao,Mozzarella Stick Eating and Reviews
382
+ 13.905457,5.2842813,13.361612,4,like-good-eat-cheese,want Cesar salad mozzarella stick parm,Mozzarella Stick Eating and Reviews
383
+ 12.566337,6.3806076,15.8779955,4,like-good-eat-cheese,bar smell like mozzarella stick thank goodnight,Mozzarella Stick Eating and Reviews
384
+ 14.184322,5.8460474,15.418263,0,cheese-lol-like-time,Just tried mozzarella stick first time lol,Mozzarella Stick Obsession
385
+ 10.091812,7.842477,16.925167,2,face-weary-open-craving,What last mozzarella stick thinking facegrimacing faceneutral face,Mozzarella Stick Cravings
386
+ 13.873086,5.8461404,14.1654,4,like-good-eat-cheese,big cup malt beverage Sichuan beef single mozzarella stick,Mozzarella Stick Eating and Reviews
387
+ 13.996554,6.561019,15.646594,0,cheese-lol-like-time,thing hit harder good mozzarella stick,Mozzarella Stick Obsession
388
+ 8.561945,7.4201245,14.540041,1,face-joy-stick-joyface,face tear joyface tear joyface tear joy dude look like burnt mozzarella stick face tear joyface tear joyface tear joy,Mozzarella Stick Joy.
389
+ 9.580184,9.470294,14.41853,6,stick-face-loudly-faceloudly,Nibble nosh loudly cry faceloudly cry face Mozzarella stick solitaire loudly cry faceheart suit,Mozzarella Stick Complaints and Experiences
390
+ 10.634911,7.8160233,17.245726,2,face-weary-open-craving,Mozzarella stick stick weary face,Mozzarella Stick Cravings
391
+ 12.162072,5.4404125,14.769068,4,like-good-eat-cheese,Sudowudo mozzarella stick kid,Mozzarella Stick Eating and Reviews
392
+ 11.017435,4.5951366,15.751215,5,like-look-looked-kinda,Gholdengo look like could peel gold plating reveal tender mozzarella stick underneath,Mozzarella Stick Comparisons
393
+ 13.931996,5.4681954,13.634947,4,like-good-eat-cheese,ordered mozzarella stick sandwich funsies Just mozzarella stick bread finish,Mozzarella Stick Eating and Reviews
394
+ 10.260558,9.243193,15.175461,6,stick-face-loudly-faceloudly,LMFAO fault sapnap make proper mozzarella stick loudly cry face,Mozzarella Stick Complaints and Experiences
395
+ 10.15695,4.702259,15.502274,5,like-look-looked-kinda,She look like mozzarella stick left lunch bag hot day,Mozzarella Stick Comparisons
396
+ 13.656685,7.2815633,15.255045,4,like-good-eat-cheese,eats Cheese stick battle Choose weapon choose mozzarella,Mozzarella Stick Eating and Reviews
397
+ 12.267933,6.614786,14.629168,4,like-good-eat-cheese,mention full mozzarella stick mozzarella stick wednesday guess,Mozzarella Stick Eating and Reviews
398
+ 11.240517,4.9657545,15.676138,5,like-look-looked-kinda,hard imagine mozzarella stick would look like irl,Mozzarella Stick Comparisons
399
+ 12.130938,5.0731554,16.495203,3,like-cheese-good-lol,yes definitely like mozzarella stick mozzarella cheese poptarts hungry cyclone,Mozzarella Stick Obsession
400
+ 11.920494,5.1075573,14.892597,4,like-good-eat-cheese,Steel17 Jets need gap come hop nothing mozzarella stick throwing ball need number throw Then puzzle completed top football world,Mozzarella Stick Eating and Reviews
401
+ 11.093598,4.3948393,15.561805,5,like-look-looked-kinda,natttttttt LMFAO KINDA LOOKS THO BUT ITS JUST MELTED MOZZARELLA STICK,Mozzarella Stick Comparisons
402
+ 13.441419,5.444012,14.947504,0,cheese-lol-like-time,Lifestyle What dinner Get cheesy mozzarella stick lasagna dish Get recipe,Mozzarella Stick Obsession
403
+ 13.603224,5.7105584,15.453608,0,cheese-lol-like-time,Get cheesy mozzarella stick lasagna dish,Mozzarella Stick Obsession
404
+ 12.57655,7.506521,15.480004,4,like-good-eat-cheese,One dream one day enough money Italy eat best expensive mozzarella stick taste bud ever exposed,Mozzarella Stick Eating and Reviews
405
+ 13.900985,6.1958575,14.236359,4,like-good-eat-cheese,want piece mozzarella stick Like real crunchy type,Mozzarella Stick Eating and Reviews
406
+ 13.014634,5.990296,16.284403,3,like-cheese-good-lol,This new improved food pyramid From Danish Mozzarella Stick Does anyone WANT stay SICK FAT,Mozzarella Stick Obsession
407
+ 12.981341,6.466434,15.100999,4,like-good-eat-cheese,anytime Black Mozzarella Stick Not sure feel Kinda cool,Mozzarella Stick Eating and Reviews
408
+ 13.721718,6.106058,15.296128,0,cheese-lol-like-time,Human Mozzarella Stick,Mozzarella Stick Obsession
409
+ 13.468122,6.64042,15.905713,0,cheese-lol-like-time,Call mozzarella way ride around stick,Mozzarella Stick Obsession
410
+ 14.457543,5.7967052,15.469915,0,cheese-lol-like-time,Maybe Clue solution Raspberry Kitchen Mozzarella Stick,Mozzarella Stick Obsession
411
+ 11.783989,5.8560643,14.511867,4,like-good-eat-cheese,mozzarella stick Marcie military Marcie know,Mozzarella Stick Eating and Reviews
412
+ 12.803842,6.6097856,16.801176,4,like-good-eat-cheese,everytime see mozzarella stick think kai,Mozzarella Stick Eating and Reviews
413
+ 9.125401,7.145834,15.299714,1,face-joy-stick-joyface,Cafe Mocha smiling face tear mozzarella stick since,Mozzarella Stick Joy.
414
+ 11.657362,6.113938,14.307407,4,like-good-eat-cheese,Congratulations pending mozzarella stick nuptials,Mozzarella Stick Eating and Reviews
415
+ 10.471476,4.374413,15.595195,5,like-look-looked-kinda,ngl think hair change since wouldve looked like mozzarella stick,Mozzarella Stick Comparisons
416
+ 12.819766,6.417597,16.979471,4,like-good-eat-cheese,stayin stick cuz chasin mozzarella,Mozzarella Stick Eating and Reviews
417
+ 11.918229,6.5677114,14.088743,4,like-good-eat-cheese,like thank making first mozzarella stick year possible Delightful glutenfree,Mozzarella Stick Eating and Reviews
418
+ 9.384695,7.2561264,15.319682,1,face-joy-stick-joyface,love Mozzarella Cheese Sticks wan Mozzarella Cheese Stick face holding back tear,Mozzarella Stick Joy.
419
+ 13.734068,6.112004,15.124437,0,cheese-lol-like-time,First food review year Mozzarella stick big,Mozzarella Stick Obsession
420
+ 11.494103,4.7013655,15.6253395,5,like-look-looked-kinda,feel like cheese mortician unzipping lil cheese body bag opening mozzarella stick,Mozzarella Stick Comparisons
421
+ 12.199591,4.863118,15.088026,4,like-good-eat-cheese,Cheeto mozzarella stick yes dragrace,Mozzarella Stick Eating and Reviews
422
+ 11.898816,5.203333,14.748422,4,like-good-eat-cheese,LOVE MOZZARELLA STICK MUCH DragRace,Mozzarella Stick Eating and Reviews
423
+ 12.902207,5.943791,14.473079,4,like-good-eat-cheese,like first meal day single mozzarella stick warm sprite,Mozzarella Stick Eating and Reviews
424
+ 12.198398,5.59811,15.714002,4,like-good-eat-cheese,stare shake head love mozzarella Just eat warm like cold cheese stick warm cheese insisted hot mozzarella stick store proceeded eat breading leave cheese And ate sideways mozz,Mozzarella Stick Eating and Reviews
425
+ 14.832407,6.6581326,15.432766,0,cheese-lol-like-time,HumbleTeej Fam said give gawk gawk mozzarella stick size forearm wrong,Mozzarella Stick Obsession
426
+ 11.754124,6.3019233,14.0536175,4,like-good-eat-cheese,girlies way monthly pancake mozzarella stick dinner date,Mozzarella Stick Eating and Reviews
427
+ 10.081195,9.067812,14.6578865,6,stick-face-loudly-faceloudly,Tbh think failure restaurant classify mozzarella stick appetizer Like let order mozzarella stick platter meal loudly cry faceloudly cry faceloudly cry face,Mozzarella Stick Complaints and Experiences
428
+ 11.688239,5.5027714,16.6928,3,like-cheese-good-lol,crunchy outside gooey inside like good mozzarella stick,Mozzarella Stick Obsession
429
+ 12.199914,6.5440416,14.277082,4,like-good-eat-cheese,mozzarella stick good one back day,Mozzarella Stick Eating and Reviews
430
+ 12.687185,7.2915635,16.679552,4,like-good-eat-cheese,What kind monster eats mozzarella stick think yes enough,Mozzarella Stick Eating and Reviews
431
+ 12.359677,6.913423,15.90566,4,like-good-eat-cheese,gon shove mozzarella stick local friend,Mozzarella Stick Eating and Reviews
432
+ 10.755765,4.5250297,14.797354,5,like-look-looked-kinda,think look like churro think look like mozzarella stick pizza sauce top still eat though KidsBakingChionship,Mozzarella Stick Comparisons
433
+ 10.887928,4.2045383,14.951165,5,like-look-looked-kinda,may look like mozzarella stick definitely look like meatball,Mozzarella Stick Comparisons
434
+ 12.9122,6.969997,15.189198,4,like-good-eat-cheese,anxious age showing kick flip mozzarella stick,Mozzarella Stick Eating and Reviews
435
+ 14.517357,6.9394784,15.803313,0,cheese-lol-like-time,Mozzarella stick unspeakable,Mozzarella Stick Obsession
436
+ 13.229318,5.103245,16.298847,3,like-cheese-good-lol,almost like bite sized mozzarella stick better,Mozzarella Stick Obsession
437
+ 10.94324,4.229456,14.941517,5,like-look-looked-kinda,looked like fried mozzarella stick,Mozzarella Stick Comparisons
438
+ 13.061536,7.1268578,15.967434,4,like-good-eat-cheese,You mozzarella stick money,Mozzarella Stick Eating and Reviews
439
+ 10.332752,9.330854,15.395826,6,stick-face-loudly-faceloudly,face exhalingface holding back tear shawty speaking sit eat mozzarella stick knowing trainer gone Major Payne weary face,Mozzarella Stick Complaints and Experiences
440
+ 12.465527,5.7149405,14.582392,4,like-good-eat-cheese,First mozzarella stick 2023,Mozzarella Stick Eating and Reviews
441
+ 12.606001,6.0344768,14.16743,4,like-good-eat-cheese,vegan mozzarella stick tower good way end year,Mozzarella Stick Eating and Reviews
442
+ 12.746616,5.9726176,14.641874,4,like-good-eat-cheese,mozzarella stick per minute pace 2023 probably sustained going try HappyNewYear,Mozzarella Stick Eating and Reviews