BlendMMM commited on
Commit
3b48627
·
1 Parent(s): 4651c7e

Upload 73 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 +6 -0
  2. 4_Model_Build_persistant_data.py +714 -0
  3. 7_Build_Response_Curves.py +185 -0
  4. 8_Scenario_Planner.py +464 -0
  5. DB/User.db +0 -0
  6. Data_prep_functions.py +236 -0
  7. Eda_functions.py +172 -0
  8. Full_Logo_Blue.jpeg +0 -0
  9. Full_Logo_Blue.jpg +0 -0
  10. Full_Logo_Blue.png +0 -0
  11. Full_Logo_Vibrant_Turquoise.png +0 -0
  12. Home.py +631 -0
  13. Home_old_version.py +538 -0
  14. Home_redirecting.py +536 -0
  15. LIME_logo.png +0 -0
  16. Media_data_for_model.csv +182 -0
  17. Media_data_for_model_dma_level.csv +538 -0
  18. Model/summary_df.pkl +3 -0
  19. Model_Results_Pretrained.py +349 -0
  20. Overview_data_test.xlsx +0 -0
  21. Overview_data_test_panel@#app_installs.xlsx +0 -0
  22. Overview_data_test_panel@#revenue.xlsx +0 -0
  23. Overview_data_test_panelreplace_meapp_installs.xlsx +0 -0
  24. Pickle_files/category_dict +0 -0
  25. Pickle_files/main_df +3 -0
  26. Scenario.py +338 -0
  27. Test/X_test_tuned_trend.csv +971 -0
  28. Test/X_train_test_tuned_trend.csv +0 -0
  29. Test/X_train_tuned_trend.csv +0 -0
  30. Test/media_data.csv +0 -0
  31. Test/merged_df_contri.csv +0 -0
  32. Test/output_df.csv +29 -0
  33. Test/scenario_test_df.csv +29 -0
  34. Test/x_test_contribution.csv +0 -0
  35. Test/x_test_to_save.csv +0 -0
  36. Test/x_train_contribution.csv +0 -0
  37. Test/x_train_to_save.csv +0 -0
  38. Transformation_functions.py +133 -0
  39. Users/saved_scenarios.pkl +3 -0
  40. classes-gk.py +541 -0
  41. classes.py +541 -0
  42. config.yaml +32 -0
  43. data_test_overview_panel_#total_approved_accounts_appsflyer.xlsx +3 -0
  44. data_test_overview_panel_#total_approved_accounts_revenue.xlsx +0 -0
  45. db_creation.py +98 -0
  46. lime_img.png +0 -0
  47. mastercard_logo.png +0 -0
  48. metrics_level_data/Overview_data_test_panel@#app_installs.xlsx +0 -0
  49. metrics_level_data/Overview_data_test_panel@#revenue.xlsx +0 -0
  50. model_output.csv +6 -0
.gitattributes CHANGED
@@ -33,3 +33,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data_test_overview_panel_\#total_approved_accounts_appsflyer.xlsx filter=lfs diff=lfs merge=lfs -text
37
+ Pickle_files/main_df filter=lfs diff=lfs merge=lfs -text
38
+ raw_data_nov7_combined1.xlsx filter=lfs diff=lfs merge=lfs -text
39
+ upf_data_converted_old.xlsx filter=lfs diff=lfs merge=lfs -text
40
+ upf_data_converted_randomized_resp_metrics.xlsx filter=lfs diff=lfs merge=lfs -text
41
+ upf_data_converted.xlsx filter=lfs diff=lfs merge=lfs -text
4_Model_Build_persistant_data.py ADDED
@@ -0,0 +1,714 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ MMO Build Sprint 3
3
+ additions : adding more variables to session state for saved model : random effect, predicted train & test
4
+
5
+ MMO Build Sprint 4
6
+ additions : ability to run models for different response metrics
7
+ '''
8
+
9
+ import streamlit as st
10
+ import pandas as pd
11
+ import plotly.express as px
12
+ import plotly.graph_objects as go
13
+ from Eda_functions import format_numbers
14
+ import numpy as np
15
+ import pickle
16
+ from st_aggrid import AgGrid
17
+ from st_aggrid import GridOptionsBuilder, GridUpdateMode
18
+ from utilities import set_header, load_local_css
19
+ from st_aggrid import GridOptionsBuilder
20
+ import time
21
+ import itertools
22
+ import statsmodels.api as sm
23
+ import numpy as npc
24
+ import re
25
+ import itertools
26
+ from sklearn.metrics import mean_absolute_error, r2_score, mean_absolute_percentage_error
27
+ from sklearn.preprocessing import MinMaxScaler
28
+ import os
29
+ import matplotlib.pyplot as plt
30
+ from statsmodels.stats.outliers_influence import variance_inflation_factor
31
+
32
+ st.set_option('deprecation.showPyplotGlobalUse', False)
33
+ import statsmodels.api as sm
34
+ import statsmodels.formula.api as smf
35
+
36
+ from datetime import datetime
37
+ import seaborn as sns
38
+ from Data_prep_functions import *
39
+
40
+
41
+ @st.cache_resource(show_spinner=False)
42
+ def save_to_pickle(file_path, final_df):
43
+ # Open the file in write-binary mode and dump the objects
44
+ with open(file_path, "wb") as f:
45
+ pickle.dump({"final_df_transformed": final_df}, f)
46
+
47
+ def get_random_effects(media_data, panel_col, mdf):
48
+ random_eff_df = pd.DataFrame(columns=[panel_col, "random_effect"])
49
+
50
+ for i, market in enumerate(media_data[panel_col].unique()):
51
+ print(i, end='\r')
52
+ intercept = mdf.random_effects[market].values[0]
53
+ random_eff_df.loc[i, 'random_effect'] = intercept
54
+ random_eff_df.loc[i, panel_col] = market
55
+
56
+ return random_eff_df
57
+
58
+
59
+ def mdf_predict(X_df, mdf, random_eff_df):
60
+ X = X_df.copy()
61
+ X['fixed_effect'] = mdf.predict(X)
62
+ X = pd.merge(X, random_eff_df, on=panel_col, how='left')
63
+ X['pred'] = X['fixed_effect'] + X['random_effect']
64
+ # X.to_csv('Test/megred_df.csv',index=False)
65
+ X.drop(columns=['fixed_effect', 'random_effect'], inplace=True)
66
+ return X['pred']
67
+
68
+
69
+ st.set_page_config(
70
+ page_title="Model Build",
71
+ page_icon=":shark:",
72
+ layout="wide",
73
+ initial_sidebar_state='collapsed'
74
+ )
75
+
76
+ load_local_css('styles.css')
77
+ set_header()
78
+
79
+ st.header(pd.__version__)
80
+ st.title('1. Build Your Model')
81
+ with open("data_import.pkl", "rb") as f:
82
+ data = pickle.load(f)
83
+
84
+ st.session_state['bin_dict'] = data["bin_dict"]
85
+
86
+ #st.write(data["bin_dict"])
87
+
88
+ with open("final_df_transformed.pkl", "rb") as f:
89
+ data = pickle.load(f)
90
+
91
+ # Accessing the loaded objects
92
+ media_data = data["final_df_transformed"]
93
+ # Sprint4 - available response metrics is a list of all reponse metrics in the data
94
+ ## these will be put in a drop down
95
+
96
+ st.session_state['media_data']=media_data
97
+
98
+ if 'available_response_metrics' not in st.session_state:
99
+ # st.session_state['available_response_metrics'] = ['Total Approved Accounts - Revenue',
100
+ # 'Total Approved Accounts - Appsflyer',
101
+ # 'Account Requests - Appsflyer',
102
+ # 'App Installs - Appsflyer']
103
+
104
+ st.session_state['available_response_metrics']=st.session_state['bin_dict']["Response Metrics"]
105
+ # Sprint4
106
+ if "is_tuned_model" not in st.session_state:
107
+ st.session_state["is_tuned_model"] = {}
108
+ for resp_metric in st.session_state['available_response_metrics'] :
109
+ resp_metric=resp_metric.lower().replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_")
110
+ st.session_state["is_tuned_model"][resp_metric] = False
111
+
112
+ # Sprint4 - used_response_metrics is a list of resp metrics for which user has created & saved a model
113
+ if 'used_response_metrics' not in st.session_state:
114
+ st.session_state['used_response_metrics'] = []
115
+
116
+ # Sprint4 - saved_model_names
117
+ if 'saved_model_names' not in st.session_state:
118
+ st.session_state['saved_model_names'] = []
119
+
120
+
121
+ if 'Model' not in st.session_state:
122
+ if "session_state_saved" in st.session_state["project_dct"]["model_build"].keys() and \
123
+ st.session_state["project_dct"]["model_build"]['session_state_saved'] is not None and \
124
+ 'Model' in st.session_state["project_dct"]["model_build"]["session_state_saved"].keys():
125
+ st.session_state['Model'] = st.session_state["project_dct"]["model_build"]["session_state_saved"]['Model']
126
+ else:
127
+ st.session_state['Model'] = {}
128
+
129
+ # Sprint4 - select a response metric
130
+ default_target_idx = st.session_state["project_dct"]["model_build"].get("sel_target_col", None) if st.session_state["project_dct"]["model_build"].get("sel_target_col", None) is not None else st.session_state['available_response_metrics'][0]
131
+
132
+ sel_target_col = st.selectbox("Select the response metric",
133
+ st.session_state['available_response_metrics'],
134
+ index=st.session_state['available_response_metrics'].index(default_target_idx))
135
+ # , on_change=reset_save())
136
+ st.session_state["project_dct"]["model_build"]["sel_target_col"] = sel_target_col
137
+
138
+ target_col = sel_target_col.lower().replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_")
139
+ new_name_dct={col:col.lower().replace('.','_').lower().replace('@','_').replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_") for col in media_data.columns}
140
+ media_data.columns=[col.lower().replace('.','_').replace('@','_').replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_") for col in media_data.columns]
141
+ panel_col = [col.lower().replace('.','_').replace('@','_').replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_") for col in st.session_state['bin_dict']['Panel Level 1']][0]# set the panel column
142
+ date_col = 'date'
143
+
144
+ is_panel = True if len(panel_col)>0 else False
145
+
146
+ if 'is_panel' not in st.session_state:
147
+ st.session_state['is_panel']=is_panel
148
+
149
+
150
+ if is_panel :
151
+ media_data.sort_values([date_col, panel_col], inplace=True)
152
+ else :
153
+ media_data.sort_values(date_col, inplace=True)
154
+
155
+ media_data.reset_index(drop=True, inplace=True)
156
+
157
+ date = media_data[date_col]
158
+ st.session_state['date'] = date
159
+ y = media_data[target_col]
160
+
161
+ if is_panel:
162
+ spends_data = media_data[
163
+ [c for c in media_data.columns if "_cost" in c.lower() or "_spend" in c.lower()] + [date_col, panel_col]]
164
+ # Sprint3 - spends for resp curves
165
+ else:
166
+ spends_data = media_data[
167
+ [c for c in media_data.columns if "_cost" in c.lower() or "_spend" in c.lower()] + [date_col]]
168
+
169
+ y = media_data[target_col]
170
+ media_data.drop([date_col], axis=1, inplace=True)
171
+ media_data.reset_index(drop=True, inplace=True)
172
+
173
+
174
+ columns = st.columns(2)
175
+
176
+ old_shape = media_data.shape
177
+
178
+ if "old_shape" not in st.session_state:
179
+ st.session_state['old_shape'] = old_shape
180
+
181
+ if 'media_data' not in st.session_state:
182
+ st.session_state['media_data'] = pd.DataFrame()
183
+
184
+ # Sprint3
185
+ if "orig_media_data" not in st.session_state:
186
+ st.session_state['orig_media_data'] = pd.DataFrame()
187
+
188
+ # Sprint3 additions
189
+ if 'random_effects' not in st.session_state:
190
+ st.session_state['random_effects'] = pd.DataFrame()
191
+ if 'pred_train' not in st.session_state:
192
+ st.session_state['pred_train'] = []
193
+ if 'pred_test' not in st.session_state:
194
+ st.session_state['pred_test'] = []
195
+ # end of Sprint3 additions
196
+
197
+ # Section 3 - Create combinations
198
+
199
+ # bucket=['paid_search', 'kwai','indicacao','infleux', 'influencer','FB: Level Achieved - Tier 1 Impressions',
200
+ # ' FB: Level Achieved - Tier 2 Impressions','paid_social_others',
201
+ # ' GA App: Will And Cid Pequena Baixo Risco Clicks',
202
+ # 'digital_tactic_others',"programmatic"
203
+ # ]
204
+
205
+ # srishti - bucket names changed
206
+ bucket = ['paid_search', 'kwai', 'indicacao', 'infleux', 'influencer', 'fb_level_achieved_tier_2',
207
+ 'fb_level_achieved_tier_1', 'paid_social_others',
208
+ 'ga_app',
209
+ 'digital_tactic_others', "programmatic"
210
+ ]
211
+
212
+ with columns[0]:
213
+ if st.button('Create Combinations of Variables'):
214
+
215
+ top_3_correlated_features = []
216
+ # # for col in st.session_state['media_data'].columns[:19]:
217
+ # original_cols = [c for c in st.session_state['media_data'].columns if
218
+ # "_clicks" in c.lower() or "_impressions" in c.lower()]
219
+ #original_cols = [c for c in original_cols if "_lag" not in c.lower() and "_adstock" not in c.lower()]
220
+
221
+ original_cols=st.session_state['bin_dict']['Media'] + st.session_state['bin_dict']['Internal']
222
+
223
+ original_cols=[col.lower().replace('.','_').replace('@','_').replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_") for col in original_cols]
224
+ original_cols = [col for col in original_cols if "_cost" not in col]
225
+ # for col in st.session_state['media_data'].columns[:19]:
226
+ for col in original_cols: # srishti - new
227
+ corr_df = pd.concat([st.session_state['media_data'].filter(regex=col),
228
+ y], axis=1).corr()[target_col].iloc[:-1]
229
+ top_3_correlated_features.append(list(corr_df.sort_values(ascending=False).head(2).index))
230
+ flattened_list = [item for sublist in top_3_correlated_features for item in sublist]
231
+ # all_features_set={var:[col for col in flattened_list if var in col] for var in bucket}
232
+ all_features_set = {var: [col for col in flattened_list if var in col] for var in bucket if
233
+ len([col for col in flattened_list if var in col]) > 0} # srishti
234
+ channels_all = [values for values in all_features_set.values()]
235
+ st.session_state['combinations'] = list(itertools.product(*channels_all))
236
+ # if 'combinations' not in st.session_state:
237
+ # st.session_state['combinations']=combinations_all
238
+
239
+ st.session_state['final_selection'] = st.session_state['combinations']
240
+ st.success('Done')
241
+
242
+ # revenue.reset_index(drop=True,inplace=True)
243
+ y.reset_index(drop=True, inplace=True)
244
+ if 'Model_results' not in st.session_state:
245
+ st.session_state['Model_results'] = {'Model_object': [],
246
+ 'Model_iteration': [],
247
+ 'Feature_set': [],
248
+ 'MAPE': [],
249
+ 'R2': [],
250
+ 'ADJR2': [],
251
+ 'pos_count': []
252
+ }
253
+
254
+
255
+ def reset_model_result_dct():
256
+ st.session_state['Model_results'] = {'Model_object': [],
257
+ 'Model_iteration': [],
258
+ 'Feature_set': [],
259
+ 'MAPE': [],
260
+ 'R2': [],
261
+ 'ADJR2': [],
262
+ 'pos_count': []
263
+ }
264
+
265
+ # if st.button('Build Model'):
266
+
267
+
268
+ if 'iterations' not in st.session_state:
269
+ st.session_state['iterations'] = 0
270
+
271
+ if 'final_selection' not in st.session_state:
272
+ st.session_state['final_selection'] = False
273
+
274
+ save_path = r"Model/"
275
+ with columns[1]:
276
+ if st.session_state['final_selection']:
277
+ st.write(f'Total combinations created {format_numbers(len(st.session_state["final_selection"]))}')
278
+
279
+ # st.session_state["project_dct"]["model_build"]["all_iters_check"] = False
280
+
281
+ checkbox_default = st.session_state["project_dct"]["model_build"]["all_iters_check"] if st.session_state["project_dct"]["model_build"]['all_iters_check'] is not None else False
282
+
283
+ if st.checkbox('Build all iterations', value=checkbox_default):
284
+ # st.session_state["project_dct"]["model_build"]["all_iters_check"]
285
+ iterations = len(st.session_state['final_selection'])
286
+ st.session_state["project_dct"]["model_build"]["all_iters_check"] = True
287
+
288
+ else:
289
+ iterations = st.number_input('Select the number of iterations to perform', min_value=0, step=100,
290
+ value=st.session_state['iterations'], on_change=reset_model_result_dct)
291
+ st.session_state["project_dct"]["model_build"]["all_iters_check"] = False
292
+ st.session_state["project_dct"]["model_build"]["iterations"] = iterations
293
+ if iterations <1:
294
+ st.error('Please enter a number greater than 0')
295
+ # st.stop()
296
+
297
+ # build_button = st.session_state["project_dct"]["model_build"]["build_button"] if \
298
+ # "build_button" in st.session_state["project_dct"]["model_build"].keys() else False
299
+
300
+ if st.button('Build Model', on_click=reset_model_result_dct):
301
+ if len(st.session_state["final_selection"]) < 1 :
302
+ st.error('Please create combinations')
303
+ st.session_state["project_dct"]["model_build"]["build_button"]=True
304
+ st.session_state['iterations'] = iterations
305
+
306
+ # Section 4 - Model
307
+ # st.session_state['media_data'] = st.session_state['media_data'].fillna(method='ffill')
308
+ st.session_state['media_data'] = st.session_state['media_data'].ffill()
309
+ st.markdown(
310
+ 'Data Split -- Training Period: May 9th, 2023 - October 5th,2023 , Testing Period: October 6th, 2023 - November 7th, 2023 ')
311
+ progress_bar = st.progress(0) # Initialize the progress bar
312
+ # time_remaining_text = st.empty() # Create an empty space for time remaining text
313
+ start_time = time.time() # Record the start time
314
+ progress_text = st.empty()
315
+
316
+ # time_elapsed_text = st.empty()
317
+ # for i, selected_features in enumerate(st.session_state["final_selection"][40000:40000 + int(iterations)]):
318
+ # st.write(st.session_state["final_selection"])
319
+ # for i, selected_features in enumerate(st.session_state["final_selection"]):
320
+
321
+ if is_panel == True:
322
+ for i, selected_features in enumerate(st.session_state["final_selection"][0:int(iterations)]): # srishti
323
+ df = st.session_state['media_data']
324
+
325
+ fet = [var for var in selected_features if len(var) > 0]
326
+ inp_vars_str = " + ".join(fet) # new
327
+
328
+ X = df[fet]
329
+ y = df[target_col]
330
+ ss = MinMaxScaler()
331
+ X = pd.DataFrame(ss.fit_transform(X), columns=X.columns)
332
+
333
+ X[target_col] = y # Sprint2
334
+ X[panel_col] = df[panel_col] # Sprint2
335
+
336
+ X_train = X.iloc[:8000]
337
+ X_test = X.iloc[8000:]
338
+ y_train = y.iloc[:8000]
339
+ y_test = y.iloc[8000:]
340
+
341
+ print(X_train.shape)
342
+ # model = sm.OLS(y_train, X_train).fit()
343
+ md_str = target_col + " ~ " + inp_vars_str
344
+ # md = smf.mixedlm("total_approved_accounts_revenue ~ {}".format(inp_vars_str),
345
+ # data=X_train[[target_col] + fet],
346
+ # groups=X_train[panel_col])
347
+ md = smf.mixedlm(md_str,
348
+ data=X_train[[target_col] + fet],
349
+ groups=X_train[panel_col])
350
+ mdf = md.fit()
351
+ predicted_values = mdf.fittedvalues
352
+
353
+ coefficients = mdf.fe_params.to_dict()
354
+ model_positive = [col for col in coefficients.keys() if coefficients[col] > 0]
355
+
356
+ pvalues = [var for var in list(mdf.pvalues) if var <= 0.06]
357
+
358
+ if (len(model_positive) / len(selected_features)) > 0 and (
359
+ len(pvalues) / len(selected_features)) >= 0: # srishti - changed just for testing, revert later
360
+ # predicted_values = model.predict(X_train)
361
+ mape = mean_absolute_percentage_error(y_train, predicted_values)
362
+ r2 = r2_score(y_train, predicted_values)
363
+ adjr2 = 1 - (1 - r2) * (len(y_train) - 1) / (len(y_train) - len(selected_features) - 1)
364
+
365
+ filename = os.path.join(save_path, f"model_{i}.pkl")
366
+ with open(filename, "wb") as f:
367
+ pickle.dump(mdf, f)
368
+ # with open(r"C:\Users\ManojP\Documents\MMM\simopt\Model\model.pkl", 'rb') as file:
369
+ # model = pickle.load(file)
370
+
371
+ st.session_state['Model_results']['Model_object'].append(filename)
372
+ st.session_state['Model_results']['Model_iteration'].append(i)
373
+ st.session_state['Model_results']['Feature_set'].append(fet)
374
+ st.session_state['Model_results']['MAPE'].append(mape)
375
+ st.session_state['Model_results']['R2'].append(r2)
376
+ st.session_state['Model_results']['pos_count'].append(len(model_positive))
377
+ st.session_state['Model_results']['ADJR2'].append(adjr2)
378
+
379
+ current_time = time.time()
380
+ time_taken = current_time - start_time
381
+ time_elapsed_minutes = time_taken / 60
382
+ completed_iterations_text = f"{i + 1}/{iterations}"
383
+ progress_bar.progress((i + 1) / int(iterations))
384
+ progress_text.text(
385
+ f'Completed iterations: {completed_iterations_text},Time Elapsed (min): {time_elapsed_minutes:.2f}')
386
+ st.write(
387
+ f'Out of {st.session_state["iterations"]} iterations : {len(st.session_state["Model_results"]["Model_object"])} valid models')
388
+
389
+ else:
390
+
391
+ for i, selected_features in enumerate(st.session_state["final_selection"][0:int(iterations)]): # srishti
392
+ df = st.session_state['media_data']
393
+
394
+ fet = [var for var in selected_features if len(var) > 0]
395
+ inp_vars_str = " + ".join(fet)
396
+
397
+ X = df[fet]
398
+ y = df[target_col]
399
+ ss = MinMaxScaler()
400
+ X = pd.DataFrame(ss.fit_transform(X), columns=X.columns)
401
+ X = sm.add_constant(X)
402
+ X_train = X.iloc[:130]
403
+ X_test = X.iloc[130:]
404
+ y_train = y.iloc[:130]
405
+ y_test = y.iloc[130:]
406
+
407
+ model = sm.OLS(y_train, X_train).fit()
408
+
409
+
410
+ coefficients = model.params.to_list()
411
+ model_positive = [coef for coef in coefficients if coef > 0]
412
+ predicted_values = model.predict(X_train)
413
+ pvalues = [var for var in list(model.pvalues) if var <= 0.06]
414
+
415
+ # if (len(model_possitive) / len(selected_features)) > 0.9 and (len(pvalues) / len(selected_features)) >= 0.8:
416
+ if (len(model_positive) / len(selected_features)) > 0 and (len(pvalues) / len(
417
+ selected_features)) >= 0.5: # srishti - changed just for testing, revert later VALID MODEL CRITERIA
418
+ # predicted_values = model.predict(X_train)
419
+ mape = mean_absolute_percentage_error(y_train, predicted_values)
420
+ adjr2 = model.rsquared_adj
421
+ r2 = model.rsquared
422
+
423
+ filename = os.path.join(save_path, f"model_{i}.pkl")
424
+ with open(filename, "wb") as f:
425
+ pickle.dump(model, f)
426
+ # with open(r"C:\Users\ManojP\Documents\MMM\simopt\Model\model.pkl", 'rb') as file:
427
+ # model = pickle.load(file)
428
+
429
+ st.session_state['Model_results']['Model_object'].append(filename)
430
+ st.session_state['Model_results']['Model_iteration'].append(i)
431
+ st.session_state['Model_results']['Feature_set'].append(fet)
432
+ st.session_state['Model_results']['MAPE'].append(mape)
433
+ st.session_state['Model_results']['R2'].append(r2)
434
+ st.session_state['Model_results']['ADJR2'].append(adjr2)
435
+ st.session_state['Model_results']['pos_count'].append(len(model_positive))
436
+
437
+ current_time = time.time()
438
+ time_taken = current_time - start_time
439
+ time_elapsed_minutes = time_taken / 60
440
+ completed_iterations_text = f"{i + 1}/{iterations}"
441
+ progress_bar.progress((i + 1) / int(iterations))
442
+ progress_text.text(
443
+ f'Completed iterations: {completed_iterations_text},Time Elapsed (min): {time_elapsed_minutes:.2f}')
444
+ st.write(
445
+ f'Out of {st.session_state["iterations"]} iterations : {len(st.session_state["Model_results"]["Model_object"])} valid models')
446
+
447
+ pd.DataFrame(st.session_state['Model_results']).to_csv('model_output.csv')
448
+
449
+
450
+ def to_percentage(value):
451
+ return f'{value * 100:.1f}%'
452
+
453
+ ## Section 5 - Select Model
454
+ st.title('2. Select Models')
455
+ show_results_defualt = st.session_state["project_dct"]["model_build"]["show_results_check"] if st.session_state["project_dct"]["model_build"]['show_results_check'] is not None else False
456
+ if 'tick' not in st.session_state:
457
+ st.session_state['tick'] = False
458
+ if st.checkbox('Show results of top 10 models (based on MAPE and Adj. R2)', value=show_results_defualt):
459
+ st.session_state["project_dct"]["model_build"]["show_results_check"] = True
460
+ st.session_state['tick'] = True
461
+ st.write('Select one model iteration to generate performance metrics for it:')
462
+ data = pd.DataFrame(st.session_state['Model_results'])
463
+ data = data[data['pos_count']==data['pos_count'].max()].reset_index(drop=True) # Sprint4 -- Srishti -- only show models with the lowest num of neg coeffs
464
+ data.sort_values(by=['ADJR2'], ascending=False, inplace=True)
465
+ data.drop_duplicates(subset='Model_iteration', inplace=True)
466
+ top_10 = data.head(10)
467
+ top_10['Rank'] = np.arange(1, len(top_10) + 1, 1)
468
+ top_10[['MAPE', 'R2', 'ADJR2']] = np.round(top_10[['MAPE', 'R2', 'ADJR2']], 4).applymap(to_percentage)
469
+ top_10_table = top_10[['Rank', 'Model_iteration', 'MAPE', 'ADJR2', 'R2']]
470
+ # top_10_table.columns=[['Rank','Model Iteration Index','MAPE','Adjusted R2','R2']]
471
+ gd = GridOptionsBuilder.from_dataframe(top_10_table)
472
+ gd.configure_pagination(enabled=True)
473
+
474
+ gd.configure_selection(
475
+ use_checkbox=True,
476
+ selection_mode="single",
477
+ pre_select_all_rows=False,
478
+ pre_selected_rows=[1],
479
+ )
480
+
481
+ gridoptions = gd.build()
482
+
483
+ table = AgGrid(top_10, gridOptions=gridoptions, update_mode=GridUpdateMode.SELECTION_CHANGED)
484
+
485
+ selected_rows = table.selected_rows
486
+ # if st.session_state["selected_rows"] != selected_rows:
487
+ # st.session_state["build_rc_cb"] = False
488
+ st.session_state["selected_rows"] = selected_rows
489
+
490
+
491
+
492
+ # Section 6 - Display Results
493
+
494
+ if len(selected_rows) > 0:
495
+ st.header('2.1 Results Summary')
496
+
497
+ model_object = data[data['Model_iteration'] == selected_rows[0]['Model_iteration']]['Model_object']
498
+ features_set = data[data['Model_iteration'] == selected_rows[0]['Model_iteration']]['Feature_set']
499
+
500
+ with open(str(model_object.values[0]), 'rb') as file:
501
+ # print(file)
502
+ model = pickle.load(file)
503
+ st.write(model.summary())
504
+ st.header('2.2 Actual vs. Predicted Plot')
505
+
506
+ if is_panel :
507
+ df = st.session_state['media_data']
508
+ X = df[features_set.values[0]]
509
+ y = df[target_col]
510
+
511
+ ss = MinMaxScaler()
512
+ X = pd.DataFrame(ss.fit_transform(X), columns=X.columns)
513
+
514
+ # Sprint2 changes
515
+ X[target_col] = y # new
516
+ X[panel_col] = df[panel_col]
517
+ X[date_col] = date
518
+
519
+ X_train = X.iloc[:8000]
520
+ X_test = X.iloc[8000:].reset_index(drop=True)
521
+ y_train = y.iloc[:8000]
522
+ y_test = y.iloc[8000:].reset_index(drop=True)
523
+
524
+ test_spends = spends_data[8000:] # Sprint3 - test spends for resp curves
525
+ random_eff_df = get_random_effects(media_data, panel_col, model)
526
+ train_pred = model.fittedvalues
527
+ test_pred = mdf_predict(X_test, model, random_eff_df)
528
+ print("__" * 20, test_pred.isna().sum())
529
+
530
+ else :
531
+ df = st.session_state['media_data']
532
+ X = df[features_set.values[0]]
533
+ y = df[target_col]
534
+
535
+ ss = MinMaxScaler()
536
+ X = pd.DataFrame(ss.fit_transform(X), columns=X.columns)
537
+ X = sm.add_constant(X)
538
+
539
+ X[date_col] = date
540
+
541
+ X_train = X.iloc[:130]
542
+ X_test = X.iloc[130:].reset_index(drop=True)
543
+ y_train = y.iloc[:130]
544
+ y_test = y.iloc[130:].reset_index(drop=True)
545
+
546
+ test_spends = spends_data[130:] # Sprint3 - test spends for resp curves
547
+ train_pred = model.predict(X_train[features_set.values[0]+['const']])
548
+ test_pred = model.predict(X_test[features_set.values[0]+['const']])
549
+
550
+
551
+ # save x test to test - srishti
552
+ # x_test_to_save = X_test.copy()
553
+ # x_test_to_save['Actuals'] = y_test
554
+ # x_test_to_save['Predictions'] = test_pred
555
+ #
556
+ # x_train_to_save = X_train.copy()
557
+ # x_train_to_save['Actuals'] = y_train
558
+ # x_train_to_save['Predictions'] = train_pred
559
+ #
560
+ # x_train_to_save.to_csv('Test/x_train_to_save.csv', index=False)
561
+ # x_test_to_save.to_csv('Test/x_test_to_save.csv', index=False)
562
+
563
+ st.session_state['X'] = X_train
564
+ st.session_state['features_set'] = features_set.values[0]
565
+ print("**" * 20, "selected model features : ", features_set.values[0])
566
+ metrics_table, line, actual_vs_predicted_plot = plot_actual_vs_predicted(X_train[date_col], y_train, train_pred,
567
+ model, target_column=sel_target_col,
568
+ is_panel=is_panel) # Sprint2
569
+
570
+ st.plotly_chart(actual_vs_predicted_plot, use_container_width=True)
571
+
572
+ st.markdown('## 2.3 Residual Analysis')
573
+ columns = st.columns(2)
574
+ with columns[0]:
575
+ fig = plot_residual_predicted(y_train, train_pred, X_train) # Sprint2
576
+ st.plotly_chart(fig)
577
+
578
+ with columns[1]:
579
+ st.empty()
580
+ fig = qqplot(y_train, train_pred) # Sprint2
581
+ st.plotly_chart(fig)
582
+
583
+ with columns[0]:
584
+ fig = residual_distribution(y_train, train_pred) # Sprint2
585
+ st.pyplot(fig)
586
+
587
+ vif_data = pd.DataFrame()
588
+ # X=X.drop('const',axis=1)
589
+ X_train_orig = X_train.copy() # Sprint2 -- creating a copy of xtrain. Later deleting panel, target & date from xtrain
590
+ del_col_list = list(set([target_col, panel_col, date_col]).intersection(set(X_train.columns)))
591
+ X_train.drop(columns=del_col_list, inplace=True) # Sprint2
592
+
593
+ vif_data["Variable"] = X_train.columns
594
+ vif_data["VIF"] = [variance_inflation_factor(X_train.values, i) for i in range(X_train.shape[1])]
595
+ vif_data.sort_values(by=['VIF'], ascending=False, inplace=True)
596
+ vif_data = np.round(vif_data)
597
+ vif_data['VIF'] = vif_data['VIF'].astype(float)
598
+ st.header('2.4 Variance Inflation Factor (VIF)')
599
+ # st.dataframe(vif_data)
600
+ color_mapping = {
601
+ 'darkgreen': (vif_data['VIF'] < 3),
602
+ 'orange': (vif_data['VIF'] >= 3) & (vif_data['VIF'] <= 10),
603
+ 'darkred': (vif_data['VIF'] > 10)
604
+ }
605
+
606
+ # Create a horizontal bar plot
607
+ fig, ax = plt.subplots()
608
+ fig.set_figwidth(10) # Adjust the width of the figure as needed
609
+
610
+ # Sort the bars by descending VIF values
611
+ vif_data = vif_data.sort_values(by='VIF', ascending=False)
612
+
613
+ # Iterate through the color mapping and plot bars with corresponding colors
614
+ for color, condition in color_mapping.items():
615
+ subset = vif_data[condition]
616
+ bars = ax.barh(subset["Variable"], subset["VIF"], color=color, label=color)
617
+
618
+ # Add text annotations on top of the bars
619
+ for bar in bars:
620
+ width = bar.get_width()
621
+ ax.annotate(f'{width:}', xy=(width, bar.get_y() + bar.get_height() / 2), xytext=(5, 0),
622
+ textcoords='offset points', va='center')
623
+
624
+ # Customize the plot
625
+ ax.set_xlabel('VIF Values')
626
+ # ax.set_title('2.4 Variance Inflation Factor (VIF)')
627
+ # ax.legend(loc='upper right')
628
+
629
+ # Display the plot in Streamlit
630
+ st.pyplot(fig)
631
+
632
+ with st.expander('Results Summary Test data'):
633
+ # ss = MinMaxScaler()
634
+ # X_test = pd.DataFrame(ss.fit_transform(X_test), columns=X_test.columns)
635
+ st.header('2.2 Actual vs. Predicted Plot')
636
+
637
+ metrics_table, line, actual_vs_predicted_plot = plot_actual_vs_predicted(X_test[date_col], y_test,
638
+ test_pred, model,
639
+ target_column=sel_target_col,
640
+ is_panel=is_panel) # Sprint2
641
+
642
+ st.plotly_chart(actual_vs_predicted_plot, use_container_width=True)
643
+
644
+ st.markdown('## 2.3 Residual Analysis')
645
+ columns = st.columns(2)
646
+ with columns[0]:
647
+ fig = plot_residual_predicted(y, test_pred, X_test) # Sprint2
648
+ st.plotly_chart(fig)
649
+
650
+ with columns[1]:
651
+ st.empty()
652
+ fig = qqplot(y, test_pred) # Sprint2
653
+ st.plotly_chart(fig)
654
+
655
+ with columns[0]:
656
+ fig = residual_distribution(y, test_pred) # Sprint2
657
+ st.pyplot(fig)
658
+
659
+ value = False
660
+ save_button_model = st.checkbox('Save this model to tune', key='build_rc_cb') # , on_click=set_save())
661
+
662
+ if save_button_model:
663
+ mod_name = st.text_input('Enter model name')
664
+ if len(mod_name) > 0:
665
+ mod_name = mod_name + "__" + target_col # Sprint4 - adding target col to model name
666
+ if is_panel :
667
+ pred_train= model.fittedvalues
668
+ pred_test= mdf_predict(X_test, model, random_eff_df)
669
+ else :
670
+ st.session_state['features_set'] = st.session_state['features_set'] + ['const']
671
+ pred_train= model.predict(X_train_orig[st.session_state['features_set']])
672
+ pred_test= model.predict(X_test[st.session_state['features_set']])
673
+
674
+ st.session_state['Model'][mod_name] = {"Model_object": model,
675
+ 'feature_set': st.session_state['features_set'],
676
+ 'X_train': X_train_orig,
677
+ 'X_test': X_test,
678
+ 'y_train': y_train,
679
+ 'y_test': y_test,
680
+ 'pred_train':pred_train,
681
+ 'pred_test': pred_test
682
+ }
683
+ st.session_state['X_train'] = X_train_orig
684
+ st.session_state['X_test_spends'] = test_spends
685
+ st.session_state['saved_model_names'].append(mod_name)
686
+ # Sprint3 additions
687
+ if is_panel :
688
+ random_eff_df = get_random_effects(media_data, panel_col, model)
689
+ st.session_state['random_effects'] = random_eff_df
690
+
691
+
692
+
693
+ with open("best_models.pkl", "wb") as f:
694
+ pickle.dump(st.session_state['Model'], f)
695
+ st.success(mod_name + ' model saved! Proceed to the next page to tune the model')
696
+
697
+ urm = st.session_state['used_response_metrics']
698
+ urm.append(sel_target_col)
699
+ st.session_state['used_response_metrics'] = list(set(urm))
700
+ mod_name = ""
701
+ # Sprint4 - add the formatted name of the target col to used resp metrics
702
+ value = False
703
+
704
+ st.session_state["project_dct"]["model_build"]["session_state_saved"] = {}
705
+ for key in ['Model', 'bin_dict', 'used_response_metrics', 'date', 'saved_model_names', 'media_data', 'X_test_spends']:
706
+ st.session_state["project_dct"]["model_build"]["session_state_saved"][key] = st.session_state[key]
707
+
708
+ project_dct_path = os.path.join(st.session_state['project_path'], "project_dct.pkl")
709
+ with open(project_dct_path, 'wb') as f:
710
+ pickle.dump(st.session_state["project_dct"], f)
711
+
712
+ st.toast("💾 Saved Successfully!")
713
+ else :
714
+ st.session_state["project_dct"]["model_build"]["show_results_check"] = False
7_Build_Response_Curves.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import plotly.express as px
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ from utilities_with_panel import channel_name_formating, load_authenticator, initialize_data
6
+ from sklearn.metrics import r2_score
7
+ from collections import OrderedDict
8
+ from classes import class_from_dict,class_to_dict
9
+ import pickle
10
+ import json
11
+ from utilities import (
12
+ load_local_css,
13
+ set_header,
14
+ channel_name_formating,
15
+ )
16
+
17
+ for k, v in st.session_state.items():
18
+ if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
19
+ st.session_state[k] = v
20
+
21
+ def s_curve(x,K,b,a,x0):
22
+ return K / (1 + b*np.exp(-a*(x-x0)))
23
+
24
+ def save_scenario(scenario_name):
25
+ """
26
+ Save the current scenario with the mentioned name in the session state
27
+
28
+ Parameters
29
+ ----------
30
+ scenario_name
31
+ Name of the scenario to be saved
32
+ """
33
+ if 'saved_scenarios' not in st.session_state:
34
+ st.session_state = OrderedDict()
35
+
36
+ #st.session_state['saved_scenarios'][scenario_name] = st.session_state['scenario'].save()
37
+ st.session_state['saved_scenarios'][scenario_name] = class_to_dict(st.session_state['scenario'])
38
+ st.session_state['scenario_input'] = ""
39
+ print(type(st.session_state['saved_scenarios']))
40
+ with open('../saved_scenarios.pkl', 'wb') as f:
41
+ pickle.dump(st.session_state['saved_scenarios'],f)
42
+
43
+
44
+ def reset_curve_parameters():
45
+ del st.session_state['K']
46
+ del st.session_state['b']
47
+ del st.session_state['a']
48
+ del st.session_state['x0']
49
+
50
+ def update_response_curve():
51
+ # st.session_state['rcs'][selected_channel_name]['K'] = st.session_state['K']
52
+ # st.session_state['rcs'][selected_channel_name]['b'] = st.session_state['b']
53
+ # st.session_state['rcs'][selected_channel_name]['a'] = st.session_state['a']
54
+ # st.session_state['rcs'][selected_channel_name]['x0'] = st.session_state['x0']
55
+ # rcs = st.session_state['rcs']
56
+ _channel_class = st.session_state['scenario'].channels[selected_channel_name]
57
+ _channel_class.update_response_curves({
58
+ 'K' : st.session_state['K'],
59
+ 'b' : st.session_state['b'],
60
+ 'a' : st.session_state['a'],
61
+ 'x0' : st.session_state['x0']})
62
+
63
+
64
+ # authenticator = st.session_state.get('authenticator')
65
+ # if authenticator is None:
66
+ # authenticator = load_authenticator()
67
+
68
+ # name, authentication_status, username = authenticator.login('Login', 'main')
69
+ # auth_status = st.session_state.get('authentication_status')
70
+
71
+ # if auth_status == True:
72
+ # is_state_initiaized = st.session_state.get('initialized',False)
73
+ # if not is_state_initiaized:
74
+ # print("Scenario page state reloaded")
75
+
76
+ # Sprint4 - if used_response_metrics is not blank, then select one of the used_response_metrics, else target is revenue by default
77
+ st.set_page_config(layout='wide')
78
+ load_local_css('styles.css')
79
+ set_header()
80
+
81
+ if "used_response_metrics" in st.session_state and st.session_state['used_response_metrics']!=[]:
82
+ sel_target_col = st.selectbox("Select the response metric", st.session_state['used_response_metrics'])
83
+ target_col = sel_target_col.lower().replace(" ", "_").replace('-', '').replace(':', '').replace("__", "_")
84
+ else :
85
+ sel_target_col = 'Total Approved Accounts - Revenue'
86
+ target_col = 'total_approved_accounts_revenue'
87
+
88
+ initialize_data(target_col)
89
+
90
+ st.subheader("Build response curves")
91
+
92
+ channels_list = st.session_state['channels_list']
93
+ selected_channel_name = st.selectbox('Channel', st.session_state['channels_list'] + ['Others'], format_func=channel_name_formating,on_change=reset_curve_parameters)
94
+
95
+ rcs = {}
96
+ for channel_name in channels_list:
97
+ rcs[channel_name] = st.session_state['scenario'].channels[channel_name].response_curve_params
98
+ # rcs = st.session_state['rcs']
99
+
100
+
101
+ if 'K' not in st.session_state:
102
+ st.session_state['K'] = rcs[selected_channel_name]['K']
103
+ if 'b' not in st.session_state:
104
+ st.session_state['b'] = rcs[selected_channel_name]['b']
105
+ if 'a' not in st.session_state:
106
+ st.session_state['a'] = rcs[selected_channel_name]['a']
107
+ if 'x0' not in st.session_state:
108
+ st.session_state['x0'] = rcs[selected_channel_name]['x0']
109
+
110
+ x = st.session_state['actual_input_df'][selected_channel_name].values
111
+ y = st.session_state['actual_contribution_df'][selected_channel_name].values
112
+
113
+ power = (np.ceil(np.log(x.max()) / np.log(10) )- 3)
114
+
115
+ # fig = px.scatter(x, s_curve(x/10**power,
116
+ # st.session_state['K'],
117
+ # st.session_state['b'],
118
+ # st.session_state['a'],
119
+ # st.session_state['x0']))
120
+
121
+ fig = px.scatter(x=x, y=y)
122
+ fig.add_trace(go.Scatter(x=sorted(x), y=s_curve(sorted(x)/10**power,st.session_state['K'],
123
+ st.session_state['b'],
124
+ st.session_state['a'],
125
+ st.session_state['x0']),
126
+ line=dict(color='red')))
127
+
128
+ fig.update_layout(title_text="Response Curve",showlegend=False)
129
+ fig.update_annotations(font_size=10)
130
+ fig.update_xaxes(title='Spends')
131
+ fig.update_yaxes(title=sel_target_col)
132
+
133
+ st.plotly_chart(fig,use_container_width=True)
134
+
135
+ r2 = r2_score(y, s_curve(x / 10**power,
136
+ st.session_state['K'],
137
+ st.session_state['b'],
138
+ st.session_state['a'],
139
+ st.session_state['x0']))
140
+
141
+ st.metric('R2',round(r2,2))
142
+ columns = st.columns(4)
143
+
144
+ with columns[0]:
145
+ st.number_input('K',key='K',format="%0.5f")
146
+ with columns[1]:
147
+ st.number_input('b',key='b',format="%0.5f")
148
+ with columns[2]:
149
+ st.number_input('a',key='a',step=0.0001,format="%0.5f")
150
+ with columns[3]:
151
+ st.number_input('x0',key='x0',format="%0.5f")
152
+
153
+
154
+ st.button('Update parameters',on_click=update_response_curve)
155
+ st.button('Reset parameters',on_click=reset_curve_parameters)
156
+ scenario_name = st.text_input('Scenario name', key='scenario_input',placeholder='Scenario name',label_visibility='collapsed')
157
+ st.button('Save', on_click=lambda : save_scenario(scenario_name),disabled=len(st.session_state['scenario_input']) == 0)
158
+
159
+ file_name = st.text_input('rcs download file name', key='file_name_input',placeholder='file name',label_visibility='collapsed')
160
+ st.download_button(
161
+ label="Download response curves",
162
+ data=json.dumps(rcs),
163
+ file_name=f"{file_name}.json",
164
+ mime="application/json",
165
+ disabled= len(file_name) == 0,
166
+ )
167
+
168
+
169
+ def s_curve_derivative(x, K, b, a, x0):
170
+ # Derivative of the S-curve function
171
+ return a * b * K * np.exp(-a * (x - x0)) / ((1 + b * np.exp(-a * (x - x0))) ** 2)
172
+
173
+ # Parameters of the S-curve
174
+ K = st.session_state['K']
175
+ b = st.session_state['b']
176
+ a = st.session_state['a']
177
+ x0 = st.session_state['x0']
178
+
179
+ # Optimized spend value obtained from the tool
180
+ optimized_spend = st.number_input('value of x') # Replace this with your optimized spend value
181
+
182
+ # Calculate the slope at the optimized spend value
183
+ slope_at_optimized_spend = s_curve_derivative(optimized_spend, K, b, a, x0)
184
+
185
+ st.write("Slope ", slope_at_optimized_spend)
8_Scenario_Planner.py ADDED
@@ -0,0 +1,464 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from numerize.numerize import numerize
3
+ import numpy as np
4
+ from functools import partial
5
+ from collections import OrderedDict
6
+ from plotly.subplots import make_subplots
7
+ import plotly.graph_objects as go
8
+ from utilities import format_numbers,load_local_css,set_header,initialize_data,load_authenticator,send_email,channel_name_formating
9
+ from classes import class_from_dict,class_to_dict
10
+ import pickle
11
+ import streamlit_authenticator as stauth
12
+ import yaml
13
+ from yaml import SafeLoader
14
+ import re
15
+ import pandas as pd
16
+ import plotly.express as px
17
+ target='Revenue'
18
+ st.set_page_config(layout='wide')
19
+ load_local_css('styles.css')
20
+ set_header()
21
+
22
+ for k, v in st.session_state.items():
23
+ if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
24
+ st.session_state[k] = v
25
+ # ======================================================== #
26
+ # ======================= Functions ====================== #
27
+ # ======================================================== #
28
+
29
+
30
+ def optimize():
31
+ """
32
+ Optimize the spends for the sales
33
+ """
34
+
35
+ channel_list = [key for key,value in st.session_state['optimization_channels'].items() if value]
36
+ print('channel_list')
37
+ print(channel_list)
38
+ print('@@@@@@@@')
39
+ if len(channel_list) > 0 :
40
+ scenario = st.session_state['scenario']
41
+ result = st.session_state['scenario'].optimize(st.session_state['total_spends_change'],channel_list)
42
+ for channel_name, modified_spends in result:
43
+ st.session_state[channel_name] = numerize(modified_spends * scenario.channels[channel_name].conversion_rate,1)
44
+ prev_spends = st.session_state['scenario'].channels[channel_name].actual_total_spends
45
+ st.session_state[f'{channel_name}_change'] = round(100*(modified_spends - prev_spends) / prev_spends,2)
46
+
47
+
48
+ def save_scenario(scenario_name):
49
+ """
50
+ Save the current scenario with the mentioned name in the session state
51
+
52
+ Parameters
53
+ ----------
54
+ scenario_name
55
+ Name of the scenario to be saved
56
+ """
57
+ if 'saved_scenarios' not in st.session_state:
58
+ st.session_state = OrderedDict()
59
+
60
+ #st.session_state['saved_scenarios'][scenario_name] = st.session_state['scenario'].save()
61
+ st.session_state['saved_scenarios'][scenario_name] = class_to_dict(st.session_state['scenario'])
62
+ st.session_state['scenario_input'] = ""
63
+ print(type(st.session_state['saved_scenarios']))
64
+ with open('../saved_scenarios.pkl', 'wb') as f:
65
+ pickle.dump(st.session_state['saved_scenarios'],f)
66
+
67
+ def update_all_spends():
68
+ """
69
+ Updates spends for all the channels with the given overall spends change
70
+ """
71
+ percent_change = st.session_state['total_spends_change']
72
+ for channel_name in st.session_state['channels_list']:
73
+ channel = st.session_state['scenario'].channels[channel_name]
74
+ current_spends = channel.actual_total_spends
75
+ modified_spends = (1 + percent_change/100) * current_spends
76
+ st.session_state['scenario'].update(channel_name, modified_spends)
77
+ st.session_state[channel_name] = numerize(modified_spends*channel.conversion_rate,1)
78
+ st.session_state[f'{channel_name}_change'] = percent_change
79
+
80
+ def extract_number_for_string(string_input):
81
+ string_input = string_input.upper()
82
+ if string_input.endswith('K'):
83
+ return float(string_input[:-1])*10**3
84
+ elif string_input.endswith('M'):
85
+ return float(string_input[:-1])*10**6
86
+ elif string_input.endswith('B'):
87
+ return float(string_input[:-1])*10**9
88
+
89
+ def validate_input(string_input):
90
+ pattern = r'\d+\.?\d*[K|M|B]$'
91
+ match = re.match(pattern, string_input)
92
+ if match is None:
93
+ return False
94
+ return True
95
+
96
+ def update_data_by_percent(channel_name):
97
+ prev_spends = st.session_state['scenario'].channels[channel_name].actual_total_spends * st.session_state['scenario'].channels[channel_name].conversion_rate
98
+ modified_spends = prev_spends * (1 + st.session_state[f'{channel_name}_change']/100)
99
+ st.session_state[channel_name] = numerize(modified_spends,1)
100
+ st.session_state['scenario'].update(channel_name, modified_spends/st.session_state['scenario'].channels[channel_name].conversion_rate)
101
+
102
+ def update_data(channel_name):
103
+ """
104
+ Updates the spends for the given channel
105
+ """
106
+
107
+ if validate_input(st.session_state[channel_name]):
108
+ modified_spends = extract_number_for_string(st.session_state[channel_name])
109
+ prev_spends = st.session_state['scenario'].channels[channel_name].actual_total_spends * st.session_state['scenario'].channels[channel_name].conversion_rate
110
+ st.session_state[f'{channel_name}_change'] = round(100*(modified_spends - prev_spends) / prev_spends,2)
111
+ st.session_state['scenario'].update(channel_name, modified_spends/st.session_state['scenario'].channels[channel_name].conversion_rate)
112
+ # st.session_state['scenario'].update(channel_name, modified_spends)
113
+ # else:
114
+ # try:
115
+ # modified_spends = float(st.session_state[channel_name])
116
+ # prev_spends = st.session_state['scenario'].channels[channel_name].actual_total_spends * st.session_state['scenario'].channels[channel_name].conversion_rate
117
+ # st.session_state[f'{channel_name}_change'] = round(100*(modified_spends - prev_spends) / prev_spends,2)
118
+ # st.session_state['scenario'].update(channel_name, modified_spends/st.session_state['scenario'].channels[channel_name].conversion_rate)
119
+ # st.session_state[f'{channel_name}'] = numerize(modified_spends,1)
120
+ # except ValueError:
121
+ # st.write('Invalid input')
122
+
123
+ def select_channel_for_optimization(channel_name):
124
+ """
125
+ Marks the given channel for optimization
126
+ """
127
+ st.session_state['optimization_channels'][channel_name] = st.session_state[f'{channel_name}_selected']
128
+
129
+ def select_all_channels_for_optimization():
130
+ """
131
+ Marks all the channel for optimization
132
+ """
133
+ for channel_name in st.session_state['optimization_channels'].keys():
134
+ st.session_state[f'{channel_name}_selected' ] = st.session_state['optimze_all_channels']
135
+ st.session_state['optimization_channels'][channel_name] = st.session_state['optimze_all_channels']
136
+
137
+ def update_penalty():
138
+ """
139
+ Updates the penalty flag for sales calculation
140
+ """
141
+ st.session_state['scenario'].update_penalty(st.session_state['apply_penalty'])
142
+
143
+ def reset_scenario():
144
+ # print(st.session_state['default_scenario_dict'])
145
+ # st.session_state['scenario'] = class_from_dict(st.session_state['default_scenario_dict'])
146
+ # for channel in st.session_state['scenario'].channels.values():
147
+ # st.session_state[channel.name] = float(channel.actual_total_spends * channel.conversion_rate)
148
+ initialize_data()
149
+ for channel_name in st.session_state['channels_list']:
150
+ st.session_state[f'{channel_name}_selected'] = False
151
+ st.session_state[f'{channel_name}_change'] = 0
152
+ st.session_state['optimze_all_channels'] = False
153
+
154
+ def format_number(num):
155
+ if num >= 1_000_000:
156
+ return f"{num / 1_000_000:.2f}M"
157
+ elif num >= 1_000:
158
+ return f"{num / 1_000:.0f}K"
159
+ else:
160
+ return f"{num:.2f}"
161
+
162
+ def summary_plot(data, x, y, title, text_column):
163
+ fig = px.bar(data, x=x, y=y, orientation='h',
164
+ title=title, text=text_column, color='Channel_name')
165
+
166
+ # Convert text_column to numeric values
167
+ data[text_column] = pd.to_numeric(data[text_column], errors='coerce')
168
+
169
+ # Update the format of the displayed text based on magnitude
170
+ fig.update_traces(texttemplate='%{text:.2s}', textposition='outside', hovertemplate='%{x:.2s}')
171
+
172
+ fig.update_layout(xaxis_title=x, yaxis_title='Channel Name', showlegend=False)
173
+ return fig
174
+
175
+ def s_curve(x,K,b,a,x0):
176
+ return K / (1 + b*np.exp(-a*(x-x0)))
177
+
178
+ @st.cache
179
+ def plot_response_curves():
180
+ cols=4
181
+ rcs = st.session_state['rcs']
182
+ shapes = []
183
+ fig = make_subplots(rows=6, cols=cols,subplot_titles=channels_list)
184
+ for i in range(0, len(channels_list)):
185
+ col = channels_list[i]
186
+ x = st.session_state['actual_df'][col].values
187
+ spends = x.sum()
188
+ power = (np.ceil(np.log(x.max()) / np.log(10) )- 3)
189
+ x = np.linspace(0,3*x.max(),200)
190
+
191
+ K = rcs[col]['K']
192
+ b = rcs[col]['b']
193
+ a = rcs[col]['a']
194
+ x0 = rcs[col]['x0']
195
+
196
+ y = s_curve(x/10**power,K,b,a,x0)
197
+ roi = y/x
198
+ marginal_roi = a * (y)*(1-y/K)
199
+ fig.add_trace(
200
+ go.Scatter(x=52*x*st.session_state['scenario'].channels[col].conversion_rate,
201
+ y=52*y,
202
+ name=col,
203
+ customdata = np.stack((roi, marginal_roi),axis=-1),
204
+ hovertemplate="Spend:%{x:$.2s}<br>Sale:%{y:$.2s}<br>ROI:%{customdata[0]:.3f}<br>MROI:%{customdata[1]:.3f}"),
205
+ row=1+(i)//cols , col=i%cols + 1
206
+ )
207
+
208
+ fig.add_trace(go.Scatter(x=[spends*st.session_state['scenario'].channels[col].conversion_rate],
209
+ y=[52*s_curve(spends/(10**power*52),K,b,a,x0)],
210
+ name=col,
211
+ legendgroup=col,
212
+ showlegend=False,
213
+ marker=dict(color=['black'])),
214
+ row=1+(i)//cols , col=i%cols + 1)
215
+
216
+ shapes.append(go.layout.Shape(type="line",
217
+ x0=0,
218
+ y0=52*s_curve(spends/(10**power*52),K,b,a,x0),
219
+ x1=spends*st.session_state['scenario'].channels[col].conversion_rate,
220
+ y1=52*s_curve(spends/(10**power*52),K,b,a,x0),
221
+ line_width=1,
222
+ line_dash="dash",
223
+ line_color="black",
224
+ xref= f'x{i+1}',
225
+ yref= f'y{i+1}'))
226
+
227
+ shapes.append(go.layout.Shape(type="line",
228
+ x0=spends*st.session_state['scenario'].channels[col].conversion_rate,
229
+ y0=0,
230
+ x1=spends*st.session_state['scenario'].channels[col].conversion_rate,
231
+ y1=52*s_curve(spends/(10**power*52),K,b,a,x0),
232
+ line_width=1,
233
+ line_dash="dash",
234
+ line_color="black",
235
+ xref= f'x{i+1}',
236
+ yref= f'y{i+1}'))
237
+
238
+
239
+
240
+ fig.update_layout(height=1500, width=1000, title_text="Response Curves",showlegend=False,shapes=shapes)
241
+ fig.update_annotations(font_size=10)
242
+ fig.update_xaxes(title='Spends')
243
+ fig.update_yaxes(title=target)
244
+ return fig
245
+
246
+
247
+
248
+ # ======================================================== #
249
+ # ==================== HTML Components =================== #
250
+ # ======================================================== #
251
+
252
+ def generate_spending_header(heading):
253
+ return st.markdown(f"""<h2 class="spends-header">{heading}</h2>""",unsafe_allow_html=True)
254
+
255
+
256
+ # ======================================================== #
257
+ # =================== Session variables ================== #
258
+ # ======================================================== #
259
+
260
+ with open('config.yaml') as file:
261
+ config = yaml.load(file, Loader=SafeLoader)
262
+ st.session_state['config'] = config
263
+
264
+ authenticator = stauth.Authenticate(
265
+ config['credentials'],
266
+ config['cookie']['name'],
267
+ config['cookie']['key'],
268
+ config['cookie']['expiry_days'],
269
+ config['preauthorized']
270
+ )
271
+ st.session_state['authenticator'] = authenticator
272
+ name, authentication_status, username = authenticator.login('Login', 'main')
273
+ auth_status = st.session_state.get('authentication_status')
274
+ if auth_status == True:
275
+ authenticator.logout('Logout', 'main')
276
+ is_state_initiaized = st.session_state.get('initialized',False)
277
+ if not is_state_initiaized:
278
+ initialize_data()
279
+
280
+
281
+ channels_list = st.session_state['channels_list']
282
+
283
+
284
+ # ======================================================== #
285
+ # ========================== UI ========================== #
286
+ # ======================================================== #
287
+
288
+ print(list(st.session_state.keys()))
289
+
290
+ st.header('Simulation')
291
+ main_header = st.columns((2,2))
292
+ sub_header = st.columns((1,1,1,1))
293
+ _scenario = st.session_state['scenario']
294
+
295
+ with main_header[0]:
296
+ st.subheader('Actual')
297
+
298
+ with main_header[-1]:
299
+ st.subheader('Simulated')
300
+
301
+ with sub_header[0]:
302
+ st.metric(label = 'Spends', value=format_numbers(_scenario.actual_total_spends))
303
+
304
+ with sub_header[1]:
305
+ st.metric(label = target, value=format_numbers(float(_scenario.actual_total_sales),include_indicator=False))
306
+
307
+ with sub_header[2]:
308
+ st.metric(label = 'Spends',
309
+ value=format_numbers(_scenario.modified_total_spends),
310
+ delta=numerize(_scenario.delta_spends,1))
311
+
312
+ with sub_header[3]:
313
+ st.metric(label = target,
314
+ value=format_numbers(float(_scenario.modified_total_sales),include_indicator=False),
315
+ delta=numerize(_scenario.delta_sales,1))
316
+
317
+
318
+
319
+ with st.expander("Channel Spends Simulator"):
320
+ _columns = st.columns((2,4,1,1))
321
+ with _columns[0]:
322
+ st.checkbox(label='Optimize all Channels',
323
+ key=f'optimze_all_channels',
324
+ value=False,
325
+ on_change=select_all_channels_for_optimization,
326
+ )
327
+ st.number_input('Percent change of total spends',
328
+ key=f'total_spends_change',
329
+ step= 1,
330
+ on_change=update_all_spends)
331
+ with _columns[2]:
332
+ st.button('Optimize',on_click=optimize)
333
+ with _columns[3]:
334
+ st.button('Reset',on_click=reset_scenario)
335
+
336
+
337
+
338
+ st.markdown("""<hr class="spends-heading-seperator">""", unsafe_allow_html=True)
339
+ _columns = st.columns((2.5,2,1.5,1.5,1))
340
+ with _columns[0]:
341
+ generate_spending_header('Channel')
342
+ with _columns[1]:
343
+ generate_spending_header('Spends Input')
344
+ with _columns[2]:
345
+ generate_spending_header('Spends')
346
+ with _columns[3]:
347
+ generate_spending_header(target)
348
+ with _columns[4]:
349
+ generate_spending_header('Optimize')
350
+
351
+ st.markdown("""<hr class="spends-heading-seperator">""", unsafe_allow_html=True)
352
+
353
+ if 'acutual_predicted' not in st.session_state:
354
+ st.session_state['acutual_predicted']={'Channel_name':[],
355
+ 'Actual_spend':[],
356
+ 'Optimized_spend':[],
357
+ 'Delta':[]
358
+ }
359
+ for i,channel_name in enumerate(channels_list):
360
+ _channel_class = st.session_state['scenario'].channels[channel_name]
361
+ _columns = st.columns((2.5,1.5,1.5,1.5,1))
362
+ with _columns[0]:
363
+ st.write(channel_name_formating(channel_name))
364
+ with _columns[1]:
365
+ channel_bounds = _channel_class.bounds
366
+ channel_spends = float(_channel_class.actual_total_spends )
367
+ min_value = float((1+channel_bounds[0]/100) * channel_spends )
368
+ max_value = float((1+channel_bounds[1]/100) * channel_spends )
369
+ #print(st.session_state[channel_name])
370
+ spend_input = st.text_input(channel_name,
371
+ key=channel_name,
372
+ label_visibility='collapsed',
373
+ on_change=partial(update_data,channel_name))
374
+ if not validate_input(spend_input):
375
+ st.error('Invalid input')
376
+
377
+ st.number_input('Percent change',
378
+ key=f'{channel_name}_change',
379
+ step= 1,
380
+ on_change=partial(update_data_by_percent,channel_name))
381
+
382
+ with _columns[2]:
383
+ # spends
384
+ current_channel_spends = float(_channel_class.modified_total_spends * _channel_class.conversion_rate)
385
+ actual_channel_spends = float(_channel_class.actual_total_spends * _channel_class.conversion_rate)
386
+ spends_delta = float(_channel_class.delta_spends * _channel_class.conversion_rate)
387
+ st.session_state['acutual_predicted']['Channel_name'].append(channel_name)
388
+ st.session_state['acutual_predicted']['Actual_spend'].append(actual_channel_spends)
389
+ st.session_state['acutual_predicted']['Optimized_spend'].append(current_channel_spends)
390
+ st.session_state['acutual_predicted']['Delta'].append(spends_delta)
391
+ ## REMOVE
392
+ st.metric('Spends',
393
+ format_numbers(current_channel_spends),
394
+ delta=numerize(spends_delta,1),
395
+ label_visibility='collapsed')
396
+
397
+ with _columns[3]:
398
+ # sales
399
+ current_channel_sales = float(_channel_class.modified_total_sales)
400
+ actual_channel_sales = float(_channel_class.actual_total_sales)
401
+ sales_delta = float(_channel_class.delta_sales)
402
+ st.metric(target,
403
+ format_numbers(current_channel_sales,include_indicator=False),
404
+ delta=numerize(sales_delta,1),
405
+ label_visibility='collapsed')
406
+
407
+ with _columns[4]:
408
+
409
+ st.checkbox(label='select for optimization',
410
+ key=f'{channel_name}_selected',
411
+ value=False,
412
+ on_change=partial(select_channel_for_optimization,channel_name),
413
+ label_visibility='collapsed')
414
+
415
+
416
+ st.markdown("""<hr class="spends-child-seperator">""",unsafe_allow_html=True)
417
+
418
+
419
+ with st.expander("See Response Curves"):
420
+ fig = plot_response_curves()
421
+ st.plotly_chart(fig,use_container_width=True)
422
+
423
+ _columns = st.columns(2)
424
+ with _columns[0]:
425
+ st.subheader('Save Scenario')
426
+ scenario_name = st.text_input('Scenario name', key='scenario_input',placeholder='Scenario name',label_visibility='collapsed')
427
+ st.button('Save', on_click=lambda : save_scenario(scenario_name),disabled=len(st.session_state['scenario_input']) == 0)
428
+
429
+ summary_df=pd.DataFrame(st.session_state['acutual_predicted'])
430
+ summary_df.drop_duplicates(subset='Channel_name',keep='last',inplace=True)
431
+
432
+ summary_df_sorted = summary_df.sort_values(by='Delta', ascending=False)
433
+ summary_df_sorted['Delta_percent'] = np.round(((summary_df_sorted['Optimized_spend'] / summary_df_sorted['Actual_spend'])-1) * 100, 2)
434
+
435
+ with open("summary_df.pkl", "wb") as f:
436
+ pickle.dump(summary_df_sorted, f)
437
+ #st.dataframe(summary_df_sorted)
438
+ # ___columns=st.columns(3)
439
+ # with ___columns[2]:
440
+ # fig=summary_plot(summary_df_sorted, x='Delta_percent', y='Channel_name', title='Delta', text_column='Delta_percent')
441
+ # st.plotly_chart(fig,use_container_width=True)
442
+ # with ___columns[0]:
443
+ # fig=summary_plot(summary_df_sorted, x='Actual_spend', y='Channel_name', title='Actual Spend', text_column='Actual_spend')
444
+ # st.plotly_chart(fig,use_container_width=True)
445
+ # with ___columns[1]:
446
+ # fig=summary_plot(summary_df_sorted, x='Optimized_spend', y='Channel_name', title='Planned Spend', text_column='Optimized_spend')
447
+ # st.plotly_chart(fig,use_container_width=True)
448
+
449
+ elif auth_status == False:
450
+ st.error('Username/Password is incorrect')
451
+
452
+ if auth_status != True:
453
+ try:
454
+ username_forgot_pw, email_forgot_password, random_password = authenticator.forgot_password('Forgot password')
455
+ if username_forgot_pw:
456
+ st.session_state['config']['credentials']['usernames'][username_forgot_pw]['password'] = stauth.Hasher([random_password]).generate()[0]
457
+ send_email(email_forgot_password, random_password)
458
+ st.success('New password sent securely')
459
+ # Random password to be transferred to user securely
460
+ elif username_forgot_pw == False:
461
+ st.error('Username not found')
462
+ except Exception as e:
463
+ st.error(e)
464
+
DB/User.db ADDED
Binary file (32.8 kB). View file
 
Data_prep_functions.py ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ import numpy as np
6
+ import pickle
7
+ import statsmodels.api as sm
8
+ import numpy as np
9
+ from sklearn.metrics import mean_absolute_error, r2_score,mean_absolute_percentage_error
10
+ from sklearn.preprocessing import MinMaxScaler
11
+ import matplotlib.pyplot as plt
12
+ from statsmodels.stats.outliers_influence import variance_inflation_factor
13
+ from plotly.subplots import make_subplots
14
+
15
+ st.set_option('deprecation.showPyplotGlobalUse', False)
16
+ from datetime import datetime
17
+ import seaborn as sns
18
+
19
+ def calculate_discount(promo_price_series, non_promo_price_series):
20
+ # Calculate the 4-week moving average of non-promo price
21
+ window_size = 4
22
+ base_price = non_promo_price_series.rolling(window=window_size).mean()
23
+
24
+ # Calculate discount_raw
25
+ discount_raw_series = (1 - promo_price_series / base_price) * 100
26
+
27
+ # Calculate discount_final
28
+ discount_final_series = discount_raw_series.where(discount_raw_series >= 5, 0)
29
+
30
+ return base_price, discount_raw_series, discount_final_series
31
+
32
+
33
+ def create_dual_axis_line_chart(date_series, promo_price_series, non_promo_price_series, base_price_series, discount_series):
34
+ # Create traces for the primary axis (price vars)
35
+ trace1 = go.Scatter(
36
+ x=date_series,
37
+ y=promo_price_series,
38
+ name='Promo Price',
39
+ yaxis='y1'
40
+ )
41
+
42
+ trace2 = go.Scatter(
43
+ x=date_series,
44
+ y=non_promo_price_series,
45
+ name='Non-Promo Price',
46
+ yaxis='y1'
47
+ )
48
+
49
+ trace3 = go.Scatter(
50
+ x=date_series,
51
+ y=base_price_series,
52
+ name='Base Price',
53
+ yaxis='y1'
54
+ )
55
+
56
+ # Create a trace for the secondary axis (discount)
57
+ trace4 = go.Scatter(
58
+ x=date_series,
59
+ y=discount_series,
60
+ name='Discount',
61
+ yaxis='y2'
62
+ )
63
+
64
+ # Create the layout with dual axes
65
+ layout = go.Layout(
66
+ title='Price and Discount Over Time',
67
+ yaxis=dict(
68
+ title='Price',
69
+ side='left'
70
+ ),
71
+ yaxis2=dict(
72
+ title='Discount',
73
+ side='right',
74
+ overlaying='y',
75
+ showgrid=False
76
+ ),
77
+ xaxis=dict(title='Date'),
78
+ )
79
+
80
+ # Create the figure with the defined traces and layout
81
+ fig = go.Figure(data=[trace1, trace2, trace3, trace4], layout=layout)
82
+
83
+ return fig
84
+
85
+
86
+ def to_percentage(value):
87
+ return f'{value * 100:.1f}%'
88
+
89
+ def plot_actual_vs_predicted(date, y, predicted_values, model,target_column=None, flag=None, repeat_all_years=False, is_panel=False):
90
+ if flag is not None :
91
+ fig = make_subplots(specs=[[{"secondary_y": True}]])
92
+ else :
93
+ fig = go.Figure()
94
+
95
+ if is_panel :
96
+ df=pd.DataFrame()
97
+ df['date'] = date
98
+ df['Actual'] = y
99
+ df['Predicted'] = predicted_values
100
+ df_agg = df.groupby('date').agg({'Actual':'sum', 'Predicted':'sum'}).reset_index()
101
+ df_agg.columns = ['date', 'Actual', 'Predicted']
102
+ assert len(df_agg) == pd.Series(date).nunique()
103
+ # date = df_agg['date']
104
+ # y = df_agg['Actual']
105
+ # predicted_values = df_agg['Predicted']
106
+ # ymax = df_agg['Actual'].max() # Sprint3 - ymax to set y value for flag
107
+
108
+ fig.add_trace(go.Scatter(x=df_agg['date'], y=df_agg['Actual'], mode='lines', name='Actual', line=dict(color='#08083B')))
109
+ fig.add_trace(go.Scatter(x=df_agg['date'], y=df_agg['Predicted'], mode='lines', name='Predicted', line=dict(color='#11B6BD')))
110
+
111
+ else :
112
+ fig.add_trace(go.Scatter(x=date, y=y, mode='lines', name='Actual', line=dict(color='#08083B')))
113
+ fig.add_trace(go.Scatter(x=date, y=predicted_values, mode='lines', name='Predicted', line=dict(color='#11B6BD')))
114
+
115
+ line_values=[]
116
+ if flag:
117
+ min_date, max_date = flag[0], flag[1]
118
+ min_week = datetime.strptime(str(min_date), "%Y-%m-%d").strftime("%U")
119
+ max_week = datetime.strptime(str(max_date), "%Y-%m-%d").strftime("%U")
120
+ month=pd.to_datetime(min_date).month
121
+ day=pd.to_datetime(min_date).day
122
+ #st.write(pd.to_datetime(min_date).week)
123
+ #st.write(min_week)
124
+ # Initialize an empty list to store line values
125
+
126
+ # Sprint3 change : put flags to secondary axis, & made their y value to 1 instead of 5M
127
+ if repeat_all_years:
128
+ #line_values=list(pd.to_datetime((pd.Series(date)).dt.week).map(lambda x: 10000 if x==min_week else 0 ))
129
+ #st.write(pd.Series(date).map(lambda x: pd.Timestamp(x).week))
130
+ line_values=list(pd.Series(date).map(lambda x: 1 if (pd.Timestamp(x).week >=int(min_week)) & (pd.Timestamp(x).week <=int(max_week)) else 0))
131
+ assert len(line_values) == len(date)
132
+ #st.write(line_values)
133
+ fig.add_trace(go.Scatter(x=date, y=line_values, mode='lines', name='Flag', line=dict(color='#FF5733')),secondary_y=True)
134
+ else:
135
+ line_values = []
136
+
137
+ line_values = list(pd.Series(date).map(lambda x: 1 if (pd.Timestamp(x) >= pd.Timestamp(min_date)) and (pd.Timestamp(x) <= pd.Timestamp(max_date)) else 0))
138
+
139
+ #st.write(line_values)
140
+ fig.add_trace(go.Scatter(x=date, y=line_values, mode='lines', name='Flag', line=dict(color='#FF5733')),secondary_y=True)
141
+
142
+
143
+ # Calculate MAPE
144
+ mape = mean_absolute_percentage_error(y, predicted_values)
145
+
146
+ # Calculate AdjR2 # Assuming X is your feature matrix
147
+ r2 = r2_score(y, predicted_values)
148
+ adjr2 = 1 - (1 - r2) * (len(y) - 1) / (len(y) - len(model.fe_params) - 1)
149
+
150
+ # Create a table to display the metrics
151
+ metrics_table = pd.DataFrame({
152
+ 'Metric': ['MAPE', 'R-squared', 'AdjR-squared'],
153
+ 'Value': [mape, r2, adjr2]
154
+ })
155
+ # st.write(metrics_table)
156
+ fig.update_layout(
157
+ xaxis=dict(title='Date'),
158
+ yaxis=dict(title=target_column),
159
+ xaxis_tickangle=-30
160
+ )
161
+ fig.add_annotation(
162
+ text=f"MAPE: {mape*100:0.1f}%, Adjr2: {adjr2 *100:.1f}%",
163
+ xref="paper",
164
+ yref="paper",
165
+ x=0.95, # Adjust these values to position the annotation
166
+ y=1.2,
167
+ showarrow=False,
168
+ )
169
+ # print("{}{}"*20, len(line_values))
170
+ #metrics_table.set_index(['Metric'],inplace=True)
171
+ return metrics_table,line_values, fig
172
+
173
+ def plot_residual_predicted(actual, predicted, df):
174
+ df_=df.copy()
175
+ df_['Residuals'] = actual - pd.Series(predicted)
176
+ df_['StdResidual'] = (df_['Residuals'] - df_['Residuals'].mean()) / df_['Residuals'].std()
177
+
178
+ # Create a Plotly scatter plot
179
+ fig = px.scatter(df_, x=predicted, y='StdResidual', opacity=0.5,color_discrete_sequence=["#11B6BD"])
180
+
181
+ # Add horizontal lines
182
+ fig.add_hline(y=0, line_dash="dash", line_color="darkorange")
183
+ fig.add_hline(y=2, line_color="red")
184
+ fig.add_hline(y=-2, line_color="red")
185
+
186
+ fig.update_xaxes(title='Predicted')
187
+ fig.update_yaxes(title='Standardized Residuals (Actual - Predicted)')
188
+
189
+ # Set the same width and height for both figures
190
+ fig.update_layout(title='2.3.1 Residuals over Predicted Values', autosize=False, width=600, height=400)
191
+
192
+ return fig
193
+
194
+ def residual_distribution(actual, predicted):
195
+ Residuals = actual - pd.Series(predicted)
196
+
197
+ # Create a Seaborn distribution plot
198
+ sns.set(style="whitegrid")
199
+ plt.figure(figsize=(6, 4))
200
+ sns.histplot(Residuals, kde=True, color="#11B6BD")
201
+
202
+ plt.title('2.3.3 Distribution of Residuals')
203
+ plt.xlabel('Residuals')
204
+ plt.ylabel('Probability Density')
205
+
206
+ return plt
207
+
208
+
209
+ def qqplot(actual, predicted):
210
+ Residuals = actual - pd.Series(predicted)
211
+ Residuals = pd.Series(Residuals)
212
+ Resud_std = (Residuals - Residuals.mean()) / Residuals.std()
213
+
214
+ # Create a QQ plot using Plotly with custom colors
215
+ fig = go.Figure()
216
+ fig.add_trace(go.Scatter(x=sm.ProbPlot(Resud_std).theoretical_quantiles,
217
+ y=sm.ProbPlot(Resud_std).sample_quantiles,
218
+ mode='markers',
219
+ marker=dict(size=5, color="#11B6BD"),
220
+ name='QQ Plot'))
221
+
222
+ # Add the 45-degree reference line
223
+ diagonal_line = go.Scatter(
224
+ x=[-2, 2], # Adjust the x values as needed to fit the range of your data
225
+ y=[-2, 2], # Adjust the y values accordingly
226
+ mode='lines',
227
+ line=dict(color='red'), # Customize the line color and style
228
+ name=' '
229
+ )
230
+ fig.add_trace(diagonal_line)
231
+
232
+ # Customize the layout
233
+ fig.update_layout(title='2.3.2 QQ Plot of Residuals',title_x=0.5, autosize=False, width=600, height=400,
234
+ xaxis_title='Theoretical Quantiles', yaxis_title='Sample Quantiles')
235
+
236
+ return fig
Eda_functions.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import plotly.express as px
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ from sklearn.metrics import r2_score
6
+ from collections import OrderedDict
7
+ import plotly.express as px
8
+ import plotly.graph_objects as go
9
+ import pandas as pd
10
+ import seaborn as sns
11
+ import matplotlib.pyplot as plt
12
+ import streamlit as st
13
+ import re
14
+ from matplotlib.colors import ListedColormap
15
+ # from st_aggrid import AgGrid, GridOptionsBuilder
16
+ # from src.agstyler import PINLEFT, PRECISION_TWO, draw_grid
17
+
18
+
19
+ def format_numbers(x):
20
+ if abs(x) >= 1e6:
21
+ # Format as millions with one decimal place and commas
22
+ return f'{x/1e6:,.1f}M'
23
+ elif abs(x) >= 1e3:
24
+ # Format as thousands with one decimal place and commas
25
+ return f'{x/1e3:,.1f}K'
26
+ else:
27
+ # Format with one decimal place and commas for values less than 1000
28
+ return f'{x:,.1f}'
29
+
30
+
31
+
32
+ def line_plot(data, x_col, y1_cols, y2_cols, title):
33
+ fig = go.Figure()
34
+
35
+ for y1_col in y1_cols:
36
+ fig.add_trace(go.Scatter(x=data[x_col], y=data[y1_col], mode='lines', name=y1_col,line=dict(color='#11B6BD')))
37
+
38
+ for y2_col in y2_cols:
39
+ fig.add_trace(go.Scatter(x=data[x_col], y=data[y2_col], mode='lines', name=y2_col, yaxis='y2',line=dict(color='#739FAE')))
40
+ if len(y2_cols)!=0:
41
+ fig.update_layout(yaxis=dict(), yaxis2=dict(overlaying='y', side='right'))
42
+ else:
43
+ fig.update_layout(yaxis=dict(), yaxis2=dict(overlaying='y', side='right'))
44
+ if title:
45
+ fig.update_layout(title=title)
46
+ fig.update_xaxes(showgrid=False)
47
+ fig.update_yaxes(showgrid=False)
48
+ fig.update_layout(legend=dict(
49
+ orientation="h",
50
+ yanchor="top",
51
+ y=1.1,
52
+ xanchor="center",
53
+ x=0.5
54
+ ))
55
+
56
+ return fig
57
+
58
+
59
+ def line_plot_target(df,target,title):
60
+
61
+ coefficients = np.polyfit(df['date'].view('int64'), df[target], 1)
62
+ trendline = np.poly1d(coefficients)
63
+ fig = go.Figure()
64
+
65
+ fig.add_trace(go.Scatter(x=df['date'], y=df[target], mode='lines', name=target,line=dict(color='#11B6BD')))
66
+ trendline_x = df['date']
67
+ trendline_y = trendline(df['date'].view('int64'))
68
+
69
+
70
+ fig.add_trace(go.Scatter(x=trendline_x, y=trendline_y, mode='lines', name='Trendline', line=dict(color='#739FAE')))
71
+
72
+ fig.update_layout(
73
+ title=title,
74
+ xaxis=dict(type='date')
75
+ )
76
+
77
+ for year in df['date'].dt.year.unique()[1:]:
78
+
79
+ january_1 = pd.Timestamp(year=year, month=1, day=1)
80
+ fig.add_shape(
81
+ go.layout.Shape(
82
+ type="line",
83
+ x0=january_1,
84
+ x1=january_1,
85
+ y0=0,
86
+ y1=1,
87
+ xref="x",
88
+ yref="paper",
89
+ line=dict(color="grey", width=1.5, dash="dash"),
90
+ )
91
+ )
92
+ fig.update_layout(legend=dict(
93
+ orientation="h",
94
+ yanchor="top",
95
+ y=1.1,
96
+ xanchor="center",
97
+ x=0.5
98
+ ))
99
+ return fig
100
+
101
+ def correlation_plot(df,selected_features,target):
102
+ custom_cmap = ListedColormap(['#08083B', "#11B6BD"])
103
+ corr_df=df[selected_features]
104
+ corr_df=pd.concat([corr_df,df[target]],axis=1)
105
+ fig, ax = plt.subplots(figsize=(16, 12))
106
+ sns.heatmap(corr_df.corr(),annot=True, cmap='Blues', fmt=".2f", linewidths=0.5,mask=np.triu(corr_df.corr()))
107
+ #plt.title('Correlation Plot')
108
+ plt.xticks(rotation=45)
109
+ plt.yticks(rotation=0)
110
+ return fig
111
+
112
+ def summary(data,selected_feature,spends,Target=None):
113
+
114
+ if Target:
115
+ sum_df = data[selected_feature]
116
+ sum_df['Year']=data['date'].dt.year
117
+ sum_df=sum_df.groupby('Year')[selected_feature].sum()
118
+ sum_df=sum_df.reset_index()
119
+ total_sum = sum_df.sum(numeric_only=True)
120
+ total_sum['Year'] = 'Total'
121
+ #sum_df = pd.concat([sum_df, total_sum.to_frame().T],axis=0,ignore_index=True).copy()
122
+ sum_df = sum_df.append(total_sum, ignore_index=True)
123
+ #st.write(sum_df)
124
+ sum_df.set_index(['Year'],inplace=True)
125
+ sum_df=sum_df.applymap(format_numbers)
126
+ spends_col=[col for col in sum_df.columns if any(keyword in col for keyword in ['spends', 'cost'])]
127
+ for col in spends_col:
128
+ sum_df[col]=sum_df[col].map(lambda x: f'${x}')
129
+ # st.write(spends_col)
130
+ # sum_df = sum_df.reindex(sorted(sum_df.columns), axis=1)
131
+
132
+ return sum_df
133
+ else:
134
+ #selected_feature=list(selected_feature)
135
+ selected_feature.append(spends)
136
+ selected_feature=list(set(selected_feature))
137
+ if len(selected_feature)>1:
138
+ sum_df = data[selected_feature]
139
+ sum_df['Year']=data['date'].dt.year
140
+ sum_df=sum_df.groupby('Year')[selected_feature].agg('sum')
141
+ sum_df['CPM/CPC']=(sum_df.iloc[:, 1] / sum_df.iloc[:, 0])*1000
142
+ sum_df.loc['Grand Total']=sum_df.sum()
143
+
144
+ sum_df=sum_df.applymap(format_numbers)
145
+ sum_df.fillna('-',inplace=True)
146
+ sum_df=sum_df.replace({"0.0":'-','nan':'-'})
147
+ spends_col=[col for col in sum_df.columns if any(keyword in col for keyword in ['spends', 'cost'])]
148
+ for col in spends_col:
149
+ sum_df[col]=sum_df[col].map(lambda x: f'${x}')
150
+ return sum_df
151
+ else:
152
+ sum_df = data[selected_feature]
153
+ sum_df['Year']=data['date'].dt.year
154
+ sum_df=sum_df.groupby('Year')[selected_feature].agg('sum')
155
+ sum_df.loc['Grand Total']=sum_df.sum()
156
+ sum_df=sum_df.applymap(format_numbers)
157
+ sum_df.fillna('-',inplace=True)
158
+ sum_df=sum_df.replace({"0.0":'-','nan':'-'})
159
+ spends_col=[col for col in sum_df.columns if any(keyword in col for keyword in ['spends', 'cost'])]
160
+ for col in spends_col:
161
+ sum_df[col]=sum_df[col].map(lambda x: f'${x}')
162
+ return sum_df
163
+
164
+
165
+ def sanitize_key(key, prefix=""):
166
+ # Use regular expressions to remove non-alphanumeric characters and spaces
167
+ key = re.sub(r'[^a-zA-Z0-9]', '', key)
168
+ return f"{prefix}{key}"
169
+
170
+
171
+
172
+
Full_Logo_Blue.jpeg ADDED
Full_Logo_Blue.jpg ADDED
Full_Logo_Blue.png ADDED
Full_Logo_Vibrant_Turquoise.png ADDED
Home.py ADDED
@@ -0,0 +1,631 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ import uuid
3
+ import streamlit as st
4
+ from utilities import (
5
+ load_local_css,
6
+ set_header,
7
+ load_authenticator,
8
+ send_email,
9
+ )
10
+ import streamlit_authenticator as stauth
11
+ import yaml
12
+ from yaml import SafeLoader
13
+ import os
14
+ import datetime
15
+ import shutil
16
+ import pandas as pd
17
+ from st_aggrid import AgGrid
18
+ from st_aggrid import GridOptionsBuilder, GridUpdateMode
19
+ import pickle
20
+ from pathlib import Path
21
+
22
+ st.set_page_config(layout="wide")
23
+ load_local_css("styles.css")
24
+ set_header()
25
+
26
+ # def authenticator():
27
+ for k, v in st.session_state.items():
28
+ if k not in ["logout", "login", "config"] and not k.startswith(
29
+ "FormSubmitter"
30
+ ):
31
+ st.session_state[k] = v
32
+ with open("config.yaml") as file:
33
+ config = yaml.load(file, Loader=SafeLoader)
34
+ st.session_state["config"] = config
35
+ authenticator = stauth.Authenticate(
36
+ config["credentials"],
37
+ config["cookie"]["name"],
38
+ config["cookie"]["key"],
39
+ config["cookie"]["expiry_days"],
40
+ config["preauthorized"],
41
+ )
42
+ st.session_state["authenticator"] = authenticator
43
+ name, authentication_status, username = authenticator.login("Login", "main")
44
+ auth_status = st.session_state.get("authentication_status")
45
+
46
+ st.session_state["name"] = name
47
+ if auth_status == True:
48
+ authenticator.logout("Logout", "main")
49
+ is_state_initiaized = st.session_state.get("initialized", False)
50
+
51
+ if not is_state_initiaized:
52
+
53
+ if "session_name" not in st.session_state:
54
+ st.session_state["session_name"] = None
55
+
56
+ cols1 = st.columns([2, 1])
57
+
58
+ with cols1[0]:
59
+ st.markdown(f"**Welcome {name}**")
60
+ with cols1[1]:
61
+ st.markdown(
62
+ f"**Current Session: {st.session_state['session_name']}**"
63
+ )
64
+
65
+ # relative_path = Path('DB_Sample','..' ,'DB', 'User.db')
66
+ # absolute_path = Path.cwd() / relative_path
67
+ # st.write(absolute_path)
68
+ # database_file=Path(__file__).parent / relative_path
69
+
70
+ database_file = r"DB/User.db"
71
+
72
+ conn = sqlite3.connect(
73
+ database_file, check_same_thread=False
74
+ ) # connection with sql db
75
+ c = conn.cursor()
76
+
77
+ # c.execute('DELETE FROM sessions')
78
+ # conn.commit()
79
+ # c.executemany("INSERT INTO users (username, email) VALUES (?, ?)",
80
+ # [("Geetha Krishna", "geetha1732@gmail.com"),
81
+ # ("Samkeet Sangai", "samkeet.sangai@blend360.com"),
82
+ # ('Manoj P','manojp1732@gmcail.com'),
83
+ # ('Srishti Verma','srishti.verma@blend360.com'),
84
+ # ('Ismail mohammed',"mohammed.ismail@blend360.com"),
85
+ # ('Sharon Sheng','sharon.sheng@mastercard.com'),
86
+ # ('Ioannis Papadopoulos','ioannis.papadopoulos@mastercard.com'),
87
+ # ('Herman Kwong',"herman.kwong@mastercard.com")
88
+ # ])
89
+
90
+ # conn.commit()
91
+
92
+ # c.execute(f"PRAGMA table_info({'sessions'})")
93
+ # conn.commit()
94
+
95
+ # st.write(c.fetchall())
96
+
97
+ # c.execute("Select * from users")
98
+ # st.write(c.fetchall())
99
+
100
+ page_name = "Home Page"
101
+
102
+ c.execute(
103
+ "SELECT email, user_id, user_type FROM users WHERE username = ?",
104
+ (name,),
105
+ )
106
+ user_data = c.fetchone()
107
+
108
+ email, user_id, user_type = user_data
109
+
110
+ # st.write(user_type)
111
+ # with st.sidebar:
112
+ # # if user_type != 'technical':
113
+ # st.page_link("home.py", label="Home123")
114
+ # st.page_link('pages/1_Data_Import.py',label='Data Import')
115
+ # st.page_link('pages/2_Data_Validation.py',label="Data Validation")
116
+ # st.page_link('pages/3_Transformations.py',label='Transformations')
117
+ # st.page_link("pages/4_Model_Build.py")
118
+ # st.page_link('pages/5_Model_Tuning_with_panel.py',label='Model Tuning')
119
+
120
+ # st.page_link('pages/5_Saved_Model_Results.py',label="Saved Model Results")
121
+
122
+ # st.write(pd.to_datetime(created_time))
123
+ # c.execute("DELETE FROM sessions")
124
+ # # c.execute('select * from sessions')
125
+ # conn.commit()
126
+ # output = c.fetchall()
127
+
128
+ # st.write(output)
129
+
130
+ # if emails is not None:
131
+ # email = emails[0]
132
+
133
+ folder_path = r"Users"
134
+ user_folder_path = os.path.join(folder_path, email)
135
+
136
+ # project_dct = {
137
+ # 'data_import': {
138
+ # "granularity_selection":0,
139
+ # 'cat_dct':{},
140
+ # "merged_df":None,
141
+ # 'edited_df':None,
142
+ # "numeric_columns":None,
143
+ # "files_dict":None,
144
+ # 'formatted_panel1_values':None,
145
+ # 'formatted_panel2_values':None,
146
+ # "missing_stats_df":None,
147
+ # 'edited_stats_df':None
148
+
149
+ # },
150
+
151
+ # 'data_validation': {"target_column":0,
152
+ # 'selected_panels':None,
153
+ # "selected_feature":0,
154
+ # "validated_variables":[],
155
+ # "Non_media_variables":0
156
+
157
+ # },
158
+ # 'transformations': {},
159
+ # 'model_build': {},
160
+ # 'model_tuning':{},
161
+ # 'saved_model_results': {},
162
+ # 'model_result_overview': {},
163
+ # 'build_response_curves': {},
164
+ # 'scenario_planner': {},
165
+ # 'saved_scenarios': {},
166
+ # 'optimized_result_analysis': {}
167
+ # }
168
+ # st.session_state['project_dct']=project_dct
169
+
170
+ # st.write(project_dct)
171
+
172
+ def dump_session_details_db(allowed_users, session_name):
173
+
174
+ created_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
175
+
176
+ session_id = str(uuid.uuid4())
177
+
178
+ if len(allowed_users) == 0:
179
+ c.execute(
180
+ "INSERT INTO sessions VALUES (?, ?, ?, ?, ?, ?, ?,?)",
181
+ (
182
+ user_id,
183
+ name,
184
+ session_id,
185
+ session_name,
186
+ page_name,
187
+ created_time,
188
+ created_time,
189
+ None,
190
+ ),
191
+ )
192
+ conn.commit()
193
+ else:
194
+ for allowed_user in allowed_users:
195
+ c.execute(
196
+ "INSERT INTO sessions VALUES (?, ?, ?, ?, ?, ?, ?,?)",
197
+ (
198
+ user_id,
199
+ name,
200
+ session_id,
201
+ session_name,
202
+ "1_Home.py",
203
+ created_time,
204
+ created_time,
205
+ allowed_user,
206
+ ),
207
+ )
208
+ conn.commit()
209
+
210
+ def update_project_name_box():
211
+ st.session_state["project_name_box"] = ""
212
+
213
+ # st.success('Project created')
214
+
215
+ if "session_path" not in st.session_state:
216
+ st.session_state["session_path"] = None
217
+
218
+ # creating dir for user
219
+
220
+ if not os.path.exists(user_folder_path):
221
+ os.makedirs(user_folder_path)
222
+
223
+ c.execute("SELECT DISTINCT username FROM users ")
224
+ allowed_users_db = [user[0] for user in c.fetchall() if user[0] != name]
225
+
226
+ c.execute(
227
+ "SELECT session_name from sessions WHERE allowed_users = ?", (name,)
228
+ )
229
+ available_sessions = c.fetchall() # all sessions available for user
230
+
231
+ c.execute(
232
+ "SELECT Distinct Session_name, status, updated_time as last_updated FROM sessions WHERE owner=?",
233
+ (name,),
234
+ )
235
+
236
+ session_summary = c.fetchall()
237
+
238
+ session_summary_df = pd.DataFrame(
239
+ session_summary,
240
+ columns=["Project Name", "Last Page Edited", "Modified Date"],
241
+ )
242
+ session_summary_df["Modified Date"] = session_summary_df[
243
+ "Modified Date"
244
+ ].map(lambda x: pd.to_datetime(x))
245
+
246
+ session_summary_df = session_summary_df.sort_values(
247
+ by=["Modified Date"], ascending=False
248
+ )
249
+
250
+ session_summary_df["Last Page Modified"] = session_summary_df[
251
+ "Last Page Edited"
252
+ ].map(lambda x: x[2:].replace("_", " ").replace(".py", ""))
253
+
254
+ st.header("Manage Projects")
255
+
256
+ st.markdown(
257
+ """
258
+ * **Load Existing Project:** Select the project you want and click 'Load Project'.
259
+ * **Delete Project:** If you wish to delete a project, select it and click 'Delete Project'.
260
+ * **Modify User Access:** Make changes to user access permissions as needed.
261
+
262
+ """
263
+ )
264
+
265
+ # session_col=st.columns([5,5])
266
+ # with session_col[0]:
267
+ gd = GridOptionsBuilder.from_dataframe(session_summary_df)
268
+ gd.configure_pagination(
269
+ enabled=True, paginationAutoPageSize=False, paginationPageSize=10
270
+ )
271
+ gd.configure_selection(use_checkbox=True)
272
+
273
+ gridoptions = gd.build()
274
+
275
+ column_defs = gridoptions["columnDefs"]
276
+ columns_to_hide = ["Last Page Edited"]
277
+ for col in column_defs:
278
+ if col["headerName"] in columns_to_hide:
279
+ col["hide"] = True
280
+
281
+ if session_summary_df.shape[0] < 5:
282
+ height = (session_summary_df.shape[0]) * 20 + 100
283
+
284
+ else:
285
+ height = None
286
+
287
+ table = AgGrid(
288
+ session_summary_df,
289
+ gridOptions=gridoptions,
290
+ update_mode=GridUpdateMode.SELECTION_CHANGED,
291
+ height=height,
292
+ fit_columns_on_grid_load=True,
293
+ )
294
+
295
+ if len(table.selected_rows) > 0:
296
+
297
+ selected_rows = table.selected_rows
298
+
299
+ project_name = selected_rows[0]["Project Name"]
300
+
301
+ st.session_state["project_name"] = project_name
302
+
303
+ project_col = st.columns(2)
304
+
305
+ with project_col[0]:
306
+
307
+ project_path = os.path.join(user_folder_path, project_name)
308
+
309
+ st.session_state["project_path"] = project_path # load project dct
310
+
311
+ project_dct_path = os.path.join(project_path, "project_dct.pkl")
312
+
313
+ with open(project_dct_path, "rb") as f:
314
+ st.session_state["project_dct"] = pickle.load(f)
315
+
316
+ # st.write(st.session_state['project_dct'])
317
+
318
+ with st.spinner("Redirecting to last Saved Page"):
319
+
320
+ try:
321
+ page_link = st.page_link(
322
+ f"pages/{selected_rows[0]['Last Page Edited']}",
323
+ label=f"Load Project - **{project_name}**",
324
+ )
325
+ except Exception as e:
326
+ try:
327
+ pag_link = st.page_link(
328
+ "pages/1_Data_Import.py",
329
+ label=f"Load Project - **{project_name}**",
330
+ )
331
+ except Exception as e:
332
+ st.error("Something went wrong")
333
+
334
+ with project_col[1]:
335
+
336
+ if st.button(
337
+ f"Delete Project - **{selected_rows[0]['Project Name']}**"):
338
+
339
+ project_name_to_delete = selected_rows[0]["Project Name"]
340
+ st.warning(
341
+ f"{project_name_to_delete} will be deleted permanentaly and all the information regarding the project will be lost"
342
+ )
343
+ c.execute(
344
+ "Delete FROM sessions WHERE session_name =? AND owner =?",
345
+ (
346
+ project_name_to_delete,
347
+ st.session_state["name"],
348
+ ),
349
+ )
350
+ if os.path.exists(project_path):
351
+ shutil.rmtree(project_path)
352
+
353
+ conn.commit()
354
+ st.rerun()
355
+
356
+
357
+ with st.expander("Modify user access for selected project"):
358
+
359
+ c.execute(
360
+ "SELECT DISTINCT allowed_users FROM sessions WHERE session_name = ?",
361
+ (project_name,),
362
+ )
363
+
364
+ present_users = c.fetchall()
365
+
366
+ present_users = [
367
+ user[0]
368
+ for user in present_users
369
+ if user[0] != name and user[0] is not None
370
+ ]
371
+
372
+ present_users = None if len(present_users) == 0 else present_users
373
+
374
+ allowed_users = st.multiselect(
375
+ "Modify other users access",
376
+ allowed_users_db,
377
+ default=present_users,
378
+ )
379
+
380
+ if st.button("Save Changes", use_container_width=True):
381
+ pass
382
+
383
+ c.execute("SELECT Session_name FROM sessions WHERE owner=?", (name,))
384
+
385
+ user_projects = [
386
+ project[0] for project in c.fetchall()
387
+ ] # user owned sessions
388
+
389
+ with st.expander("Create New Project"):
390
+ st.markdown(
391
+ "To create a new project, Enter Project name below, select user who you want to give access of this project and click **Create New Project**"
392
+ )
393
+
394
+ project_col1 = st.columns(2)
395
+ with project_col1[0]:
396
+ project_name = st.text_input("Enter Project Name",key="project_name_box")
397
+
398
+ if project_name in user_projects:
399
+ st.warning("Project already exists please enter new name")
400
+
401
+ with project_col1[1]:
402
+
403
+ allowed_users = st.multiselect(
404
+ "Select Users who can access to this Project", allowed_users_db
405
+ )
406
+ allowed_users = list(allowed_users)
407
+
408
+ Create = st.button("Create New Project", use_container_width=True)
409
+
410
+ if Create:
411
+ if len(project_name) == 0:
412
+ st.error("Plase enter a valid project name")
413
+ st.stop()
414
+ allowed_users.append(name)
415
+
416
+ if project_name in user_projects:
417
+
418
+ st.warning("Project already exists please enter new name")
419
+ st.stop()
420
+
421
+ project_path = os.path.join(user_folder_path, project_name)
422
+
423
+ os.makedirs(project_path)
424
+
425
+ dump_session_details_db(allowed_users, project_name)
426
+
427
+ project_dct = {
428
+ "data_import": {
429
+ "granularity_selection": 0,
430
+ "cat_dct": {},
431
+ "merged_df": None,
432
+ "edited_df": None,
433
+ "numeric_columns": None,
434
+ "files_dict": None,
435
+ "formatted_panel1_values": None,
436
+ "formatted_panel2_values": None,
437
+ "missing_stats_df": None,
438
+ "edited_stats_df": None,
439
+ "default_df": None,
440
+ "final_df": None,
441
+ "edited_df": None,
442
+ },
443
+ "data_validation": {
444
+ "target_column": 0,
445
+ "selected_panels": None,
446
+ "selected_feature": 0,
447
+ "validated_variables": [],
448
+ "Non_media_variables": 0,
449
+ },
450
+ "transformations": {"Media": {}, "Exogenous": {}},
451
+ "model_build": {
452
+ "sel_target_col": None,
453
+ "all_iters_check": False,
454
+ "iterations": 0,
455
+ "build_button": False,
456
+ "show_results_check": False,
457
+ "session_state_saved": {},
458
+ },
459
+ "model_tuning": {
460
+ "sel_target_col": None,
461
+ "sel_model": {},
462
+ "flag_expander": False,
463
+ "start_date_default": None,
464
+ "end_date_default": None,
465
+ "repeat_default": "No",
466
+ "flags": {},
467
+ "select_all_flags_check": {},
468
+ "selected_flags": {},
469
+ "trend_check": False,
470
+ "week_num_check": False,
471
+ "sine_cosine_check": False,
472
+ "session_state_saved": {},
473
+ },
474
+ "saved_model_results": {
475
+ "selected_options": None,
476
+ "model_grid_sel": [1],
477
+ },
478
+ "model_result_overview": {},
479
+ "build_response_curves": {
480
+ "response_metrics_selectbox": 0,
481
+ "panel_selected_selectbox": 0,
482
+ "selected_channel_name_selectbox": 0,
483
+ "K_number_input": "default",
484
+ "b_number_input": "default",
485
+ "a_number_input": "default",
486
+ "x0_number_input": "default",
487
+ },
488
+ "scenario_planner": {
489
+ "panel_selected": 0,
490
+ "metrics_selected": 0,
491
+ "scenario": None,
492
+ "optimization_key_value": None,
493
+ "total_spends_change": None,
494
+ "optimze_all_channels": False,
495
+ },
496
+ "saved_scenarios": {
497
+ "selected_scenario_selectbox_key": 0,
498
+ },
499
+ "optimized_result_analysis": {
500
+ "selected_scenario_selectbox_visualize": 0,
501
+ "metric_selectbox_visualize": 0,
502
+ },
503
+ }
504
+
505
+ st.session_state["project_dct"] = project_dct
506
+
507
+ st.session_state["project_path"] = project_path
508
+
509
+ project_dct_path = os.path.join(project_path, "project_dct.pkl")
510
+
511
+ with open(project_dct_path, "wb") as f:
512
+ pickle.dump(project_dct, f)
513
+
514
+ st.success("Project Created")
515
+ st.rerun()
516
+ # st.session_state['project_name_box']=''
517
+ # st.rerun()
518
+
519
+ # st.header('Clone Project')
520
+
521
+ with st.expander("**Clone saved projects**"):
522
+
523
+ c.execute(
524
+ "SELECT DISTINCT owner FROM sessions WHERE allowed_users=?",
525
+ (name,),
526
+ ) # owner
527
+ owners = c.fetchall()
528
+
529
+ owners = [owner[0] for owner in owners]
530
+
531
+ if len(owners) == 0:
532
+
533
+ st.warning("You dont have any shared project yet!")
534
+
535
+ st.stop()
536
+
537
+ cols = st.columns(2)
538
+
539
+ with cols[0]:
540
+
541
+ owner = st.selectbox("Select Owner", owners)
542
+
543
+ c.execute("SELECT email FROM users WHERE username=?", (owner,))
544
+
545
+ owner_email = c.fetchone()[0]
546
+
547
+ owner_folder_path = os.path.join(folder_path, owner_email)
548
+
549
+ with cols[1]:
550
+
551
+ c.execute(
552
+ "SELECT session_name FROM sessions WHERE owner=? AND allowed_users = ?",
553
+ (owner, name),
554
+ ) # available sessions for user
555
+ project_names = c.fetchall()
556
+
557
+ project_name_owner = st.selectbox(
558
+ "Select a saved Project available for you",
559
+ [project_name[0] for project_name in project_names],
560
+ )
561
+ owner_project_path = os.path.join(owner_folder_path, project_name)
562
+
563
+ with cols[0]:
564
+ project_name_user = st.text_input(
565
+ "Enter Project Name", value=project_name_owner
566
+ )
567
+
568
+ if project_name in user_projects:
569
+
570
+ st.warning(
571
+ "This Project name already exists in your directory Please enter a different name"
572
+ )
573
+
574
+ # st.stop()
575
+
576
+ project_path = os.path.join(user_folder_path, project_name_user)
577
+
578
+ owner_project_path = os.path.join(
579
+ owner_folder_path, project_name_owner
580
+ )
581
+
582
+ with cols[1]:
583
+
584
+ allowed_users = st.multiselect(
585
+ "Select Users who can access this session", allowed_users_db
586
+ )
587
+ allowed_users = list(allowed_users)
588
+
589
+ if st.button("Load Project", use_container_width=True):
590
+
591
+ if os.path.exists(project_path):
592
+
593
+ st.warning(
594
+ "This Project name already exists in your directory Please enter a different name"
595
+ )
596
+
597
+ st.stop()
598
+
599
+ shutil.copytree(owner_project_path, project_path)
600
+
601
+ project_dct_path = os.path.join(project_path, "project_dct.pkl")
602
+
603
+ with open(project_dct_path, "rb") as f:
604
+ st.session_state["project_dct"] = pickle.load(f)
605
+
606
+ st.session_state["project_path"] = project_path
607
+
608
+ # st.write(st.session_state['project_dct'])
609
+
610
+ dump_session_details_db(allowed_users, project_name_user)
611
+ st.success("Project Cloned")
612
+
613
+ elif auth_status == False:
614
+ st.error("Username/Password is incorrect")
615
+
616
+ if auth_status != True:
617
+ try:
618
+ username_forgot_pw, email_forgot_password, random_password = (
619
+ authenticator.forgot_password("Forgot password")
620
+ )
621
+ if username_forgot_pw:
622
+ st.session_state["config"]["credentials"]["usernames"][
623
+ username_forgot_pw
624
+ ]["password"] = stauth.Hasher([random_password]).generate()[0]
625
+ send_email(email_forgot_password, random_password)
626
+ st.success("New password sent securely")
627
+ # Random password to be transferred to user securely
628
+ elif username_forgot_pw == False:
629
+ st.error("Username not found")
630
+ except Exception as e:
631
+ st.error(e)
Home_old_version.py ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ import uuid
3
+ import json
4
+ import streamlit as st
5
+ from utilities import (
6
+ load_local_css,
7
+ set_header,
8
+ load_authenticator,
9
+ send_email,
10
+ )
11
+ import streamlit_authenticator as stauth
12
+ import yaml
13
+ from yaml import SafeLoader
14
+ import os
15
+ import datetime
16
+ import subprocess
17
+ import shutil
18
+ import pandas as pd
19
+ from st_aggrid import AgGrid
20
+ from st_aggrid import GridOptionsBuilder, GridUpdateMode
21
+ import pickle
22
+ from pathlib import Path
23
+
24
+ st.set_page_config(layout="wide")
25
+ load_local_css("styles.css")
26
+ set_header()
27
+
28
+ # def authenticator():
29
+ for k, v in st.session_state.items():
30
+ if k not in ["logout", "login", "config"] and not k.startswith(
31
+ "FormSubmitter"
32
+ ):
33
+ st.session_state[k] = v
34
+ with open("config.yaml") as file:
35
+ config = yaml.load(file, Loader=SafeLoader)
36
+ st.session_state["config"] = config
37
+ authenticator = stauth.Authenticate(
38
+ config["credentials"],
39
+ config["cookie"]["name"],
40
+ config["cookie"]["key"],
41
+ config["cookie"]["expiry_days"],
42
+ config["preauthorized"],
43
+ )
44
+ st.session_state["authenticator"] = authenticator
45
+ name, authentication_status, username = authenticator.login("Login", "main")
46
+ auth_status = st.session_state.get("authentication_status")
47
+
48
+ if auth_status == True:
49
+ authenticator.logout("Logout", "main")
50
+ is_state_initiaized = st.session_state.get("initialized", False)
51
+
52
+ if not is_state_initiaized:
53
+
54
+ if "session_name" not in st.session_state:
55
+ st.session_state["session_name"] = None
56
+
57
+ cols1 = st.columns([2, 1])
58
+
59
+ with cols1[0]:
60
+ st.markdown(f"**Welcome {name}**")
61
+ with cols1[1]:
62
+ st.markdown(
63
+ f"**Current Session: {st.session_state['session_name']}**"
64
+ )
65
+
66
+ # relative_path = Path('DB_Sample','..' ,'DB', 'User.db')
67
+ # absolute_path = Path.cwd() / relative_path
68
+ # st.write(absolute_path)
69
+ # database_file=Path(__file__).parent / relative_path
70
+
71
+ database_file = r"C:\Users\ManojP\Documents\Mastercard\Build\DB_Sample\V6_persistant_data_home_page_connected_pages\DB\User.db"
72
+
73
+ conn = sqlite3.connect(database_file) # connection with sql db
74
+ c = conn.cursor()
75
+ c.execute("SELECT * from sessions")
76
+ st.write(c.fetchall())
77
+ # c.executemany("INSERT INTO users (username, email) VALUES (?, ?)",
78
+ # [("Geetha Krishna", "geetha1732@gmail.com"),
79
+ # ("Samkeet Sangai", "samkeet.sangai@blend360.com"),
80
+ # ('Manoj P','manojp1732@gmail.com'),
81
+ # ('Srishti Verma','srishti.verma@blend360.com'),
82
+ # ('Ismail mohammed',"mohammed.ismail@blend360.com"),
83
+ # ('Sharon Sheng','sharon.sheng@mastercard.com'),
84
+ # ('Ioannis Papadopoulos','ioannis.papadopoulos@mastercard.com'),
85
+ # ('Herman Kwong',"herman.kwong@mastercard.com")
86
+ # ])
87
+
88
+ # conn.commit()
89
+
90
+ # c.execute("DELETE from sessions")
91
+ # conn.commit()
92
+ # st.write(c.fetchall())
93
+
94
+ page_name = "Home Page"
95
+
96
+ c.execute(
97
+ "SELECT email, user_id, user_type FROM users WHERE username = ?",
98
+ (name,),
99
+ )
100
+ user_data = c.fetchone()
101
+ email, user_id, user_type = user_data
102
+
103
+ # st.write(user_type)
104
+ # with st.sidebar:
105
+ # # if user_type != 'technical':
106
+ # st.page_link("home.py", label="Home123")
107
+ # st.page_link('pages/1_Data_Import.py',label='Data Import')
108
+ # st.page_link('pages/2_Data_Validation.py',label="Data Validation")
109
+ # st.page_link('pages/3_Transformations.py',label='Transformations')
110
+ # st.page_link("pages/4_Model_Build.py")
111
+ # st.page_link('pages/5_Model_Tuning_with_panel.py',label='Model Tuning')
112
+
113
+ # st.page_link('pages/5_Saved_Model_Results.py',label="Saved Model Results")
114
+
115
+ # st.write(pd.to_datetime(created_time))
116
+ # c.execute("DELETE FROM sessions")
117
+ # c.execute('select * from sessions')
118
+ # conn.commit()
119
+ # output = c.fetchall()
120
+
121
+ # st.write(output)
122
+
123
+ # if emails is not None:
124
+ # email = emails[0]
125
+
126
+ folder_path = r"C:\Users\ManojP\Documents\Mastercard\Build\DB_Sample\V6_persistant_data_home_page_connected_pages\Users"
127
+ user_folder_path = os.path.join(folder_path, email)
128
+
129
+ # project_dct = {
130
+ # 'data_import': {
131
+ # "granularity_selection":0,
132
+ # 'cat_dct':{},
133
+ # "merged_df":None,
134
+ # 'edited_df':None,
135
+ # "numeric_columns":None,
136
+ # "files_dict":None,
137
+ # 'formatted_panel1_values':None,
138
+ # 'formatted_panel2_values':None,
139
+ # "missing_stats_df":None,
140
+ # 'edited_stats_df':None
141
+
142
+ # },
143
+
144
+ # 'data_validation': {"target_column":0,
145
+ # 'selected_panels':None,
146
+ # "selected_feature":0,
147
+ # "validated_variables":[],
148
+ # "Non_media_variables":0
149
+
150
+ # },
151
+ # 'transformations': {},
152
+ # 'model_build': {},
153
+ # 'model_tuning':{},
154
+ # 'saved_model_results': {},
155
+ # 'model_result_overview': {},
156
+ # 'build_response_curves': {},
157
+ # 'scenario_planner': {},
158
+ # 'saved_scenarios': {},
159
+ # 'optimized_result_analysis': {}
160
+ # }
161
+ # st.session_state['project_dct']=project_dct
162
+
163
+ # st.write(project_dct)
164
+
165
+ def dump_session_details_db(allowed_users, session_name):
166
+ created_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
167
+
168
+ session_id = str(uuid.uuid4())
169
+
170
+ if len(allowed_users) == 0:
171
+ c.execute(
172
+ "INSERT INTO sessions VALUES (?, ?, ?, ?, ?, ?, ?,?)",
173
+ (
174
+ user_id,
175
+ name,
176
+ session_id,
177
+ session_name,
178
+ page_name,
179
+ created_time,
180
+ created_time,
181
+ None,
182
+ ),
183
+ )
184
+ conn.commit()
185
+ else:
186
+ for allowed_user in allowed_users:
187
+ c.execute(
188
+ "INSERT INTO sessions VALUES (?, ?, ?, ?, ?, ?, ?,?)",
189
+ (
190
+ user_id,
191
+ name,
192
+ session_id,
193
+ session_name,
194
+ page_name,
195
+ created_time,
196
+ created_time,
197
+ allowed_user,
198
+ ),
199
+ )
200
+ conn.commit()
201
+
202
+ # st.success('Project created')
203
+
204
+ if "session_path" not in st.session_state:
205
+ st.session_state["session_path"] = None
206
+
207
+ # creating dir for user
208
+
209
+ if not os.path.exists(user_folder_path):
210
+ os.makedirs(user_folder_path)
211
+
212
+ c.execute("SELECT DISTINCT username FROM users ")
213
+ allowed_users_db = [user[0] for user in c.fetchall() if user[0] != name]
214
+
215
+ c.execute(
216
+ "SELECT session_name from sessions WHERE allowed_users = ?", (name,)
217
+ )
218
+ available_sessions = c.fetchall() # all sessions available for user
219
+
220
+ c.execute(
221
+ "SELECT Distinct Session_name, status, updated_time as last_updated FROM sessions WHERE owner=?",
222
+ (name,),
223
+ )
224
+
225
+ session_summary = c.fetchall()
226
+
227
+ session_summary_df = pd.DataFrame(
228
+ session_summary,
229
+ columns=["Project Name", "Last Page Edited", "Modified Date"],
230
+ )
231
+ session_summary_df["Modified Date"] = session_summary_df[
232
+ "Modified Date"
233
+ ].map(lambda x: pd.to_datetime(x))
234
+
235
+ session_summary_df = session_summary_df.sort_values(
236
+ by=["Modified Date"], ascending=False
237
+ )
238
+
239
+ st.header("Manage Projects")
240
+
241
+ st.markdown(
242
+ """
243
+ * **Load Existing Project:** Select the project you want and click 'Load Project'.
244
+ * **Delete Project:** If you wish to delete a project, select it and click 'Delete Project'.
245
+ * **Modify User Access:** Make changes to user access permissions as needed.
246
+
247
+ """
248
+ )
249
+
250
+ # session_col=st.columns([5,5])
251
+ # with session_col[0]:
252
+ gd = GridOptionsBuilder.from_dataframe(session_summary_df)
253
+ gd.configure_pagination(
254
+ enabled=True, paginationAutoPageSize=False, paginationPageSize=10
255
+ )
256
+ gd.configure_selection(use_checkbox=True)
257
+
258
+ gridoptions = gd.build()
259
+
260
+ if session_summary_df.shape[0] < 5:
261
+ height = (session_summary_df.shape[0]) * 20 + 100
262
+
263
+ else:
264
+ height = None
265
+
266
+ table = AgGrid(
267
+ session_summary_df,
268
+ gridOptions=gridoptions,
269
+ update_mode=GridUpdateMode.SELECTION_CHANGED,
270
+ height=height,
271
+ fit_columns_on_grid_load=True,
272
+ )
273
+
274
+ if len(table.selected_rows) > 0:
275
+
276
+ selected_rows = table.selected_rows
277
+
278
+ project_name = selected_rows[0]["Project Name"]
279
+
280
+ project_col = st.columns(2)
281
+
282
+ with project_col[0]:
283
+
284
+ project_path = os.path.join(user_folder_path, project_name)
285
+
286
+ st.session_state["project_path"] = project_path # load project dct
287
+
288
+ project_dct_path = os.path.join(project_path, "project_dct.pkl")
289
+
290
+ with open(project_dct_path, "rb") as f:
291
+ st.session_state["project_dct"] = pickle.load(f)
292
+
293
+ # st.write(st.session_state['project_dct'])
294
+
295
+ with st.spinner("Redirecting to last Saved Page"):
296
+
297
+ page_link = st.page_link(
298
+ "pages/1_Data_Import.py",
299
+ label=f"Load Project - **{project_name}**",
300
+ )
301
+
302
+ with project_col[1]:
303
+
304
+ if st.button(
305
+ f"Delete Project - **{selected_rows[0]['Project Name']}**"
306
+ ):
307
+
308
+ project_name_to_delete = selected_rows[0]["Project Name"]
309
+ st.warning(
310
+ f"{project_name_to_delete} will be deleted permanentaly and all the information regarding the project will be lost"
311
+ )
312
+
313
+ with st.expander("Modify user access for selected project"):
314
+
315
+ c.execute(
316
+ "SELECT DISTINCT allowed_users FROM sessions WHERE session_name = ?",
317
+ (project_name,),
318
+ )
319
+
320
+ present_users = c.fetchall()
321
+
322
+ present_users = [
323
+ user[0]
324
+ for user in present_users
325
+ if user[0] != name and user[0] is not None
326
+ ]
327
+
328
+ present_users = None if len(present_users) == 0 else present_users
329
+
330
+ allowed_users = st.multiselect(
331
+ "Modify other users access",
332
+ allowed_users_db,
333
+ default=present_users,
334
+ )
335
+
336
+ if st.button("Save Changes", use_container_width=True):
337
+ pass
338
+
339
+ c.execute("SELECT Session_name FROM sessions WHERE owner=?", (name,))
340
+ user_projects = [
341
+ project[0] for project in c.fetchall()
342
+ ] # user owned sessions
343
+
344
+ with st.expander("Create New Project"):
345
+ st.markdown(
346
+ "To create a new project, Enter Project name below, select user who you want to give access of this project and click **Create New Project**"
347
+ )
348
+ project_col1 = st.columns(2)
349
+ with project_col1[0]:
350
+ project_name = st.text_input("Enter Project Name")
351
+
352
+ if project_name in user_projects:
353
+ st.warning("Project already exists please enter new name")
354
+
355
+ with project_col1[1]:
356
+
357
+ allowed_users = st.multiselect(
358
+ "Select Users who can access to this Project", allowed_users_db
359
+ )
360
+ allowed_users = list(allowed_users)
361
+
362
+ Create = st.button("Create New Project", use_container_width=True)
363
+ # st.button("Label", use_container_width=True)
364
+
365
+ if Create:
366
+
367
+ allowed_users.append(name)
368
+
369
+ if project_name in user_projects:
370
+
371
+ st.warning("Project already exists please enter new name")
372
+ st.stop()
373
+
374
+ project_path = os.path.join(user_folder_path, project_name)
375
+
376
+ os.makedirs(project_path)
377
+
378
+ dump_session_details_db(allowed_users, project_name)
379
+
380
+ project_dct = {
381
+ "data_import": {
382
+ "granularity_selection": 0,
383
+ "cat_dct": {},
384
+ "merged_df": None,
385
+ "edited_df": None,
386
+ "numeric_columns": None,
387
+ "files_dict": None,
388
+ "formatted_panel1_values": None,
389
+ "formatted_panel2_values": None,
390
+ "missing_stats_df": None,
391
+ "edited_stats_df": None,
392
+ },
393
+ "data_validation": {
394
+ "target_column": 0,
395
+ "selected_panels": None,
396
+ "selected_feature": 0,
397
+ "validated_variables": [],
398
+ "Non_media_variables": 0,
399
+ },
400
+ "transformations": {"Media": {}, "Exogenous": {}},
401
+ "model_build": {
402
+ "sel_target_col": None,
403
+ "all_iters_check": False,
404
+ "iterations": 0,
405
+ "build_button": False,
406
+ "show_results_check": False,
407
+ "session_state_saved": {},
408
+ },
409
+ "model_tuning": {
410
+ "sel_target_col": None,
411
+ "sel_model": {},
412
+ "flag_expander": False,
413
+ "start_date_default": None,
414
+ "end_date_default": None,
415
+ "repeat_default": "No",
416
+ "flags": None,
417
+ "select_all_flags_check": {},
418
+ "selected_flags": {},
419
+ "trend_check": False,
420
+ "week_num_check": False,
421
+ "sine_cosine_check": False,
422
+ "session_state_saved": {},
423
+ },
424
+ "saved_model_results": {
425
+ "selected_options": None,
426
+ "model_grid_sel": [1],
427
+ },
428
+ "model_result_overview": {},
429
+ "build_response_curves": {},
430
+ "scenario_planner": {},
431
+ "saved_scenarios": {},
432
+ "optimized_result_analysis": {},
433
+ }
434
+ st.session_state["project_dct"] = project_dct
435
+
436
+ st.session_state["project_path"] = project_path
437
+
438
+ project_dct_path = os.path.join(project_path, "project_dct.pkl")
439
+ st.session_state["session_path"] = project_path
440
+
441
+ with open(project_dct_path, "wb") as f:
442
+ pickle.dump(project_dct, f)
443
+
444
+ st.success("Project Created")
445
+
446
+ # st.header('Clone Project')
447
+
448
+ with st.expander("**Clone saved projects**"):
449
+
450
+ c.execute(
451
+ "SELECT DISTINCT owner FROM sessions WHERE allowed_users=?",
452
+ (name,),
453
+ ) # owner
454
+ owners = c.fetchall()
455
+
456
+ owners = [owner[0] for owner in owners]
457
+
458
+ if len(owners) == 0:
459
+
460
+ st.warning("You dont have any shared project yet!")
461
+
462
+ st.stop()
463
+
464
+ cols = st.columns(2)
465
+
466
+ with cols[0]:
467
+
468
+ owner = st.selectbox("Select Owner", owners)
469
+
470
+ c.execute("SELECT email FROM users WHERE username=?", (owner,))
471
+
472
+ owner_email = c.fetchone()[0]
473
+
474
+ owner_folder_path = os.path.join(folder_path, owner_email)
475
+
476
+ with cols[1]:
477
+
478
+ c.execute(
479
+ "SELECT session_name FROM sessions WHERE owner=? AND allowed_users = ?",
480
+ (owner, name),
481
+ ) # available sessions for user
482
+ project_names = c.fetchall()
483
+
484
+ project_name_owner = st.selectbox(
485
+ "Select a saved Project available for you",
486
+ [project_name[0] for project_name in project_names],
487
+ )
488
+ owner_project_path = os.path.join(owner_folder_path, project_name)
489
+
490
+ with cols[0]:
491
+ project_name_user = st.text_input(
492
+ "Enter Project Name", value=project_name_owner
493
+ )
494
+
495
+ if project_name in user_projects:
496
+
497
+ st.warning(
498
+ "This Project name already exists in your directory Please enter a different name"
499
+ )
500
+
501
+ # st.stop()
502
+
503
+ project_path = os.path.join(user_folder_path, project_name_user)
504
+
505
+ owner_project_path = os.path.join(
506
+ owner_folder_path, project_name_owner
507
+ )
508
+
509
+ with cols[1]:
510
+
511
+ allowed_users = st.multiselect(
512
+ "Select Users who can access this session", allowed_users_db
513
+ )
514
+ allowed_users = list(allowed_users)
515
+
516
+ if st.button("Load Project", use_container_width=True):
517
+
518
+ if os.path.exists(project_path):
519
+
520
+ st.warning(
521
+ "This Project name already exists in your directory Please enter a different name"
522
+ )
523
+
524
+ st.stop()
525
+
526
+ shutil.copytree(owner_project_path, project_path)
527
+
528
+ project_dct_path = os.path.join(project_path, "project_dct.pkl")
529
+
530
+ with open(project_dct_path, "rb") as f:
531
+ st.session_state["project_dct"] = pickle.load(f)
532
+ st.session_state["session_path"] = project_path
533
+ st.session_state["project_path"] = project_path
534
+
535
+ # st.write(st.session_state['project_dct'])
536
+
537
+ dump_session_details_db(allowed_users, project_name_user)
538
+ st.success("Project Cloned")
Home_redirecting.py ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def home():
2
+ import sqlite3
3
+ import uuid
4
+ import json
5
+ import streamlit as st
6
+ from utilities import (
7
+ load_local_css,
8
+ set_header,
9
+ load_authenticator,
10
+ send_email,
11
+ )
12
+ import streamlit_authenticator as stauth
13
+ import yaml
14
+ from yaml import SafeLoader
15
+ import os
16
+ import datetime
17
+ import subprocess
18
+ import shutil
19
+ import pandas as pd
20
+ from st_aggrid import AgGrid
21
+ from st_aggrid import GridOptionsBuilder, GridUpdateMode
22
+ import pickle
23
+ from pathlib import Path
24
+
25
+ # st.set_page_config(layout="wide")
26
+ load_local_css("styles.css")
27
+ # set_header()
28
+
29
+ # def authenticator():
30
+ for k, v in st.session_state.items():
31
+ if k not in ["logout", "login", "config"] and not k.startswith(
32
+ "FormSubmitter"
33
+ ):
34
+ st.session_state[k] = v
35
+ with open("config.yaml") as file:
36
+ config = yaml.load(file, Loader=SafeLoader)
37
+ st.session_state["config"] = config
38
+ authenticator = stauth.Authenticate(
39
+ config["credentials"],
40
+ config["cookie"]["name"],
41
+ config["cookie"]["key"],
42
+ config["cookie"]["expiry_days"],
43
+ config["preauthorized"],
44
+ )
45
+ st.session_state["authenticator"] = authenticator
46
+ name, authentication_status, username = authenticator.login(
47
+ "Login", "main"
48
+ )
49
+ auth_status = st.session_state.get("authentication_status")
50
+
51
+ if auth_status == True:
52
+ authenticator.logout("Logout", "main")
53
+ is_state_initiaized = st.session_state.get("initialized", False)
54
+
55
+ if not is_state_initiaized:
56
+
57
+ if "session_name" not in st.session_state:
58
+ st.session_state["session_name"] = None
59
+
60
+ cols1 = st.columns([2, 1])
61
+
62
+ with cols1[0]:
63
+ st.markdown(f"**Welcome {name}**")
64
+ with cols1[1]:
65
+ st.markdown(
66
+ f"**Current Session: {st.session_state['session_name']}**"
67
+ )
68
+
69
+ # relative_path = Path('DB_Sample','..' ,'DB', 'User.db')
70
+ # absolute_path = Path.cwd() / relative_path
71
+ # st.write(absolute_path)
72
+ # database_file=Path(__file__).parent / relative_path
73
+
74
+ database_file = r"C:\Users\ManojP\Documents\Mastercard\Build\DB_Sample\DB\User.db"
75
+
76
+ conn = sqlite3.connect(database_file) # connection with sql db
77
+ c = conn.cursor()
78
+
79
+ # c.executemany("INSERT INTO users (username, email) VALUES (?, ?)",
80
+ # [("Geetha Krishna", "geetha1732@gmail.com"),
81
+ # ("Samkeet Sangai", "samkeet.sangai@blend360.com"),
82
+ # ('Manoj P','manojp1732@gmail.com'),
83
+ # ('Srishti Verma','srishti.verma@blend360.com'),
84
+ # ('Ismail mohammed',"mohammed.ismail@blend360.com"),
85
+ # ('Sharon Sheng','sharon.sheng@mastercard.com'),
86
+ # ('Ioannis Papadopoulos','ioannis.papadopoulos@mastercard.com'),
87
+ # ('Herman Kwong',"herman.kwong@mastercard.com")
88
+ # ])
89
+
90
+ # conn.commit()
91
+
92
+ # c.execute("DELETE from sessions")
93
+ # conn.commit()
94
+ # st.write(c.fetchall())
95
+
96
+ page_name = "Home Page"
97
+ c.execute(
98
+ "SELECT email, user_id, user_type FROM users WHERE username = ?",
99
+ (name,),
100
+ )
101
+ user_data = c.fetchone()
102
+ email, user_id, user_type = user_data
103
+
104
+ # st.write(user_type)
105
+ # with st.sidebar:
106
+ # # if user_type != 'technical':
107
+ # st.page_link("home.py", label="Home123")
108
+ # st.page_link('pages/1_Data_Import.py',label='Data Import')
109
+ # st.page_link('pages/2_Data_Validation.py',label="Data Validation")
110
+ # st.page_link('pages/3_Transformations.py',label='Transformations')
111
+ # st.page_link("pages/4_Model_Build.py")
112
+ # st.page_link('pages/5_Model_Tuning_with_panel.py',label='Model Tuning')
113
+
114
+ # st.page_link('pages/5_Saved_Model_Results.py',label="Saved Model Results")
115
+
116
+ # st.write(pd.to_datetime(created_time))
117
+ # c.execute("DELETE FROM sessions")
118
+ # c.execute('select * from sessions')
119
+ # conn.commit()
120
+ # output = c.fetchall()
121
+
122
+ # st.write(output)
123
+
124
+ # if emails is not None:
125
+ # email = emails[0]
126
+
127
+ folder_path = (
128
+ r"C:\Users\ManojP\Documents\Mastercard\Build\DB_Sample\Users"
129
+ )
130
+ user_folder_path = os.path.join(folder_path, email)
131
+
132
+ # project_dct = {
133
+ # 'data_import': {
134
+ # "granularity_selection":0,
135
+ # 'cat_dct':{},
136
+ # "merged_df":None,
137
+ # 'edited_df':None,
138
+ # "numeric_columns":None,
139
+ # "files_dict":None,
140
+ # 'formatted_panel1_values':None,
141
+ # 'formatted_panel2_values':None,
142
+ # "missing_stats_df":None,
143
+ # 'edited_stats_df':None
144
+
145
+ # },
146
+
147
+ # 'data_validation': {"target_column":0,
148
+ # 'selected_panels':None,
149
+ # "selected_feature":0,
150
+ # "validated_variables":[],
151
+ # "Non_media_variables":0
152
+
153
+ # },
154
+ # 'transformations': {},
155
+ # 'model_build': {},
156
+ # 'model_tuning':{},
157
+ # 'saved_model_results': {},
158
+ # 'model_result_overview': {},
159
+ # 'build_response_curves': {},
160
+ # 'scenario_planner': {},
161
+ # 'saved_scenarios': {},
162
+ # 'optimized_result_analysis': {}
163
+ # }
164
+ # st.session_state['project_dct']=project_dct
165
+
166
+ # st.write(project_dct)
167
+
168
+ def dump_session_details_db(allowed_users, session_name):
169
+ created_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
170
+
171
+ session_id = str(uuid.uuid4())
172
+
173
+ if len(allowed_users) == 0:
174
+ c.execute(
175
+ "INSERT INTO sessions VALUES (?, ?, ?, ?, ?, ?, ?,?)",
176
+ (
177
+ user_id,
178
+ name,
179
+ session_id,
180
+ session_name,
181
+ page_name,
182
+ created_time,
183
+ created_time,
184
+ None,
185
+ ),
186
+ )
187
+ conn.commit()
188
+ else:
189
+ for allowed_user in allowed_users:
190
+ c.execute(
191
+ "INSERT INTO sessions VALUES (?, ?, ?, ?, ?, ?, ?,?)",
192
+ (
193
+ user_id,
194
+ name,
195
+ session_id,
196
+ session_name,
197
+ page_name,
198
+ created_time,
199
+ created_time,
200
+ allowed_user,
201
+ ),
202
+ )
203
+ conn.commit()
204
+
205
+ # st.success('Project created')
206
+
207
+ if "session_path" not in st.session_state:
208
+ st.session_state["session_path"] = None
209
+
210
+ # creating dir for user
211
+
212
+ if not os.path.exists(user_folder_path):
213
+ os.makedirs(user_folder_path)
214
+
215
+ c.execute("SELECT DISTINCT username FROM users ")
216
+ allowed_users_db = [
217
+ user[0] for user in c.fetchall() if user[0] != name
218
+ ]
219
+
220
+ c.execute(
221
+ "SELECT session_name from sessions WHERE allowed_users = ?",
222
+ (name,),
223
+ )
224
+ available_sessions = c.fetchall() # all sessions available for user
225
+
226
+ c.execute(
227
+ "SELECT Distinct Session_name, status, updated_time as last_updated FROM sessions WHERE owner=?",
228
+ (name,),
229
+ )
230
+
231
+ session_summary = c.fetchall()
232
+
233
+ session_summary_df = pd.DataFrame(
234
+ session_summary,
235
+ columns=["Project Name", "Last Page Edited", "Modified Date"],
236
+ )
237
+ session_summary_df["Modified Date"] = session_summary_df[
238
+ "Modified Date"
239
+ ].map(lambda x: pd.to_datetime(x))
240
+
241
+ session_summary_df = session_summary_df.sort_values(
242
+ by=["Modified Date"], ascending=False
243
+ )
244
+
245
+ st.header("Manage Projects")
246
+
247
+ st.markdown(
248
+ """
249
+ * **Load Existing Project:** Select the project you want and click 'Load Project'.
250
+ * **Delete Project:** If you wish to delete a project, select it and click 'Delete Project'.
251
+ * **Modify User Access:** Make changes to user access permissions as needed.
252
+
253
+ """
254
+ )
255
+
256
+ # session_col=st.columns([5,5])
257
+ # with session_col[0]:
258
+ gd = GridOptionsBuilder.from_dataframe(session_summary_df)
259
+ gd.configure_pagination(
260
+ enabled=True, paginationAutoPageSize=False, paginationPageSize=10
261
+ )
262
+ gd.configure_selection(use_checkbox=True)
263
+
264
+ gridoptions = gd.build()
265
+
266
+ if session_summary_df.shape[0] < 5:
267
+ height = (session_summary_df.shape[0]) * 20 + 100
268
+
269
+ else:
270
+ height = None
271
+
272
+ table = AgGrid(
273
+ session_summary_df,
274
+ gridOptions=gridoptions,
275
+ update_mode=GridUpdateMode.SELECTION_CHANGED,
276
+ height=height,
277
+ fit_columns_on_grid_load=True,
278
+ )
279
+
280
+ if len(table.selected_rows) > 0:
281
+
282
+ selected_rows = table.selected_rows
283
+
284
+ project_name = selected_rows[0]["Project Name"]
285
+
286
+ project_col = st.columns(2)
287
+
288
+ with project_col[0]:
289
+
290
+ project_path = os.path.join(user_folder_path, project_name)
291
+
292
+ st.session_state["project_path"] = (
293
+ project_path # load project dct
294
+ )
295
+
296
+ project_dct_path = os.path.join(
297
+ project_path, "project_dct.pkl"
298
+ )
299
+
300
+ with open(project_dct_path, "rb") as f:
301
+ st.session_state["project_dct"] = pickle.load(f)
302
+
303
+ st.write(st.session_state["project_dct"])
304
+
305
+ with st.spinner("Redirecting to last Saved Page"):
306
+
307
+ page_link = st.page_link(
308
+ "pages/1_Data_Import.py",
309
+ label=f"Load Project - **{project_name}**",
310
+ )
311
+
312
+ with project_col[1]:
313
+
314
+ if st.button(
315
+ f"Delete Project - **{selected_rows[0]['Project Name']}**"
316
+ ):
317
+
318
+ project_name_to_delete = selected_rows[0]["Project Name"]
319
+ st.warning(
320
+ f"{project_name_to_delete} will be deleted permanentaly and all the information regarding the project will be lost"
321
+ )
322
+
323
+ with st.expander("Modify user access for selected project"):
324
+
325
+ c.execute(
326
+ "SELECT DISTINCT allowed_users FROM sessions WHERE session_name = ?",
327
+ (project_name,),
328
+ )
329
+
330
+ present_users = c.fetchall()
331
+
332
+ present_users = [
333
+ user[0]
334
+ for user in present_users
335
+ if user[0] != name and user[0] is not None
336
+ ]
337
+
338
+ present_users = (
339
+ None if len(present_users) == 0 else present_users
340
+ )
341
+
342
+ allowed_users = st.multiselect(
343
+ "Modify other users access",
344
+ allowed_users_db,
345
+ default=present_users,
346
+ )
347
+
348
+ if st.button("Save Changes", use_container_width=True):
349
+ pass
350
+
351
+ c.execute("SELECT Session_name FROM sessions WHERE owner=?", (name,))
352
+
353
+ user_projects = [
354
+ project[0] for project in c.fetchall()
355
+ ] # user owned sessions
356
+
357
+ with st.expander("Create New Project"):
358
+ st.markdown(
359
+ "To create a new project, Enter Project name below, select user who you want to give access of this project and click **Create New Project**"
360
+ )
361
+
362
+ project_col1 = st.columns(2)
363
+ with project_col1[0]:
364
+ project_name = st.text_input("Enter Project Name")
365
+
366
+ if project_name in user_projects:
367
+ st.warning("Project already exists please enter new name")
368
+
369
+ with project_col1[1]:
370
+
371
+ allowed_users = st.multiselect(
372
+ "Select Users who can access to this Project",
373
+ allowed_users_db,
374
+ )
375
+ allowed_users = list(allowed_users)
376
+
377
+ Create = st.button("Create New Project", use_container_width=True)
378
+
379
+ if Create:
380
+
381
+ allowed_users.append(name)
382
+
383
+ if project_name in user_projects:
384
+
385
+ st.warning("Project already exists please enter new name")
386
+ st.stop()
387
+
388
+ project_path = os.path.join(user_folder_path, project_name)
389
+
390
+ os.makedirs(project_path)
391
+
392
+ dump_session_details_db(allowed_users, project_name)
393
+
394
+ project_dct = {
395
+ "data_import": {
396
+ "granularity_selection": 0,
397
+ "cat_dct": {},
398
+ "merged_df": None,
399
+ "edited_df": None,
400
+ "numeric_columns": None,
401
+ "files_dict": None,
402
+ "formatted_panel1_values": None,
403
+ "formatted_panel2_values": None,
404
+ "missing_stats_df": None,
405
+ "edited_stats_df": None,
406
+ },
407
+ "data_validation": {
408
+ "target_column": 0,
409
+ "selected_panels": None,
410
+ "selected_feature": 0,
411
+ "validated_variables": [],
412
+ "Non_media_variables": 0,
413
+ },
414
+ "transformations": {},
415
+ "model_build": {},
416
+ "model_tuning": {},
417
+ "saved_model_results": {},
418
+ "model_result_overview": {},
419
+ "build_response_curves": {},
420
+ "scenario_planner": {},
421
+ "saved_scenarios": {},
422
+ "optimized_result_analysis": {},
423
+ }
424
+ st.session_state["project_dct"] = project_dct
425
+
426
+ # st.session_state['project_path']=project_path
427
+
428
+ project_dct_path = os.path.join(
429
+ project_path, "project_dct.pkl"
430
+ )
431
+
432
+ with open(project_dct_path, "wb") as f:
433
+ pickle.dump(project_dct, f)
434
+
435
+ st.success("Project Created")
436
+
437
+ # st.header('Clone Project')
438
+
439
+ with st.expander("**Clone saved projects**"):
440
+
441
+ c.execute(
442
+ "SELECT DISTINCT owner FROM sessions WHERE allowed_users=?",
443
+ (name,),
444
+ ) # owner
445
+ owners = c.fetchall()
446
+
447
+ owners = [owner[0] for owner in owners]
448
+
449
+ if len(owners) == 0:
450
+
451
+ st.warning("You dont have any shared project yet!")
452
+
453
+ st.stop()
454
+
455
+ cols = st.columns(2)
456
+
457
+ with cols[0]:
458
+
459
+ owner = st.selectbox("Select Owner", owners)
460
+
461
+ c.execute("SELECT email FROM users WHERE username=?", (owner,))
462
+
463
+ owner_email = c.fetchone()[0]
464
+
465
+ owner_folder_path = os.path.join(folder_path, owner_email)
466
+
467
+ with cols[1]:
468
+
469
+ c.execute(
470
+ "SELECT session_name FROM sessions WHERE owner=? AND allowed_users = ?",
471
+ (owner, name),
472
+ ) # available sessions for user
473
+ project_names = c.fetchall()
474
+
475
+ project_name_owner = st.selectbox(
476
+ "Select a saved Project available for you",
477
+ [project_name[0] for project_name in project_names],
478
+ )
479
+ owner_project_path = os.path.join(
480
+ owner_folder_path, project_name
481
+ )
482
+
483
+ with cols[0]:
484
+ project_name_user = st.text_input(
485
+ "Enter Project Name", value=project_name_owner
486
+ )
487
+
488
+ if project_name in user_projects:
489
+
490
+ st.warning(
491
+ "This Project name already exists in your directory Please enter a different name"
492
+ )
493
+
494
+ # st.stop()
495
+
496
+ project_path = os.path.join(
497
+ user_folder_path, project_name_user
498
+ )
499
+
500
+ owner_project_path = os.path.join(
501
+ owner_folder_path, project_name_owner
502
+ )
503
+
504
+ with cols[1]:
505
+
506
+ allowed_users = st.multiselect(
507
+ "Select Users who can access this session",
508
+ allowed_users_db,
509
+ )
510
+ allowed_users = list(allowed_users)
511
+
512
+ if st.button("Load Project", use_container_width=True):
513
+
514
+ if os.path.exists(project_path):
515
+
516
+ st.warning(
517
+ "This Project name already exists in your directory Please enter a different name"
518
+ )
519
+
520
+ st.stop()
521
+
522
+ shutil.copytree(owner_project_path, project_path)
523
+
524
+ project_dct_path = os.path.join(
525
+ project_path, "project_dct.pkl"
526
+ )
527
+
528
+ with open(project_dct_path, "rb") as f:
529
+ st.session_state["project_dct"] = pickle.load(f)
530
+
531
+ st.session_state["project_path"] = project_path
532
+
533
+ # st.write(st.session_state['project_dct'])
534
+
535
+ dump_session_details_db(allowed_users, project_name_user)
536
+ st.success("Project Cloned")
LIME_logo.png ADDED
Media_data_for_model.csv ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,paid_search_impressions,paid_search_clicks,kwai_impressions,kwai_clicks,programmaticimpressions,programmaticclicks,affiliates_impressions,affiliates_clicks,indicacao_impressions,indicacao_clicks,infleux_impressions,infleux_clicks,influencer_impressions,influencer_clicks,Total Approved Accounts - Revenue,FB: Level Achieved - Tier 1 Impressions, FB: Level Achieved - Tier 2 Impressions,paid_social_others, GA App: Will And Cid Pequena Baixo Risco Clicks,digital_tactic_others
2
+ 2023-05-09,6111,1916,1365036.0,5044.0,104781,31371909,0,3341,0,11190,0,61956,0,457,5066400,2371841.0,1021599.0,2302543.0,34816.0,19205.0
3
+ 2023-05-10,6233,1888,1234034.0,3899.0,140810,32973036,0,3214,0,9988,0,52049,0,705,5480000,2100238.0,943808.0,2336369.0,19716.0,17415.0
4
+ 2023-05-11,5568,1816,1016155.0,2788.0,102248,50729517,0,3203,0,10869,0,8042,0,381,4133100,2461265.0,1127717.0,1110415.0,21547.0,11051.0
5
+ 2023-05-12,5109,1769,1228032.0,3101.0,100246,63142114,0,2492,0,7096,0,10596,0,299,3573910,2313368.0,1107256.0,1191901.0,31966.0,11081.0
6
+ 2023-05-13,3712,1231,1344557.0,3399.0,100714,59509032,0,3986,0,4282,0,9753,0,366,2776120,3067797.0,1388882.0,1403486.0,38518.0,10762.0
7
+ 2023-05-14,3719,1241,1520157.0,3491.0,120162,49538293,0,1891,0,3002,0,7363,0,278,2611960,3140882.0,1429620.0,2518831.0,44744.0,12151.0
8
+ 2023-05-15,7735,2663,2102264.0,5175.0,106903,46609819,0,2518,0,4548,0,16201,0,880,3951760,2916228.0,1288902.0,2456845.0,36269.0,15290.0
9
+ 2023-05-16,9409,3206,2134290.0,5636.0,88201,9662393,0,2247,0,6690,0,15031,0,1588,4150900,3161940.0,1370882.0,2403330.0,37393.0,14187.0
10
+ 2023-05-17,8409,2785,1473128.0,4336.0,56382,2232239,0,2557,0,6401,0,8946,0,322,3788540,3199527.0,1379566.0,2608845.0,39190.0,12591.0
11
+ 2023-05-18,8364,2873,1733275.0,5009.0,38145,7321146,0,2912,0,7286,0,14366,0,660,3652210,2623727.0,1115471.0,1723470.0,36020.0,12100.0
12
+ 2023-05-19,6432,2050,1784426.0,5063.0,23340,8715910,0,3934,0,6035,0,20378,0,362,3777590,2995998.0,1287313.0,1959870.0,36885.0,12848.0
13
+ 2023-05-20,5428,1724,1635604.0,4408.0,34693,8783612,0,3318,0,4714,0,21030,0,236,3437270,2996479.0,1326416.0,1903323.0,31048.0,12256.0
14
+ 2023-05-21,5657,1807,1788487.0,4492.0,24812,5015214,0,2253,0,4227,0,11656,0,494,3020020,3167634.0,1309450.0,3651254.0,33361.0,13073.0
15
+ 2023-05-22,5768,2036,2176947.0,5688.0,25298,3002995,0,2739,0,8313,0,25663,0,1147,3643240,3573865.0,1548365.0,3939226.0,33410.0,14092.0
16
+ 2023-05-23,5051,1720,2359219.0,6966.0,24773,3005057,0,4738,0,13827,0,47900,0,965,5146270,3248157.0,1376975.0,3631390.0,35016.0,13025.0
17
+ 2023-05-24,6078,1977,1612918.0,4924.0,24591,2833280,0,4816,0,12417,0,94489,0,1254,5832220,3572793.0,1550315.0,3532105.0,37491.0,12546.0
18
+ 2023-05-25,6547,2075,1468456.0,3624.0,19705,2771412,0,5070,0,7395,0,70016,0,762,5217860,3164337.0,1353382.0,3253308.0,34658.0,13154.0
19
+ 2023-05-26,3719,1189,1770048.0,4874.0,16879,2875657,0,2855,0,6964,0,29015,0,627,4123930,2989794.0,1248779.0,3345390.0,38267.0,12788.0
20
+ 2023-05-27,3620,1145,1900387.0,5061.0,14156,2663378,0,3295,0,4472,0,5625,0,1473,2668440,3576647.0,1527545.0,3694843.0,40685.0,12844.0
21
+ 2023-05-28,4195,1302,2026053.0,5703.0,12334,2609966,0,2190,0,3737,0,5030,0,1401,2630380,3376177.0,1447089.0,2563297.0,42359.0,13543.0
22
+ 2023-05-29,5265,1798,2328823.0,6483.0,14783,2537637,0,3954,0,5211,0,221,0,1575,3057510,3765997.0,1720747.0,2865333.0,39579.0,8116.0
23
+ 2023-05-30,3879,1366,2294654.0,6008.0,15979,2489630,0,4465,0,6041,0,6,0,1192,3360270,3790830.0,1751416.0,2822819.0,37234.0,8830.0
24
+ 2023-05-31,3933,1348,1645187.0,4081.0,14208,2337652,0,3797,0,4794,0,6,0,888,3158130,4151434.0,1953620.0,2714074.0,45856.0,6861.0
25
+ 2023-06-01,4817,1530,1862175.0,4841.0,48192,3241822,0,3060,0,4802,0,12820,0,1137,3322330,4151797.0,1903421.0,2255850.0,51175.0,7095.0
26
+ 2023-06-02,5733,1800,966546.0,2646.0,43573,4582872,0,1563,0,10678,0,46810,0,1309,4244170,4313201.0,2009602.0,2074692.0,47378.0,6120.0
27
+ 2023-06-03,4142,1290,2445721.0,11111.0,90587,4764628,0,2176,0,5144,0,27735,0,518,3711670,4514302.0,2083217.0,2095544.0,58527.0,5748.0
28
+ 2023-06-04,5143,1613,2296690.0,6790.0,40929,4717779,0,1280,0,4237,0,5606,0,325,2851980,4179140.0,1889452.0,2152476.0,45239.0,6093.0
29
+ 2023-06-05,5384,1832,3509278.0,8938.0,56272,19979584,0,1377,0,11493,0,25647,0,579,4117320,3683204.0,1641254.0,3616732.0,40356.0,6453.0
30
+ 2023-06-06,4802,1594,3216944.0,7861.0,20049,33102789,0,1485,0,9086,0,36532,0,545,4627290,3822453.0,1716540.0,3687300.0,53347.0,6334.0
31
+ 2023-06-07,5072,1648,2143372.0,5356.0,22553,21321547,0,1576,0,7213,0,21215,0,628,4019320,4178339.0,1811963.0,2354753.0,51632.0,6259.0
32
+ 2023-06-08,4444,1465,3190766.0,8024.0,53653,10254268,0,2046,0,10491,0,19549,0,769,4272770,3941272.0,1738344.0,2283350.0,59291.0,6775.0
33
+ 2023-06-09,4818,1605,3278715.0,9328.0,18347,4890758,0,1925,0,8360,0,32385,0,1732,4788710,3969227.0,1777864.0,2353376.0,52000.0,6026.0
34
+ 2023-06-10,3465,1207,2887842.0,8529.0,725,5489947,0,1230,0,5401,0,37954,0,2136,4707070,4458593.0,2061762.0,2535928.0,66567.0,5554.0
35
+ 2023-06-11,4727,1501,3149290.0,8114.0,738,5313957,0,1839,0,8198,0,32493,0,1533,4560170,4442610.0,2006438.0,2183963.0,47655.0,6008.0
36
+ 2023-06-12,6437,2208,4416005.0,12345.0,149561,5298884,0,1905,0,8542,0,101079,0,472,7031980,4645531.0,1995891.0,3301882.0,38760.0,4966.0
37
+ 2023-06-13,3556,1254,4626697.0,12984.0,258088,5952266,0,2095,0,10415,0,59770,0,1016,5335600,4508060.0,1912958.0,3440789.0,47281.0,4630.0
38
+ 2023-06-14,3178,1060,3389530.0,10298.0,685692,10454400,0,2258,0,24457,0,16016,0,1101,4382390,4573214.0,1920050.0,3160905.0,41549.0,5083.0
39
+ 2023-06-15,2981,999,3131350.0,10791.0,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4334320,4075106.0,1690702.0,3267810.0,50496.0,5037.0
40
+ 2023-06-16,2705,947,2923279.0,11124.0,1166424,11840950,0,1780,0,8938,0,24339,0,966,4560830,4533368.0,1939737.0,2881833.0,41872.0,4604.0
41
+ 2023-06-17,3697,1154,2955836.0,10440.0,807683,9748201,0,2139,0,5741,0,54129,0,766,4890110,4958344.0,2059487.0,3183051.0,52618.0,3675.0
42
+ 2023-06-18,3229,1080,3280006.0,12373.0,116340,8176712,0,1481,0,4741,0,16724,0,864,3388060,4270249.0,1735486.0,3251229.0,39780.0,3696.0
43
+ 2023-06-19,3082,1003,6545797.0,24462.0,55763,4841897,0,2098,0,10520,0,26558,0,2211,4639400,4137846.0,1743715.0,2680413.0,43156.0,4347.0
44
+ 2023-06-20,2422,857,6734594.0,28910.0,52166,4718912,0,2205,0,10284,0,30610,0,1002,4969720,4218772.0,1771102.0,2058734.0,42288.0,4260.0
45
+ 2023-06-21,3366,1132,4784180.0,17247.0,52817,5971594,0,3387,0,9277,0,41697,0,645,4489250,4113884.0,1743016.0,2111350.0,44159.0,4193.0
46
+ 2023-06-22,2841,924,3300680.0,13360.0,29784,6803330,0,4064,0,7068,0,68638,0,481,5006920,3738171.0,1533407.0,1597072.0,35381.0,4173.0
47
+ 2023-06-23,2474,805,2284446.0,9012.0,80066,6833289,0,3274,0,7379,0,13501,0,721,3069350,4479743.0,1889155.0,1647740.0,39089.0,3640.0
48
+ 2023-06-24,2462,814,1947190.0,7247.0,50309,6526903,0,2767,0,4703,0,8438,0,616,2776800,3758421.0,1565736.0,1648519.0,46332.0,3834.0
49
+ 2023-06-25,2082,679,3560248.0,14850.0,50806,6368664,0,2767,0,4414,0,5346,0,628,2860440,4038846.0,1700182.0,2514456.0,43065.0,4201.0
50
+ 2023-06-26,2399,839,5999950.0,28401.0,23209,10788275,0,3699,0,13383,0,13592,0,790,3928490,3427918.0,1403888.0,3598236.0,33883.0,4642.0
51
+ 2023-06-27,2307,804,5005495.0,18260.0,81344,14103220,0,7082,0,8898,0,40917,0,945,5851320,3819654.0,1523667.0,3556028.0,35326.0,4628.0
52
+ 2023-06-28,2215,759,3721084.0,11248.0,20153,10547995,0,8387,0,7120,0,39693,0,944,6083570,3671994.0,1568555.0,1397196.0,33212.0,2998.0
53
+ 2023-06-29,2013,706,3918049.0,10226.0,155296,8525871,0,10096,0,5693,0,24049,0,1512,4328260,3937747.0,1585655.0,3393043.0,30700.0,2519.0
54
+ 2023-06-30,1258,454,3088874.0,7943.0,902115,10945715,0,8904,0,9611,0,62404,0,1029,5252540,4945464.0,1946944.0,1835310.0,52445.0,2839.0
55
+ 2023-07-01,1641,539,3872657.0,12034.0,191537,12141356,0,4956,0,6049,0,31194,0,923,4626340,5328149.0,2224200.0,2123805.0,56724.0,2513.0
56
+ 2023-07-02,1336,485,5799582.0,17238.0,576858,12180985,0,4148,0,4670,0,4766,0,617,3416990,4527404.0,1997256.0,2038953.0,50510.0,21201.0
57
+ 2023-07-03,2712,924,9986061.0,28191.0,442261,14059535,0,5347,0,7408,0,19028,0,1044,4925290,4179823.0,1854231.0,2234940.0,57543.0,14473.0
58
+ 2023-07-04,4137,1419,4717456.0,14519.0,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4394760,4449073.0,1959412.0,2350308.0,49085.0,9854.0
59
+ 2023-07-05,4166,1422,4779589.0,12676.0,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4497600,4464681.0,1969744.0,2390838.0,41411.0,12751.0
60
+ 2023-07-06,4182,1444,4939385.0,12222.0,2364811,15879491,0,6575,0,8461,0,18225,0,997,5114750,4490815.0,1942923.0,2239375.0,44808.0,16216.0
61
+ 2023-07-07,3497,1181,3121447.0,7534.0,1063284,17341347,0,6025,0,8113,0,25962,0,659,4910810,4891573.0,2128787.0,1976413.0,57373.0,12464.0
62
+ 2023-07-08,2760,856,3295227.0,9788.0,1119268,19207341,0,4102,0,6195,0,40506,0,832,4471260,5039604.0,2277255.0,2330435.0,44052.0,15163.0
63
+ 2023-07-09,2809,875,3913741.0,11815.0,749310,25182206,0,6420,0,5222,0,49626,0,718,5706060,4669470.0,2144473.0,3908306.0,49659.0,11716.0
64
+ 2023-07-10,4312,1489,5972974.0,18402.0,1511035,25950979,0,9842,0,10638,0,36204,0,935,5299330,4584106.0,2019220.0,4391654.0,52303.0,12983.0
65
+ 2023-07-11,4579,1550,4999618.0,16469.0,559119,23938153,0,11688,0,36570,0,25216,0,1289,5532390,4458364.0,1932300.0,4150666.0,47979.0,12292.0
66
+ 2023-07-12,4079,1418,4465722.0,13191.0,583520,25196511,0,4610,0,9813,0,20388,0,1210,5067480,4558876.0,2000168.0,4109583.0,54631.0,12366.0
67
+ 2023-07-13,3719,1260,4635033.0,12302.0,903614,25720336,0,7867,0,6792,0,22248,0,857,4393760,4596184.0,1957206.0,3729970.0,48474.0,11017.0
68
+ 2023-07-14,3632,1224,3441594.0,9800.0,1566300,28606996,0,6726,0,6172,0,14670,0,432,3983150,4683387.0,2007387.0,3912229.0,52588.0,10079.0
69
+ 2023-07-15,2909,941,6025085.0,21326.0,1836196,28705476,0,5705,0,4369,0,31202,0,595,4220310,5008167.0,2251661.0,3727627.0,58143.0,10214.0
70
+ 2023-07-16,2818,853,7339565.0,26586.0,4043959,26752554,0,7733,0,3961,0,27180,0,1082,3832400,4716541.0,2092258.0,2114014.0,59204.0,11281.0
71
+ 2023-07-17,4420,1486,9638491.0,32269.0,819444,29437537,0,11485,0,5220,0,66236,0,2418,5691990,4359325.0,1937825.0,1989872.0,55815.0,11896.0
72
+ 2023-07-18,4574,1551,9498457.0,31230.0,1206114,29164369,0,5012,0,7146,0,47074,0,2358,5347820,4882304.0,2163458.0,2157773.0,69573.0,12604.0
73
+ 2023-07-19,4632,1537,9742535.0,26935.0,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4690310,4613422.0,2080215.0,1981362.0,67495.0,12116.0
74
+ 2023-07-20,4891,1632,7630122.0,20720.0,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4576570,4484291.0,1922090.0,1663127.0,75312.0,12252.0
75
+ 2023-07-21,3978,1378,7284968.0,21477.0,2456715,17869335,0,6360,0,10877,0,11431,0,769,4357960,4519305.0,1975730.0,1686467.0,68931.0,10065.0
76
+ 2023-07-22,3151,978,5638955.0,16181.0,2015345,12808440,0,7097,0,5145,0,13811,0,699,3959970,4689346.0,2086993.0,1861883.0,71898.0,9081.0
77
+ 2023-07-23,2905,986,6133144.0,16089.0,881691,11267535,0,5593,0,4746,0,68021,0,514,5284400,4242878.0,1843843.0,1681215.0,61164.0,10797.0
78
+ 2023-07-24,4606,1651,8830736.0,21931.0,189913,35658281,0,8836,0,6040,0,64066,0,1626,6253530,3943001.0,1708849.0,1900126.0,59494.0,10236.0
79
+ 2023-07-25,4414,1597,7750251.0,15384.0,3348941,25011847,0,10262,0,9572,0,15072,0,916,4938210,3976490.0,1729916.0,1911109.0,68826.0,11468.0
80
+ 2023-07-26,4488,1530,8125332.0,16391.0,1040452,24380635,0,9947,0,16453,0,38777,0,1551,5687460,3837786.0,1680967.0,1856885.0,74924.0,13290.0
81
+ 2023-07-27,4105,1494,8054962.0,14724.0,220302,13070502,0,6758,0,8841,0,20622,0,1313,5138270,3636297.0,1544742.0,1772602.0,63935.0,11680.0
82
+ 2023-07-28,3743,1318,6955526.0,11566.0,3991586,5347413,0,10451,0,8496,0,20184,0,1563,4621140,3890784.0,1680538.0,1608577.0,73120.0,11390.0
83
+ 2023-07-29,3395,1192,5132501.0,9837.0,1349895,4441709,0,7115,0,5449,0,18983,0,1129,3893270,4295602.0,1813637.0,1824777.0,80511.0,11911.0
84
+ 2023-07-30,2746,903,4903153.0,11018.0,710000,4431986,0,8491,0,4599,0,24834,0,1109,4020490,3924352.0,1733790.0,1740605.0,72221.0,11440.0
85
+ 2023-07-31,4208,1476,6832832.0,19648.0,1721973,4079656,0,7754,0,7818,0,27918,0,2050,4709550,3760475.0,1501134.0,1957900.0,62124.0,11605.0
86
+ 2023-08-01,4203,1489,6398210.0,15890.0,2250090,5457683,0,7588,0,7948,0,61894,0,1248,5602170,3687038.0,1439092.0,1774701.0,61448.0,11492.0
87
+ 2023-08-02,4285,1515,5402871.0,14825.0,785167,6582085,0,6079,0,7236,0,79041,0,1345,5992910,3807266.0,1493340.0,2025308.0,54506.0,11515.0
88
+ 2023-08-03,4667,1744,4724924.0,8903.0,1111815,10407793,0,9077,0,7117,0,31714,0,1983,4941800,3797879.0,1479623.0,1718831.0,52587.0,11408.0
89
+ 2023-08-04,4201,1562,3732952.0,9116.0,4574481,10660977,0,8436,0,6970,0,25097,0,1055,4659060,3814852.0,1466211.0,1374674.0,57482.0,10785.0
90
+ 2023-08-05,3080,1110,3310732.0,9884.0,3460283,11580456,0,5735,0,5049,0,5911,0,704,3260640,4048945.0,1601234.0,1442690.0,65158.0,9942.0
91
+ 2023-08-06,2809,979,4153998.0,11663.0,5103054,8381689,0,4868,0,4184,0,28658,0,637,4005470,4040770.0,1250223.0,1844909.0,47698.0,10816.0
92
+ 2023-08-07,3522,1186,3164171.0,10000.0,4137349,8709017,0,6112,0,6640,0,43866,0,1285,5034960,3928811.0,1288638.0,1861166.0,44623.0,11648.0
93
+ 2023-08-08,4111,1495,6020074.0,15008.0,2923076,5012245,0,6684,0,6961,0,12257,0,3038,4235970,3921429.0,1094791.0,2059462.0,48047.0,10379.0
94
+ 2023-08-09,3609,1285,5616011.0,13195.0,2483117,3900778,0,8177,0,6447,0,12774,0,1309,4131270,3322165.0,452000.0,2262292.0,52219.0,11047.0
95
+ 2023-08-10,3872,1330,5270940.0,11342.0,1305507,3614496,0,6927,0,6602,0,21830,0,986,4946040,2868345.0,452896.0,1541791.0,46720.0,10556.0
96
+ 2023-08-11,3673,1257,4485834.0,10445.0,3562053,5521177,0,5810,0,13751,0,5797,0,751,3309470,3242607.0,511016.0,1679989.0,47262.0,10344.0
97
+ 2023-08-12,2744,960,3946512.0,10052.0,4015316,5813616,0,6205,0,10379,0,9890,0,532,3177130,3761072.0,595191.0,1931989.0,54787.0,9210.0
98
+ 2023-08-13,2418,775,5051792.0,11809.0,1869057,6348414,0,4093,0,5187,0,21320,0,399,2953700,3279816.0,503805.0,2171335.0,55136.0,10546.0
99
+ 2023-08-14,3551,1196,4839009.0,11805.0,1765326,3758610,0,6170,0,7226,0,19575,0,706,3873510,2974893.0,427940.0,1822890.0,49127.0,11042.0
100
+ 2023-08-15,3430,1312,6520709.0,24857.0,1792924,1852314,0,6063,0,9302,0,34681,0,778,4412810,3080012.0,462344.0,1935145.0,57900.0,11083.0
101
+ 2023-08-16,3253,1175,4844378.0,27290.0,3478033,1293346,0,5884,0,8280,0,29077,0,1055,4074580,3150093.0,468159.0,2094524.0,58937.0,11823.0
102
+ 2023-08-17,3714,1417,4702754.0,23408.0,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3587780,3071572.0,444690.0,1961293.0,58681.0,10987.0
103
+ 2023-08-18,1936,710,4370177.0,18919.0,3789636,1020973,0,9525,0,8958,0,32346,0,909,3722530,3252966.0,461174.0,2031390.0,61098.0,10354.0
104
+ 2023-08-19,1998,723,3683868.0,14860.0,5187185,1336224,0,8305,0,6265,0,13396,0,1267,2943410,3460234.0,494225.0,2037289.0,68988.0,9709.0
105
+ 2023-08-20,2458,839,5558511.0,16917.0,6444084,1333600,0,8083,0,5668,0,9425,0,593,2640290,3233047.0,427550.0,2093935.0,58698.0,11658.0
106
+ 2023-08-21,2316,892,5802540.0,21997.0,1578062,1099659,0,9057,0,8434,0,11204,0,597,3510210,3110596.0,442523.0,1991499.0,71910.0,13059.0
107
+ 2023-08-22,2208,845,5006504.0,13886.0,598218,939529,0,18631,0,11119,0,18304,0,666,3877380,3020862.0,419659.0,1960342.0,66769.0,12591.0
108
+ 2023-08-23,2104,821,5240143.0,16309.0,1941212,2081327,0,17073,0,8077,0,6042,0,709,3219310,2634348.0,409468.0,1726842.0,53998.0,13783.0
109
+ 2023-08-24,2011,685,5623870.0,14314.0,380971,2132605,0,13223,0,7340,0,11449,0,1774,3474730,2244344.0,385012.0,1409286.0,55699.0,13185.0
110
+ 2023-08-25,1889,680,4674166.0,13506.0,1119189,1818097,0,33200,0,7250,0,16577,0,3622,4003360,2405697.0,395219.0,1564070.0,61103.0,13348.0
111
+ 2023-08-26,1229,379,5475213.0,18030.0,476090,1048919,0,15316,0,4976,0,16625,0,3546,3448630,2662312.0,434769.0,1789446.0,61768.0,13346.0
112
+ 2023-08-27,1333,486,5591938.0,13138.0,956722,732493,0,12952,0,4227,0,19562,0,2354,3032970,2470188.0,417919.0,1980888.0,53707.0,14151.0
113
+ 2023-08-28,2031,760,7120359.0,17304.0,592505,571748,0,44816,0,8728,0,19999,0,3813,3941750,2357294.0,420574.0,1878047.0,50335.0,13442.0
114
+ 2023-08-29,1560,550,6349650.0,18074.0,395464,276869,0,217642,0,8742,0,36555,0,2778,4403680,2437012.0,455532.0,1707585.0,52913.0,12648.0
115
+ 2023-08-30,1788,623,6774580.0,17019.0,804715,227676,0,92490,0,7576,0,33376,0,1815,4493600,2461827.0,452647.0,1924554.0,57945.0,12244.0
116
+ 2023-08-31,2251,790,6881955.0,16586.0,462096,216142,0,177608,0,7188,0,13212,0,1862,3467310,2630688.0,508779.0,1691540.0,44071.0,12093.0
117
+ 2023-09-01,2763,930,5360505.0,17680.0,259775,323504,0,21865,0,7383,0,4899,0,1313,2588380,2723715.0,529388.0,1841032.0,48663.0,11275.0
118
+ 2023-09-02,2597,870,4478842.0,15289.0,1226680,320820,0,26924,0,6477,0,4896,0,1454,2531920,2929332.0,613163.0,1945160.0,60288.0,10815.0
119
+ 2023-09-03,2332,762,5174329.0,13994.0,449228,288375,0,20423,0,5755,0,10890,0,1494,2747410,2516381.0,558353.0,1697712.0,54329.0,11996.0
120
+ 2023-09-04,3561,1229,5334952.0,17444.0,296660,306771,0,324815,0,7849,0,41134,0,2069,3987700,2485534.0,613680.0,1823512.0,52578.0,12787.0
121
+ 2023-09-05,2261,816,6113505.0,20426.0,302910,227998,0,287642,0,7998,0,21025,0,1448,3377390,2453507.0,595873.0,1648165.0,49590.0,11749.0
122
+ 2023-09-06,2868,1031,5558783.0,13407.0,1266416,255848,0,203777,0,8887,0,9020,0,933,2814330,2766708.0,736889.0,1987155.0,47189.0,10851.0
123
+ 2023-09-07,2394,832,4907653.0,9041.0,191893,285511,0,202017,0,8317,0,6879,0,801,2893090,2616416.0,630668.0,1712157.0,47089.0,11632.0
124
+ 2023-09-08,2689,910,4752031.0,8867.0,157343,302141,0,201772,0,8717,0,5684,0,1428,2858250,2705167.0,791338.0,1852090.0,43707.0,10493.0
125
+ 2023-09-09,2204,752,3975657.0,10022.0,227113,245700,0,201776,0,7299,0,4098,0,758,2717380,2929279.0,827015.0,2001938.0,50033.0,10082.0
126
+ 2023-09-10,2167,743,4243960.0,10399.0,270612,291468,0,201256,0,6099,0,8097,0,809,2878400,2352670.0,1241029.0,1966290.0,41767.0,10185.0
127
+ 2023-09-11,3381,1227,4492340.0,10684.0,1192346,154867,0,202476,0,8393,0,6493,0,838,2923700,2573007.0,1455728.0,1830559.0,39596.0,12910.0
128
+ 2023-09-12,2511,884,4936079.0,10015.0,199137,170680,0,50740,0,8506,0,26721,0,1085,4318830,2527461.0,1481401.0,1856155.0,40974.0,11883.0
129
+ 2023-09-13,2143,778,5115564.0,10338.0,292239,238162,0,2408,0,7172,0,36811,0,836,3837560,2621020.0,1580825.0,1962940.0,39948.0,11634.0
130
+ 2023-09-14,2307,798,4859067.0,12717.0,1181194,308251,0,948,0,7404,0,38152,0,1282,3797130,2677877.0,1397139.0,1251585.0,46129.0,10253.0
131
+ 2023-09-15,2467,882,4260164.0,9702.0,399193,291844,0,756,0,6932,0,16060,0,2982,3201640,2751748.0,1416780.0,1269521.0,57909.0,10048.0
132
+ 2023-09-16,2076,687,3350011.0,7707.0,620978,196303,0,663,0,6018,0,9889,0,1188,2843020,3083552.0,1564491.0,1439332.0,61159.0,9435.0
133
+ 2023-09-17,2467,802,4503316.0,11119.0,581720,236009,0,637,0,4814,0,10024,0,2464,2605750,2935930.0,1503370.0,1649587.0,48796.0,10073.0
134
+ 2023-09-18,2910,1024,5568066.0,14302.0,184276,143660,0,888,0,6922,0,10381,0,1767,3209930,2373681.0,1330212.0,1479501.0,51224.0,10488.0
135
+ 2023-09-19,3252,1309,6105220.0,12193.0,208312,187769,0,1464,0,5210,0,8092,0,1504,3291230,2373344.0,1285881.0,1407015.0,40642.0,10547.0
136
+ 2023-09-20,2796,1185,6055420.0,14003.0,291395,272928,0,1077,0,4246,0,10472,0,1830,3121460,2565110.0,1425196.0,1460886.0,48962.0,10318.0
137
+ 2023-09-21,2208,878,5225528.0,8679.0,697480,160425,0,1033,0,6726,0,13928,0,1357,3634580,2686089.0,1447330.0,1236533.0,49940.0,10259.0
138
+ 2023-09-22,1734,783,4373391.0,8141.0,2220006,88968,0,738,0,9534,0,8771,0,1690,3160370,2460283.0,1353647.0,1258771.0,45467.0,9910.0
139
+ 2023-09-23,1190,492,4948823.0,10035.0,2432739,154849,0,702,0,8285,0,4369,0,806,2718390,2740252.0,1531672.0,1407980.0,51747.0,8665.0
140
+ 2023-09-24,1124,496,6239124.0,10744.0,248085,231243,0,477,0,8032,0,8640,0,1449,2680930,2648532.0,1476875.0,1294436.0,36638.0,10410.0
141
+ 2023-09-25,2358,1041,5325249.0,9804.0,251517,447312,0,591,0,11299,0,21103,0,1135,3830560,2371891.0,1333464.0,1222194.0,36894.0,9191.0
142
+ 2023-09-26,2092,994,5361926.0,13223.0,90916,351820,0,910,0,10598,0,27697,0,2803,3971740,2612585.0,1502573.0,1256804.0,33211.0,8893.0
143
+ 2023-09-27,1835,792,4600061.0,14060.0,728920,347014,0,1111,0,8811,0,104094,0,1780,5686340,2488689.0,1390273.0,1203937.0,33935.0,8769.0
144
+ 2023-09-28,1787,807,4114657.0,9434.0,84913,564139,0,279332,0,6975,0,51946,0,2516,4377350,2290090.0,1309586.0,1316086.0,32443.0,8606.0
145
+ 2023-09-29,1513,641,4477584.0,8505.0,211297,372199,0,443,0,4039,0,4466,0,1774,2520650,2429135.0,1379398.0,1425850.0,31700.0,7184.0
146
+ 2023-09-30,1127,478,4089760.0,9316.0,222854,364180,0,517,0,3251,0,13297,0,1425,2765900,1049942.0,435407.0,548780.0,10869.0,4505.0
147
+ 2023-10-01,1021,436,748856.0,2639.0,301970,224135,0,846,0,2731,0,7574,0,962,2069510,935755.0,413098.0,1084400.0,13147.0,5335.0
148
+ 2023-10-02,1673,764,1692932.0,4211.0,387802,237932,0,1564,0,12820,0,9400,0,1463,2321500,877002.0,383352.0,1016934.0,14302.0,5965.0
149
+ 2023-10-03,1516,725,1757367.0,3947.0,568156,171003,0,1739,0,21454,0,5276,0,1640,2455260,833524.0,365270.0,973716.0,14227.0,5936.0
150
+ 2023-10-04,1786,763,1733340.0,3119.0,567654,129402,0,1726,0,15833,0,13543,0,2940,2496730,836392.0,368220.0,1029847.0,13931.0,5864.0
151
+ 2023-10-05,1986,861,1671129.0,3736.0,504268,159069,0,1747,0,24285,0,8234,0,3163,2626960,830805.0,380396.0,476125.0,13399.0,5529.0
152
+ 2023-10-06,1774,753,1348401.0,2784.0,702326,205479,0,1686,0,15228,0,12269,0,2107,2378150,817142.0,382879.0,504402.0,11840.0,5476.0
153
+ 2023-10-07,1150,416,1175733.0,2242.0,359848,180366,0,1446,0,19417,0,27951,0,2050,3080590,921412.0,418533.0,520370.0,11215.0,5083.0
154
+ 2023-10-08,999,337,1296701.0,2609.0,662748,293989,0,1415,0,14589,0,18476,0,1786,2484160,768086.0,352949.0,357821.0,12788.0,5550.0
155
+ 2023-10-09,772,289,1942734.0,4167.0,3096792,191352,0,1855,0,24331,0,21658,0,1757,2722910,653538.0,261410.0,590317.0,14449.0,6333.0
156
+ 2023-10-10,737,241,1911227.0,4238.0,565419,164827,0,2101,0,11526,0,9057,0,2720,2528280,734200.0,300476.0,568450.0,13952.0,6145.0
157
+ 2023-10-11,681,256,2171216.0,4714.0,503802,216630,0,1921,0,7255,0,7549,0,2025,2463820,958835.0,399349.0,595481.0,12432.0,5599.0
158
+ 2023-10-12,673,240,1820266.0,4067.0,233553,161215,0,8042,0,4686,0,5288,0,1408,2044540,861845.0,336598.0,557239.0,13130.0,5889.0
159
+ 2023-10-13,595,233,1529402.0,3094.0,68852,156834,0,7184,0,4986,0,14364,0,1924,2576940,801772.0,317596.0,563967.0,12222.0,5539.0
160
+ 2023-10-14,748,266,1013578.0,2156.0,48430,185877,0,3043,0,4287,0,14809,0,2117,2441800,929822.0,362662.0,603684.0,11533.0,5191.0
161
+ 2023-10-15,602,201,1596953.0,4098.0,55580,222305,0,12269,0,4366,0,15778,0,1639,2190130,891052.0,327915.0,425822.0,13301.0,6358.0
162
+ 2023-10-16,964,369,2144206.0,5169.0,31683,118393,0,6488,0,5537,0,65656,0,1254,4509620,842123.0,317951.0,810650.0,16455.0,7813.0
163
+ 2023-10-17,1105,415,2112245.0,5363.0,69479,70676,0,4964,0,4816,0,18719,0,2353,2816530,816941.0,328053.0,766996.0,14912.0,7402.0
164
+ 2023-10-18,913,348,1892230.0,4633.0,451927,111742,0,4068,0,4855,0,32612,0,2028,3728560,957593.0,377866.0,689470.0,15228.0,7272.0
165
+ 2023-10-19,914,302,1550243.0,3817.0,100009,183549,0,4309,0,4468,0,68322,0,2169,4292380,846076.0,336810.0,775970.0,14394.0,6925.0
166
+ 2023-10-20,663,208,1100622.0,2740.0,174916,181797,0,3695,0,4056,0,58835,0,1887,4493840,910115.0,366406.0,653096.0,15447.0,6572.0
167
+ 2023-10-21,559,184,1405730.0,3216.0,207981,276329,0,2723,0,3213,0,44899,0,1893,3204000,1184901.0,485051.0,850250.0,14780.0,6181.0
168
+ 2023-10-22,545,198,1467468.0,3228.0,520836,253840,0,2213,0,2850,0,27411,0,1911,2969510,1154732.0,423852.0,1027954.0,10344.0,4893.0
169
+ 2023-10-23,625,231,2018062.0,5517.0,333114,436011,0,2839,0,3772,0,11121,0,1351,2287750,1208181.0,428535.0,1111507.0,11684.0,6220.0
170
+ 2023-10-24,574,226,1889784.0,5099.0,188275,228582,0,2709,0,2462,0,1109,0,1918,1952480,1083131.0,378488.0,1161439.0,11452.0,5728.0
171
+ 2023-10-25,536,184,2276229.0,5661.0,77308,332105,0,2708,0,2679,0,525,0,2402,1869210,905535.0,310989.0,865636.0,11200.0,5884.0
172
+ 2023-10-26,609,200,1753696.0,4367.0,85971,236204,0,2136,0,2300,0,10,0,3842,1710220,968078.0,332008.0,771447.0,10098.0,5558.0
173
+ 2023-10-27,563,209,1636932.0,3338.0,246909,285904,0,1992,0,2323,0,5,0,2851,1458010,1063329.0,352124.0,929257.0,9507.0,5001.0
174
+ 2023-10-28,450,155,1588245.0,4276.0,235960,324079,0,2716,0,1753,0,1,0,2585,1510690,1191854.0,384343.0,1028724.0,8578.0,4958.0
175
+ 2023-10-29,309,117,1731474.0,5065.0,70210,331208,0,2241,0,1708,0,5,0,3120,1547290,1137463.0,385520.0,764681.0,10186.0,5650.0
176
+ 2023-10-31,486,182,2220653.0,5950.0,41641,213812,0,149,0,2404,0,15,0,1380,1648060,913362.0,318222.0,1020094.0,10416.0,3703.0
177
+ 2023-11-01,296,123,1834772.0,4275.0,201158,313487,0,889,0,2485,0,33093,0,2287,2939670,862276.0,316545.0,798469.0,11740.0,3972.0
178
+ 2023-11-02,346,111,1697213.0,2987.0,1586296,64435,0,957,0,2130,0,16368,0,3586,2385890,840477.0,298617.0,830972.0,10008.0,3641.0
179
+ 2023-11-03,224,89,1759831.0,2940.0,93667,74522,0,962,0,2484,0,14150,0,953,1937810,952592.0,350909.0,800378.0,11090.0,3818.0
180
+ 2023-11-04,214,76,1677064.0,2752.0,65182,61325,0,1796,0,3084,0,10438,0,1148,1622250,957265.0,344580.0,821570.0,11309.0,4380.0
181
+ 2023-11-05,350,100,1553224.0,3167.0,224953,172587,0,727,0,2295,0,17642,0,1535,2117090,,,,,
182
+ 2023-11-06,217,81,718827.0,1492.0,197532,226189,0,8785,0,3391,0,13745,0,1229,2102830,,,,,
Media_data_for_model_dma_level.csv ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,paid_search_impressions,paid_search_clicks,kwai_impressions,kwai_clicks,programmaticimpressions,programmaticclicks,affiliates_impressions,affiliates_clicks,indicacao_impressions,indicacao_clicks,infleux_impressions,infleux_clicks,influencer_impressions,influencer_clicks,FB: Level Achieved - Tier 1 Impressions, FB: Level Achieved - Tier 2 Impressions,paid_social_others, GA App: Will And Cid Pequena Baixo Risco Clicks,digital_tactic_others,DMA,Panel,Account Requests - Appsflyer,App Installs - Appsflyer,BAU approved clients - Appsflyer,BAU approved clients - Revenue,Gamified approved clients - Appsflyer,Gamified approved clients - Revenue,Total Approved Accounts - Appsflyer,Total Approved Accounts - Revenue,Adjusted Account Approval,Adjusted Account Approval BAU
2
+ 9/5/2023,6111,1916,1365036,5044,104781,31371909,0,3341,0,11190,0,61956,0,457,2371841,1021599,2302543,34816,19205,D1,P1,35411,86251,2786,4926900,1395,139500,4181,5066400,6110.89,4301.97
3
+ 10/5/2023,6233,1888,1234034,3899,140810,32973036,0,3214,0,9988,0,52049,0,705,2100238,943808,2336369,19716,17415,D1,P1,37986,96199,3087,5328400,1515,151500,4603,5480000,7186.64,5128.37
4
+ 11/5/2023,5568,1816,1016155,2788,102248,50729517,0,3203,0,10869,0,8042,0,381,2461265,1127717,1110415,21547,11051,D1,P1,24496,77036,2337,4001750,1327,132700,3663,4133100,5892.4,4091.77
5
+ 12/5/2023,5109,1769,1228032,3101,100246,63142114,0,2492,0,7096,0,10596,0,299,2313368,1107256,1191901,31966,11081,D1,P1,21030,75112,2052,3462310,1116,111600,3168,3573910,5091.46,3601.62
6
+ 13/05/2023,3712,1231,1344557,3399,100714,59509032,0,3986,0,4282,0,9753,0,366,3067797,1388882,1403486,38518,10762,D1,P1,16294,64652,1611,2693420,827,82700,2438,2776120,3925.27,2780.04
7
+ 14/05/2023,3719,1241,1520157,3491,120162,49538293,0,1891,0,3002,0,7363,0,278,3140882,1429620,2518831,44744,12151,D1,P1,13378,55706,1428,2535460,765,76500,2193,2611960,3658.41,2543.11
8
+ 15/05/2023,7735,2663,2102264,5175,106903,46609819,0,2518,0,4548,0,16201,0,880,2916228,1288902,2456845,36269,15290,D1,P1,21857,67301,2149,3844360,1075,107500,3223,3951760,5540.69,3945.07
9
+ 16/05/2023,9409,3206,2134290,5636,88201,9662393,0,2247,0,6690,0,15031,0,1588,3161940,1370882,2403330,37393,14187,D1,P1,26562,53380,2486,4026650,1251,125100,3736,4150900,6839.28,4817.99
10
+ 17/05/2023,8409,2785,1473128,4336,56382,2232239,0,2557,0,6401,0,8946,0,322,3199527,1379566,2608845,39190,12591,D1,P1,21930,41033,2100,3675940,1126,112600,3226,3788540,6156.6,4185.47
11
+ 18/05/2023,8364,2873,1733275,5009,38145,7321146,0,2912,0,7286,0,14366,0,660,2623727,1115471,1723470,36020,12100,D1,P1,21813,40251,1987,3528210,1240,124000,3227,3652210,6388.27,4150.71
12
+ 19/05/2023,6432,2050,1784426,5063,23340,8715910,0,3934,0,6035,0,20378,0,362,2995998,1287313,1959870,36885,12848,D1,P1,19874,38360,1888,3663690,1140,114000,3027,3777590,5981.25,3891.85
13
+ 20/05/2023,5428,1724,1635604,4408,34693,8783612,0,3318,0,4714,0,21030,0,236,2996479,1326416,1903323,31048,12256,D1,P1,17568,33060,1691,3342720,931,93100,2623,3437270,5113.91,3453.26
14
+ 21/05/2023,5657,1807,1788487,4492,24812,5015214,0,2253,0,4227,0,11656,0,494,3167634,1309450,3651254,33361,13073,D1,P1,14766,28367,1461,2940020,800,80000,2261,3020020,4874.35,3300.96
15
+ 22/05/2023,5768,2036,2176947,5688,25298,3002995,0,2739,0,8313,0,25663,0,1147,3573865,1548365,3939226,33410,14092,D1,P1,21520,40205,1854,3533540,1097,109700,2951,3643240,6425.41,4211.67
16
+ 23/05/2023,5051,1720,2359219,6966,24773,3005057,0,4738,0,13827,0,47900,0,965,3248157,1376975,3631390,35016,13025,D1,P1,29860,51811,2527,5012370,1339,133900,3866,5146270,7978.08,5238.68
17
+ 24/05/2023,6078,1977,1612918,4924,24591,2833280,0,4816,0,12417,0,94489,0,1254,3572793,1550315,3532105,37491,12546,D1,P1,41297,68099,2993,5666720,1655,165500,4648,5832220,8715.48,5761.11
18
+ 25/05/2023,6547,2075,1468456,3624,19705,2771412,0,5070,0,7395,0,70016,0,762,3164337,1353382,3253308,34658,13154,D1,P1,33436,56714,2588,5066960,1509,150900,4097,5217860,7939.09,5062.98
19
+ 26/05/2023,3719,1189,1770048,4874,16879,2875657,0,2855,0,6964,0,29015,0,627,2989794,1248779,3345390,38267,12788,D1,P1,22185,40261,2101,4010930,1130,113000,3231,4123930,6785.57,4495.67
20
+ 27/05/2023,3620,1145,1900387,5061,14156,2663378,0,3295,0,4472,0,5625,0,1473,3576647,1527545,3694843,40685,12844,D1,P1,13490,26751,1407,2592840,756,75600,2163,2668440,5325.41,3549.17
21
+ 28/05/2023,4195,1302,2026053,5703,12334,2609966,0,2190,0,3737,0,5030,0,1401,3376177,1447089,2563297,42359,13543,D1,P1,13124,25607,1374,2558180,722,72200,2096,2630380,5282.85,3554.29
22
+ 29/05/2023,5265,1798,2328823,6483,14783,2537637,0,3954,0,5211,0,221,0,1575,3765997,1720747,2865333,39579,8116,D1,P1,15619,30688,1585,2979010,785,78500,2370,3057510,5961.63,4097.14
23
+ 30/05/2023,3879,1366,2294654,6008,15979,2489630,0,4465,0,6041,0,6,0,1192,3790830,1751416,2822819,37234,8830,D1,P1,17258,32693,1773,3270270,900,90000,2673,3360270,6752.47,4596.75
24
+ 31/05/2023,3933,1348,1645187,4081,14208,2337652,0,3797,0,4794,0,6,0,888,4151434,1953620,2714074,45856,6861,D1,P1,16458,31379,1688,3065730,924,92400,2612,3158130,6598.66,4373.22
25
+ 1/6/2023,4817,1530,1862175,4841,48192,3241822,0,3060,0,4802,0,12820,0,1137,4151797,1903421,2255850,51175,7095,D1,P1,17582,34622,1700,3231430,909,90900,2609,3322330,6342.48,4257.19
26
+ 2/6/2023,5733,1800,966546,2646,43573,4582872,0,1563,0,10678,0,46810,0,1309,4313201,2009602,2074692,47378,6120,D1,P1,25710,47869,2271,4131170,1130,113000,3401,4244170,6992.72,4747.36
27
+ 3/6/2023,4142,1290,2445721,11111,90587,4764628,0,2176,0,5144,0,27735,0,518,4514302,2083217,2095544,58527,5748,D1,P1,19247,37244,1905,3615570,961,96100,2866,3711670,5996.2,4065.63
28
+ 4/6/2023,5143,1613,2296690,6790,40929,4717779,0,1280,0,4237,0,5606,0,325,4179140,1889452,2152476,45239,6093,D1,P1,13474,29405,1475,2776480,755,75500,2230,2851980,5219.47,3571.73
29
+ 5/6/2023,5384,1832,3509278,8938,56272,19979584,0,1377,0,11493,0,25647,0,579,3683204,1641254,3616732,40356,6453,D1,P1,22558,54639,2114,4004520,1128,112800,3242,4117320,6672.4,4468.93
30
+ 6/6/2023,4802,1594,3216944,7861,20049,33102789,0,1485,0,9086,0,36532,0,545,3822453,1716540,3687300,53347,6334,D1,P1,26643,69935,2358,4505090,1222,122200,3580,4627290,6855.89,4686.82
31
+ 7/6/2023,5072,1648,2143372,5356,22553,21321547,0,1576,0,7213,0,21215,0,628,4178339,1811963,2354753,51632,6259,D1,P1,22242,56660,2125,3900920,1184,118400,3309,4019320,6611.5,4370.78
32
+ 8/6/2023,4444,1465,3190766,8024,53653,10254268,0,2046,0,10491,0,19549,0,769,3941272,1738344,2283350,59291,6775,D1,P1,23293,50105,2238,4145770,1270,127000,3508,4272770,6851.85,4515.66
33
+ 9/6/2023,4818,1605,3278715,9328,18347,4890758,0,1925,0,8360,0,32385,0,1732,3969227,1777864,2353376,52000,6026,D1,P1,25950,50611,2404,4657210,1315,131500,3719,4788710,6881.12,4639.8
34
+ 10/6/2023,3465,1207,2887842,8529,725,5489947,0,1230,0,5401,0,37954,0,2136,4458593,2061762,2535928,66567,5554,D1,P1,24413,47973,2370,4584570,1225,122500,3595,4707070,6334.68,4283.38
35
+ 11/6/2023,4727,1501,3149290,8114,738,5313957,0,1839,0,8198,0,32493,0,1533,4442610,2006438,2183963,47655,6008,D1,P1,23656,46275,2220,4441870,1183,118300,3403,4560170,6134.11,4098
36
+ 12/6/2023,6437,2208,4416005,12345,149561,5298884,0,1905,0,8542,0,101079,0,472,4645531,1995891,3301882,38760,4966,D1,P1,44382,76997,3520,6853780,1782,178200,5302,7031980,8549.02,5779.3
37
+ 13/06/2023,3556,1254,4626697,12984,258088,5952266,0,2095,0,10415,0,59770,0,1016,4508060,1912958,3440789,47281,4630,D1,P1,35764,67060,2737,5184020,1530,153000,4266,5335600,7908.1,5200.7
38
+ 14/06/2023,3178,1060,3389530,10298,685692,10454400,0,2258,0,24457,0,16016,0,1101,4573214,1920050,3160905,41549,5083,D1,P1,27677,56158,2257,4257990,1244,124400,3501,4382390,7187.71,4826.11
39
+ 15/06/2023,2981,999,3131350,10791,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4075106,1690702,3267810,50496,5037,D1,P1,23775,50354,2201,4212820,1215,121500,3416,4334320,7339.75,4890.1
40
+ 16/06/2023,2705,947,2923279,11124,1166424,11840950,0,1780,0,8938,0,24339,0,966,4533368,1939737,2881833,41872,4604,D1,P1,22957,49677,2225,4445430,1154,115400,3379,4560830,6663.77,4416.03
41
+ 17/06/2023,3697,1154,2955836,10440,807683,9748201,0,2139,0,5741,0,54129,0,766,4958344,2059487,3183051,52618,3675,D1,P1,26623,53187,2434,4755560,1286,128600,3723,4890110,6983.5,4694.41
42
+ 18/06/2023,3229,1080,3280006,12373,116340,8176712,0,1481,0,4741,0,16724,0,864,4270249,1735486,3251229,39780,3696,D1,P1,16690,36522,1715,3294460,936,93600,2651,3388060,5614.57,3749.6
43
+ 19/06/2023,3082,1003,6545797,24462,55763,4841897,0,2098,0,10520,0,26558,0,2211,4137846,1743715,2680413,43156,4347,D1,P1,25736,50759,2343,4515000,1244,124400,3587,4639400,7090.09,4789.96
44
+ 20/06/2023,2422,857,6734594,28910,52166,4718912,0,2205,0,10284,0,30610,0,1002,4218772,1771102,2058734,42288,4260,D1,P1,27941,52107,2478,4829920,1398,139800,3876,4969720,7584.9,4974.28
45
+ 21/06/2023,3366,1132,4784180,17247,52817,5971594,0,3387,0,9277,0,41697,0,645,4113884,1743016,2111350,44159,4193,D1,P1,28338,53853,2376,4353550,1357,135700,3733,4489250,7214.21,4702.88
46
+ 22/06/2023,2841,924,3300680,13360,29784,6803330,0,4064,0,7068,0,68638,0,481,3738171,1533407,1597072,35381,4173,D1,P1,34683,62182,2532,4863520,1434,143400,3966,5006920,7223.75,4679.68
47
+ 23/06/2023,2474,805,2284446,9012,80066,6833289,0,3274,0,7379,0,13501,0,721,4479743,1889155,1647740,39089,3640,D1,P1,16506,35549,1530,2980550,888,88800,2418,3069350,5295.75,3457.41
48
+ 24/06/2023,2462,814,1947190,7247,50309,6526903,0,2767,0,4703,0,8438,0,616,3758421,1565736,1648519,46332,3834,D1,P1,13804,31588,1381,2698000,788,78800,2169,2776800,4822.39,3136
49
+ 25/06/2023,2082,679,3560248,14850,50806,6368664,0,2767,0,4414,0,5346,0,628,4038846,1700182,2514456,43065,4201,D1,P1,13435,30121,1424,2782640,778,77800,2202,2860440,5082.66,3353.86
50
+ 26/06/2023,2399,839,5999950,28401,23209,10788275,0,3699,0,13383,0,13592,0,790,3427918,1403888,3598236,33883,4642,D1,P1,21114,49622,1959,3810990,1175,117500,3134,3928490,6965.39,4504.75
51
+ 27/06/2023,2307,804,5005495,18260,81344,14103220,0,7082,0,8898,0,40917,0,945,3819654,1523667,3556028,35326,4628,D1,P1,32019,65348,2877,5691820,1595,159500,4472,5851320,9589,6333.48
52
+ 28/06/2023,2215,759,3721084,11248,20153,10547995,0,8387,0,7120,0,39693,0,944,3671994,1568555,1397196,33212,2998,D1,P1,30267,63086,2863,5931970,1516,151600,4379,6083570,8919.81,5942.75
53
+ 29/06/2023,2013,706,3918049,10226,155296,8525871,0,10096,0,5693,0,24049,0,1512,3937747,1585655,3393043,30700,2519,D1,P1,22893,54097,2125,4215060,1132,113200,3257,4328260,7178.85,4806.94
54
+ 30/06/2023,1258,454,3088874,7943,902115,10945715,0,8904,0,9611,0,62404,0,1029,4945464,1946944,1835310,52445,2839,D1,P1,30707,67849,2616,5112840,1397,139700,4013,5252540,7664.09,5203.16
55
+ 1/7/2023,1641,539,3872657,12034,191537,12141356,0,4956,0,6049,0,31194,0,923,5328149,2224200,2123805,56724,2513,D1,P1,22229,54353,2266,4505840,1205,120500,3471,4626340,6983.83,4746.37
56
+ 2/7/2023,1336,485,5799582,17238,576858,12180985,0,4148,0,4670,0,4766,0,617,4527404,1997256,2038953,50510,21201,D1,P1,15205,43684,1672,3328290,886,88600,2559,3416990,5952.59,4038.91
57
+ 3/7/2023,2712,924,9986061,28191,442261,14059535,0,5347,0,7408,0,19028,0,1044,4179823,1854231,2234940,57543,14473,D1,P1,22798,57392,2425,4796940,1308,130800,3732,4925290,7701.44,5182.84
58
+ 4/7/2023,4137,1419,4717456,14519,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4449073,1959412,2350308,49085,9854,D1,P1,23585,60143,2220,4262060,1327,132700,3547,4394760,7689.38,5021.95
59
+ 5/7/2023,4166,1422,4779589,12676,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4464681,1969744,2390838,41411,12751,D1,P1,22847,61021,2348,4359400,1422,142200,3769,4497600,7976.49,5170.89
60
+ 6/7/2023,4182,1444,4939385,12222,2364811,15879491,0,6575,0,8461,0,18225,0,997,4490815,1942923,2239375,44808,16216,D1,P1,23716,60282,2602,4960450,1543,154300,4145,5114750,8225.73,5423.76
61
+ 7/7/2023,3497,1181,3121447,7534,1063284,17341347,0,6025,0,8113,0,25962,0,659,4891573,2128787,1976413,57373,12464,D1,P1,23336,58252,2335,4783910,1269,126900,3604,4910810,7182.26,4846.37
62
+ 8/7/2023,2760,856,3295227,9788,1119268,19207341,0,4102,0,6195,0,40506,0,832,5039604,2277255,2330435,44052,15163,D1,P1,22278,62471,2128,4352160,1191,119100,3319,4471260,6706.12,4485.38
63
+ 9/7/2023,2809,875,3913741,11815,749310,25182206,0,6420,0,5222,0,49626,0,718,4669470,2144473,3908306,49659,11716,D1,P1,24736,69003,2620,5573560,1325,132500,3945,5706060,7673.85,5278.59
64
+ 10/7/2023,4312,1489,5972974,18402,1511035,25950979,0,9842,0,10638,0,36204,0,935,4584106,2019220,4391654,52303,12983,D1,P1,28497,78251,2578,5157430,1419,141900,3997,5299330,8174.81,5453.8
65
+ 11/7/2023,4579,1550,4999618,16469,559119,23938153,0,11688,0,36570,0,25216,0,1289,4458364,1932300,4150666,47979,12292,D1,P1,28688,77223,2707,5384090,1483,148300,4190,5532390,8594.12,5787.78
66
+ 12/7/2023,4079,1418,4465722,13191,583520,25196511,0,4610,0,9813,0,20388,0,1210,4558876,2000168,4109583,54631,12366,D1,P1,25749,73523,2403,4926480,1410,141000,3813,5067480,8000.73,5259.61
67
+ 13/07/2023,3719,1260,4635033,12302,903614,25720336,0,7867,0,6792,0,22248,0,857,4596184,1957206,3729970,48474,11017,D1,P1,22447,69283,2134,4261960,1312,131200,3447,4393760,7385.89,4769.15
68
+ 14/07/2023,3632,1224,3441594,9800,1566300,28606996,0,6726,0,6172,0,14670,0,432,4683387,2007387,3912229,52588,10079,D1,P1,19225,67928,2002,3875450,1077,107700,3079,3983150,6615.15,4505.74
69
+ 15/07/2023,2909,941,6025085,21326,1836196,28705476,0,5705,0,4369,0,31202,0,595,5008167,2251661,3727627,58143,10214,D1,P1,19533,64001,2026,4112810,1066,106600,3093,4220310,6115.73,4122.89
70
+ 16/07/2023,2818,853,7339565,26586,4043959,26752554,0,7733,0,3961,0,27180,0,1082,4716541,2092258,2114014,59204,11281,D1,P1,18871,60797,1956,3715100,1126,112600,3084,3832400,6216.99,4066.5
71
+ 17/07/2023,4420,1486,9638491,32269,819444,29437537,0,11485,0,5220,0,66236,0,2418,4359325,1937825,1989872,55815,11896,D1,P1,35493,89662,2771,5539890,1521,152100,4292,5691990,8025.2,5388.69
72
+ 18/07/2023,4574,1551,9498457,31230,1206114,29164369,0,5012,0,7146,0,47074,0,2358,4882304,2163458,2157773,69573,12604,D1,P1,32238,84091,2687,5214920,1329,132900,4016,5347820,7833.63,5336.47
73
+ 19/07/2023,4632,1537,9742535,26935,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4613422,2080215,1981362,67495,12116,D1,P1,23193,69138,2342,4581910,1084,108400,3426,4690310,7118.68,4991.3
74
+ 20/07/2023,4891,1632,7630122,20720,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4484291,1922090,1663127,75312,12252,D1,P1,23193,63445,2209,4471970,995,99500,3255,4576570,6700.79,4599.1
75
+ 21/07/2023,3978,1378,7284968,21477,2456715,17869335,0,6360,0,10877,0,11431,0,769,4519305,1975730,1686467,68931,10065,D1,P1,21478,57996,2115,4257360,1006,100600,3121,4357960,6467.01,4497.43
76
+ 22/07/2023,3151,978,5638955,16181,2015345,12808440,0,7097,0,5145,0,13811,0,699,4689346,2086993,1861883,71898,9081,D1,P1,17602,50209,1897,3876970,830,83000,2727,3959970,5812.35,4126.62
77
+ 23/07/2023,2905,986,6133144,16089,881691,11267535,0,5593,0,4746,0,68021,0,514,4242878,1843843,1681215,61164,10797,D1,P1,25804,58279,2442,5168300,1161,116100,3603,5284400,6622.56,4639.27
78
+ 24/07/2023,4606,1651,8830736,21931,189913,35658281,0,8836,0,6040,0,64066,0,1626,3943001,1708849,1900126,59494,10236,D1,P1,31953,73505,2898,6111230,1424,142400,4321,6253530,8030.22,5492.47
79
+ 25/07/2023,4414,1597,7750251,15384,3348941,25011847,0,10262,0,9572,0,15072,0,916,3976490,1729916,1911109,68826,11468,D1,P1,26162,65005,2440,4822810,1154,115400,3594,4938210,7092.81,4965.39
80
+ 26/07/2023,4488,1530,8125332,16391,1040452,24380635,0,9947,0,16453,0,38777,0,1551,3837786,1680967,1856885,74924,13290,D1,P1,31894,69746,2797,5552460,1348,134800,4147,5687460,7359.12,5027.76
81
+ 27/07/2023,4105,1494,8054962,14724,220302,13070502,0,6758,0,8841,0,20622,0,1313,3636297,1544742,1772602,63935,11680,D1,P1,24634,57255,2498,5018670,1196,119600,3694,5138270,7106.66,4875.99
82
+ 28/07/2023,3743,1318,6955526,11566,3991586,5347413,0,10451,0,8496,0,20184,0,1563,3890784,1680538,1608577,73120,11390,D1,P1,22265,50660,2204,4515740,1054,105400,3258,4621140,6441.87,4432.07
83
+ 29/07/2023,3395,1192,5132501,9837,1349895,4441709,0,7115,0,5449,0,18983,0,1129,4295602,1813637,1824777,80511,11911,D1,P1,17626,42341,1930,3807270,860,86000,2790,3893270,5519.71,3922.54
84
+ 30/07/2023,2746,903,4903153,11018,710000,4431986,0,8491,0,4599,0,24834,0,1109,3924352,1733790,1740605,72221,11440,D1,P1,17619,43309,1942,3937090,834,83400,2776,4020490,5556.3,3945.89
85
+ 31/07/2023,4208,1476,6832832,19648,1721973,4079656,0,7754,0,7818,0,27918,0,2050,3760475,1501134,1957900,62124,11605,D1,P1,22728,51399,2256,4604950,1046,104600,3302,4709550,6481.79,4556.75
86
+ 1/8/2023,4203,1489,6398210,15890,2250090,5457683,0,7588,0,7948,0,61894,0,1248,3687038,1439092,1774701,61448,11492,D1,P1,31009,67515,2609,5471270,1309,130900,3918,5602170,6825.97,4671.87
87
+ 2/8/2023,4285,1515,5402871,14825,785167,6582085,0,6079,0,7236,0,79041,0,1345,3807266,1493340,2025308,54506,11515,D1,P1,34034,74123,2858,5856910,1360,136000,4218,5992910,7171.23,4989.3
88
+ 3/8/2023,4667,1744,4724924,8903,1111815,10407793,0,9077,0,7117,0,31714,0,1983,3797879,1479623,1718831,52587,11408,D1,P1,23978,62504,2404,4832400,1095,109500,3498,4941800,6670.71,4627.48
89
+ 4/8/2023,4201,1562,3732952,9116,4574481,10660977,0,8436,0,6970,0,25097,0,1055,3814852,1466211,1374674,57482,10785,D1,P1,21714,62922,2226,4561560,975,97500,3201,4659060,6133.71,4366.77
90
+ 5/8/2023,3080,1110,3310732,9884,3460283,11580456,0,5735,0,5049,0,5911,0,704,4048945,1601234,1442690,65158,9942,D1,P1,13792,52995,1578,3188640,720,72000,2298,3260640,4760.04,3375.44
91
+ 6/8/2023,2809,979,4153998,11663,5103054,8381689,0,4868,0,4184,0,28658,0,637,4040770,1250223,1844909,47698,10816,D1,P1,17706,56827,1841,3921270,842,84200,2683,4005470,5062.91,3520.39
92
+ 7/8/2023,3522,1186,3164171,10000,4137349,8709017,0,6112,0,6640,0,43866,0,1285,3928811,1288638,1861166,44623,11648,D1,P1,26772,71580,2456,4923260,1132,113200,3587,5034960,6580.87,4648.84
93
+ 8/8/2023,4111,1495,6020074,15008,2923076,5012245,0,6684,0,6961,0,12257,0,3038,3921429,1094791,2059462,48047,10379,D1,P1,22363,60212,2075,4138870,971,97100,3046,4235970,6286.57,4418.71
94
+ 9/8/2023,3609,1285,5616011,13195,2483117,3900778,0,8177,0,6447,0,12774,0,1309,3322165,452000,2262292,52219,11047,D1,P1,21099,53059,2067,4030270,1010,101000,3077,4131270,6309.32,4273.88
95
+ 10/8/2023,3872,1330,5270940,11342,1305507,3614496,0,6927,0,6602,0,21830,0,986,2868345,452896,1541791,46720,10556,D1,P1,22515,52055,2216,4848640,974,97400,3190,4946040,6281.59,4498.26
96
+ 11/8/2023,3673,1257,4485834,10445,3562053,5521177,0,5810,0,13751,0,5797,0,751,3242607,511016,1679989,47262,10344,D1,P1,17086,46491,1551,3242370,671,67100,2222,3309470,4608.96,3355.58
97
+ 12/8/2023,2744,960,3946512,10052,4015316,5813616,0,6205,0,10379,0,9890,0,532,3761072,595191,1931989,54787,9210,D1,P1,15949,46498,1376,3113130,639,63900,2016,3177130,4121.65,2907.82
98
+ 13/08/2023,2418,775,5051792,11809,1869057,6348414,0,4093,0,5187,0,21320,0,399,3279816,503805,2171335,55136,10546,D1,P1,14745,44224,1327,2888900,648,64800,1975,2953700,3905.29,2752.8
99
+ 14/08/2023,3551,1196,4839009,11805,1765326,3758610,0,6170,0,7226,0,19575,0,706,2974893,427940,1822890,49127,11042,D1,P1,20336,49993,1770,3798710,748,74800,2518,3873510,5195.83,3786.85
100
+ 15/08/2023,3430,1312,6520709,24857,1792924,1852314,0,6063,0,9302,0,34681,0,778,3080012,462344,1935145,57900,11083,D1,P1,24449,48710,1946,4332210,807,80700,2752,4412810,5367.05,3930.18
101
+ 16/08/2023,3253,1175,4844378,27290,3478033,1293346,0,5884,0,8280,0,29077,0,1055,3150093,468159,2094524,58937,11823,D1,P1,23892,46995,1911,3996580,780,78000,2691,4074580,5452.88,3979.2
102
+ 17/08/2023,3714,1417,4702754,23408,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3071572,444690,1961293,58681,10987,D1,P1,21265,42100,1700,3517380,704,70400,2404,3587780,5150.22,3718.85
103
+ 18/08/2023,1936,710,4370177,18919,3789636,1020973,0,9525,0,8958,0,32346,0,909,3252966,461174,2031390,61098,10354,D1,P1,20983,41383,1778,3654630,679,67900,2457,3722530,5019.58,3716.93
104
+ 19/08/2023,1998,723,3683868,14860,5187185,1336224,0,8305,0,6265,0,13396,0,1267,3460234,494225,2037289,68988,9709,D1,P1,14640,31119,1331,2887610,528,52800,1860,2943410,4059.2,3012.38
105
+ 20/08/2023,2458,839,5558511,16917,6444084,1333600,0,8083,0,5668,0,9425,0,593,3233047,427550,2093935,58698,11658,D1,P1,13616,29557,1227,2592690,476,47600,1703,2640290,3842.86,2850.38
106
+ 21/08/2023,2316,892,5802540,21997,1578062,1099659,0,9057,0,8434,0,11204,0,597,3110596,442523,1991499,71910,13059,D1,P1,19336,38812,1656,3445610,663,66300,2319,3510210,5100.16,3789.37
107
+ 22/08/2023,2208,845,5006504,13886,598218,939529,0,18631,0,11119,0,18304,0,666,3020862,419659,1960342,66769,12591,D1,P1,21348,42166,1844,3824050,762,76200,2582,3877380,5610.58,4088.17
108
+ 23/08/2023,2104,821,5240143,16309,1941212,2081327,0,17073,0,8077,0,6042,0,709,2634348,409468,1726842,53998,13783,D1,P1,18864,38949,1513,3153720,655,65500,2165,3219310,4984.78,3596.01
109
+ 24/08/2023,2011,685,5623870,14314,380971,2132605,0,13223,0,7340,0,11449,0,1774,2244344,385012,1409286,55699,13185,D1,P1,18821,38282,1665,3378840,678,67800,2358,3474730,5209.76,3795.85
110
+ 25/08/2023,1889,680,4674166,13506,1119189,1818097,0,33200,0,7250,0,16577,0,3622,2405697,395219,1564070,61103,13348,D1,P1,18364,37536,1863,3939560,638,63800,2501,4003360,5070.56,3850.47
111
+ 26/08/2023,1229,379,5475213,18030,476090,1048919,0,15316,0,4976,0,16625,0,3546,2662312,434769,1789446,61768,13346,D1,P1,16076,32992,1816,3388030,606,60600,2422,3448630,4877.02,3729.33
112
+ 27/08/2023,1333,486,5591938,13138,956722,732493,0,12952,0,4227,0,19562,0,2354,2470188,417919,1980888,53707,14151,D1,P1,14834,30563,1572,2979370,536,53600,2108,3032970,4232.88,3241.64
113
+ 28/08/2023,2031,760,7120359,17304,592505,571748,0,44816,0,8728,0,19999,0,3813,2357294,420574,1878047,50335,13442,D1,P1,20994,42982,1970,3877550,642,64200,2612,3941750,5610.5,4325.83
114
+ 29/08/2023,1560,550,6349650,18074,395464,276869,0,217642,0,8742,0,36555,0,2778,2437012,455532,1707585,52913,12648,D1,P1,25919,51217,2270,4323380,803,80300,3073,4403680,6223.41,4701.59
115
+ 30/08/2023,1788,623,6774580,17019,804715,227676,0,92490,0,7576,0,33376,0,1815,2461827,452647,1924554,57945,12244,D1,P1,24015,48307,2298,4414000,796,79600,3094,4493600,5983.31,4520.44
116
+ 31/08/2023,2251,790,6881955,16586,462096,216142,0,177608,0,7188,0,13212,0,1862,2630688,508779,1691540,44071,12093,D1,P1,17587,35874,1809,3406910,604,60400,2413,3467310,5218.62,4005.29
117
+ 1/9/2023,2763,930,5360505,17680,259775,323504,0,21865,0,7383,0,4899,0,1313,2723715,529388,1841032,48663,11275,D1,P1,13457,29785,1396,2542480,459,45900,1855,2588380,4243.41,3270.46
118
+ 2/9/2023,2597,870,4478842,15289,1226680,320820,0,26924,0,6477,0,4896,0,1454,2929332,613163,1945160,60288,10815,D1,P1,12337,27451,1347,2481120,508,50800,1855,2531920,4227.98,3109.35
119
+ 3/9/2023,2332,762,5174329,13994,449228,288375,0,20423,0,5755,0,10890,0,1494,2516381,558353,1697712,54329,11996,D1,P1,12609,27028,1428,2699310,481,48100,1909,2747410,4177.46,3164.79
120
+ 4/9/2023,3561,1229,5334952,17444,296660,306771,0,324815,0,7849,0,41134,0,2069,2485534,613680,1823512,52578,12787,D1,P1,22283,45146,2065,3908960,791,79100,2855,3987700,5743.35,4264.57
121
+ 5/9/2023,2261,816,6113505,20426,302910,227998,0,287642,0,7998,0,21025,0,1448,2453507,595873,1648165,49590,11749,D1,P1,19096,40015,1818,3314870,588,58800,2407,3377390,5367.87,4153.87
122
+ 6/9/2023,2868,1031,5558783,13407,1266416,255848,0,203777,0,8887,0,9020,0,933,2766708,736889,1987155,47189,10851,D1,P1,14311,31495,1502,2764430,499,49900,2001,2814330,4575.2,3510.97
123
+ 7/9/2023,2394,832,4907653,9041,191893,285511,0,202017,0,8317,0,6879,0,801,2616416,630668,1712157,47089,11632,D1,P1,13483,29283,1544,2846790,463,46300,2007,2893090,4770.64,3739.02
124
+ 8/9/2023,2689,910,4752031,8867,157343,302141,0,201772,0,8717,0,5684,0,1428,2705167,791338,1852090,43707,10493,D1,P1,13830,29726,1531,2806450,518,51800,2049,2858250,4807.58,3697.23
125
+ 9/9/2023,2204,752,3975657,10022,227113,245700,0,201776,0,7299,0,4098,0,758,2929279,827015,2001938,50033,10082,D1,P1,12284,26212,1414,2674080,433,43300,1847,2717380,4310.87,3354.94
126
+ 10/9/2023,2167,743,4243960,10399,270612,291468,0,201256,0,6099,0,8097,0,809,2352670,1241029,1966290,41767,10185,D1,P1,12594,26398,1498,2834900,435,43500,1933,2878400,4460.59,3531.69
127
+ 11/9/2023,3381,1227,4492340,10684,1192346,154867,0,202476,0,8393,0,6493,0,838,2573007,1455728,1830559,39596,12910,D1,P1,15510,32142,1544,2881650,449,44900,1992,2923700,4715.59,3736.66
128
+ 12/9/2023,2511,884,4936079,10015,199137,170680,0,50740,0,8506,0,26721,0,1085,2527461,1481401,1856155,40974,11883,D1,P1,22786,42733,2027,4286230,326,32600,2353,4318830,5172.4,4510.57
129
+ 13/09/2023,2143,778,5115564,10338,292239,238162,0,2408,0,7172,0,36811,0,836,2621020,1580825,1962940,39948,11634,D1,P1,22084,41155,1880,3809460,281,28100,2161,3837560,4765.04,4181.98
130
+ 14/09/2023,2307,798,4859067,12717,1181194,308251,0,948,0,7404,0,38152,0,1282,2677877,1397139,1251585,46129,10253,D1,P1,21377,40308,1959,3742130,550,55000,2509,3797130,5413.06,4301.68
131
+ 15/09/2023,2467,882,4260164,9702,399193,291844,0,756,0,6932,0,16060,0,2982,2751748,1416780,1269521,57909,10048,D1,P1,16118,32895,1659,3149040,526,52600,2185,3201640,4920.59,3802.04
132
+ 16/09/2023,2076,687,3350011,7707,620978,196303,0,663,0,6018,0,9889,0,1188,3083552,1564491,1439332,61159,9435,D1,P1,12830,26945,1488,2798420,446,44600,1934,2843020,4519.52,3564.8
133
+ 17/09/2023,2467,802,4503316,11119,581720,236009,0,637,0,4814,0,10024,0,2464,2935930,1503370,1649587,48796,10073,D1,P1,12357,25262,1396,2560250,455,45500,1851,2605750,4246.67,3287.31
134
+ 18/09/2023,2910,1024,5568066,14302,184276,143660,0,888,0,6922,0,10381,0,1767,2373681,1330212,1479501,51224,10488,D1,P1,16441,33582,1727,3152630,572,57200,2300,3209930,5491.87,4171.85
135
+ 19/09/2023,3252,1309,6105220,12193,208312,187769,0,1464,0,5210,0,8092,0,1504,2373344,1285881,1407015,40642,10547,D1,P1,17770,36578,1743,3229930,653,65300,2395,3291230,5666.71,4236.34
136
+ 20/09/2023,2796,1185,6055420,14003,291395,272928,0,1077,0,4246,0,10472,0,1830,2565110,1425196,1460886,48962,10318,D1,P1,16656,34188,1627,3048960,738,73800,2365,3121460,5577.7,3950.97
137
+ 21/09/2023,2208,878,5225528,8679,697480,160425,0,1033,0,6726,0,13928,0,1357,2686089,1447330,1236533,49940,10259,D1,P1,17253,34210,1912,3553480,811,81100,2723,3634580,6248.63,4440.07
138
+ 22/09/2023,1734,783,4373391,8141,2220006,88968,0,738,0,9534,0,8771,0,1690,2460283,1353647,1258771,45467,9910,D1,P1,14958,31389,1714,3084570,758,75800,2472,3160370,5984.05,4280.38
139
+ 23/09/2023,1190,492,4948823,10035,2432739,154849,0,702,0,8285,0,4369,0,806,2740252,1531672,1407980,51747,8665,D1,P1,12641,27336,1443,2653190,652,65200,2095,2718390,5094.46,3633.56
140
+ 24/09/2023,1124,496,6239124,10744,248085,231243,0,477,0,8032,0,8640,0,1449,2648532,1476875,1294436,36638,10410,D1,P1,12153,26113,1395,2618830,621,62100,2016,2680930,4558.91,3242.77
141
+ 25/09/2023,2358,1041,5325249,9804,251517,447312,0,591,0,11299,0,21103,0,1135,2371891,1333464,1222194,36894,9191,D1,P1,18608,38878,2041,3740860,897,89700,2938,3830560,6554.2,4744.62
142
+ 26/09/2023,2092,994,5361926,13223,90916,351820,0,910,0,10598,0,27697,0,2803,2612585,1502573,1256804,33211,8893,D1,P1,21214,41166,2128,3878240,935,93500,3063,3971740,6565.1,4696.86
143
+ 27/09/2023,1835,792,4600061,14060,728920,347014,0,1111,0,8811,0,104094,0,1780,2488689,1390273,1203937,33935,8769,D1,P1,37289,65137,2933,5530540,1595,159500,4525,5686340,8073.74,5545.54
144
+ 28/09/2023,1787,807,4114657,9434,84913,564139,0,279332,0,6975,0,51946,0,2516,2290090,1309586,1316086,32443,8606,D1,P1,25651,47307,2343,4257450,1199,119900,3542,4377350,7151.36,4963.98
145
+ 29/09/2023,1513,641,4477584,8505,211297,372199,0,443,0,4039,0,4466,0,1774,2429135,1379398,1425850,31700,7184,D1,P1,12276,26946,1488,2459350,613,61300,2101,2520650,5148.56,3726.34
146
+ 30/09/2023,1127,478,4089760,9316,222854,364180,0,517,0,3251,0,13297,0,1425,1049942,435407,548780,10869,4505,D1,P1,12905,27091,1533,2701900,640,64000,2173,2765900,5022.4,3685.32
147
+ 1/10/2023,1021,436,748856,2639,301970,224135,0,846,0,2731,0,7574,0,962,935755,413098,1084400,13147,5335,D1,P1,9103,18479,1165,2022810,467,46700,1632,2069510,3823.3,2818.63
148
+ 2/10/2023,1673,764,1692932,4211,387802,237932,0,1564,0,12820,0,9400,0,1463,877002,383352,1016934,14302,5965,D1,P1,12307,24110,1290,2265000,565,56500,1855,2321500,4314.73,3091.4
149
+ 3/10/2023,1516,725,1757367,3947,568156,171003,0,1739,0,21454,0,5276,0,1640,833524,365270,973716,14227,5936,D1,P1,12568,24900,1344,2390760,645,64500,1989,2455260,4686.71,3259.46
150
+ 4/10/2023,1786,763,1733340,3119,567654,129402,0,1726,0,15833,0,13543,0,2940,836392,368220,1029847,13931,5864,D1,P1,13780,26581,1383,2427230,695,69500,2078,2496730,4764.92,3278.39
151
+ 5/10/2023,1986,861,1671129,3736,504268,159069,0,1747,0,24285,0,8234,0,3163,830805,380396,476125,13399,5529,D1,P1,12797,24819,1428,2572910,640,64050,2067,2626960,4940.4,3504.67
152
+ 6/10/2023,1774,753,1348401,2784,702326,205479,0,1686,0,15228,0,12269,0,2107,817142,382879,504402,11840,5476,D1,P1,11345,22554,1268,2317850,601,60300,1869,2378150,4247.46,3014.11
153
+ 7/10/2023,1150,416,1175733,2242,359848,180366,0,1446,0,19417,0,27951,0,2050,921412,418533,520370,11215,5083,D1,P1,14047,25738,1516,3012040,684,68550,2200,3080590,4256.92,3052.07
154
+ 8/10/2023,999,337,1296701,2609,662748,293989,0,1415,0,14589,0,18476,0,1786,768086,352949,357821,12788,5550,D1,P1,11419,21977,1320,2426760,572,57400,1892,2484160,4025.59,2933.34
155
+ 9/10/2023,772,289,1942734,4167,3096792,191352,0,1855,0,24331,0,21658,0,1757,653538,261410,590317,14449,6333,D1,P1,14624,27809,1367,2649310,715,73600,2082,2722910,4326.63,2956.14
156
+ 10/10/2023,737,241,1911227,4238,565419,164827,0,2101,0,11526,0,9057,0,2720,734200,300476,568450,13952,6145,D1,P1,12640,24537,1376,2459930,653,68350,2029,2528280,4537.77,3219.59
157
+ 11/10/2023,681,256,2171216,4714,503802,216630,0,1921,0,7255,0,7549,0,2025,958835,399349,595481,12432,5599,D1,P1,11486,22322,1319,2395980,638,66400,1958,2463820,4317.3,3006.02
158
+ 12/10/2023,673,240,1820266,4067,233553,161215,0,8042,0,4686,0,5288,0,1408,861845,336598,557239,13130,5889,D1,P1,9536,18332,1167,1988790,536,56350,1702,2044540,3786.09,2688.23
159
+ 13/10/2023,595,233,1529402,3094,68852,156834,0,7184,0,4986,0,14364,0,1924,801772,317596,563967,12222,5539,D1,P1,12220,23105,1373,2510340,641,66600,2014,2576940,4218.4,2949.55
160
+ 14/10/2023,748,266,1013578,2156,48430,185877,0,3043,0,4287,0,14809,0,2117,929822,362662,603684,11533,5191,D1,P1,11280,21172,1275,2379750,592,62050,1867,2441800,3859.27,2715.54
161
+ 15/10/2023,602,201,1596953,4098,55580,222305,0,12269,0,4366,0,15778,0,1639,891052,327915,425822,13301,6358,D1,P1,10476,19507,1178,2129330,587,60800,1765,2190130,3766.36,2609.81
162
+ 16/10/2023,964,369,2144206,5169,31683,118393,0,6488,0,5537,0,65656,0,1254,842123,317951,810650,16455,7813,D1,P1,23493,39642,2233,4391770,1136,117850,3369,4509620,5998.13,4174.09
163
+ 17/10/2023,1105,415,2112245,5363,69479,70676,0,4964,0,4816,0,18719,0,2353,816941,328053,766996,14912,7402,D1,P1,15733,28542,1531,2735230,779,81300,2310,2816530,5078.87,3496.45
164
+ 18/10/2023,913,348,1892230,4633,451927,111742,0,4068,0,4855,0,32612,0,2028,957593,377866,689470,15228,7272,D1,P1,18694,32354,1918,3636660,883,91900,2801,3728560,5610.31,3986.54
165
+ 19/10/2023,914,302,1550243,3817,100009,183549,0,4309,0,4468,0,68322,0,2169,846076,336810,775970,14394,6925,D1,P1,26120,43767,2170,4171580,1158,120800,3328,4292380,5891.41,4024.57
166
+ 20/10/2023,663,208,1100622,2740,174916,181797,0,3695,0,4056,0,58835,0,1887,910115,366406,653096,15447,6572,D1,P1,22398,38504,2218,4385190,1035,108650,3253,4493840,5680.14,4012.57
167
+ 21/10/2023,559,184,1405730,3216,207981,276329,0,2723,0,3213,0,44899,0,1893,1184901,485051,850250,14780,6181,D1,P1,17236,31207,1638,3121900,793,82100,2431,3204000,4493.8,3159.39
168
+ 22/10/2023,545,198,1467468,3228,520836,253840,0,2213,0,2850,0,27411,0,1911,1154732,423852,1027954,10344,4893,D1,P1,13607,25217,1482,2893810,725,75700,2207,2969510,4332.98,3030.72
169
+ 23/10/2023,625,231,2018062,5517,333114,436011,0,2839,0,3772,0,11121,0,1351,1208181,428535,1111507,11684,6220,D1,P1,12048,23419,1256,2226550,585,61300,1840,2287750,4042.32,2864.75
170
+ 24/10/2023,574,226,1889784,5099,188275,228582,0,2709,0,2462,0,1109,0,1918,1083131,378488,1161439,11452,5728,D1,P1,10595,21221,1092,1909130,407,43350,1499,1952480,3725.66,2756.39
171
+ 25/10/2023,536,184,2276229,5661,77308,332105,0,2708,0,2679,0,525,0,2402,905535,310989,865636,11200,5884,D1,P1,10143,20535,887,1832160,331,37050,1218,1869210,3037.38,2236.69
172
+ 26/10/2023,609,200,1753696,4367,85971,236204,0,2136,0,2300,0,10,0,3842,968078,332008,771447,10098,5558,D1,P1,9900,19640,858,1671270,347,38950,1205,1710220,2995.78,2165.99
173
+ 27/10/2023,563,209,1636932,3338,246909,285904,0,1992,0,2323,0,5,0,2851,1063329,352124,929257,9507,5001,D1,P1,8240,17233,780,1422510,309,35500,1089,1458010,2635.69,1927
174
+ 28/10/2023,450,155,1588245,4276,235960,324079,0,2716,0,1753,0,1,0,2585,1191854,384343,1028724,8578,4958,D1,P1,7529,15744,725,1476840,300,33850,1025,1510690,2588.52,1884.51
175
+ 29/10/2023,309,117,1731474,5065,70210,331208,0,2241,0,1708,0,5,0,3120,1137463,385520,764681,10186,5650,D1,P1,7535,14889,747,1514990,287,32300,1034,1547290,2594.6,1909.86
176
+ 31/10/2023,486,182,2220653,5950,41641,213812,0,149,0,2404,0,15,0,1380,913362,318222,1020094,10416,3703,D1,P1,8678,18059,784,1613510,309,34550,1093,1648060,2844.9,2076.88
177
+ 1/11/2023,296,123,1834772,4275,201158,313487,0,889,0,2485,0,33093,0,2287,862276,316545,798469,11740,3972,D1,P1,16341,28782,1292,2880920,542,58750,1834,2939670,3468.46,2536.62
178
+ 2/11/2023,346,111,1697213,2987,1586296,64435,0,957,0,2130,0,16368,0,3586,840477,298617,830972,10008,3641,D1,P1,12216,22498,1071,2342490,402,43400,1473,2385890,3237.48,2396.17
179
+ 3/11/2023,224,89,1759831,2940,93667,74522,0,962,0,2484,0,14150,0,953,952592,350909,800378,11090,3818,D1,P1,10460,20113,902,1897210,372,40600,1274,1937810,2883.8,2066.5
180
+ 4/11/2023,214,76,1677064,2752,65182,61325,0,1796,0,3084,0,10438,0,1148,957265,344580,821570,11309,4380,D1,P1,8630,17741,757,1590600,290,31650,1047,1622250,2519.34,1826.6
181
+ 9/5/2023,6111,1916,1365036,5044,104781,31371909,0,3341,0,11190,0,61956,0,457,2371841,1021599,2302543,34816,19205,D2,P2,35411,86251,2786,4926900,1395,139500,4181,5066400,6110.89,4301.97
182
+ 10/5/2023,6233,1888,1234034,3899,140810,32973036,0,3214,0,9988,0,52049,0,705,2100238,943808,2336369,19716,17415,D2,P2,37986,96199,3087,5328400,1515,151500,4603,5480000,7186.64,5128.37
183
+ 11/5/2023,5568,1816,1016155,2788,102248,50729517,0,3203,0,10869,0,8042,0,381,2461265,1127717,1110415,21547,11051,D2,P2,24496,77036,2337,4001750,1327,132700,3663,4133100,5892.4,4091.77
184
+ 12/5/2023,5109,1769,1228032,3101,100246,63142114,0,2492,0,7096,0,10596,0,299,2313368,1107256,1191901,31966,11081,D2,P2,21030,75112,2052,3462310,1116,111600,3168,3573910,5091.46,3601.62
185
+ 13/05/2023,3712,1231,1344557,3399,100714,59509032,0,3986,0,4282,0,9753,0,366,3067797,1388882,1403486,38518,10762,D2,P2,16294,64652,1611,2693420,827,82700,2438,2776120,3925.27,2780.04
186
+ 14/05/2023,3719,1241,1520157,3491,120162,49538293,0,1891,0,3002,0,7363,0,278,3140882,1429620,2518831,44744,12151,D2,P2,13378,55706,1428,2535460,765,76500,2193,2611960,3658.41,2543.11
187
+ 15/05/2023,7735,2663,2102264,5175,106903,46609819,0,2518,0,4548,0,16201,0,880,2916228,1288902,2456845,36269,15290,D2,P2,21857,67301,2149,3844360,1075,107500,3223,3951760,5540.69,3945.07
188
+ 16/05/2023,9409,3206,2134290,5636,88201,9662393,0,2247,0,6690,0,15031,0,1588,3161940,1370882,2403330,37393,14187,D2,P2,26562,53380,2486,4026650,1251,125100,3736,4150900,6839.28,4817.99
189
+ 17/05/2023,8409,2785,1473128,4336,56382,2232239,0,2557,0,6401,0,8946,0,322,3199527,1379566,2608845,39190,12591,D2,P2,21930,41033,2100,3675940,1126,112600,3226,3788540,6156.6,4185.47
190
+ 18/05/2023,8364,2873,1733275,5009,38145,7321146,0,2912,0,7286,0,14366,0,660,2623727,1115471,1723470,36020,12100,D2,P2,21813,40251,1987,3528210,1240,124000,3227,3652210,6388.27,4150.71
191
+ 19/05/2023,6432,2050,1784426,5063,23340,8715910,0,3934,0,6035,0,20378,0,362,2995998,1287313,1959870,36885,12848,D2,P2,19874,38360,1888,3663690,1140,114000,3027,3777590,5981.25,3891.85
192
+ 20/05/2023,5428,1724,1635604,4408,34693,8783612,0,3318,0,4714,0,21030,0,236,2996479,1326416,1903323,31048,12256,D2,P2,17568,33060,1691,3342720,931,93100,2623,3437270,5113.91,3453.26
193
+ 21/05/2023,5657,1807,1788487,4492,24812,5015214,0,2253,0,4227,0,11656,0,494,3167634,1309450,3651254,33361,13073,D2,P2,14766,28367,1461,2940020,800,80000,2261,3020020,4874.35,3300.96
194
+ 22/05/2023,5768,2036,2176947,5688,25298,3002995,0,2739,0,8313,0,25663,0,1147,3573865,1548365,3939226,33410,14092,D2,P2,21520,40205,1854,3533540,1097,109700,2951,3643240,6425.41,4211.67
195
+ 23/05/2023,5051,1720,2359219,6966,24773,3005057,0,4738,0,13827,0,47900,0,965,3248157,1376975,3631390,35016,13025,D2,P2,29860,51811,2527,5012370,1339,133900,3866,5146270,7978.08,5238.68
196
+ 24/05/2023,6078,1977,1612918,4924,24591,2833280,0,4816,0,12417,0,94489,0,1254,3572793,1550315,3532105,37491,12546,D2,P2,41297,68099,2993,5666720,1655,165500,4648,5832220,8715.48,5761.11
197
+ 25/05/2023,6547,2075,1468456,3624,19705,2771412,0,5070,0,7395,0,70016,0,762,3164337,1353382,3253308,34658,13154,D2,P2,33436,56714,2588,5066960,1509,150900,4097,5217860,7939.09,5062.98
198
+ 26/05/2023,3719,1189,1770048,4874,16879,2875657,0,2855,0,6964,0,29015,0,627,2989794,1248779,3345390,38267,12788,D2,P2,22185,40261,2101,4010930,1130,113000,3231,4123930,6785.57,4495.67
199
+ 27/05/2023,3620,1145,1900387,5061,14156,2663378,0,3295,0,4472,0,5625,0,1473,3576647,1527545,3694843,40685,12844,D2,P2,13490,26751,1407,2592840,756,75600,2163,2668440,5325.41,3549.17
200
+ 28/05/2023,4195,1302,2026053,5703,12334,2609966,0,2190,0,3737,0,5030,0,1401,3376177,1447089,2563297,42359,13543,D2,P2,13124,25607,1374,2558180,722,72200,2096,2630380,5282.85,3554.29
201
+ 29/05/2023,5265,1798,2328823,6483,14783,2537637,0,3954,0,5211,0,221,0,1575,3765997,1720747,2865333,39579,8116,D2,P2,15619,30688,1585,2979010,785,78500,2370,3057510,5961.63,4097.14
202
+ 30/05/2023,3879,1366,2294654,6008,15979,2489630,0,4465,0,6041,0,6,0,1192,3790830,1751416,2822819,37234,8830,D2,P2,17258,32693,1773,3270270,900,90000,2673,3360270,6752.47,4596.75
203
+ 31/05/2023,3933,1348,1645187,4081,14208,2337652,0,3797,0,4794,0,6,0,888,4151434,1953620,2714074,45856,6861,D2,P2,16458,31379,1688,3065730,924,92400,2612,3158130,6598.66,4373.22
204
+ 1/6/2023,4817,1530,1862175,4841,48192,3241822,0,3060,0,4802,0,12820,0,1137,4151797,1903421,2255850,51175,7095,D2,P2,17582,34622,1700,3231430,909,90900,2609,3322330,6342.48,4257.19
205
+ 2/6/2023,5733,1800,966546,2646,43573,4582872,0,1563,0,10678,0,46810,0,1309,4313201,2009602,2074692,47378,6120,D2,P2,25710,47869,2271,4131170,1130,113000,3401,4244170,6992.72,4747.36
206
+ 3/6/2023,4142,1290,2445721,11111,90587,4764628,0,2176,0,5144,0,27735,0,518,4514302,2083217,2095544,58527,5748,D2,P2,19247,37244,1905,3615570,961,96100,2866,3711670,5996.2,4065.63
207
+ 4/6/2023,5143,1613,2296690,6790,40929,4717779,0,1280,0,4237,0,5606,0,325,4179140,1889452,2152476,45239,6093,D2,P2,13474,29405,1475,2776480,755,75500,2230,2851980,5219.47,3571.73
208
+ 5/6/2023,5384,1832,3509278,8938,56272,19979584,0,1377,0,11493,0,25647,0,579,3683204,1641254,3616732,40356,6453,D2,P2,22558,54639,2114,4004520,1128,112800,3242,4117320,6672.4,4468.93
209
+ 6/6/2023,4802,1594,3216944,7861,20049,33102789,0,1485,0,9086,0,36532,0,545,3822453,1716540,3687300,53347,6334,D2,P2,26643,69935,2358,4505090,1222,122200,3580,4627290,6855.89,4686.82
210
+ 7/6/2023,5072,1648,2143372,5356,22553,21321547,0,1576,0,7213,0,21215,0,628,4178339,1811963,2354753,51632,6259,D2,P2,22242,56660,2125,3900920,1184,118400,3309,4019320,6611.5,4370.78
211
+ 8/6/2023,4444,1465,3190766,8024,53653,10254268,0,2046,0,10491,0,19549,0,769,3941272,1738344,2283350,59291,6775,D2,P2,23293,50105,2238,4145770,1270,127000,3508,4272770,6851.85,4515.66
212
+ 9/6/2023,4818,1605,3278715,9328,18347,4890758,0,1925,0,8360,0,32385,0,1732,3969227,1777864,2353376,52000,6026,D2,P2,25950,50611,2404,4657210,1315,131500,3719,4788710,6881.12,4639.8
213
+ 10/6/2023,3465,1207,2887842,8529,725,5489947,0,1230,0,5401,0,37954,0,2136,4458593,2061762,2535928,66567,5554,D2,P2,24413,47973,2370,4584570,1225,122500,3595,4707070,6334.68,4283.38
214
+ 11/6/2023,4727,1501,3149290,8114,738,5313957,0,1839,0,8198,0,32493,0,1533,4442610,2006438,2183963,47655,6008,D2,P2,23656,46275,2220,4441870,1183,118300,3403,4560170,6134.11,4098
215
+ 12/6/2023,6437,2208,4416005,12345,149561,5298884,0,1905,0,8542,0,101079,0,472,4645531,1995891,3301882,38760,4966,D2,P2,44382,76997,3520,6853780,1782,178200,5302,7031980,8549.02,5779.3
216
+ 13/06/2023,3556,1254,4626697,12984,258088,5952266,0,2095,0,10415,0,59770,0,1016,4508060,1912958,3440789,47281,4630,D2,P2,35764,67060,2737,5184020,1530,153000,4266,5335600,7908.1,5200.7
217
+ 14/06/2023,3178,1060,3389530,10298,685692,10454400,0,2258,0,24457,0,16016,0,1101,4573214,1920050,3160905,41549,5083,D2,P2,27677,56158,2257,4257990,1244,124400,3501,4382390,7187.71,4826.11
218
+ 15/06/2023,2981,999,3131350,10791,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4075106,1690702,3267810,50496,5037,D2,P2,23775,50354,2201,4212820,1215,121500,3416,4334320,7339.75,4890.1
219
+ 16/06/2023,2705,947,2923279,11124,1166424,11840950,0,1780,0,8938,0,24339,0,966,4533368,1939737,2881833,41872,4604,D2,P2,22957,49677,2225,4445430,1154,115400,3379,4560830,6663.77,4416.03
220
+ 17/06/2023,3697,1154,2955836,10440,807683,9748201,0,2139,0,5741,0,54129,0,766,4958344,2059487,3183051,52618,3675,D2,P2,26623,53187,2434,4755560,1286,128600,3723,4890110,6983.5,4694.41
221
+ 18/06/2023,3229,1080,3280006,12373,116340,8176712,0,1481,0,4741,0,16724,0,864,4270249,1735486,3251229,39780,3696,D2,P2,16690,36522,1715,3294460,936,93600,2651,3388060,5614.57,3749.6
222
+ 19/06/2023,3082,1003,6545797,24462,55763,4841897,0,2098,0,10520,0,26558,0,2211,4137846,1743715,2680413,43156,4347,D2,P2,25736,50759,2343,4515000,1244,124400,3587,4639400,7090.09,4789.96
223
+ 20/06/2023,2422,857,6734594,28910,52166,4718912,0,2205,0,10284,0,30610,0,1002,4218772,1771102,2058734,42288,4260,D2,P2,27941,52107,2478,4829920,1398,139800,3876,4969720,7584.9,4974.28
224
+ 21/06/2023,3366,1132,4784180,17247,52817,5971594,0,3387,0,9277,0,41697,0,645,4113884,1743016,2111350,44159,4193,D2,P2,28338,53853,2376,4353550,1357,135700,3733,4489250,7214.21,4702.88
225
+ 22/06/2023,2841,924,3300680,13360,29784,6803330,0,4064,0,7068,0,68638,0,481,3738171,1533407,1597072,35381,4173,D2,P2,34683,62182,2532,4863520,1434,143400,3966,5006920,7223.75,4679.68
226
+ 23/06/2023,2474,805,2284446,9012,80066,6833289,0,3274,0,7379,0,13501,0,721,4479743,1889155,1647740,39089,3640,D2,P2,16506,35549,1530,2980550,888,88800,2418,3069350,5295.75,3457.41
227
+ 24/06/2023,2462,814,1947190,7247,50309,6526903,0,2767,0,4703,0,8438,0,616,3758421,1565736,1648519,46332,3834,D2,P2,13804,31588,1381,2698000,788,78800,2169,2776800,4822.39,3136
228
+ 25/06/2023,2082,679,3560248,14850,50806,6368664,0,2767,0,4414,0,5346,0,628,4038846,1700182,2514456,43065,4201,D2,P2,13435,30121,1424,2782640,778,77800,2202,2860440,5082.66,3353.86
229
+ 26/06/2023,2399,839,5999950,28401,23209,10788275,0,3699,0,13383,0,13592,0,790,3427918,1403888,3598236,33883,4642,D2,P2,21114,49622,1959,3810990,1175,117500,3134,3928490,6965.39,4504.75
230
+ 27/06/2023,2307,804,5005495,18260,81344,14103220,0,7082,0,8898,0,40917,0,945,3819654,1523667,3556028,35326,4628,D2,P2,32019,65348,2877,5691820,1595,159500,4472,5851320,9589,6333.48
231
+ 28/06/2023,2215,759,3721084,11248,20153,10547995,0,8387,0,7120,0,39693,0,944,3671994,1568555,1397196,33212,2998,D2,P2,30267,63086,2863,5931970,1516,151600,4379,6083570,8919.81,5942.75
232
+ 29/06/2023,2013,706,3918049,10226,155296,8525871,0,10096,0,5693,0,24049,0,1512,3937747,1585655,3393043,30700,2519,D2,P2,22893,54097,2125,4215060,1132,113200,3257,4328260,7178.85,4806.94
233
+ 30/06/2023,1258,454,3088874,7943,902115,10945715,0,8904,0,9611,0,62404,0,1029,4945464,1946944,1835310,52445,2839,D2,P2,30707,67849,2616,5112840,1397,139700,4013,5252540,7664.09,5203.16
234
+ 1/7/2023,1641,539,3872657,12034,191537,12141356,0,4956,0,6049,0,31194,0,923,5328149,2224200,2123805,56724,2513,D2,P2,22229,54353,2266,4505840,1205,120500,3471,4626340,6983.83,4746.37
235
+ 2/7/2023,1336,485,5799582,17238,576858,12180985,0,4148,0,4670,0,4766,0,617,4527404,1997256,2038953,50510,21201,D2,P2,15205,43684,1672,3328290,886,88600,2559,3416990,5952.59,4038.91
236
+ 3/7/2023,2712,924,9986061,28191,442261,14059535,0,5347,0,7408,0,19028,0,1044,4179823,1854231,2234940,57543,14473,D2,P2,22798,57392,2425,4796940,1308,130800,3732,4925290,7701.44,5182.84
237
+ 4/7/2023,4137,1419,4717456,14519,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4449073,1959412,2350308,49085,9854,D2,P2,23585,60143,2220,4262060,1327,132700,3547,4394760,7689.38,5021.95
238
+ 5/7/2023,4166,1422,4779589,12676,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4464681,1969744,2390838,41411,12751,D2,P2,22847,61021,2348,4359400,1422,142200,3769,4497600,7976.49,5170.89
239
+ 6/7/2023,4182,1444,4939385,12222,2364811,15879491,0,6575,0,8461,0,18225,0,997,4490815,1942923,2239375,44808,16216,D2,P2,23716,60282,2602,4960450,1543,154300,4145,5114750,8225.73,5423.76
240
+ 7/7/2023,3497,1181,3121447,7534,1063284,17341347,0,6025,0,8113,0,25962,0,659,4891573,2128787,1976413,57373,12464,D2,P2,23336,58252,2335,4783910,1269,126900,3604,4910810,7182.26,4846.37
241
+ 8/7/2023,2760,856,3295227,9788,1119268,19207341,0,4102,0,6195,0,40506,0,832,5039604,2277255,2330435,44052,15163,D2,P2,22278,62471,2128,4352160,1191,119100,3319,4471260,6706.12,4485.38
242
+ 9/7/2023,2809,875,3913741,11815,749310,25182206,0,6420,0,5222,0,49626,0,718,4669470,2144473,3908306,49659,11716,D2,P2,24736,69003,2620,5573560,1325,132500,3945,5706060,7673.85,5278.59
243
+ 10/7/2023,4312,1489,5972974,18402,1511035,25950979,0,9842,0,10638,0,36204,0,935,4584106,2019220,4391654,52303,12983,D2,P2,28497,78251,2578,5157430,1419,141900,3997,5299330,8174.81,5453.8
244
+ 11/7/2023,4579,1550,4999618,16469,559119,23938153,0,11688,0,36570,0,25216,0,1289,4458364,1932300,4150666,47979,12292,D2,P2,28688,77223,2707,5384090,1483,148300,4190,5532390,8594.12,5787.78
245
+ 12/7/2023,4079,1418,4465722,13191,583520,25196511,0,4610,0,9813,0,20388,0,1210,4558876,2000168,4109583,54631,12366,D2,P2,25749,73523,2403,4926480,1410,141000,3813,5067480,8000.73,5259.61
246
+ 13/07/2023,3719,1260,4635033,12302,903614,25720336,0,7867,0,6792,0,22248,0,857,4596184,1957206,3729970,48474,11017,D2,P2,22447,69283,2134,4261960,1312,131200,3447,4393760,7385.89,4769.15
247
+ 14/07/2023,3632,1224,3441594,9800,1566300,28606996,0,6726,0,6172,0,14670,0,432,4683387,2007387,3912229,52588,10079,D2,P2,19225,67928,2002,3875450,1077,107700,3079,3983150,6615.15,4505.74
248
+ 15/07/2023,2909,941,6025085,21326,1836196,28705476,0,5705,0,4369,0,31202,0,595,5008167,2251661,3727627,58143,10214,D2,P2,19533,64001,2026,4112810,1066,106600,3093,4220310,6115.73,4122.89
249
+ 16/07/2023,2818,853,7339565,26586,4043959,26752554,0,7733,0,3961,0,27180,0,1082,4716541,2092258,2114014,59204,11281,D2,P2,18871,60797,1956,3715100,1126,112600,3084,3832400,6216.99,4066.5
250
+ 17/07/2023,4420,1486,9638491,32269,819444,29437537,0,11485,0,5220,0,66236,0,2418,4359325,1937825,1989872,55815,11896,D2,P2,35493,89662,2771,5539890,1521,152100,4292,5691990,8025.2,5388.69
251
+ 18/07/2023,4574,1551,9498457,31230,1206114,29164369,0,5012,0,7146,0,47074,0,2358,4882304,2163458,2157773,69573,12604,D2,P2,32238,84091,2687,5214920,1329,132900,4016,5347820,7833.63,5336.47
252
+ 19/07/2023,4632,1537,9742535,26935,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4613422,2080215,1981362,67495,12116,D2,P2,23193,69138,2342,4581910,1084,108400,3426,4690310,7118.68,4991.3
253
+ 20/07/2023,4891,1632,7630122,20720,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4484291,1922090,1663127,75312,12252,D2,P2,23193,63445,2209,4471970,995,99500,3255,4576570,6700.79,4599.1
254
+ 21/07/2023,3978,1378,7284968,21477,2456715,17869335,0,6360,0,10877,0,11431,0,769,4519305,1975730,1686467,68931,10065,D2,P2,21478,57996,2115,4257360,1006,100600,3121,4357960,6467.01,4497.43
255
+ 22/07/2023,3151,978,5638955,16181,2015345,12808440,0,7097,0,5145,0,13811,0,699,4689346,2086993,1861883,71898,9081,D2,P2,17602,50209,1897,3876970,830,83000,2727,3959970,5812.35,4126.62
256
+ 23/07/2023,2905,986,6133144,16089,881691,11267535,0,5593,0,4746,0,68021,0,514,4242878,1843843,1681215,61164,10797,D2,P2,25804,58279,2442,5168300,1161,116100,3603,5284400,6622.56,4639.27
257
+ 24/07/2023,4606,1651,8830736,21931,189913,35658281,0,8836,0,6040,0,64066,0,1626,3943001,1708849,1900126,59494,10236,D2,P2,31953,73505,2898,6111230,1424,142400,4321,6253530,8030.22,5492.47
258
+ 25/07/2023,4414,1597,7750251,15384,3348941,25011847,0,10262,0,9572,0,15072,0,916,3976490,1729916,1911109,68826,11468,D2,P2,26162,65005,2440,4822810,1154,115400,3594,4938210,7092.81,4965.39
259
+ 26/07/2023,4488,1530,8125332,16391,1040452,24380635,0,9947,0,16453,0,38777,0,1551,3837786,1680967,1856885,74924,13290,D2,P2,31894,69746,2797,5552460,1348,134800,4147,5687460,7359.12,5027.76
260
+ 27/07/2023,4105,1494,8054962,14724,220302,13070502,0,6758,0,8841,0,20622,0,1313,3636297,1544742,1772602,63935,11680,D2,P2,24634,57255,2498,5018670,1196,119600,3694,5138270,7106.66,4875.99
261
+ 28/07/2023,3743,1318,6955526,11566,3991586,5347413,0,10451,0,8496,0,20184,0,1563,3890784,1680538,1608577,73120,11390,D2,P2,22265,50660,2204,4515740,1054,105400,3258,4621140,6441.87,4432.07
262
+ 29/07/2023,3395,1192,5132501,9837,1349895,4441709,0,7115,0,5449,0,18983,0,1129,4295602,1813637,1824777,80511,11911,D2,P2,17626,42341,1930,3807270,860,86000,2790,3893270,5519.71,3922.54
263
+ 30/07/2023,2746,903,4903153,11018,710000,4431986,0,8491,0,4599,0,24834,0,1109,3924352,1733790,1740605,72221,11440,D2,P2,17619,43309,1942,3937090,834,83400,2776,4020490,5556.3,3945.89
264
+ 31/07/2023,4208,1476,6832832,19648,1721973,4079656,0,7754,0,7818,0,27918,0,2050,3760475,1501134,1957900,62124,11605,D2,P2,22728,51399,2256,4604950,1046,104600,3302,4709550,6481.79,4556.75
265
+ 1/8/2023,4203,1489,6398210,15890,2250090,5457683,0,7588,0,7948,0,61894,0,1248,3687038,1439092,1774701,61448,11492,D2,P2,31009,67515,2609,5471270,1309,130900,3918,5602170,6825.97,4671.87
266
+ 2/8/2023,4285,1515,5402871,14825,785167,6582085,0,6079,0,7236,0,79041,0,1345,3807266,1493340,2025308,54506,11515,D2,P2,34034,74123,2858,5856910,1360,136000,4218,5992910,7171.23,4989.3
267
+ 3/8/2023,4667,1744,4724924,8903,1111815,10407793,0,9077,0,7117,0,31714,0,1983,3797879,1479623,1718831,52587,11408,D2,P2,23978,62504,2404,4832400,1095,109500,3498,4941800,6670.71,4627.48
268
+ 4/8/2023,4201,1562,3732952,9116,4574481,10660977,0,8436,0,6970,0,25097,0,1055,3814852,1466211,1374674,57482,10785,D2,P2,21714,62922,2226,4561560,975,97500,3201,4659060,6133.71,4366.77
269
+ 5/8/2023,3080,1110,3310732,9884,3460283,11580456,0,5735,0,5049,0,5911,0,704,4048945,1601234,1442690,65158,9942,D2,P2,13792,52995,1578,3188640,720,72000,2298,3260640,4760.04,3375.44
270
+ 6/8/2023,2809,979,4153998,11663,5103054,8381689,0,4868,0,4184,0,28658,0,637,4040770,1250223,1844909,47698,10816,D2,P2,17706,56827,1841,3921270,842,84200,2683,4005470,5062.91,3520.39
271
+ 7/8/2023,3522,1186,3164171,10000,4137349,8709017,0,6112,0,6640,0,43866,0,1285,3928811,1288638,1861166,44623,11648,D2,P2,26772,71580,2456,4923260,1132,113200,3587,5034960,6580.87,4648.84
272
+ 8/8/2023,4111,1495,6020074,15008,2923076,5012245,0,6684,0,6961,0,12257,0,3038,3921429,1094791,2059462,48047,10379,D2,P2,22363,60212,2075,4138870,971,97100,3046,4235970,6286.57,4418.71
273
+ 9/8/2023,3609,1285,5616011,13195,2483117,3900778,0,8177,0,6447,0,12774,0,1309,3322165,452000,2262292,52219,11047,D2,P2,21099,53059,2067,4030270,1010,101000,3077,4131270,6309.32,4273.88
274
+ 10/8/2023,3872,1330,5270940,11342,1305507,3614496,0,6927,0,6602,0,21830,0,986,2868345,452896,1541791,46720,10556,D2,P2,22515,52055,2216,4848640,974,97400,3190,4946040,6281.59,4498.26
275
+ 11/8/2023,3673,1257,4485834,10445,3562053,5521177,0,5810,0,13751,0,5797,0,751,3242607,511016,1679989,47262,10344,D2,P2,17086,46491,1551,3242370,671,67100,2222,3309470,4608.96,3355.58
276
+ 12/8/2023,2744,960,3946512,10052,4015316,5813616,0,6205,0,10379,0,9890,0,532,3761072,595191,1931989,54787,9210,D2,P2,15949,46498,1376,3113130,639,63900,2016,3177130,4121.65,2907.82
277
+ 13/08/2023,2418,775,5051792,11809,1869057,6348414,0,4093,0,5187,0,21320,0,399,3279816,503805,2171335,55136,10546,D2,P2,14745,44224,1327,2888900,648,64800,1975,2953700,3905.29,2752.8
278
+ 14/08/2023,3551,1196,4839009,11805,1765326,3758610,0,6170,0,7226,0,19575,0,706,2974893,427940,1822890,49127,11042,D2,P2,20336,49993,1770,3798710,748,74800,2518,3873510,5195.83,3786.85
279
+ 15/08/2023,3430,1312,6520709,24857,1792924,1852314,0,6063,0,9302,0,34681,0,778,3080012,462344,1935145,57900,11083,D2,P2,24449,48710,1946,4332210,807,80700,2752,4412810,5367.05,3930.18
280
+ 16/08/2023,3253,1175,4844378,27290,3478033,1293346,0,5884,0,8280,0,29077,0,1055,3150093,468159,2094524,58937,11823,D2,P2,23892,46995,1911,3996580,780,78000,2691,4074580,5452.88,3979.2
281
+ 17/08/2023,3714,1417,4702754,23408,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3071572,444690,1961293,58681,10987,D2,P2,21265,42100,1700,3517380,704,70400,2404,3587780,5150.22,3718.85
282
+ 18/08/2023,1936,710,4370177,18919,3789636,1020973,0,9525,0,8958,0,32346,0,909,3252966,461174,2031390,61098,10354,D2,P2,20983,41383,1778,3654630,679,67900,2457,3722530,5019.58,3716.93
283
+ 19/08/2023,1998,723,3683868,14860,5187185,1336224,0,8305,0,6265,0,13396,0,1267,3460234,494225,2037289,68988,9709,D2,P2,14640,31119,1331,2887610,528,52800,1860,2943410,4059.2,3012.38
284
+ 20/08/2023,2458,839,5558511,16917,6444084,1333600,0,8083,0,5668,0,9425,0,593,3233047,427550,2093935,58698,11658,D2,P2,13616,29557,1227,2592690,476,47600,1703,2640290,3842.86,2850.38
285
+ 21/08/2023,2316,892,5802540,21997,1578062,1099659,0,9057,0,8434,0,11204,0,597,3110596,442523,1991499,71910,13059,D2,P2,19336,38812,1656,3445610,663,66300,2319,3510210,5100.16,3789.37
286
+ 22/08/2023,2208,845,5006504,13886,598218,939529,0,18631,0,11119,0,18304,0,666,3020862,419659,1960342,66769,12591,D2,P2,21348,42166,1844,3824050,762,76200,2582,3877380,5610.58,4088.17
287
+ 23/08/2023,2104,821,5240143,16309,1941212,2081327,0,17073,0,8077,0,6042,0,709,2634348,409468,1726842,53998,13783,D2,P2,18864,38949,1513,3153720,655,65500,2165,3219310,4984.78,3596.01
288
+ 24/08/2023,2011,685,5623870,14314,380971,2132605,0,13223,0,7340,0,11449,0,1774,2244344,385012,1409286,55699,13185,D2,P2,18821,38282,1665,3378840,678,67800,2358,3474730,5209.76,3795.85
289
+ 25/08/2023,1889,680,4674166,13506,1119189,1818097,0,33200,0,7250,0,16577,0,3622,2405697,395219,1564070,61103,13348,D2,P2,18364,37536,1863,3939560,638,63800,2501,4003360,5070.56,3850.47
290
+ 26/08/2023,1229,379,5475213,18030,476090,1048919,0,15316,0,4976,0,16625,0,3546,2662312,434769,1789446,61768,13346,D2,P2,16076,32992,1816,3388030,606,60600,2422,3448630,4877.02,3729.33
291
+ 27/08/2023,1333,486,5591938,13138,956722,732493,0,12952,0,4227,0,19562,0,2354,2470188,417919,1980888,53707,14151,D2,P2,14834,30563,1572,2979370,536,53600,2108,3032970,4232.88,3241.64
292
+ 28/08/2023,2031,760,7120359,17304,592505,571748,0,44816,0,8728,0,19999,0,3813,2357294,420574,1878047,50335,13442,D2,P2,20994,42982,1970,3877550,642,64200,2612,3941750,5610.5,4325.83
293
+ 29/08/2023,1560,550,6349650,18074,395464,276869,0,217642,0,8742,0,36555,0,2778,2437012,455532,1707585,52913,12648,D2,P2,25919,51217,2270,4323380,803,80300,3073,4403680,6223.41,4701.59
294
+ 30/08/2023,1788,623,6774580,17019,804715,227676,0,92490,0,7576,0,33376,0,1815,2461827,452647,1924554,57945,12244,D2,P2,24015,48307,2298,4414000,796,79600,3094,4493600,5983.31,4520.44
295
+ 31/08/2023,2251,790,6881955,16586,462096,216142,0,177608,0,7188,0,13212,0,1862,2630688,508779,1691540,44071,12093,D2,P2,17587,35874,1809,3406910,604,60400,2413,3467310,5218.62,4005.29
296
+ 1/9/2023,2763,930,5360505,17680,259775,323504,0,21865,0,7383,0,4899,0,1313,2723715,529388,1841032,48663,11275,D2,P2,13457,29785,1396,2542480,459,45900,1855,2588380,4243.41,3270.46
297
+ 2/9/2023,2597,870,4478842,15289,1226680,320820,0,26924,0,6477,0,4896,0,1454,2929332,613163,1945160,60288,10815,D2,P2,12337,27451,1347,2481120,508,50800,1855,2531920,4227.98,3109.35
298
+ 3/9/2023,2332,762,5174329,13994,449228,288375,0,20423,0,5755,0,10890,0,1494,2516381,558353,1697712,54329,11996,D2,P2,12609,27028,1428,2699310,481,48100,1909,2747410,4177.46,3164.79
299
+ 4/9/2023,3561,1229,5334952,17444,296660,306771,0,324815,0,7849,0,41134,0,2069,2485534,613680,1823512,52578,12787,D2,P2,22283,45146,2065,3908960,791,79100,2855,3987700,5743.35,4264.57
300
+ 5/9/2023,2261,816,6113505,20426,302910,227998,0,287642,0,7998,0,21025,0,1448,2453507,595873,1648165,49590,11749,D2,P2,19096,40015,1818,3314870,588,58800,2407,3377390,5367.87,4153.87
301
+ 6/9/2023,2868,1031,5558783,13407,1266416,255848,0,203777,0,8887,0,9020,0,933,2766708,736889,1987155,47189,10851,D2,P2,14311,31495,1502,2764430,499,49900,2001,2814330,4575.2,3510.97
302
+ 7/9/2023,2394,832,4907653,9041,191893,285511,0,202017,0,8317,0,6879,0,801,2616416,630668,1712157,47089,11632,D2,P2,13483,29283,1544,2846790,463,46300,2007,2893090,4770.64,3739.02
303
+ 8/9/2023,2689,910,4752031,8867,157343,302141,0,201772,0,8717,0,5684,0,1428,2705167,791338,1852090,43707,10493,D2,P2,13830,29726,1531,2806450,518,51800,2049,2858250,4807.58,3697.23
304
+ 9/9/2023,2204,752,3975657,10022,227113,245700,0,201776,0,7299,0,4098,0,758,2929279,827015,2001938,50033,10082,D2,P2,12284,26212,1414,2674080,433,43300,1847,2717380,4310.87,3354.94
305
+ 10/9/2023,2167,743,4243960,10399,270612,291468,0,201256,0,6099,0,8097,0,809,2352670,1241029,1966290,41767,10185,D2,P2,12594,26398,1498,2834900,435,43500,1933,2878400,4460.59,3531.69
306
+ 11/9/2023,3381,1227,4492340,10684,1192346,154867,0,202476,0,8393,0,6493,0,838,2573007,1455728,1830559,39596,12910,D2,P2,15510,32142,1544,2881650,449,44900,1992,2923700,4715.59,3736.66
307
+ 12/9/2023,2511,884,4936079,10015,199137,170680,0,50740,0,8506,0,26721,0,1085,2527461,1481401,1856155,40974,11883,D2,P2,22786,42733,2027,4286230,326,32600,2353,4318830,5172.4,4510.57
308
+ 13/09/2023,2143,778,5115564,10338,292239,238162,0,2408,0,7172,0,36811,0,836,2621020,1580825,1962940,39948,11634,D2,P2,22084,41155,1880,3809460,281,28100,2161,3837560,4765.04,4181.98
309
+ 14/09/2023,2307,798,4859067,12717,1181194,308251,0,948,0,7404,0,38152,0,1282,2677877,1397139,1251585,46129,10253,D2,P2,21377,40308,1959,3742130,550,55000,2509,3797130,5413.06,4301.68
310
+ 15/09/2023,2467,882,4260164,9702,399193,291844,0,756,0,6932,0,16060,0,2982,2751748,1416780,1269521,57909,10048,D2,P2,16118,32895,1659,3149040,526,52600,2185,3201640,4920.59,3802.04
311
+ 16/09/2023,2076,687,3350011,7707,620978,196303,0,663,0,6018,0,9889,0,1188,3083552,1564491,1439332,61159,9435,D2,P2,12830,26945,1488,2798420,446,44600,1934,2843020,4519.52,3564.8
312
+ 17/09/2023,2467,802,4503316,11119,581720,236009,0,637,0,4814,0,10024,0,2464,2935930,1503370,1649587,48796,10073,D2,P2,12357,25262,1396,2560250,455,45500,1851,2605750,4246.67,3287.31
313
+ 18/09/2023,2910,1024,5568066,14302,184276,143660,0,888,0,6922,0,10381,0,1767,2373681,1330212,1479501,51224,10488,D2,P2,16441,33582,1727,3152630,572,57200,2300,3209930,5491.87,4171.85
314
+ 19/09/2023,3252,1309,6105220,12193,208312,187769,0,1464,0,5210,0,8092,0,1504,2373344,1285881,1407015,40642,10547,D2,P2,17770,36578,1743,3229930,653,65300,2395,3291230,5666.71,4236.34
315
+ 20/09/2023,2796,1185,6055420,14003,291395,272928,0,1077,0,4246,0,10472,0,1830,2565110,1425196,1460886,48962,10318,D2,P2,16656,34188,1627,3048960,738,73800,2365,3121460,5577.7,3950.97
316
+ 21/09/2023,2208,878,5225528,8679,697480,160425,0,1033,0,6726,0,13928,0,1357,2686089,1447330,1236533,49940,10259,D2,P2,17253,34210,1912,3553480,811,81100,2723,3634580,6248.63,4440.07
317
+ 22/09/2023,1734,783,4373391,8141,2220006,88968,0,738,0,9534,0,8771,0,1690,2460283,1353647,1258771,45467,9910,D2,P2,14958,31389,1714,3084570,758,75800,2472,3160370,5984.05,4280.38
318
+ 23/09/2023,1190,492,4948823,10035,2432739,154849,0,702,0,8285,0,4369,0,806,2740252,1531672,1407980,51747,8665,D2,P2,12641,27336,1443,2653190,652,65200,2095,2718390,5094.46,3633.56
319
+ 24/09/2023,1124,496,6239124,10744,248085,231243,0,477,0,8032,0,8640,0,1449,2648532,1476875,1294436,36638,10410,D2,P2,12153,26113,1395,2618830,621,62100,2016,2680930,4558.91,3242.77
320
+ 25/09/2023,2358,1041,5325249,9804,251517,447312,0,591,0,11299,0,21103,0,1135,2371891,1333464,1222194,36894,9191,D2,P2,18608,38878,2041,3740860,897,89700,2938,3830560,6554.2,4744.62
321
+ 26/09/2023,2092,994,5361926,13223,90916,351820,0,910,0,10598,0,27697,0,2803,2612585,1502573,1256804,33211,8893,D2,P2,21214,41166,2128,3878240,935,93500,3063,3971740,6565.1,4696.86
322
+ 27/09/2023,1835,792,4600061,14060,728920,347014,0,1111,0,8811,0,104094,0,1780,2488689,1390273,1203937,33935,8769,D2,P2,37289,65137,2933,5530540,1595,159500,4525,5686340,8073.74,5545.54
323
+ 28/09/2023,1787,807,4114657,9434,84913,564139,0,279332,0,6975,0,51946,0,2516,2290090,1309586,1316086,32443,8606,D2,P2,25651,47307,2343,4257450,1199,119900,3542,4377350,7151.36,4963.98
324
+ 29/09/2023,1513,641,4477584,8505,211297,372199,0,443,0,4039,0,4466,0,1774,2429135,1379398,1425850,31700,7184,D2,P2,12276,26946,1488,2459350,613,61300,2101,2520650,5148.56,3726.34
325
+ 30/09/2023,1127,478,4089760,9316,222854,364180,0,517,0,3251,0,13297,0,1425,1049942,435407,548780,10869,4505,D2,P2,12905,27091,1533,2701900,640,64000,2173,2765900,5022.4,3685.32
326
+ 1/10/2023,1021,436,748856,2639,301970,224135,0,846,0,2731,0,7574,0,962,935755,413098,1084400,13147,5335,D2,P2,9103,18479,1165,2022810,467,46700,1632,2069510,3823.3,2818.63
327
+ 2/10/2023,1673,764,1692932,4211,387802,237932,0,1564,0,12820,0,9400,0,1463,877002,383352,1016934,14302,5965,D2,P2,12307,24110,1290,2265000,565,56500,1855,2321500,4314.73,3091.4
328
+ 3/10/2023,1516,725,1757367,3947,568156,171003,0,1739,0,21454,0,5276,0,1640,833524,365270,973716,14227,5936,D2,P2,12568,24900,1344,2390760,645,64500,1989,2455260,4686.71,3259.46
329
+ 4/10/2023,1786,763,1733340,3119,567654,129402,0,1726,0,15833,0,13543,0,2940,836392,368220,1029847,13931,5864,D2,P2,13780,26581,1383,2427230,695,69500,2078,2496730,4764.92,3278.39
330
+ 5/10/2023,1986,861,1671129,3736,504268,159069,0,1747,0,24285,0,8234,0,3163,830805,380396,476125,13399,5529,D2,P2,12797,24819,1428,2572910,640,64050,2067,2626960,4940.4,3504.67
331
+ 6/10/2023,1774,753,1348401,2784,702326,205479,0,1686,0,15228,0,12269,0,2107,817142,382879,504402,11840,5476,D2,P2,11345,22554,1268,2317850,601,60300,1869,2378150,4247.46,3014.11
332
+ 7/10/2023,1150,416,1175733,2242,359848,180366,0,1446,0,19417,0,27951,0,2050,921412,418533,520370,11215,5083,D2,P2,14047,25738,1516,3012040,684,68550,2200,3080590,4256.92,3052.07
333
+ 8/10/2023,999,337,1296701,2609,662748,293989,0,1415,0,14589,0,18476,0,1786,768086,352949,357821,12788,5550,D2,P2,11419,21977,1320,2426760,572,57400,1892,2484160,4025.59,2933.34
334
+ 9/10/2023,772,289,1942734,4167,3096792,191352,0,1855,0,24331,0,21658,0,1757,653538,261410,590317,14449,6333,D2,P2,14624,27809,1367,2649310,715,73600,2082,2722910,4326.63,2956.14
335
+ 10/10/2023,737,241,1911227,4238,565419,164827,0,2101,0,11526,0,9057,0,2720,734200,300476,568450,13952,6145,D2,P2,12640,24537,1376,2459930,653,68350,2029,2528280,4537.77,3219.59
336
+ 11/10/2023,681,256,2171216,4714,503802,216630,0,1921,0,7255,0,7549,0,2025,958835,399349,595481,12432,5599,D2,P2,11486,22322,1319,2395980,638,66400,1958,2463820,4317.3,3006.02
337
+ 12/10/2023,673,240,1820266,4067,233553,161215,0,8042,0,4686,0,5288,0,1408,861845,336598,557239,13130,5889,D2,P2,9536,18332,1167,1988790,536,56350,1702,2044540,3786.09,2688.23
338
+ 13/10/2023,595,233,1529402,3094,68852,156834,0,7184,0,4986,0,14364,0,1924,801772,317596,563967,12222,5539,D2,P2,12220,23105,1373,2510340,641,66600,2014,2576940,4218.4,2949.55
339
+ 14/10/2023,748,266,1013578,2156,48430,185877,0,3043,0,4287,0,14809,0,2117,929822,362662,603684,11533,5191,D2,P2,11280,21172,1275,2379750,592,62050,1867,2441800,3859.27,2715.54
340
+ 15/10/2023,602,201,1596953,4098,55580,222305,0,12269,0,4366,0,15778,0,1639,891052,327915,425822,13301,6358,D2,P2,10476,19507,1178,2129330,587,60800,1765,2190130,3766.36,2609.81
341
+ 16/10/2023,964,369,2144206,5169,31683,118393,0,6488,0,5537,0,65656,0,1254,842123,317951,810650,16455,7813,D2,P2,23493,39642,2233,4391770,1136,117850,3369,4509620,5998.13,4174.09
342
+ 17/10/2023,1105,415,2112245,5363,69479,70676,0,4964,0,4816,0,18719,0,2353,816941,328053,766996,14912,7402,D2,P2,15733,28542,1531,2735230,779,81300,2310,2816530,5078.87,3496.45
343
+ 18/10/2023,913,348,1892230,4633,451927,111742,0,4068,0,4855,0,32612,0,2028,957593,377866,689470,15228,7272,D2,P2,18694,32354,1918,3636660,883,91900,2801,3728560,5610.31,3986.54
344
+ 19/10/2023,914,302,1550243,3817,100009,183549,0,4309,0,4468,0,68322,0,2169,846076,336810,775970,14394,6925,D2,P2,26120,43767,2170,4171580,1158,120800,3328,4292380,5891.41,4024.57
345
+ 20/10/2023,663,208,1100622,2740,174916,181797,0,3695,0,4056,0,58835,0,1887,910115,366406,653096,15447,6572,D2,P2,22398,38504,2218,4385190,1035,108650,3253,4493840,5680.14,4012.57
346
+ 21/10/2023,559,184,1405730,3216,207981,276329,0,2723,0,3213,0,44899,0,1893,1184901,485051,850250,14780,6181,D2,P2,17236,31207,1638,3121900,793,82100,2431,3204000,4493.8,3159.39
347
+ 22/10/2023,545,198,1467468,3228,520836,253840,0,2213,0,2850,0,27411,0,1911,1154732,423852,1027954,10344,4893,D2,P2,13607,25217,1482,2893810,725,75700,2207,2969510,4332.98,3030.72
348
+ 23/10/2023,625,231,2018062,5517,333114,436011,0,2839,0,3772,0,11121,0,1351,1208181,428535,1111507,11684,6220,D2,P2,12048,23419,1256,2226550,585,61300,1840,2287750,4042.32,2864.75
349
+ 24/10/2023,574,226,1889784,5099,188275,228582,0,2709,0,2462,0,1109,0,1918,1083131,378488,1161439,11452,5728,D2,P2,10595,21221,1092,1909130,407,43350,1499,1952480,3725.66,2756.39
350
+ 25/10/2023,536,184,2276229,5661,77308,332105,0,2708,0,2679,0,525,0,2402,905535,310989,865636,11200,5884,D2,P2,10143,20535,887,1832160,331,37050,1218,1869210,3037.38,2236.69
351
+ 26/10/2023,609,200,1753696,4367,85971,236204,0,2136,0,2300,0,10,0,3842,968078,332008,771447,10098,5558,D2,P2,9900,19640,858,1671270,347,38950,1205,1710220,2995.78,2165.99
352
+ 27/10/2023,563,209,1636932,3338,246909,285904,0,1992,0,2323,0,5,0,2851,1063329,352124,929257,9507,5001,D2,P2,8240,17233,780,1422510,309,35500,1089,1458010,2635.69,1927
353
+ 28/10/2023,450,155,1588245,4276,235960,324079,0,2716,0,1753,0,1,0,2585,1191854,384343,1028724,8578,4958,D2,P2,7529,15744,725,1476840,300,33850,1025,1510690,2588.52,1884.51
354
+ 29/10/2023,309,117,1731474,5065,70210,331208,0,2241,0,1708,0,5,0,3120,1137463,385520,764681,10186,5650,D2,P2,7535,14889,747,1514990,287,32300,1034,1547290,2594.6,1909.86
355
+ 31/10/2023,486,182,2220653,5950,41641,213812,0,149,0,2404,0,15,0,1380,913362,318222,1020094,10416,3703,D2,P2,8678,18059,784,1613510,309,34550,1093,1648060,2844.9,2076.88
356
+ 1/11/2023,296,123,1834772,4275,201158,313487,0,889,0,2485,0,33093,0,2287,862276,316545,798469,11740,3972,D2,P2,16341,28782,1292,2880920,542,58750,1834,2939670,3468.46,2536.62
357
+ 2/11/2023,346,111,1697213,2987,1586296,64435,0,957,0,2130,0,16368,0,3586,840477,298617,830972,10008,3641,D2,P2,12216,22498,1071,2342490,402,43400,1473,2385890,3237.48,2396.17
358
+ 3/11/2023,224,89,1759831,2940,93667,74522,0,962,0,2484,0,14150,0,953,952592,350909,800378,11090,3818,D2,P2,10460,20113,902,1897210,372,40600,1274,1937810,2883.8,2066.5
359
+ 4/11/2023,214,76,1677064,2752,65182,61325,0,1796,0,3084,0,10438,0,1148,957265,344580,821570,11309,4380,D2,P2,8630,17741,757,1590600,290,31650,1047,1622250,2519.34,1826.6
360
+ 9/5/2023,6111,1916,1365036,5044,104781,31371909,0,3341,0,11190,0,61956,0,457,2371841,1021599,2302543,34816,19205,D3,P3,35411,86251,2786,4926900,1395,139500,4181,5066400,6110.89,4301.97
361
+ 10/5/2023,6233,1888,1234034,3899,140810,32973036,0,3214,0,9988,0,52049,0,705,2100238,943808,2336369,19716,17415,D3,P3,37986,96199,3087,5328400,1515,151500,4603,5480000,7186.64,5128.37
362
+ 11/5/2023,5568,1816,1016155,2788,102248,50729517,0,3203,0,10869,0,8042,0,381,2461265,1127717,1110415,21547,11051,D3,P3,24496,77036,2337,4001750,1327,132700,3663,4133100,5892.4,4091.77
363
+ 12/5/2023,5109,1769,1228032,3101,100246,63142114,0,2492,0,7096,0,10596,0,299,2313368,1107256,1191901,31966,11081,D3,P3,21030,75112,2052,3462310,1116,111600,3168,3573910,5091.46,3601.62
364
+ 13/05/2023,3712,1231,1344557,3399,100714,59509032,0,3986,0,4282,0,9753,0,366,3067797,1388882,1403486,38518,10762,D3,P3,16294,64652,1611,2693420,827,82700,2438,2776120,3925.27,2780.04
365
+ 14/05/2023,3719,1241,1520157,3491,120162,49538293,0,1891,0,3002,0,7363,0,278,3140882,1429620,2518831,44744,12151,D3,P3,13378,55706,1428,2535460,765,76500,2193,2611960,3658.41,2543.11
366
+ 15/05/2023,7735,2663,2102264,5175,106903,46609819,0,2518,0,4548,0,16201,0,880,2916228,1288902,2456845,36269,15290,D3,P3,21857,67301,2149,3844360,1075,107500,3223,3951760,5540.69,3945.07
367
+ 16/05/2023,9409,3206,2134290,5636,88201,9662393,0,2247,0,6690,0,15031,0,1588,3161940,1370882,2403330,37393,14187,D3,P3,26562,53380,2486,4026650,1251,125100,3736,4150900,6839.28,4817.99
368
+ 17/05/2023,8409,2785,1473128,4336,56382,2232239,0,2557,0,6401,0,8946,0,322,3199527,1379566,2608845,39190,12591,D3,P3,21930,41033,2100,3675940,1126,112600,3226,3788540,6156.6,4185.47
369
+ 18/05/2023,8364,2873,1733275,5009,38145,7321146,0,2912,0,7286,0,14366,0,660,2623727,1115471,1723470,36020,12100,D3,P3,21813,40251,1987,3528210,1240,124000,3227,3652210,6388.27,4150.71
370
+ 19/05/2023,6432,2050,1784426,5063,23340,8715910,0,3934,0,6035,0,20378,0,362,2995998,1287313,1959870,36885,12848,D3,P3,19874,38360,1888,3663690,1140,114000,3027,3777590,5981.25,3891.85
371
+ 20/05/2023,5428,1724,1635604,4408,34693,8783612,0,3318,0,4714,0,21030,0,236,2996479,1326416,1903323,31048,12256,D3,P3,17568,33060,1691,3342720,931,93100,2623,3437270,5113.91,3453.26
372
+ 21/05/2023,5657,1807,1788487,4492,24812,5015214,0,2253,0,4227,0,11656,0,494,3167634,1309450,3651254,33361,13073,D3,P3,14766,28367,1461,2940020,800,80000,2261,3020020,4874.35,3300.96
373
+ 22/05/2023,5768,2036,2176947,5688,25298,3002995,0,2739,0,8313,0,25663,0,1147,3573865,1548365,3939226,33410,14092,D3,P3,21520,40205,1854,3533540,1097,109700,2951,3643240,6425.41,4211.67
374
+ 23/05/2023,5051,1720,2359219,6966,24773,3005057,0,4738,0,13827,0,47900,0,965,3248157,1376975,3631390,35016,13025,D3,P3,29860,51811,2527,5012370,1339,133900,3866,5146270,7978.08,5238.68
375
+ 24/05/2023,6078,1977,1612918,4924,24591,2833280,0,4816,0,12417,0,94489,0,1254,3572793,1550315,3532105,37491,12546,D3,P3,41297,68099,2993,5666720,1655,165500,4648,5832220,8715.48,5761.11
376
+ 25/05/2023,6547,2075,1468456,3624,19705,2771412,0,5070,0,7395,0,70016,0,762,3164337,1353382,3253308,34658,13154,D3,P3,33436,56714,2588,5066960,1509,150900,4097,5217860,7939.09,5062.98
377
+ 26/05/2023,3719,1189,1770048,4874,16879,2875657,0,2855,0,6964,0,29015,0,627,2989794,1248779,3345390,38267,12788,D3,P3,22185,40261,2101,4010930,1130,113000,3231,4123930,6785.57,4495.67
378
+ 27/05/2023,3620,1145,1900387,5061,14156,2663378,0,3295,0,4472,0,5625,0,1473,3576647,1527545,3694843,40685,12844,D3,P3,13490,26751,1407,2592840,756,75600,2163,2668440,5325.41,3549.17
379
+ 28/05/2023,4195,1302,2026053,5703,12334,2609966,0,2190,0,3737,0,5030,0,1401,3376177,1447089,2563297,42359,13543,D3,P3,13124,25607,1374,2558180,722,72200,2096,2630380,5282.85,3554.29
380
+ 29/05/2023,5265,1798,2328823,6483,14783,2537637,0,3954,0,5211,0,221,0,1575,3765997,1720747,2865333,39579,8116,D3,P3,15619,30688,1585,2979010,785,78500,2370,3057510,5961.63,4097.14
381
+ 30/05/2023,3879,1366,2294654,6008,15979,2489630,0,4465,0,6041,0,6,0,1192,3790830,1751416,2822819,37234,8830,D3,P3,17258,32693,1773,3270270,900,90000,2673,3360270,6752.47,4596.75
382
+ 31/05/2023,3933,1348,1645187,4081,14208,2337652,0,3797,0,4794,0,6,0,888,4151434,1953620,2714074,45856,6861,D3,P3,16458,31379,1688,3065730,924,92400,2612,3158130,6598.66,4373.22
383
+ 1/6/2023,4817,1530,1862175,4841,48192,3241822,0,3060,0,4802,0,12820,0,1137,4151797,1903421,2255850,51175,7095,D3,P3,17582,34622,1700,3231430,909,90900,2609,3322330,6342.48,4257.19
384
+ 2/6/2023,5733,1800,966546,2646,43573,4582872,0,1563,0,10678,0,46810,0,1309,4313201,2009602,2074692,47378,6120,D3,P3,25710,47869,2271,4131170,1130,113000,3401,4244170,6992.72,4747.36
385
+ 3/6/2023,4142,1290,2445721,11111,90587,4764628,0,2176,0,5144,0,27735,0,518,4514302,2083217,2095544,58527,5748,D3,P3,19247,37244,1905,3615570,961,96100,2866,3711670,5996.2,4065.63
386
+ 4/6/2023,5143,1613,2296690,6790,40929,4717779,0,1280,0,4237,0,5606,0,325,4179140,1889452,2152476,45239,6093,D3,P3,13474,29405,1475,2776480,755,75500,2230,2851980,5219.47,3571.73
387
+ 5/6/2023,5384,1832,3509278,8938,56272,19979584,0,1377,0,11493,0,25647,0,579,3683204,1641254,3616732,40356,6453,D3,P3,22558,54639,2114,4004520,1128,112800,3242,4117320,6672.4,4468.93
388
+ 6/6/2023,4802,1594,3216944,7861,20049,33102789,0,1485,0,9086,0,36532,0,545,3822453,1716540,3687300,53347,6334,D3,P3,26643,69935,2358,4505090,1222,122200,3580,4627290,6855.89,4686.82
389
+ 7/6/2023,5072,1648,2143372,5356,22553,21321547,0,1576,0,7213,0,21215,0,628,4178339,1811963,2354753,51632,6259,D3,P3,22242,56660,2125,3900920,1184,118400,3309,4019320,6611.5,4370.78
390
+ 8/6/2023,4444,1465,3190766,8024,53653,10254268,0,2046,0,10491,0,19549,0,769,3941272,1738344,2283350,59291,6775,D3,P3,23293,50105,2238,4145770,1270,127000,3508,4272770,6851.85,4515.66
391
+ 9/6/2023,4818,1605,3278715,9328,18347,4890758,0,1925,0,8360,0,32385,0,1732,3969227,1777864,2353376,52000,6026,D3,P3,25950,50611,2404,4657210,1315,131500,3719,4788710,6881.12,4639.8
392
+ 10/6/2023,3465,1207,2887842,8529,725,5489947,0,1230,0,5401,0,37954,0,2136,4458593,2061762,2535928,66567,5554,D3,P3,24413,47973,2370,4584570,1225,122500,3595,4707070,6334.68,4283.38
393
+ 11/6/2023,4727,1501,3149290,8114,738,5313957,0,1839,0,8198,0,32493,0,1533,4442610,2006438,2183963,47655,6008,D3,P3,23656,46275,2220,4441870,1183,118300,3403,4560170,6134.11,4098
394
+ 12/6/2023,6437,2208,4416005,12345,149561,5298884,0,1905,0,8542,0,101079,0,472,4645531,1995891,3301882,38760,4966,D3,P3,44382,76997,3520,6853780,1782,178200,5302,7031980,8549.02,5779.3
395
+ 13/06/2023,3556,1254,4626697,12984,258088,5952266,0,2095,0,10415,0,59770,0,1016,4508060,1912958,3440789,47281,4630,D3,P3,35764,67060,2737,5184020,1530,153000,4266,5335600,7908.1,5200.7
396
+ 14/06/2023,3178,1060,3389530,10298,685692,10454400,0,2258,0,24457,0,16016,0,1101,4573214,1920050,3160905,41549,5083,D3,P3,27677,56158,2257,4257990,1244,124400,3501,4382390,7187.71,4826.11
397
+ 15/06/2023,2981,999,3131350,10791,1072645,11631302,0,2265,0,17304,0,10395,0,1188,4075106,1690702,3267810,50496,5037,D3,P3,23775,50354,2201,4212820,1215,121500,3416,4334320,7339.75,4890.1
398
+ 16/06/2023,2705,947,2923279,11124,1166424,11840950,0,1780,0,8938,0,24339,0,966,4533368,1939737,2881833,41872,4604,D3,P3,22957,49677,2225,4445430,1154,115400,3379,4560830,6663.77,4416.03
399
+ 17/06/2023,3697,1154,2955836,10440,807683,9748201,0,2139,0,5741,0,54129,0,766,4958344,2059487,3183051,52618,3675,D3,P3,26623,53187,2434,4755560,1286,128600,3723,4890110,6983.5,4694.41
400
+ 18/06/2023,3229,1080,3280006,12373,116340,8176712,0,1481,0,4741,0,16724,0,864,4270249,1735486,3251229,39780,3696,D3,P3,16690,36522,1715,3294460,936,93600,2651,3388060,5614.57,3749.6
401
+ 19/06/2023,3082,1003,6545797,24462,55763,4841897,0,2098,0,10520,0,26558,0,2211,4137846,1743715,2680413,43156,4347,D3,P3,25736,50759,2343,4515000,1244,124400,3587,4639400,7090.09,4789.96
402
+ 20/06/2023,2422,857,6734594,28910,52166,4718912,0,2205,0,10284,0,30610,0,1002,4218772,1771102,2058734,42288,4260,D3,P3,27941,52107,2478,4829920,1398,139800,3876,4969720,7584.9,4974.28
403
+ 21/06/2023,3366,1132,4784180,17247,52817,5971594,0,3387,0,9277,0,41697,0,645,4113884,1743016,2111350,44159,4193,D3,P3,28338,53853,2376,4353550,1357,135700,3733,4489250,7214.21,4702.88
404
+ 22/06/2023,2841,924,3300680,13360,29784,6803330,0,4064,0,7068,0,68638,0,481,3738171,1533407,1597072,35381,4173,D3,P3,34683,62182,2532,4863520,1434,143400,3966,5006920,7223.75,4679.68
405
+ 23/06/2023,2474,805,2284446,9012,80066,6833289,0,3274,0,7379,0,13501,0,721,4479743,1889155,1647740,39089,3640,D3,P3,16506,35549,1530,2980550,888,88800,2418,3069350,5295.75,3457.41
406
+ 24/06/2023,2462,814,1947190,7247,50309,6526903,0,2767,0,4703,0,8438,0,616,3758421,1565736,1648519,46332,3834,D3,P3,13804,31588,1381,2698000,788,78800,2169,2776800,4822.39,3136
407
+ 25/06/2023,2082,679,3560248,14850,50806,6368664,0,2767,0,4414,0,5346,0,628,4038846,1700182,2514456,43065,4201,D3,P3,13435,30121,1424,2782640,778,77800,2202,2860440,5082.66,3353.86
408
+ 26/06/2023,2399,839,5999950,28401,23209,10788275,0,3699,0,13383,0,13592,0,790,3427918,1403888,3598236,33883,4642,D3,P3,21114,49622,1959,3810990,1175,117500,3134,3928490,6965.39,4504.75
409
+ 27/06/2023,2307,804,5005495,18260,81344,14103220,0,7082,0,8898,0,40917,0,945,3819654,1523667,3556028,35326,4628,D3,P3,32019,65348,2877,5691820,1595,159500,4472,5851320,9589,6333.48
410
+ 28/06/2023,2215,759,3721084,11248,20153,10547995,0,8387,0,7120,0,39693,0,944,3671994,1568555,1397196,33212,2998,D3,P3,30267,63086,2863,5931970,1516,151600,4379,6083570,8919.81,5942.75
411
+ 29/06/2023,2013,706,3918049,10226,155296,8525871,0,10096,0,5693,0,24049,0,1512,3937747,1585655,3393043,30700,2519,D3,P3,22893,54097,2125,4215060,1132,113200,3257,4328260,7178.85,4806.94
412
+ 30/06/2023,1258,454,3088874,7943,902115,10945715,0,8904,0,9611,0,62404,0,1029,4945464,1946944,1835310,52445,2839,D3,P3,30707,67849,2616,5112840,1397,139700,4013,5252540,7664.09,5203.16
413
+ 1/7/2023,1641,539,3872657,12034,191537,12141356,0,4956,0,6049,0,31194,0,923,5328149,2224200,2123805,56724,2513,D3,P3,22229,54353,2266,4505840,1205,120500,3471,4626340,6983.83,4746.37
414
+ 2/7/2023,1336,485,5799582,17238,576858,12180985,0,4148,0,4670,0,4766,0,617,4527404,1997256,2038953,50510,21201,D3,P3,15205,43684,1672,3328290,886,88600,2559,3416990,5952.59,4038.91
415
+ 3/7/2023,2712,924,9986061,28191,442261,14059535,0,5347,0,7408,0,19028,0,1044,4179823,1854231,2234940,57543,14473,D3,P3,22798,57392,2425,4796940,1308,130800,3732,4925290,7701.44,5182.84
416
+ 4/7/2023,4137,1419,4717456,14519,2137830,14463201,0,6164,0,8277,0,12283,0,1531,4449073,1959412,2350308,49085,9854,D3,P3,23585,60143,2220,4262060,1327,132700,3547,4394760,7689.38,5021.95
417
+ 5/7/2023,4166,1422,4779589,12676,2354716,18574154,0,7967,0,11552,0,6628,0,1420,4464681,1969744,2390838,41411,12751,D3,P3,22847,61021,2348,4359400,1422,142200,3769,4497600,7976.49,5170.89
418
+ 6/7/2023,4182,1444,4939385,12222,2364811,15879491,0,6575,0,8461,0,18225,0,997,4490815,1942923,2239375,44808,16216,D3,P3,23716,60282,2602,4960450,1543,154300,4145,5114750,8225.73,5423.76
419
+ 7/7/2023,3497,1181,3121447,7534,1063284,17341347,0,6025,0,8113,0,25962,0,659,4891573,2128787,1976413,57373,12464,D3,P3,23336,58252,2335,4783910,1269,126900,3604,4910810,7182.26,4846.37
420
+ 8/7/2023,2760,856,3295227,9788,1119268,19207341,0,4102,0,6195,0,40506,0,832,5039604,2277255,2330435,44052,15163,D3,P3,22278,62471,2128,4352160,1191,119100,3319,4471260,6706.12,4485.38
421
+ 9/7/2023,2809,875,3913741,11815,749310,25182206,0,6420,0,5222,0,49626,0,718,4669470,2144473,3908306,49659,11716,D3,P3,24736,69003,2620,5573560,1325,132500,3945,5706060,7673.85,5278.59
422
+ 10/7/2023,4312,1489,5972974,18402,1511035,25950979,0,9842,0,10638,0,36204,0,935,4584106,2019220,4391654,52303,12983,D3,P3,28497,78251,2578,5157430,1419,141900,3997,5299330,8174.81,5453.8
423
+ 11/7/2023,4579,1550,4999618,16469,559119,23938153,0,11688,0,36570,0,25216,0,1289,4458364,1932300,4150666,47979,12292,D3,P3,28688,77223,2707,5384090,1483,148300,4190,5532390,8594.12,5787.78
424
+ 12/7/2023,4079,1418,4465722,13191,583520,25196511,0,4610,0,9813,0,20388,0,1210,4558876,2000168,4109583,54631,12366,D3,P3,25749,73523,2403,4926480,1410,141000,3813,5067480,8000.73,5259.61
425
+ 13/07/2023,3719,1260,4635033,12302,903614,25720336,0,7867,0,6792,0,22248,0,857,4596184,1957206,3729970,48474,11017,D3,P3,22447,69283,2134,4261960,1312,131200,3447,4393760,7385.89,4769.15
426
+ 14/07/2023,3632,1224,3441594,9800,1566300,28606996,0,6726,0,6172,0,14670,0,432,4683387,2007387,3912229,52588,10079,D3,P3,19225,67928,2002,3875450,1077,107700,3079,3983150,6615.15,4505.74
427
+ 15/07/2023,2909,941,6025085,21326,1836196,28705476,0,5705,0,4369,0,31202,0,595,5008167,2251661,3727627,58143,10214,D3,P3,19533,64001,2026,4112810,1066,106600,3093,4220310,6115.73,4122.89
428
+ 16/07/2023,2818,853,7339565,26586,4043959,26752554,0,7733,0,3961,0,27180,0,1082,4716541,2092258,2114014,59204,11281,D3,P3,18871,60797,1956,3715100,1126,112600,3084,3832400,6216.99,4066.5
429
+ 17/07/2023,4420,1486,9638491,32269,819444,29437537,0,11485,0,5220,0,66236,0,2418,4359325,1937825,1989872,55815,11896,D3,P3,35493,89662,2771,5539890,1521,152100,4292,5691990,8025.2,5388.69
430
+ 18/07/2023,4574,1551,9498457,31230,1206114,29164369,0,5012,0,7146,0,47074,0,2358,4882304,2163458,2157773,69573,12604,D3,P3,32238,84091,2687,5214920,1329,132900,4016,5347820,7833.63,5336.47
431
+ 19/07/2023,4632,1537,9742535,26935,1491736,30394328,0,6147,0,7028,0,11807,0,1476,4613422,2080215,1981362,67495,12116,D3,P3,23193,69138,2342,4581910,1084,108400,3426,4690310,7118.68,4991.3
432
+ 20/07/2023,4891,1632,7630122,20720,2370192,23939153,0,6261,0,5635,0,17220,0,1338,4484291,1922090,1663127,75312,12252,D3,P3,23193,63445,2209,4471970,995,99500,3255,4576570,6700.79,4599.1
433
+ 21/07/2023,3978,1378,7284968,21477,2456715,17869335,0,6360,0,10877,0,11431,0,769,4519305,1975730,1686467,68931,10065,D3,P3,21478,57996,2115,4257360,1006,100600,3121,4357960,6467.01,4497.43
434
+ 22/07/2023,3151,978,5638955,16181,2015345,12808440,0,7097,0,5145,0,13811,0,699,4689346,2086993,1861883,71898,9081,D3,P3,17602,50209,1897,3876970,830,83000,2727,3959970,5812.35,4126.62
435
+ 23/07/2023,2905,986,6133144,16089,881691,11267535,0,5593,0,4746,0,68021,0,514,4242878,1843843,1681215,61164,10797,D3,P3,25804,58279,2442,5168300,1161,116100,3603,5284400,6622.56,4639.27
436
+ 24/07/2023,4606,1651,8830736,21931,189913,35658281,0,8836,0,6040,0,64066,0,1626,3943001,1708849,1900126,59494,10236,D3,P3,31953,73505,2898,6111230,1424,142400,4321,6253530,8030.22,5492.47
437
+ 25/07/2023,4414,1597,7750251,15384,3348941,25011847,0,10262,0,9572,0,15072,0,916,3976490,1729916,1911109,68826,11468,D3,P3,26162,65005,2440,4822810,1154,115400,3594,4938210,7092.81,4965.39
438
+ 26/07/2023,4488,1530,8125332,16391,1040452,24380635,0,9947,0,16453,0,38777,0,1551,3837786,1680967,1856885,74924,13290,D3,P3,31894,69746,2797,5552460,1348,134800,4147,5687460,7359.12,5027.76
439
+ 27/07/2023,4105,1494,8054962,14724,220302,13070502,0,6758,0,8841,0,20622,0,1313,3636297,1544742,1772602,63935,11680,D3,P3,24634,57255,2498,5018670,1196,119600,3694,5138270,7106.66,4875.99
440
+ 28/07/2023,3743,1318,6955526,11566,3991586,5347413,0,10451,0,8496,0,20184,0,1563,3890784,1680538,1608577,73120,11390,D3,P3,22265,50660,2204,4515740,1054,105400,3258,4621140,6441.87,4432.07
441
+ 29/07/2023,3395,1192,5132501,9837,1349895,4441709,0,7115,0,5449,0,18983,0,1129,4295602,1813637,1824777,80511,11911,D3,P3,17626,42341,1930,3807270,860,86000,2790,3893270,5519.71,3922.54
442
+ 30/07/2023,2746,903,4903153,11018,710000,4431986,0,8491,0,4599,0,24834,0,1109,3924352,1733790,1740605,72221,11440,D3,P3,17619,43309,1942,3937090,834,83400,2776,4020490,5556.3,3945.89
443
+ 31/07/2023,4208,1476,6832832,19648,1721973,4079656,0,7754,0,7818,0,27918,0,2050,3760475,1501134,1957900,62124,11605,D3,P3,22728,51399,2256,4604950,1046,104600,3302,4709550,6481.79,4556.75
444
+ 1/8/2023,4203,1489,6398210,15890,2250090,5457683,0,7588,0,7948,0,61894,0,1248,3687038,1439092,1774701,61448,11492,D3,P3,31009,67515,2609,5471270,1309,130900,3918,5602170,6825.97,4671.87
445
+ 2/8/2023,4285,1515,5402871,14825,785167,6582085,0,6079,0,7236,0,79041,0,1345,3807266,1493340,2025308,54506,11515,D3,P3,34034,74123,2858,5856910,1360,136000,4218,5992910,7171.23,4989.3
446
+ 3/8/2023,4667,1744,4724924,8903,1111815,10407793,0,9077,0,7117,0,31714,0,1983,3797879,1479623,1718831,52587,11408,D3,P3,23978,62504,2404,4832400,1095,109500,3498,4941800,6670.71,4627.48
447
+ 4/8/2023,4201,1562,3732952,9116,4574481,10660977,0,8436,0,6970,0,25097,0,1055,3814852,1466211,1374674,57482,10785,D3,P3,21714,62922,2226,4561560,975,97500,3201,4659060,6133.71,4366.77
448
+ 5/8/2023,3080,1110,3310732,9884,3460283,11580456,0,5735,0,5049,0,5911,0,704,4048945,1601234,1442690,65158,9942,D3,P3,13792,52995,1578,3188640,720,72000,2298,3260640,4760.04,3375.44
449
+ 6/8/2023,2809,979,4153998,11663,5103054,8381689,0,4868,0,4184,0,28658,0,637,4040770,1250223,1844909,47698,10816,D3,P3,17706,56827,1841,3921270,842,84200,2683,4005470,5062.91,3520.39
450
+ 7/8/2023,3522,1186,3164171,10000,4137349,8709017,0,6112,0,6640,0,43866,0,1285,3928811,1288638,1861166,44623,11648,D3,P3,26772,71580,2456,4923260,1132,113200,3587,5034960,6580.87,4648.84
451
+ 8/8/2023,4111,1495,6020074,15008,2923076,5012245,0,6684,0,6961,0,12257,0,3038,3921429,1094791,2059462,48047,10379,D3,P3,22363,60212,2075,4138870,971,97100,3046,4235970,6286.57,4418.71
452
+ 9/8/2023,3609,1285,5616011,13195,2483117,3900778,0,8177,0,6447,0,12774,0,1309,3322165,452000,2262292,52219,11047,D3,P3,21099,53059,2067,4030270,1010,101000,3077,4131270,6309.32,4273.88
453
+ 10/8/2023,3872,1330,5270940,11342,1305507,3614496,0,6927,0,6602,0,21830,0,986,2868345,452896,1541791,46720,10556,D3,P3,22515,52055,2216,4848640,974,97400,3190,4946040,6281.59,4498.26
454
+ 11/8/2023,3673,1257,4485834,10445,3562053,5521177,0,5810,0,13751,0,5797,0,751,3242607,511016,1679989,47262,10344,D3,P3,17086,46491,1551,3242370,671,67100,2222,3309470,4608.96,3355.58
455
+ 12/8/2023,2744,960,3946512,10052,4015316,5813616,0,6205,0,10379,0,9890,0,532,3761072,595191,1931989,54787,9210,D3,P3,15949,46498,1376,3113130,639,63900,2016,3177130,4121.65,2907.82
456
+ 13/08/2023,2418,775,5051792,11809,1869057,6348414,0,4093,0,5187,0,21320,0,399,3279816,503805,2171335,55136,10546,D3,P3,14745,44224,1327,2888900,648,64800,1975,2953700,3905.29,2752.8
457
+ 14/08/2023,3551,1196,4839009,11805,1765326,3758610,0,6170,0,7226,0,19575,0,706,2974893,427940,1822890,49127,11042,D3,P3,20336,49993,1770,3798710,748,74800,2518,3873510,5195.83,3786.85
458
+ 15/08/2023,3430,1312,6520709,24857,1792924,1852314,0,6063,0,9302,0,34681,0,778,3080012,462344,1935145,57900,11083,D3,P3,24449,48710,1946,4332210,807,80700,2752,4412810,5367.05,3930.18
459
+ 16/08/2023,3253,1175,4844378,27290,3478033,1293346,0,5884,0,8280,0,29077,0,1055,3150093,468159,2094524,58937,11823,D3,P3,23892,46995,1911,3996580,780,78000,2691,4074580,5452.88,3979.2
460
+ 17/08/2023,3714,1417,4702754,23408,4058942,1186576,0,11301,0,10504,0,15462,0,1017,3071572,444690,1961293,58681,10987,D3,P3,21265,42100,1700,3517380,704,70400,2404,3587780,5150.22,3718.85
461
+ 18/08/2023,1936,710,4370177,18919,3789636,1020973,0,9525,0,8958,0,32346,0,909,3252966,461174,2031390,61098,10354,D3,P3,20983,41383,1778,3654630,679,67900,2457,3722530,5019.58,3716.93
462
+ 19/08/2023,1998,723,3683868,14860,5187185,1336224,0,8305,0,6265,0,13396,0,1267,3460234,494225,2037289,68988,9709,D3,P3,14640,31119,1331,2887610,528,52800,1860,2943410,4059.2,3012.38
463
+ 20/08/2023,2458,839,5558511,16917,6444084,1333600,0,8083,0,5668,0,9425,0,593,3233047,427550,2093935,58698,11658,D3,P3,13616,29557,1227,2592690,476,47600,1703,2640290,3842.86,2850.38
464
+ 21/08/2023,2316,892,5802540,21997,1578062,1099659,0,9057,0,8434,0,11204,0,597,3110596,442523,1991499,71910,13059,D3,P3,19336,38812,1656,3445610,663,66300,2319,3510210,5100.16,3789.37
465
+ 22/08/2023,2208,845,5006504,13886,598218,939529,0,18631,0,11119,0,18304,0,666,3020862,419659,1960342,66769,12591,D3,P3,21348,42166,1844,3824050,762,76200,2582,3877380,5610.58,4088.17
466
+ 23/08/2023,2104,821,5240143,16309,1941212,2081327,0,17073,0,8077,0,6042,0,709,2634348,409468,1726842,53998,13783,D3,P3,18864,38949,1513,3153720,655,65500,2165,3219310,4984.78,3596.01
467
+ 24/08/2023,2011,685,5623870,14314,380971,2132605,0,13223,0,7340,0,11449,0,1774,2244344,385012,1409286,55699,13185,D3,P3,18821,38282,1665,3378840,678,67800,2358,3474730,5209.76,3795.85
468
+ 25/08/2023,1889,680,4674166,13506,1119189,1818097,0,33200,0,7250,0,16577,0,3622,2405697,395219,1564070,61103,13348,D3,P3,18364,37536,1863,3939560,638,63800,2501,4003360,5070.56,3850.47
469
+ 26/08/2023,1229,379,5475213,18030,476090,1048919,0,15316,0,4976,0,16625,0,3546,2662312,434769,1789446,61768,13346,D3,P3,16076,32992,1816,3388030,606,60600,2422,3448630,4877.02,3729.33
470
+ 27/08/2023,1333,486,5591938,13138,956722,732493,0,12952,0,4227,0,19562,0,2354,2470188,417919,1980888,53707,14151,D3,P3,14834,30563,1572,2979370,536,53600,2108,3032970,4232.88,3241.64
471
+ 28/08/2023,2031,760,7120359,17304,592505,571748,0,44816,0,8728,0,19999,0,3813,2357294,420574,1878047,50335,13442,D3,P3,20994,42982,1970,3877550,642,64200,2612,3941750,5610.5,4325.83
472
+ 29/08/2023,1560,550,6349650,18074,395464,276869,0,217642,0,8742,0,36555,0,2778,2437012,455532,1707585,52913,12648,D3,P3,25919,51217,2270,4323380,803,80300,3073,4403680,6223.41,4701.59
473
+ 30/08/2023,1788,623,6774580,17019,804715,227676,0,92490,0,7576,0,33376,0,1815,2461827,452647,1924554,57945,12244,D3,P3,24015,48307,2298,4414000,796,79600,3094,4493600,5983.31,4520.44
474
+ 31/08/2023,2251,790,6881955,16586,462096,216142,0,177608,0,7188,0,13212,0,1862,2630688,508779,1691540,44071,12093,D3,P3,17587,35874,1809,3406910,604,60400,2413,3467310,5218.62,4005.29
475
+ 1/9/2023,2763,930,5360505,17680,259775,323504,0,21865,0,7383,0,4899,0,1313,2723715,529388,1841032,48663,11275,D3,P3,13457,29785,1396,2542480,459,45900,1855,2588380,4243.41,3270.46
476
+ 2/9/2023,2597,870,4478842,15289,1226680,320820,0,26924,0,6477,0,4896,0,1454,2929332,613163,1945160,60288,10815,D3,P3,12337,27451,1347,2481120,508,50800,1855,2531920,4227.98,3109.35
477
+ 3/9/2023,2332,762,5174329,13994,449228,288375,0,20423,0,5755,0,10890,0,1494,2516381,558353,1697712,54329,11996,D3,P3,12609,27028,1428,2699310,481,48100,1909,2747410,4177.46,3164.79
478
+ 4/9/2023,3561,1229,5334952,17444,296660,306771,0,324815,0,7849,0,41134,0,2069,2485534,613680,1823512,52578,12787,D3,P3,22283,45146,2065,3908960,791,79100,2855,3987700,5743.35,4264.57
479
+ 5/9/2023,2261,816,6113505,20426,302910,227998,0,287642,0,7998,0,21025,0,1448,2453507,595873,1648165,49590,11749,D3,P3,19096,40015,1818,3314870,588,58800,2407,3377390,5367.87,4153.87
480
+ 6/9/2023,2868,1031,5558783,13407,1266416,255848,0,203777,0,8887,0,9020,0,933,2766708,736889,1987155,47189,10851,D3,P3,14311,31495,1502,2764430,499,49900,2001,2814330,4575.2,3510.97
481
+ 7/9/2023,2394,832,4907653,9041,191893,285511,0,202017,0,8317,0,6879,0,801,2616416,630668,1712157,47089,11632,D3,P3,13483,29283,1544,2846790,463,46300,2007,2893090,4770.64,3739.02
482
+ 8/9/2023,2689,910,4752031,8867,157343,302141,0,201772,0,8717,0,5684,0,1428,2705167,791338,1852090,43707,10493,D3,P3,13830,29726,1531,2806450,518,51800,2049,2858250,4807.58,3697.23
483
+ 9/9/2023,2204,752,3975657,10022,227113,245700,0,201776,0,7299,0,4098,0,758,2929279,827015,2001938,50033,10082,D3,P3,12284,26212,1414,2674080,433,43300,1847,2717380,4310.87,3354.94
484
+ 10/9/2023,2167,743,4243960,10399,270612,291468,0,201256,0,6099,0,8097,0,809,2352670,1241029,1966290,41767,10185,D3,P3,12594,26398,1498,2834900,435,43500,1933,2878400,4460.59,3531.69
485
+ 11/9/2023,3381,1227,4492340,10684,1192346,154867,0,202476,0,8393,0,6493,0,838,2573007,1455728,1830559,39596,12910,D3,P3,15510,32142,1544,2881650,449,44900,1992,2923700,4715.59,3736.66
486
+ 12/9/2023,2511,884,4936079,10015,199137,170680,0,50740,0,8506,0,26721,0,1085,2527461,1481401,1856155,40974,11883,D3,P3,22786,42733,2027,4286230,326,32600,2353,4318830,5172.4,4510.57
487
+ 13/09/2023,2143,778,5115564,10338,292239,238162,0,2408,0,7172,0,36811,0,836,2621020,1580825,1962940,39948,11634,D3,P3,22084,41155,1880,3809460,281,28100,2161,3837560,4765.04,4181.98
488
+ 14/09/2023,2307,798,4859067,12717,1181194,308251,0,948,0,7404,0,38152,0,1282,2677877,1397139,1251585,46129,10253,D3,P3,21377,40308,1959,3742130,550,55000,2509,3797130,5413.06,4301.68
489
+ 15/09/2023,2467,882,4260164,9702,399193,291844,0,756,0,6932,0,16060,0,2982,2751748,1416780,1269521,57909,10048,D3,P3,16118,32895,1659,3149040,526,52600,2185,3201640,4920.59,3802.04
490
+ 16/09/2023,2076,687,3350011,7707,620978,196303,0,663,0,6018,0,9889,0,1188,3083552,1564491,1439332,61159,9435,D3,P3,12830,26945,1488,2798420,446,44600,1934,2843020,4519.52,3564.8
491
+ 17/09/2023,2467,802,4503316,11119,581720,236009,0,637,0,4814,0,10024,0,2464,2935930,1503370,1649587,48796,10073,D3,P3,12357,25262,1396,2560250,455,45500,1851,2605750,4246.67,3287.31
492
+ 18/09/2023,2910,1024,5568066,14302,184276,143660,0,888,0,6922,0,10381,0,1767,2373681,1330212,1479501,51224,10488,D3,P3,16441,33582,1727,3152630,572,57200,2300,3209930,5491.87,4171.85
493
+ 19/09/2023,3252,1309,6105220,12193,208312,187769,0,1464,0,5210,0,8092,0,1504,2373344,1285881,1407015,40642,10547,D3,P3,17770,36578,1743,3229930,653,65300,2395,3291230,5666.71,4236.34
494
+ 20/09/2023,2796,1185,6055420,14003,291395,272928,0,1077,0,4246,0,10472,0,1830,2565110,1425196,1460886,48962,10318,D3,P3,16656,34188,1627,3048960,738,73800,2365,3121460,5577.7,3950.97
495
+ 21/09/2023,2208,878,5225528,8679,697480,160425,0,1033,0,6726,0,13928,0,1357,2686089,1447330,1236533,49940,10259,D3,P3,17253,34210,1912,3553480,811,81100,2723,3634580,6248.63,4440.07
496
+ 22/09/2023,1734,783,4373391,8141,2220006,88968,0,738,0,9534,0,8771,0,1690,2460283,1353647,1258771,45467,9910,D3,P3,14958,31389,1714,3084570,758,75800,2472,3160370,5984.05,4280.38
497
+ 23/09/2023,1190,492,4948823,10035,2432739,154849,0,702,0,8285,0,4369,0,806,2740252,1531672,1407980,51747,8665,D3,P3,12641,27336,1443,2653190,652,65200,2095,2718390,5094.46,3633.56
498
+ 24/09/2023,1124,496,6239124,10744,248085,231243,0,477,0,8032,0,8640,0,1449,2648532,1476875,1294436,36638,10410,D3,P3,12153,26113,1395,2618830,621,62100,2016,2680930,4558.91,3242.77
499
+ 25/09/2023,2358,1041,5325249,9804,251517,447312,0,591,0,11299,0,21103,0,1135,2371891,1333464,1222194,36894,9191,D3,P3,18608,38878,2041,3740860,897,89700,2938,3830560,6554.2,4744.62
500
+ 26/09/2023,2092,994,5361926,13223,90916,351820,0,910,0,10598,0,27697,0,2803,2612585,1502573,1256804,33211,8893,D3,P3,21214,41166,2128,3878240,935,93500,3063,3971740,6565.1,4696.86
501
+ 27/09/2023,1835,792,4600061,14060,728920,347014,0,1111,0,8811,0,104094,0,1780,2488689,1390273,1203937,33935,8769,D3,P3,37289,65137,2933,5530540,1595,159500,4525,5686340,8073.74,5545.54
502
+ 28/09/2023,1787,807,4114657,9434,84913,564139,0,279332,0,6975,0,51946,0,2516,2290090,1309586,1316086,32443,8606,D3,P3,25651,47307,2343,4257450,1199,119900,3542,4377350,7151.36,4963.98
503
+ 29/09/2023,1513,641,4477584,8505,211297,372199,0,443,0,4039,0,4466,0,1774,2429135,1379398,1425850,31700,7184,D3,P3,12276,26946,1488,2459350,613,61300,2101,2520650,5148.56,3726.34
504
+ 30/09/2023,1127,478,4089760,9316,222854,364180,0,517,0,3251,0,13297,0,1425,1049942,435407,548780,10869,4505,D3,P3,12905,27091,1533,2701900,640,64000,2173,2765900,5022.4,3685.32
505
+ 1/10/2023,1021,436,748856,2639,301970,224135,0,846,0,2731,0,7574,0,962,935755,413098,1084400,13147,5335,D3,P3,9103,18479,1165,2022810,467,46700,1632,2069510,3823.3,2818.63
506
+ 2/10/2023,1673,764,1692932,4211,387802,237932,0,1564,0,12820,0,9400,0,1463,877002,383352,1016934,14302,5965,D3,P3,12307,24110,1290,2265000,565,56500,1855,2321500,4314.73,3091.4
507
+ 3/10/2023,1516,725,1757367,3947,568156,171003,0,1739,0,21454,0,5276,0,1640,833524,365270,973716,14227,5936,D3,P3,12568,24900,1344,2390760,645,64500,1989,2455260,4686.71,3259.46
508
+ 4/10/2023,1786,763,1733340,3119,567654,129402,0,1726,0,15833,0,13543,0,2940,836392,368220,1029847,13931,5864,D3,P3,13780,26581,1383,2427230,695,69500,2078,2496730,4764.92,3278.39
509
+ 5/10/2023,1986,861,1671129,3736,504268,159069,0,1747,0,24285,0,8234,0,3163,830805,380396,476125,13399,5529,D3,P3,12797,24819,1428,2572910,640,64050,2067,2626960,4940.4,3504.67
510
+ 6/10/2023,1774,753,1348401,2784,702326,205479,0,1686,0,15228,0,12269,0,2107,817142,382879,504402,11840,5476,D3,P3,11345,22554,1268,2317850,601,60300,1869,2378150,4247.46,3014.11
511
+ 7/10/2023,1150,416,1175733,2242,359848,180366,0,1446,0,19417,0,27951,0,2050,921412,418533,520370,11215,5083,D3,P3,14047,25738,1516,3012040,684,68550,2200,3080590,4256.92,3052.07
512
+ 8/10/2023,999,337,1296701,2609,662748,293989,0,1415,0,14589,0,18476,0,1786,768086,352949,357821,12788,5550,D3,P3,11419,21977,1320,2426760,572,57400,1892,2484160,4025.59,2933.34
513
+ 9/10/2023,772,289,1942734,4167,3096792,191352,0,1855,0,24331,0,21658,0,1757,653538,261410,590317,14449,6333,D3,P3,14624,27809,1367,2649310,715,73600,2082,2722910,4326.63,2956.14
514
+ 10/10/2023,737,241,1911227,4238,565419,164827,0,2101,0,11526,0,9057,0,2720,734200,300476,568450,13952,6145,D3,P3,12640,24537,1376,2459930,653,68350,2029,2528280,4537.77,3219.59
515
+ 11/10/2023,681,256,2171216,4714,503802,216630,0,1921,0,7255,0,7549,0,2025,958835,399349,595481,12432,5599,D3,P3,11486,22322,1319,2395980,638,66400,1958,2463820,4317.3,3006.02
516
+ 12/10/2023,673,240,1820266,4067,233553,161215,0,8042,0,4686,0,5288,0,1408,861845,336598,557239,13130,5889,D3,P3,9536,18332,1167,1988790,536,56350,1702,2044540,3786.09,2688.23
517
+ 13/10/2023,595,233,1529402,3094,68852,156834,0,7184,0,4986,0,14364,0,1924,801772,317596,563967,12222,5539,D3,P3,12220,23105,1373,2510340,641,66600,2014,2576940,4218.4,2949.55
518
+ 14/10/2023,748,266,1013578,2156,48430,185877,0,3043,0,4287,0,14809,0,2117,929822,362662,603684,11533,5191,D3,P3,11280,21172,1275,2379750,592,62050,1867,2441800,3859.27,2715.54
519
+ 15/10/2023,602,201,1596953,4098,55580,222305,0,12269,0,4366,0,15778,0,1639,891052,327915,425822,13301,6358,D3,P3,10476,19507,1178,2129330,587,60800,1765,2190130,3766.36,2609.81
520
+ 16/10/2023,964,369,2144206,5169,31683,118393,0,6488,0,5537,0,65656,0,1254,842123,317951,810650,16455,7813,D3,P3,23493,39642,2233,4391770,1136,117850,3369,4509620,5998.13,4174.09
521
+ 17/10/2023,1105,415,2112245,5363,69479,70676,0,4964,0,4816,0,18719,0,2353,816941,328053,766996,14912,7402,D3,P3,15733,28542,1531,2735230,779,81300,2310,2816530,5078.87,3496.45
522
+ 18/10/2023,913,348,1892230,4633,451927,111742,0,4068,0,4855,0,32612,0,2028,957593,377866,689470,15228,7272,D3,P3,18694,32354,1918,3636660,883,91900,2801,3728560,5610.31,3986.54
523
+ 19/10/2023,914,302,1550243,3817,100009,183549,0,4309,0,4468,0,68322,0,2169,846076,336810,775970,14394,6925,D3,P3,26120,43767,2170,4171580,1158,120800,3328,4292380,5891.41,4024.57
524
+ 20/10/2023,663,208,1100622,2740,174916,181797,0,3695,0,4056,0,58835,0,1887,910115,366406,653096,15447,6572,D3,P3,22398,38504,2218,4385190,1035,108650,3253,4493840,5680.14,4012.57
525
+ 21/10/2023,559,184,1405730,3216,207981,276329,0,2723,0,3213,0,44899,0,1893,1184901,485051,850250,14780,6181,D3,P3,17236,31207,1638,3121900,793,82100,2431,3204000,4493.8,3159.39
526
+ 22/10/2023,545,198,1467468,3228,520836,253840,0,2213,0,2850,0,27411,0,1911,1154732,423852,1027954,10344,4893,D3,P3,13607,25217,1482,2893810,725,75700,2207,2969510,4332.98,3030.72
527
+ 23/10/2023,625,231,2018062,5517,333114,436011,0,2839,0,3772,0,11121,0,1351,1208181,428535,1111507,11684,6220,D3,P3,12048,23419,1256,2226550,585,61300,1840,2287750,4042.32,2864.75
528
+ 24/10/2023,574,226,1889784,5099,188275,228582,0,2709,0,2462,0,1109,0,1918,1083131,378488,1161439,11452,5728,D3,P3,10595,21221,1092,1909130,407,43350,1499,1952480,3725.66,2756.39
529
+ 25/10/2023,536,184,2276229,5661,77308,332105,0,2708,0,2679,0,525,0,2402,905535,310989,865636,11200,5884,D3,P3,10143,20535,887,1832160,331,37050,1218,1869210,3037.38,2236.69
530
+ 26/10/2023,609,200,1753696,4367,85971,236204,0,2136,0,2300,0,10,0,3842,968078,332008,771447,10098,5558,D3,P3,9900,19640,858,1671270,347,38950,1205,1710220,2995.78,2165.99
531
+ 27/10/2023,563,209,1636932,3338,246909,285904,0,1992,0,2323,0,5,0,2851,1063329,352124,929257,9507,5001,D3,P3,8240,17233,780,1422510,309,35500,1089,1458010,2635.69,1927
532
+ 28/10/2023,450,155,1588245,4276,235960,324079,0,2716,0,1753,0,1,0,2585,1191854,384343,1028724,8578,4958,D3,P3,7529,15744,725,1476840,300,33850,1025,1510690,2588.52,1884.51
533
+ 29/10/2023,309,117,1731474,5065,70210,331208,0,2241,0,1708,0,5,0,3120,1137463,385520,764681,10186,5650,D3,P3,7535,14889,747,1514990,287,32300,1034,1547290,2594.6,1909.86
534
+ 31/10/2023,486,182,2220653,5950,41641,213812,0,149,0,2404,0,15,0,1380,913362,318222,1020094,10416,3703,D3,P3,8678,18059,784,1613510,309,34550,1093,1648060,2844.9,2076.88
535
+ 1/11/2023,296,123,1834772,4275,201158,313487,0,889,0,2485,0,33093,0,2287,862276,316545,798469,11740,3972,D3,P3,16341,28782,1292,2880920,542,58750,1834,2939670,3468.46,2536.62
536
+ 2/11/2023,346,111,1697213,2987,1586296,64435,0,957,0,2130,0,16368,0,3586,840477,298617,830972,10008,3641,D3,P3,12216,22498,1071,2342490,402,43400,1473,2385890,3237.48,2396.17
537
+ 3/11/2023,224,89,1759831,2940,93667,74522,0,962,0,2484,0,14150,0,953,952592,350909,800378,11090,3818,D3,P3,10460,20113,902,1897210,372,40600,1274,1937810,2883.8,2066.5
538
+ 4/11/2023,214,76,1677064,2752,65182,61325,0,1796,0,3084,0,10438,0,1148,957265,344580,821570,11309,4380,D3,P3,8630,17741,757,1590600,290,31650,1047,1622250,2519.34,1826.6
Model/summary_df.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:acd8580c5c2bddd6a5d6cedbf29320b52812abe71afb1d1a81bb6eb086cb944b
3
+ size 1482
Model_Results_Pretrained.py ADDED
@@ -0,0 +1,349 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import plotly.express as px
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ from sklearn.metrics import r2_score
6
+ from collections import OrderedDict
7
+ import pickle
8
+ import json
9
+ import streamlit as st
10
+ import plotly.express as px
11
+ import numpy as np
12
+ import plotly.graph_objects as go
13
+ from sklearn.metrics import r2_score
14
+ import pickle
15
+ import json
16
+ import pandas as pd
17
+ import statsmodels.api as sm
18
+ from sklearn.metrics import mean_absolute_percentage_error
19
+ import sys
20
+ import os
21
+ from utilities import (set_header,
22
+ initialize_data,
23
+ load_local_css,
24
+ create_channel_summary,
25
+ create_contribution_pie,
26
+ create_contribuion_stacked_plot,
27
+ create_channel_spends_sales_plot,
28
+ format_numbers,
29
+ channel_name_formating,
30
+ load_authenticator)
31
+ import seaborn as sns
32
+ import matplotlib.pyplot as plt
33
+ import sweetviz as sv
34
+ import tempfile
35
+
36
+ original_stdout = sys.stdout
37
+ sys.stdout = open('temp_stdout.txt', 'w')
38
+ sys.stdout.close()
39
+ sys.stdout = original_stdout
40
+
41
+ st.set_page_config(layout='wide')
42
+ load_local_css('styles.css')
43
+ set_header()
44
+
45
+ for k, v in st.session_state.items():
46
+ if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
47
+ st.session_state[k] = v
48
+
49
+ authenticator = st.session_state.get('authenticator')
50
+ if authenticator is None:
51
+ authenticator = load_authenticator()
52
+
53
+ name, authentication_status, username = authenticator.login('Login', 'main')
54
+ auth_status = st.session_state.get('authentication_status')
55
+
56
+ if auth_status == True:
57
+ is_state_initiaized = st.session_state.get('initialized',False)
58
+ if not is_state_initiaized:
59
+ a=1
60
+
61
+
62
+ def plot_residual_predicted(actual, predicted, df_):
63
+ df_['Residuals'] = actual - pd.Series(predicted)
64
+ df_['StdResidual'] = (df_['Residuals'] - df_['Residuals'].mean()) / df_['Residuals'].std()
65
+
66
+ # Create a Plotly scatter plot
67
+ fig = px.scatter(df_, x=predicted, y='StdResidual', opacity=0.5,color_discrete_sequence=["#11B6BD"])
68
+
69
+ # Add horizontal lines
70
+ fig.add_hline(y=0, line_dash="dash", line_color="darkorange")
71
+ fig.add_hline(y=2, line_color="red")
72
+ fig.add_hline(y=-2, line_color="red")
73
+
74
+ fig.update_xaxes(title='Predicted')
75
+ fig.update_yaxes(title='Standardized Residuals (Actual - Predicted)')
76
+
77
+ # Set the same width and height for both figures
78
+ fig.update_layout(title='Residuals over Predicted Values', autosize=False, width=600, height=400)
79
+
80
+ return fig
81
+
82
+ def residual_distribution(actual, predicted):
83
+ Residuals = actual - pd.Series(predicted)
84
+
85
+ # Create a Seaborn distribution plot
86
+ sns.set(style="whitegrid")
87
+ plt.figure(figsize=(6, 4))
88
+ sns.histplot(Residuals, kde=True, color="#11B6BD")
89
+
90
+ plt.title(' Distribution of Residuals')
91
+ plt.xlabel('Residuals')
92
+ plt.ylabel('Probability Density')
93
+
94
+ return plt
95
+
96
+
97
+ def qqplot(actual, predicted):
98
+ Residuals = actual - pd.Series(predicted)
99
+ Residuals = pd.Series(Residuals)
100
+ Resud_std = (Residuals - Residuals.mean()) / Residuals.std()
101
+
102
+ # Create a QQ plot using Plotly with custom colors
103
+ fig = go.Figure()
104
+ fig.add_trace(go.Scatter(x=sm.ProbPlot(Resud_std).theoretical_quantiles,
105
+ y=sm.ProbPlot(Resud_std).sample_quantiles,
106
+ mode='markers',
107
+ marker=dict(size=5, color="#11B6BD"),
108
+ name='QQ Plot'))
109
+
110
+ # Add the 45-degree reference line
111
+ diagonal_line = go.Scatter(
112
+ x=[-2, 2], # Adjust the x values as needed to fit the range of your data
113
+ y=[-2, 2], # Adjust the y values accordingly
114
+ mode='lines',
115
+ line=dict(color='red'), # Customize the line color and style
116
+ name=' '
117
+ )
118
+ fig.add_trace(diagonal_line)
119
+
120
+ # Customize the layout
121
+ fig.update_layout(title='QQ Plot of Residuals',title_x=0.5, autosize=False, width=600, height=400,
122
+ xaxis_title='Theoretical Quantiles', yaxis_title='Sample Quantiles')
123
+
124
+ return fig
125
+
126
+
127
+ def plot_actual_vs_predicted(date, y, predicted_values, model):
128
+ fig = go.Figure()
129
+
130
+ fig.add_trace(go.Scatter(x=date, y=y, mode='lines', name='Actual', line=dict(color='blue')))
131
+ fig.add_trace(go.Scatter(x=date, y=predicted_values, mode='lines', name='Predicted', line=dict(color='orange')))
132
+
133
+ # Calculate MAPE
134
+ mape = mean_absolute_percentage_error(y, predicted_values)*100
135
+
136
+ # Calculate R-squared
137
+ rss = np.sum((y - predicted_values) ** 2)
138
+ tss = np.sum((y - np.mean(y)) ** 2)
139
+ r_squared = 1 - (rss / tss)
140
+
141
+ # Get the number of predictors
142
+ num_predictors = model.df_model
143
+
144
+ # Get the number of samples
145
+ num_samples = len(y)
146
+
147
+ # Calculate Adjusted R-squared
148
+ adj_r_squared = 1 - ((1 - r_squared) * ((num_samples - 1) / (num_samples - num_predictors - 1)))
149
+ metrics_table = pd.DataFrame({
150
+ 'Metric': ['MAPE', 'R-squared', 'AdjR-squared'],
151
+ 'Value': [mape, r_squared, adj_r_squared]})
152
+ fig.update_layout(
153
+ xaxis=dict(title='Date'),
154
+ yaxis=dict(title='Value'),
155
+ title=f'MAPE : {mape:.2f}%, AdjR2: {adj_r_squared:.2f}',
156
+ xaxis_tickangle=-30
157
+ )
158
+
159
+ return metrics_table,fig
160
+
161
+
162
+
163
+
164
+ # # Perform linear regression
165
+ # model = sm.OLS(y, X).fit()
166
+ eda_columns=st.columns(3)
167
+ with eda_columns[0]:
168
+ tactic=st.checkbox('Tactic Level Model')
169
+ if tactic:
170
+ with open('mastercard_mmm_model.pkl', 'rb') as file:
171
+ model = pickle.load(file)
172
+ train=pd.read_csv('train_mastercard.csv')
173
+ test=pd.read_csv('test_mastercard.csv')
174
+ train['Date']=pd.to_datetime(train['Date'])
175
+ test['Date']=pd.to_datetime(test['Date'])
176
+ train.set_index('Date',inplace=True)
177
+ test.set_index('Date',inplace=True)
178
+ test.dropna(inplace=True)
179
+ X_train=train.drop(["total_approved_accounts_revenue"],axis=1)
180
+ y_train=train['total_approved_accounts_revenue']
181
+ X_test=test.drop(["total_approved_accounts_revenue"],axis=1)
182
+ X_train=sm.add_constant(X_train)
183
+ X_test=sm.add_constant(X_test)
184
+ y_test=test['total_approved_accounts_revenue']
185
+
186
+ # sys.stdout.close()
187
+ # sys.stdout = original_stdout
188
+
189
+ # st.set_page_config(layout='wide')
190
+ # load_local_css('styles.css')
191
+ # set_header()
192
+
193
+ channel_data=pd.read_excel("Channel_wise_imp_click_spends_new.xlsx",sheet_name='Sheet3')
194
+ target_column='Total Approved Accounts - Revenue'
195
+
196
+
197
+ with eda_columns[1]:
198
+ if st.button('Generate EDA Report'):
199
+ def generate_report_with_target(channel_data, target_feature):
200
+ report = sv.analyze([channel_data, "Dataset"], target_feat=target_feature,verbose=False)
201
+ temp_dir = tempfile.mkdtemp()
202
+ report_path = os.path.join(temp_dir, "report.html")
203
+ report.show_html(filepath=report_path, open_browser=False) # Generate the report as an HTML file
204
+ return report_path
205
+
206
+ report_file = generate_report_with_target(channel_data, target_column)
207
+
208
+ if os.path.exists(report_file):
209
+ with open(report_file, 'rb') as f:
210
+ st.download_button(
211
+ label="Download EDA Report",
212
+ data=f.read(),
213
+ file_name="report.html",
214
+ mime="text/html"
215
+ )
216
+ else:
217
+ st.warning("Report generation failed. Unable to find the report file.")
218
+
219
+
220
+ st.title('Analysis of Result')
221
+
222
+ st.write(model.summary(yname='Revenue'))
223
+
224
+ metrics_table_train,fig_train= plot_actual_vs_predicted(X_train.index, y_train, model.predict(X_train), model)
225
+ metrics_table_test,fig_test= plot_actual_vs_predicted(X_test.index, y_test, model.predict(X_test), model)
226
+
227
+ metrics_table_train=metrics_table_train.set_index('Metric').transpose()
228
+ metrics_table_train.index=['Train']
229
+ metrics_table_test=metrics_table_test.set_index('Metric').transpose()
230
+ metrics_table_test.index=['test']
231
+ metrics_table=np.round(pd.concat([metrics_table_train,metrics_table_test]),2)
232
+
233
+ st.markdown('Result Overview')
234
+ st.dataframe(np.round(metrics_table,2),use_container_width=True)
235
+
236
+ st.subheader('Actual vs Predicted Plot Train')
237
+
238
+ st.plotly_chart(fig_train,use_container_width=True)
239
+ st.subheader('Actual vs Predicted Plot Test')
240
+ st.plotly_chart(fig_test,use_container_width=True)
241
+
242
+ st.markdown('## Residual Analysis')
243
+ columns=st.columns(2)
244
+ Xtrain1=X_train.copy()
245
+ with columns[0]:
246
+ fig=plot_residual_predicted(y_train,model.predict(Xtrain1),Xtrain1)
247
+ st.plotly_chart(fig)
248
+
249
+ with columns[1]:
250
+ st.empty()
251
+ fig = qqplot(y_train,model.predict(X_train))
252
+ st.plotly_chart(fig)
253
+
254
+ with columns[0]:
255
+ fig=residual_distribution(y_train,model.predict(X_train))
256
+ st.pyplot(fig)
257
+ else:
258
+ with open('mastercard_mmm_model_channel.pkl', 'rb') as file:
259
+ model = pickle.load(file)
260
+ train=pd.read_csv('train_mastercard_channel.csv')
261
+ test=pd.read_csv('test_mastercard_channel.csv')
262
+ # train['Date']=pd.to_datetime(train['Date'])
263
+ # test['Date']=pd.to_datetime(test['Date'])
264
+ # train.set_index('Date',inplace=True)
265
+ # test.set_index('Date',inplace=True)
266
+ test.dropna(inplace=True)
267
+ X_train=train.drop(["total_approved_accounts_revenue"],axis=1)
268
+ y_train=train['total_approved_accounts_revenue']
269
+ X_test=test.drop(["total_approved_accounts_revenue"],axis=1)
270
+ X_train=sm.add_constant(X_train)
271
+ X_test=sm.add_constant(X_test)
272
+ y_test=test['total_approved_accounts_revenue']
273
+
274
+
275
+
276
+ channel_data=pd.read_excel("Channel_wise_imp_click_spends_new.xlsx",sheet_name='Sheet3')
277
+ target_column='Total Approved Accounts - Revenue'
278
+ with eda_columns[1]:
279
+ if st.button('Generate EDA Report'):
280
+ def generate_report_with_target(channel_data, target_feature):
281
+ report = sv.analyze([channel_data, "Dataset"], target_feat=target_feature)
282
+ temp_dir = tempfile.mkdtemp()
283
+ report_path = os.path.join(temp_dir, "report.html")
284
+ report.show_html(filepath=report_path, open_browser=False) # Generate the report as an HTML file
285
+ return report_path
286
+
287
+ report_file = generate_report_with_target(channel_data, target_column)
288
+
289
+ # Provide a link to download the generated report
290
+ with open(report_file, 'rb') as f:
291
+ st.download_button(
292
+ label="Download EDA Report",
293
+ data=f.read(),
294
+ file_name="report.html",
295
+ mime="text/html"
296
+ )
297
+
298
+
299
+ st.title('Analysis of Result')
300
+
301
+ st.write(model.summary(yname='Revenue'))
302
+
303
+ metrics_table_train,fig_train= plot_actual_vs_predicted(X_train.index, y_train, model.predict(X_train), model)
304
+ metrics_table_test,fig_test= plot_actual_vs_predicted(X_test.index, y_test, model.predict(X_test), model)
305
+
306
+ metrics_table_train=metrics_table_train.set_index('Metric').transpose()
307
+ metrics_table_train.index=['Train']
308
+ metrics_table_test=metrics_table_test.set_index('Metric').transpose()
309
+ metrics_table_test.index=['test']
310
+ metrics_table=np.round(pd.concat([metrics_table_train,metrics_table_test]),2)
311
+
312
+ st.markdown('Result Overview')
313
+ st.dataframe(np.round(metrics_table,2),use_container_width=True)
314
+
315
+ st.subheader('Actual vs Predicted Plot Train')
316
+
317
+ st.plotly_chart(fig_train,use_container_width=True)
318
+ st.subheader('Actual vs Predicted Plot Test')
319
+ st.plotly_chart(fig_test,use_container_width=True)
320
+
321
+ st.markdown('## Residual Analysis')
322
+ columns=st.columns(2)
323
+ Xtrain1=X_train.copy()
324
+ with columns[0]:
325
+ fig=plot_residual_predicted(y_train,model.predict(Xtrain1),Xtrain1)
326
+ st.plotly_chart(fig)
327
+
328
+ with columns[1]:
329
+ st.empty()
330
+ fig = qqplot(y_train,model.predict(X_train))
331
+ st.plotly_chart(fig)
332
+
333
+ with columns[0]:
334
+ fig=residual_distribution(y_train,model.predict(X_train))
335
+ st.pyplot(fig)
336
+
337
+ elif auth_status == False:
338
+ st.error('Username/Password is incorrect')
339
+
340
+ if auth_status != True:
341
+ try:
342
+ username_forgot_pw, email_forgot_password, random_password = authenticator.forgot_password('Forgot password')
343
+ if username_forgot_pw:
344
+ st.success('New password sent securely')
345
+ # Random password to be transferred to user securely
346
+ elif username_forgot_pw == False:
347
+ st.error('Username not found')
348
+ except Exception as e:
349
+ st.error(e)
Overview_data_test.xlsx ADDED
Binary file (27.4 kB). View file
 
Overview_data_test_panel@#app_installs.xlsx ADDED
Binary file (28.1 kB). View file
 
Overview_data_test_panel@#revenue.xlsx ADDED
Binary file (28.1 kB). View file
 
Overview_data_test_panelreplace_meapp_installs.xlsx ADDED
Binary file (28.1 kB). View file
 
Pickle_files/category_dict ADDED
Binary file (796 Bytes). View file
 
Pickle_files/main_df ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0ed723abf96a19138a886dc00961bef6d05391483deeca9bea4a50f05045d48e
3
+ size 2221488
Scenario.py ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ import numpy as np
6
+ import plotly.express as px
7
+ import plotly.graph_objects as go
8
+ import pandas as pd
9
+ import seaborn as sns
10
+ import matplotlib.pyplot as plt
11
+ import datetime
12
+ from utilities import set_header,initialize_data,load_local_css
13
+ from scipy.optimize import curve_fit
14
+ import statsmodels.api as sm
15
+ from plotly.subplots import make_subplots
16
+
17
+ st.set_page_config(
18
+ page_title="Data Validation",
19
+ page_icon=":shark:",
20
+ layout="wide",
21
+ initial_sidebar_state='collapsed'
22
+ )
23
+ load_local_css('styles.css')
24
+ set_header()
25
+
26
+ def format_numbers(x):
27
+ if abs(x) >= 1e6:
28
+ # Format as millions with one decimal place and commas
29
+ return f'{x/1e6:,.1f}M'
30
+ elif abs(x) >= 1e3:
31
+ # Format as thousands with one decimal place and commas
32
+ return f'{x/1e3:,.1f}K'
33
+ else:
34
+ # Format with one decimal place and commas for values less than 1000
35
+ return f'{x:,.1f}'
36
+
37
+ def format_axis(x):
38
+ if isinstance(x, tuple):
39
+ x = x[0] # Extract the numeric value from the tuple
40
+ if abs(x) >= 1e6:
41
+ return f'{x / 1e6:.0f}M'
42
+ elif abs(x) >= 1e3:
43
+ return f'{x / 1e3:.0f}k'
44
+ else:
45
+ return f'{x:.0f}'
46
+
47
+
48
+ attributred_app_installs=pd.read_csv("attributed_app_installs.csv")
49
+ attributred_app_installs_tactic=pd.read_excel('attributed_app_installs_tactic.xlsx')
50
+ data=pd.read_excel('Channel_wise_imp_click_spends.xlsx')
51
+ data['Date']=pd.to_datetime(data['Date'])
52
+ st.header('Saturation Curves')
53
+
54
+ # st.dataframe(data.head(2))
55
+ st.markdown('Data QC')
56
+
57
+ st.markdown('Channel wise summary')
58
+ summary_df=data.groupby(data['Date'].dt.strftime('%B %Y')).sum()
59
+ summary_df=summary_df.sort_index(key=lambda x: pd.to_datetime(x, format='%B %Y'))
60
+ st.dataframe(summary_df.applymap(format_numbers))
61
+
62
+
63
+
64
+ def line_plot_target(df,target,title):
65
+ df=df
66
+ df['Date_unix'] = df['Date'].apply(lambda x: x.timestamp())
67
+
68
+ # Perform polynomial fitting
69
+ coefficients = np.polyfit(df['Date_unix'], df[target], 1)
70
+ # st.dataframe(df)
71
+ coefficients = np.polyfit(df['Date'].view('int64'), df[target], 1)
72
+ trendline = np.poly1d(coefficients)
73
+ fig = go.Figure()
74
+
75
+ fig.add_trace(go.Scatter(x=df['Date'], y=df[target], mode='lines', name=target,line=dict(color='#11B6BD')))
76
+ trendline_x = df['Date']
77
+ trendline_y = trendline(df['Date'].view('int64'))
78
+
79
+
80
+ fig.add_trace(go.Scatter(x=trendline_x, y=trendline_y, mode='lines', name='Trendline', line=dict(color='#739FAE')))
81
+
82
+ fig.update_layout(
83
+ title=title,
84
+ xaxis=dict(type='date')
85
+ )
86
+
87
+ for year in df['Date'].dt.year.unique()[1:]:
88
+
89
+ january_1 = pd.Timestamp(year=year, month=1, day=1)
90
+ fig.add_shape(
91
+ go.layout.Shape(
92
+ type="line",
93
+ x0=january_1,
94
+ x1=january_1,
95
+ y0=0,
96
+ y1=1,
97
+ xref="x",
98
+ yref="paper",
99
+ line=dict(color="grey", width=1.5, dash="dash"),
100
+ )
101
+ )
102
+
103
+ return fig
104
+ channels_d= data.columns[:28]
105
+ channels=list(set([col.replace('_impressions','').replace('_clicks','').replace('_spend','') for col in channels_d if col.lower()!='date']))
106
+ channel= st.selectbox('Select Channel_name',channels)
107
+ target_column = st.selectbox('Select Channel)',[col for col in data.columns if col.startswith(channel)])
108
+ fig=line_plot_target(data, target=str(target_column), title=f'{str(target_column)} Over Time')
109
+ st.plotly_chart(fig, use_container_width=True)
110
+
111
+ # st.markdown('## Saturation Curve')
112
+
113
+
114
+ st.header('Build saturation curve')
115
+
116
+ # Your data
117
+ # st.write(len(attributred_app_installs))
118
+ # st.write(len(data))
119
+ # col=st.columns(3)
120
+ # with col[0]:
121
+ col=st.columns(2)
122
+ with col[0]:
123
+ if st.checkbox('Cap Outliers'):
124
+ x = data[target_column]
125
+ x.index=data['Date']
126
+ # st.write(x)
127
+ result = sm.tsa.seasonal_decompose(x, model='additive')
128
+ x_resid=result.resid
129
+ # fig = make_subplots(rows=1, cols=1, shared_xaxes=True, vertical_spacing=0.02)
130
+ # trace_x = go.Scatter(x=data['Date'], y=x, mode='lines', name='x')
131
+ # fig.add_trace(trace_x)
132
+ # trace_x_resid = go.Scatter(x=data['Date'], y=x_resid, mode='lines', name='x_resid', yaxis='y2',line=dict(color='orange'))
133
+
134
+ # fig.add_trace(trace_x_resid)
135
+ # fig.update_layout(title='',
136
+ # xaxis=dict(title='Date'),
137
+ # yaxis=dict(title='x', side='left'),
138
+ # yaxis2=dict(title='x_resid', side='right'))
139
+ # st.title('')
140
+ # st.plotly_chart(fig)
141
+
142
+ # x=result.resid
143
+ # x=x.fillna(0)
144
+ x_mean = np.mean(x)
145
+ x_std = np.std(x)
146
+ x_scaled = (x - x_mean) / x_std
147
+ lower_threshold = -2.0
148
+ upper_threshold = 2.0
149
+ x_scaled = np.clip(x_scaled, lower_threshold, upper_threshold)
150
+ else:
151
+ x = data[target_column]
152
+ x_mean = np.mean(x)
153
+ x_std = np.std(x)
154
+ x_scaled = (x - x_mean) / x_std
155
+ with col[1]:
156
+ if st.checkbox('Attributed'):
157
+ column=[col for col in attributred_app_installs.columns if col in target_column]
158
+ data['app_installs_appsflyer']=attributred_app_installs[column]
159
+ y=data['app_installs_appsflyer']
160
+ title='Attributed-App_installs_appsflyer'
161
+ # st.dataframe(y)
162
+ # st.dataframe(x)
163
+ # st.dataframe(x_scaled)
164
+ else:
165
+ y=data["app_installs_appsflyer"]
166
+ title='App_installs_appsflyer'
167
+ # st.write(len(y))
168
+ # Curve fitting function
169
+ def sigmoid(x, K, a, x0):
170
+ return K / (1 + np.exp(-a * (x - x0)))
171
+
172
+ initial_K = np.max(y)
173
+ initial_a = 1
174
+ initial_x0 = 0
175
+ columns=st.columns(3)
176
+
177
+
178
+ with columns[0]:
179
+ K = st.number_input('K (Amplitude)', min_value=0.01, max_value=2.0 * np.max(y), value=float(initial_K), step=5.0)
180
+ with columns[1]:
181
+ a = st.number_input('a (Slope)', min_value=0.01, max_value=5.0, value=float(initial_a), step=0.5)
182
+ with columns[2]:
183
+ x0 = st.number_input('x0 (Center)', min_value=float(min(x_scaled)), max_value=float(max(x_scaled)), value=float(initial_x0), step=2.0)
184
+ params, _ = curve_fit(sigmoid, x_scaled, y, p0=[K, a, x0], maxfev=20000)
185
+
186
+
187
+ x_slider = st.slider('X Value', min_value=float(min(x)), max_value=float(max(x))+1, value=float(x_mean), step=1.)
188
+
189
+ # Calculate the corresponding value on the fitted curve
190
+ x_slider_scaled = (x_slider - x_mean) / x_std
191
+ y_slider_fit = sigmoid(x_slider_scaled, *params)
192
+
193
+ # Display the corresponding value
194
+ st.write(f'{target_column}: {format_numbers(x_slider)}')
195
+ st.write(f'Corresponding App_installs: {format_numbers(y_slider_fit)}')
196
+
197
+ # Scatter plot of your data
198
+ fig = px.scatter(data_frame=data, x=x_scaled, y=y, labels={'x': f'{target_column}', 'y': 'App Installs'}, title=title)
199
+
200
+ # Add the fitted sigmoid curve to the plot
201
+ x_fit = np.linspace(min(x_scaled), max(x_scaled), 100) # Generate x values for the curve
202
+ y_fit = sigmoid(x_fit, *params)
203
+ fig.add_trace(px.line(x=x_fit, y=y_fit).data[0])
204
+ fig.data[1].update(line=dict(color='orange'))
205
+ fig.add_vline(x=x_slider_scaled, line_dash='dash', line_color='red', annotation_text=f'{format_numbers(x_slider)}')
206
+
207
+ x_tick_labels = {format_axis(x_scaled[i]): format_axis(x[i]) for i in range(len(x_scaled))}
208
+ num_points = 30 # Number of points you want to select
209
+ keys = list(x_tick_labels.keys())
210
+ values = list(x_tick_labels.values())
211
+ spacing = len(keys) // num_points # Calculate the spacing
212
+ if spacing==0:
213
+ spacing=15
214
+ selected_keys = keys[::spacing]
215
+ selected_values = values[::spacing]
216
+ else:
217
+ selected_keys = keys[::spacing]
218
+ selected_values = values[::spacing]
219
+
220
+ # Update the x-axis ticks with the selected keys and values
221
+ fig.update_xaxes(tickvals=selected_keys, ticktext=selected_values)
222
+ fig.update_xaxes(tickvals=list(x_tick_labels.keys()), ticktext=list(x_tick_labels.values()))
223
+ # Show the plot using st.plotly_chart
224
+
225
+ fig.update_xaxes(showgrid=False)
226
+ fig.update_yaxes(showgrid=False)
227
+ fig.update_layout(
228
+ width=600, # Adjust the width as needed
229
+ height=600 # Adjust the height as needed
230
+ )
231
+ st.plotly_chart(fig)
232
+
233
+
234
+
235
+
236
+ st.markdown('Tactic level')
237
+ if channel=='paid_social':
238
+
239
+ tactic_data=pd.read_excel("Tatcic_paid.xlsx",sheet_name='paid_social_impressions')
240
+ else:
241
+ tactic_data=pd.read_excel("Tatcic_paid.xlsx",sheet_name='digital_app_display_impressions')
242
+ target_column = st.selectbox('Select Channel)',[col for col in tactic_data.columns if col!='Date' and col!='app_installs_appsflyer'])
243
+ fig=line_plot_target(tactic_data, target=str(target_column), title=f'{str(target_column)} Over Time')
244
+ st.plotly_chart(fig, use_container_width=True)
245
+
246
+ if st.checkbox('Cap Outliers',key='tactic1'):
247
+ x = tactic_data[target_column]
248
+ x_mean = np.mean(x)
249
+ x_std = np.std(x)
250
+ x_scaled = (x - x_mean) / x_std
251
+ lower_threshold = -2.0
252
+ upper_threshold = 2.0
253
+ x_scaled = np.clip(x_scaled, lower_threshold, upper_threshold)
254
+ else:
255
+ x = tactic_data[target_column]
256
+ x_mean = np.mean(x)
257
+ x_std = np.std(x)
258
+ x_scaled = (x - x_mean) / x_std
259
+
260
+ if st.checkbox('Attributed',key='tactic2'):
261
+ column=[col for col in attributred_app_installs_tactic.columns if col in target_column]
262
+ tactic_data['app_installs_appsflyer']=attributred_app_installs_tactic[column]
263
+ y=tactic_data['app_installs_appsflyer']
264
+ title='Attributed-App_installs_appsflyer'
265
+ # st.dataframe(y)
266
+ # st.dataframe(x)
267
+ # st.dataframe(x_scaled)
268
+ else:
269
+ y=data["app_installs_appsflyer"]
270
+ title='App_installs_appsflyer'
271
+ # st.write(len(y))
272
+ # Curve fitting function
273
+ def sigmoid(x, K, a, x0):
274
+ return K / (1 + np.exp(-a * (x - x0)))
275
+
276
+ # Curve fitting
277
+ # st.dataframe(x_scaled.head(3))
278
+ # # y=y.astype(float)
279
+ # st.dataframe(y.head(3))
280
+ initial_K = np.max(y)
281
+ initial_a = 1
282
+ initial_x0 = 0
283
+ K = st.number_input('K (Amplitude)', min_value=0.01, max_value=2.0 * np.max(y), value=float(initial_K), step=5.0,key='tactic3')
284
+ a = st.number_input('a (Slope)', min_value=0.01, max_value=5.0, value=float(initial_a), step=2.0,key='tactic41')
285
+ x0 = st.number_input('x0 (Center)', min_value=float(min(x_scaled)), max_value=float(max(x_scaled)), value=float(initial_x0), step=2.0,key='tactic4')
286
+ params, _ = curve_fit(sigmoid, x_scaled, y, p0=[K, a, x0], maxfev=20000)
287
+
288
+ # Slider to vary x
289
+ x_slider = st.slider('X Value', min_value=float(min(x)), max_value=float(max(x)), value=float(x_mean), step=1.,key='tactic7')
290
+
291
+ # Calculate the corresponding value on the fitted curve
292
+ x_slider_scaled = (x_slider - x_mean) / x_std
293
+ y_slider_fit = sigmoid(x_slider_scaled, *params)
294
+
295
+ # Display the corresponding value
296
+ st.write(f'{target_column}: {format_axis(x_slider)}')
297
+ st.write(f'Corresponding App_installs: {format_axis(y_slider_fit)}')
298
+
299
+ # Scatter plot of your data
300
+ fig = px.scatter(data_frame=data, x=x_scaled, y=y, labels={'x': f'{target_column}', 'y': 'App Installs'}, title=title)
301
+
302
+ # Add the fitted sigmoid curve to the plot
303
+ x_fit = np.linspace(min(x_scaled), max(x_scaled), 100) # Generate x values for the curve
304
+ y_fit = sigmoid(x_fit, *params)
305
+ fig.add_trace(px.line(x=x_fit, y=y_fit).data[0])
306
+ fig.data[1].update(line=dict(color='orange'))
307
+ fig.add_vline(x=x_slider_scaled, line_dash='dash', line_color='red', annotation_text=f'{format_numbers(x_slider)}')
308
+
309
+
310
+
311
+ x_tick_labels = {format_axis((x_scaled[i],0)): format_axis(x[i]) for i in range(len(x_scaled))}
312
+ num_points = 50 # Number of points you want to select
313
+ keys = list(x_tick_labels.keys())
314
+ values = list(x_tick_labels.values())
315
+ spacing = len(keys) // num_points # Calculate the spacing
316
+ if spacing==0:
317
+ spacing=2
318
+ selected_keys = keys[::spacing]
319
+ selected_values = values[::spacing]
320
+ else:
321
+ selected_keys = keys[::spacing]
322
+ selected_values = values[::spacing]
323
+
324
+ # Update the x-axis ticks with the selected keys and values
325
+ fig.update_xaxes(tickvals=selected_keys, ticktext=selected_values)
326
+
327
+ # Round the x-axis and y-axis tick values to zero decimal places
328
+ fig.update_xaxes(tickformat=".f") # Format x-axis ticks to zero decimal places
329
+ fig.update_yaxes(tickformat=".f") # Format y-axis ticks to zero decimal places
330
+
331
+ # Show the plot using st.plotly_chart
332
+ fig.update_xaxes(showgrid=False)
333
+ fig.update_yaxes(showgrid=False)
334
+ fig.update_layout(
335
+ width=600, # Adjust the width as needed
336
+ height=600 # Adjust the height as needed
337
+ )
338
+ st.plotly_chart(fig)
Test/X_test_tuned_trend.csv ADDED
@@ -0,0 +1,971 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ paid_search_clicks,kwai_clicks,fb_level_achieved_tier_2_clicks_lag_2,fb_level_achieved_tier_1_impressions,ga_app_clicks,digital_tactic_others_impressions_lag_2,programmatic_clicks_lag_3,total_approved_accounts_revenue,date,dma,Trend
2
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06194251734390485,31.746,8/7/2023,Albany/Schenectady/Troy SMM Food,124
3
+ 0.0,0.0010625686993517797,0.0,0.0,0.005135905343058742,0.0,0.0,30.66,8/8/2022,Albany/Schenectady/Troy SMM Food,125
4
+ 0.0,0.0,0.0,0.0,0.0019373305473274695,0.0,0.0,31.61,8/9/2021,Albany/Schenectady/Troy SMM Food,126
5
+ 0.0,0.0,0.006928265811381233,0.0,0.0,0.04710893906935569,0.062438057482656094,31.871,9/11/2023,Albany/Schenectady/Troy SMM Food,127
6
+ 0.0,0.0,0.0,0.013920804779456755,0.0,0.0,0.0,34.48,9/12/2022,Albany/Schenectady/Troy SMM Food,128
7
+ 0.0,0.0,0.0,0.0,0.0014406267064896794,0.0,0.0,34.3,9/13/2021,Albany/Schenectady/Troy SMM Food,129
8
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06442021803766104,38.922,9/18/2023,Albany/Schenectady/Troy SMM Food,130
9
+ 0.0,0.0,0.0,0.014511012797352662,0.0,0.0,0.0,34.78,9/19/2022,Albany/Schenectady/Troy SMM Food,131
10
+ 0.0,0.0,0.0,0.0,0.0010515523405034157,0.0,0.0,34.23,9/20/2021,Albany/Schenectady/Troy SMM Food,132
11
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06838453914767095,36.091,9/25/2023,Albany/Schenectady/Troy SMM Food,133
12
+ 0.0,0.0,0.0,0.016489078958499923,0.0,0.0,0.0,34.21,9/26/2022,Albany/Schenectady/Troy SMM Food,134
13
+ 0.0,0.0,0.0,0.0,0.0011647488571576068,0.0,0.0,33.64,9/27/2021,Albany/Schenectady/Troy SMM Food,135
14
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06045589692765114,31.809,9/4/2023,Albany/Schenectady/Troy SMM Food,136
15
+ 0.0,0.0,0.0,0.014564429905722917,0.0,0.0,0.0,30.83,9/5/2022,Albany/Schenectady/Troy SMM Food,137
16
+ 0.0,0.0,0.0,0.0,0.0016552670959924358,0.0,0.0,32.16,9/6/2021,Albany/Schenectady/Troy SMM Food,138
17
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06293359762140734,19.524,8/7/2023,Albuquerque/Santa FE SMM Food,124
18
+ 0.0,0.0011847395500790977,0.0,0.0,0.005197761363088355,0.0,0.0,17.41,8/8/2022,Albuquerque/Santa FE SMM Food,125
19
+ 0.0,0.0,0.0,0.0,0.0011734086999617528,0.0,0.0,20.25,8/9/2021,Albuquerque/Santa FE SMM Food,126
20
+ 0.0,0.0,0.006270420242227,0.0,0.0,0.05228225082270357,0.06045589692765114,20.598,9/11/2023,Albuquerque/Santa FE SMM Food,127
21
+ 0.0,0.0,0.0,0.013504398628886482,0.0,0.0,0.0,18.96,9/12/2022,Albuquerque/Santa FE SMM Food,128
22
+ 0.0,0.0,0.0,0.0,0.0015389777783367637,0.0,0.0,22.17,9/13/2021,Albuquerque/Santa FE SMM Food,129
23
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05252725470763132,20.817,9/18/2023,Albuquerque/Santa FE SMM Food,130
24
+ 0.0,0.0,0.0,0.014076952049886973,0.0,0.0,0.0,19.46,9/19/2022,Albuquerque/Santa FE SMM Food,131
25
+ 0.0,0.0,0.0,0.0,0.0015210395325281761,0.0,0.0,21.48,9/20/2021,Albuquerque/Santa FE SMM Food,132
26
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.051040634291377604,19.984,9/25/2023,Albuquerque/Santa FE SMM Food,133
27
+ 0.0,0.0,0.0,0.015995849296932277,0.0,0.0,0.0,21.41,9/26/2022,Albuquerque/Santa FE SMM Food,134
28
+ 0.0,0.0,0.0,0.0,0.0009569126298581084,0.0,0.0,20.66,9/27/2021,Albuquerque/Santa FE SMM Food,135
29
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05153617443012884,19.474,9/4/2023,Albuquerque/Santa FE SMM Food,136
30
+ 0.0,0.0,0.0,0.014128771317940983,0.0,0.0,0.0,18.86,9/5/2022,Albuquerque/Santa FE SMM Food,137
31
+ 0.0,0.0,0.0,0.0,0.0009513455880554432,0.0,0.0,22.19,9/6/2021,Albuquerque/Santa FE SMM Food,138
32
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.211595639246779,261.197,8/7/2023,Atlanta SMM Food,124
33
+ 0.0,0.008222704775902465,0.0,0.0,0.020853520032583325,0.0,0.0,156.16,8/8/2022,Atlanta SMM Food,125
34
+ 0.0,0.0,0.0,0.0,0.004707243124253526,0.0,0.0,101.3,8/9/2021,Atlanta SMM Food,126
35
+ 0.0,0.0,0.07059033189111122,0.0,0.0,0.25431693894538904,0.1952428146679881,140.383,9/11/2023,Atlanta SMM Food,127
36
+ 0.0,0.0,0.0,0.05367166201076247,0.0,0.0,0.0,112.47,9/12/2022,Atlanta SMM Food,128
37
+ 0.0,0.0,0.0,0.0,0.0042668282616426835,0.0,0.0,110.36,9/13/2021,Atlanta SMM Food,129
38
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20069375619425173,132.639,9/18/2023,Atlanta SMM Food,130
39
+ 0.0,0.0,0.0,0.05594720898632875,0.0,0.0,0.0,106.1,9/19/2022,Atlanta SMM Food,131
40
+ 0.0,0.0,0.0,0.0,0.004526623545767057,0.0,0.0,122.59,9/20/2021,Atlanta SMM Food,132
41
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17195242814667988,131.807,9/25/2023,Atlanta SMM Food,133
42
+ 0.0,0.0,0.0,0.06357364295489033,0.0,0.0,0.0,117.87,9/26/2022,Atlanta SMM Food,134
43
+ 0.0,0.0,0.0,0.0,0.0025589835486250767,0.0,0.0,116.38,9/27/2021,Atlanta SMM Food,135
44
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.19127849355797819,138.316,9/4/2023,Atlanta SMM Food,136
45
+ 0.0,0.0,0.0,0.05615315864933586,0.0,0.0,0.0,101.43,9/5/2022,Atlanta SMM Food,137
46
+ 0.0,0.0,0.0,0.0,0.005283741230929517,0.0,0.0,109.49,9/6/2021,Atlanta SMM Food,138
47
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08969276511397423,50.534,8/7/2023,Baltimore SMM Food,124
48
+ 0.0,0.003010948271471134,0.0,0.0,0.010581709346465842,0.0,0.0,54.66,8/8/2022,Baltimore SMM Food,125
49
+ 0.0,0.0,0.0,0.0,0.002178569025442959,0.0,0.0,54.51,8/9/2021,Baltimore SMM Food,126
50
+ 0.0,0.0,0.013868768647461295,0.0,0.0,0.09580695439115328,0.06987115956392467,63.01,9/11/2023,Baltimore SMM Food,127
51
+ 0.0,0.0,0.0,0.02379803605790658,0.0,0.0,0.0,58.19,9/12/2022,Baltimore SMM Food,128
52
+ 0.0,0.0,0.0,0.0,0.002276920097290043,0.0,0.0,61.67,9/13/2021,Baltimore SMM Food,129
53
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06442021803766104,72.253,9/18/2023,Baltimore SMM Food,130
54
+ 0.0,0.0,0.0,0.024807014486139218,0.0,0.0,0.0,60.84,9/19/2022,Baltimore SMM Food,131
55
+ 0.0,0.0,0.0,0.0,0.001681865184605169,0.0,0.0,56.75,9/20/2021,Baltimore SMM Food,132
56
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07383548067393458,74.369,9/25/2023,Baltimore SMM Food,133
57
+ 0.0,0.0,0.0,0.028188578310361815,0.0,0.0,0.0,63.62,9/26/2022,Baltimore SMM Food,134
58
+ 0.0,0.0,0.0,0.0,0.0016020709187669687,0.0,0.0,55.3,9/27/2021,Baltimore SMM Food,135
59
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07433102081268583,56.708,9/4/2023,Baltimore SMM Food,136
60
+ 0.0,0.0,0.0,0.024898332642610616,0.0,0.0,0.0,57.06,9/5/2022,Baltimore SMM Food,137
61
+ 0.0,0.0,0.0,0.0,0.0019039282965114788,0.0,0.0,64.56,9/6/2021,Baltimore SMM Food,138
62
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.028245787908820614,2.491,8/7/2023,Baton Rouge SMM Food,124
63
+ 0.0,0.0005060126015939978,0.0,0.0,0.0027847580217331635,0.0,0.0,2.29,8/8/2022,Baton Rouge SMM Food,125
64
+ 0.0,0.0,0.0,0.0,0.0007769116115719355,0.0,0.0,2.82,8/9/2021,Baton Rouge SMM Food,126
65
+ 0.0,0.0,0.0026347580075683306,0.0,0.0,0.0372315586355452,0.019821605550049554,3.282,9/11/2023,Baton Rouge SMM Food,127
66
+ 0.0,0.0,0.0,0.009473010003288533,0.0,0.0,0.0,2.93,9/12/2022,Baton Rouge SMM Food,128
67
+ 0.0,0.0,0.0,0.0,0.000550518578263553,0.0,0.0,6.28,9/13/2021,Baton Rouge SMM Food,129
68
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.027254707631318136,3.751,9/18/2023,Baton Rouge SMM Food,130
69
+ 0.0,0.0,0.0,0.009874642417058198,0.0,0.0,0.0,1.6,9/19/2022,Baton Rouge SMM Food,131
70
+ 0.0,0.0,0.0,0.0,0.0007249525547470607,0.0,0.0,3.84,9/20/2021,Baton Rouge SMM Food,132
71
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.020317145688800792,2.883,9/25/2023,Baton Rouge SMM Food,133
72
+ 0.0,0.0,0.0,0.01122070256617374,0.0,0.0,0.0,1.98,9/26/2022,Baton Rouge SMM Food,134
73
+ 0.0,0.0,0.0,0.0,0.0005325803324549652,0.0,0.0,2.19,9/27/2021,Baton Rouge SMM Food,135
74
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.02081268582755203,5.023,9/4/2023,Baton Rouge SMM Food,136
75
+ 0.0,0.0,0.0,0.009910992383390915,0.0,0.0,0.0,3.56,9/5/2022,Baton Rouge SMM Food,137
76
+ 0.0,0.0,0.0,0.0,0.000716911272143211,0.0,0.0,2.76,9/6/2021,Baton Rouge SMM Food,138
77
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07086223984142716,30.899,8/7/2023,Birmingham/Anniston/Tuscaloosa SMM Food,124
78
+ 0.0,0.0015968856587974965,0.0,0.0,0.006559212363940131,0.0,0.0,21.32,8/8/2022,Birmingham/Anniston/Tuscaloosa SMM Food,125
79
+ 0.0,0.0,0.0,0.0,0.002610324045249656,0.0,0.0,12.39,8/9/2021,Birmingham/Anniston/Tuscaloosa SMM Food,126
80
+ 0.0,0.0,0.011830671085553057,0.0,0.0,0.06832539296539691,0.05302279484638256,11.227,9/11/2023,Birmingham/Anniston/Tuscaloosa SMM Food,127
81
+ 0.0,0.0,0.0,0.020386457479869002,0.0,0.0,0.0,11.48,9/12/2022,Birmingham/Anniston/Tuscaloosa SMM Food,128
82
+ 0.0,0.0,0.0,0.0,0.0017505253668380393,0.0,0.0,12.29,9/13/2021,Birmingham/Anniston/Tuscaloosa SMM Food,129
83
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06095143706640238,11.018,9/18/2023,Birmingham/Anniston/Tuscaloosa SMM Food,130
84
+ 0.0,0.0,0.0,0.021250793330832705,0.0,0.0,0.0,9.71,9/19/2022,Birmingham/Anniston/Tuscaloosa SMM Food,131
85
+ 0.0,0.0,0.0,0.0,0.002048671383380772,0.0,0.0,12.55,9/20/2021,Birmingham/Anniston/Tuscaloosa SMM Food,132
86
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.055996035678889985,9.499,9/25/2023,Birmingham/Anniston/Tuscaloosa SMM Food,133
87
+ 0.0,0.0,0.0,0.02414759149407838,0.0,0.0,0.0,9.26,9/26/2022,Birmingham/Anniston/Tuscaloosa SMM Food,134
88
+ 0.0,0.0,0.0,0.0,0.001227223437387516,0.0,0.0,11.65,9/27/2021,Birmingham/Anniston/Tuscaloosa SMM Food,135
89
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.051040634291377604,14.16,9/4/2023,Birmingham/Anniston/Tuscaloosa SMM Food,136
90
+ 0.0,0.0,0.0,0.021329020533966504,0.0,0.0,0.0,13.7,9/5/2022,Birmingham/Anniston/Tuscaloosa SMM Food,137
91
+ 0.0,0.0,0.0,0.0,0.001038562576297197,0.0,0.0,12.02,9/6/2021,Birmingham/Anniston/Tuscaloosa SMM Food,138
92
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20416253716551042,142.058,8/7/2023,Boston/Manchester SMM Food,124
93
+ 0.0,0.006427977432121013,0.0,0.0,0.02215311501340549,0.0,0.0,133.68,8/8/2022,Boston/Manchester SMM Food,125
94
+ 0.0,0.0,0.0,0.0,0.006543129798732431,0.0,0.0,118.91,8/9/2021,Boston/Manchester SMM Food,126
95
+ 0.0,0.0,0.04895274042536989,0.0,0.0,0.16361847104901653,0.1798810703666997,172.275,9/11/2023,Boston/Manchester SMM Food,127
96
+ 0.0,0.0,0.0,0.06149452980004475,0.0,0.0,0.0,167.04,9/12/2022,Boston/Manchester SMM Food,128
97
+ 0.0,0.0,0.0,0.0,0.0038660012518507932,0.0,0.0,117.31,9/13/2021,Boston/Manchester SMM Food,129
98
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.19425173439048563,178.545,9/18/2023,Boston/Manchester SMM Food,130
99
+ 0.0,0.0,0.0,0.06410174720660182,0.0,0.0,0.0,145.96,9/19/2022,Boston/Manchester SMM Food,131
100
+ 0.0,0.0,0.0,0.0,0.0032907402655753953,0.0,0.0,113.79,9/20/2021,Boston/Manchester SMM Food,132
101
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.22398414271555994,156.549,9/25/2023,Boston/Manchester SMM Food,133
102
+ 0.0,0.0,0.0,0.07283976560910188,0.0,0.0,0.0,157.5,9/26/2022,Boston/Manchester SMM Food,134
103
+ 0.0,0.0,0.0,0.0,0.0044307467147211566,0.0,0.0,114.52,9/27/2021,Boston/Manchester SMM Food,135
104
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.19573835480673935,149.121,9/4/2023,Boston/Manchester SMM Food,136
105
+ 0.0,0.0,0.0,0.06433771488842611,0.0,0.0,0.0,138.78,9/5/2022,Boston/Manchester SMM Food,137
106
+ 0.0,0.0,0.0,0.0,0.004624356057413845,0.0,0.0,116.39,9/6/2021,Boston/Manchester SMM Food,138
107
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07036669970267592,21.059,8/7/2023,Buffalo SMM Food,124
108
+ 0.0,0.001065745719110646,0.0,0.0,0.006125601663532545,0.0,0.0,14.52,8/8/2022,Buffalo SMM Food,125
109
+ 0.0,0.0,0.0,0.0,0.002417333262757264,0.0,0.0,16.9,8/9/2021,Buffalo SMM Food,126
110
+ 0.0,0.0,0.007447706411528032,0.0,0.0,0.05334496751978329,0.06987115956392467,21.384,9/11/2023,Buffalo SMM Food,127
111
+ 0.0,0.0,0.0,0.016659126610822184,0.0,0.0,0.0,16.16,9/12/2022,Buffalo SMM Food,128
112
+ 0.0,0.0,0.0,0.0,0.0018525877998869001,0.0,0.0,17.94,9/13/2021,Buffalo SMM Food,129
113
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07333994053518335,19.469,9/18/2023,Buffalo SMM Food,130
114
+ 0.0,0.0,0.0,0.017365432764953035,0.0,0.0,0.0,15.79,9/19/2022,Buffalo SMM Food,131
115
+ 0.0,0.0,0.0,0.0,0.0014635134339006364,0.0,0.0,13.96,9/20/2021,Buffalo SMM Food,132
116
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07284440039643211,19.007,9/25/2023,Buffalo SMM Food,133
117
+ 0.0,0.0,0.0,0.019732598682000637,0.0,0.0,0.0,17.25,9/26/2022,Buffalo SMM Food,134
118
+ 0.0,0.0,0.0,0.0,0.0011474291715493155,0.0,0.0,16.09,9/27/2021,Buffalo SMM Food,135
119
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05698711595639247,24.686,9/4/2023,Buffalo SMM Food,136
120
+ 0.0,0.0,0.0,0.01742935740030342,0.0,0.0,0.0,24.05,9/5/2022,Buffalo SMM Food,137
121
+ 0.0,0.0,0.0,0.0,0.002140218293024599,0.0,0.0,18.49,9/6/2021,Buffalo SMM Food,138
122
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11248761149653122,91.731,8/7/2023,Charlotte SMM Food,124
123
+ 0.0,0.00275216557111256,0.0,0.0,0.01447925716853174,0.0,0.0,105.22,8/8/2022,Charlotte SMM Food,125
124
+ 0.0,0.0,0.0,0.0,0.00312867749309781,0.0,0.0,68.53,8/9/2021,Charlotte SMM Food,126
125
+ 0.0,0.0,0.019428597524418424,0.0,0.0,0.14467607804531682,0.10257680872150644,109.118,9/11/2023,Charlotte SMM Food,127
126
+ 0.0,0.0,0.0,0.0334917711067763,0.0,0.0,0.0,90.2,9/12/2022,Charlotte SMM Food,128
127
+ 0.0,0.0,0.0,0.0,0.0033154826735872405,0.0,0.0,71.22,9/13/2021,Charlotte SMM Food,129
128
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09712586719524281,95.013,9/18/2023,Charlotte SMM Food,130
129
+ 0.0,0.0,0.0,0.03491174014852976,0.0,0.0,0.0,80.4,9/19/2022,Charlotte SMM Food,131
130
+ 0.0,0.0,0.0,0.0,0.0025410453028164894,0.0,0.0,67.35,9/20/2021,Charlotte SMM Food,132
131
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10009910802775024,115.348,9/25/2023,Charlotte SMM Food,133
132
+ 0.0,0.0,0.0,0.03967072787903239,0.0,0.0,0.0,69.61,9/26/2022,Charlotte SMM Food,134
133
+ 0.0,0.0,0.0,0.0,0.0018940313333067407,0.0,0.0,67.22,9/27/2021,Charlotte SMM Food,135
134
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09514370664023786,64.194,9/4/2023,Charlotte SMM Food,136
135
+ 0.0,0.0,0.0,0.035040255247413665,0.0,0.0,0.0,69.04,9/5/2022,Charlotte SMM Food,137
136
+ 0.0,0.0,0.0,0.0,0.0029257897474006802,0.0,0.0,95.05,9/6/2021,Charlotte SMM Food,138
137
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2259663032705649,127.164,8/7/2023,Chicago SMM Food,124
138
+ 0.0,0.021210939190104566,0.0,0.0,0.029393362157871656,0.0,0.0,128.34,8/8/2022,Chicago SMM Food,125
139
+ 0.0,0.0,0.0,0.0,0.007107256701402499,0.0,0.0,131.14,8/9/2021,Chicago SMM Food,126
140
+ 0.0,0.0,0.15988812078214787,0.0,0.0,0.2559436219550531,0.21110009910802774,139.546,9/11/2023,Chicago SMM Food,127
141
+ 0.0,0.0,0.0,0.07186262484115848,0.0,0.0,0.0,115.04,9/12/2022,Chicago SMM Food,128
142
+ 0.0,0.0,0.0,0.0,0.004144971902184347,0.0,0.0,126.47,9/13/2021,Chicago SMM Food,129
143
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2423191278493558,150.534,9/18/2023,Chicago SMM Food,130
144
+ 0.0,0.0,0.0,0.07490942409399909,0.0,0.0,0.0,112.06,9/19/2022,Chicago SMM Food,131
145
+ 0.0,0.0,0.0,0.0,0.004689304878444938,0.0,0.0,105.95,9/20/2021,Chicago SMM Food,132
146
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17443012884043607,140.18,9/25/2023,Chicago SMM Food,133
147
+ 0.0,0.0,0.0,0.0851206890876872,0.0,0.0,0.0,113.37,9/26/2022,Chicago SMM Food,134
148
+ 0.0,0.0,0.0,0.0,0.005144565185862888,0.0,0.0,112.47,9/27/2021,Chicago SMM Food,135
149
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17938553022794845,134.87,9/4/2023,Chicago SMM Food,136
150
+ 0.0,0.0,0.0,0.07518517635856978,0.0,0.0,0.0,128.32,9/5/2022,Chicago SMM Food,137
151
+ 0.0,0.0,0.0,0.0,0.005288071152331588,0.0,0.0,132.52,9/6/2021,Chicago SMM Food,138
152
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1442021803766105,72.288,8/7/2023,Cleveland/Akron/Canton SMM Food,124
153
+ 0.0,0.0,0.0,0.0,0.010643565366495456,0.0,0.0,88.44,8/8/2022,Cleveland/Akron/Canton SMM Food,125
154
+ 0.0,0.0,0.0,0.0,0.005229307933303457,0.0,0.0,81.13,8/9/2021,Cleveland/Akron/Canton SMM Food,126
155
+ 0.0,0.0,0.018360600644668993,0.0,0.0,0.003847068303229848,0.13082259663032705,77.361,9/11/2023,Cleveland/Akron/Canton SMM Food,127
156
+ 0.0,0.0,0.0,0.04319655098784653,0.0,0.0,0.0,83.99,9/12/2022,Cleveland/Akron/Canton SMM Food,128
157
+ 0.0,0.0,0.0,0.0,0.0038678569324516817,0.0,0.0,81.0,9/13/2021,Cleveland/Akron/Canton SMM Food,129
158
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1367690782953419,74.588,9/18/2023,Cleveland/Akron/Canton SMM Food,130
159
+ 0.0,0.0,0.0,0.045027978918762056,0.0,0.0,0.0,68.98,9/19/2022,Cleveland/Akron/Canton SMM Food,131
160
+ 0.0,0.0,0.0,0.0,0.004016929940723048,0.0,0.0,79.08,9/20/2021,Cleveland/Akron/Canton SMM Food,132
161
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1337958374628345,75.304,9/25/2023,Cleveland/Akron/Canton SMM Food,133
162
+ 0.0,0.0,0.0,0.05116595995981537,0.0,0.0,0.0,73.72,9/26/2022,Cleveland/Akron/Canton SMM Food,134
163
+ 0.0,0.0,0.0,0.0,0.003246203931154074,0.0,0.0,72.7,9/27/2021,Cleveland/Akron/Canton SMM Food,135
164
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12983151635282458,85.988,9/4/2023,Cleveland/Akron/Canton SMM Food,136
165
+ 0.0,0.0,0.0,0.04519373333208909,0.0,0.0,0.0,95.79,9/5/2022,Cleveland/Akron/Canton SMM Food,137
166
+ 0.0,0.0,0.0,0.0,0.0032332141669478556,0.0,0.0,84.14,9/6/2021,Cleveland/Akron/Canton SMM Food,138
167
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10555004955401387,54.72,8/7/2023,Columbus OH SMM Food,124
168
+ 0.0,0.0016355875358600512,0.0,0.0,0.010457378746206322,0.0,0.0,58.12,8/8/2022,Columbus OH SMM Food,125
169
+ 0.0,0.0,0.0,0.0,0.003066821473068197,0.0,0.0,54.05,8/9/2021,Columbus OH SMM Food,126
170
+ 0.0,0.0,0.012976309777184706,0.0,0.0,0.09535695517348619,0.09563924677898909,56.575,9/11/2023,Columbus OH SMM Food,127
171
+ 0.0,0.0,0.0,0.026403905702080413,0.0,0.0,0.0,54.07,9/12/2022,Columbus OH SMM Food,128
172
+ 0.0,0.0,0.0,0.0,0.002041867221177515,0.0,0.0,53.22,9/13/2021,Columbus OH SMM Food,129
173
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0931615460852329,59.875,9/18/2023,Columbus OH SMM Food,130
174
+ 0.0,0.0,0.0,0.0275233666153899,0.0,0.0,0.0,51.71,9/19/2022,Columbus OH SMM Food,131
175
+ 0.0,0.0,0.0,0.0,0.0023913537343448264,0.0,0.0,47.83,9/20/2021,Columbus OH SMM Food,132
176
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0753221010901883,61.444,9/25/2023,Columbus OH SMM Food,133
177
+ 0.0,0.0,0.0,0.031275209501753144,0.0,0.0,0.0,56.01,9/26/2022,Columbus OH SMM Food,134
178
+ 0.0,0.0,0.0,0.0,0.0023177450705095877,0.0,0.0,51.58,9/27/2021,Columbus OH SMM Food,135
179
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0817641228939544,60.308,9/4/2023,Columbus OH SMM Food,136
180
+ 0.0,0.0,0.0,0.027624684053467907,0.0,0.0,0.0,61.28,9/5/2022,Columbus OH SMM Food,137
181
+ 0.0,0.0,0.0,0.0,0.0019162995005174012,0.0,0.0,56.04,9/6/2021,Columbus OH SMM Food,138
182
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.22150644202180375,73.064,8/7/2023,Dallas/Ft. Worth SMM Food,124
183
+ 0.0,0.007823266746219531,0.0,0.0,0.02227744561366501,0.0,0.0,55.67,8/8/2022,Dallas/Ft. Worth SMM Food,125
184
+ 0.0,0.0,0.0,0.0,0.00542044303519496,0.0,0.0,58.56,8/9/2021,Dallas/Ft. Worth SMM Food,126
185
+ 0.0,0.0,0.053580445593371474,0.0,0.0,0.2960835671223029,0.20366699702675917,82.586,9/11/2023,Dallas/Ft. Worth SMM Food,127
186
+ 0.0,0.0,0.0,0.055526458478242974,0.0,0.0,0.0,62.13,9/12/2022,Dallas/Ft. Worth SMM Food,128
187
+ 0.0,0.0,0.0,0.0,0.004551365953778902,0.0,0.0,54.28,9/13/2021,Dallas/Ft. Worth SMM Food,129
188
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20862239841427155,77.309,9/18/2023,Dallas/Ft. Worth SMM Food,130
189
+ 0.0,0.0,0.0,0.05788064427948714,0.0,0.0,0.0,58.16,9/19/2022,Dallas/Ft. Worth SMM Food,131
190
+ 0.0,0.0,0.0,0.0,0.005119822777851043,0.0,0.0,55.82,9/20/2021,Dallas/Ft. Worth SMM Food,132
191
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.21258671952428146,75.709,9/25/2023,Dallas/Ft. Worth SMM Food,133
192
+ 0.0,0.0,0.0,0.06577063414997705,0.0,0.0,0.0,62.33,9/26/2022,Dallas/Ft. Worth SMM Food,134
193
+ 0.0,0.0,0.0,0.0,0.003531360183490589,0.0,0.0,56.4,9/27/2021,Dallas/Ft. Worth SMM Food,135
194
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1734390485629336,80.36,9/4/2023,Dallas/Ft. Worth SMM Food,136
195
+ 0.0,0.0,0.0,0.058093711196037776,0.0,0.0,0.0,60.65,9/5/2022,Dallas/Ft. Worth SMM Food,137
196
+ 0.0,0.0,0.0,0.0,0.004822913881708902,0.0,0.0,60.16,9/6/2021,Dallas/Ft. Worth SMM Food,138
197
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06095143706640238,19.057,8/7/2023,Des Moines/Ames SMM Food,124
198
+ 0.0,0.001062279879373701,0.0,0.0,0.002908470061792389,0.0,0.0,21.69,8/8/2022,Des Moines/Ames SMM Food,125
199
+ 0.0,0.0,0.0,0.0,0.0009030978924323453,0.0,0.0,15.48,8/9/2021,Des Moines/Ames SMM Food,126
200
+ 0.0,0.0,0.007034601336350359,0.0,0.0,0.038076904404842446,0.0639246778989098,17.536,9/11/2023,Des Moines/Ames SMM Food,127
201
+ 0.0,0.0,0.0,0.009818746375673355,0.0,0.0,0.0,19.26,9/12/2022,Des Moines/Ames SMM Food,128
202
+ 0.0,0.0,0.0,0.0,0.0007459836015571291,0.0,0.0,16.86,9/13/2021,Des Moines/Ames SMM Food,129
203
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05401387512388503,19.413,9/18/2023,Des Moines/Ames SMM Food,130
204
+ 0.0,0.0,0.0,0.010235037169468615,0.0,0.0,0.0,17.91,9/19/2022,Des Moines/Ames SMM Food,131
205
+ 0.0,0.0,0.0,0.0,0.0005560856200662181,0.0,0.0,16.58,9/20/2021,Des Moines/Ames SMM Food,132
206
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05797819623389494,20.201,9/25/2023,Des Moines/Ames SMM Food,133
207
+ 0.0,0.0,0.0,0.011630224459597573,0.0,0.0,0.0,17.11,9/26/2022,Des Moines/Ames SMM Food,134
208
+ 0.0,0.0,0.0,0.0,0.000921036138240933,0.0,0.0,12.87,9/27/2021,Des Moines/Ames SMM Food,135
209
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04707631318136769,20.614,9/4/2023,Des Moines/Ames SMM Food,136
210
+ 0.0,0.0,0.0,0.010272713801757724,0.0,0.0,0.0,19.45,9/5/2022,Des Moines/Ames SMM Food,137
211
+ 0.0,0.0,0.0,0.0,0.0008585615580110242,0.0,0.0,16.73,9/6/2021,Des Moines/Ames SMM Food,138
212
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14073339940535184,124.957,8/7/2023,Detroit SMM Food,124
213
+ 0.0,0.004029038694198784,0.0,0.0,0.01633679345002101,0.0,0.0,129.16,8/8/2022,Detroit SMM Food,125
214
+ 0.0,0.0,0.0,0.0,0.005138998144060223,0.0,0.0,98.0,8/9/2021,Detroit SMM Food,126
215
+ 0.0,0.0,0.027197842309067383,0.0,0.0,0.16679364832597332,0.1367690782953419,114.674,9/11/2023,Detroit SMM Food,127
216
+ 0.0,0.0,0.0,0.05264923653159416,0.0,0.0,0.0,99.78,9/12/2022,Detroit SMM Food,128
217
+ 0.0,0.0,0.0,0.0,0.003737959290389495,0.0,0.0,105.22,9/13/2021,Detroit SMM Food,129
218
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13478691774033696,132.01,9/18/2023,Detroit SMM Food,130
219
+ 0.0,0.0,0.0,0.05488143517450875,0.0,0.0,0.0,98.35,9/19/2022,Detroit SMM Food,131
220
+ 0.0,0.0,0.0,0.0,0.004616314774809995,0.0,0.0,76.97,9/20/2021,Detroit SMM Food,132
221
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12041625371655104,134.155,9/25/2023,Detroit SMM Food,133
222
+ 0.0,0.0,0.0,0.062362588370685694,0.0,0.0,0.0,111.04,9/26/2022,Detroit SMM Food,134
223
+ 0.0,0.0,0.0,0.0,0.004344766846879995,0.0,0.0,88.84,9/27/2021,Detroit SMM Food,135
224
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11397423191278494,147.194,9/4/2023,Detroit SMM Food,136
225
+ 0.0,0.0,0.0,0.05508346156574187,0.0,0.0,0.0,125.93,9/5/2022,Detroit SMM Food,137
226
+ 0.0,0.0,0.0,0.0,0.00365569078375011,0.0,0.0,109.54,9/6/2021,Detroit SMM Food,138
227
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09365708622398414,71.874,8/7/2023,Grand Rapids SMM Food,124
228
+ 0.0,0.0,0.0,0.0,0.008291799484969583,0.0,0.0,89.36,8/8/2022,Grand Rapids SMM Food,125
229
+ 0.0,0.0,0.0,0.0,0.0016558856561927318,0.0,0.0,60.59,8/9/2021,Grand Rapids SMM Food,126
230
+ 0.0,0.0,0.010334378341344649,0.0,0.0,0.004593258733825526,0.06937561942517344,59.484,9/11/2023,Grand Rapids SMM Food,127
231
+ 0.0,0.0,0.0,0.022162738793584366,0.0,0.0,0.0,51.84,9/12/2022,Grand Rapids SMM Food,128
232
+ 0.0,0.0,0.0,0.0,0.0015989781177654881,0.0,0.0,62.76,9/13/2021,Grand Rapids SMM Food,129
233
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10852329038652131,84.959,9/18/2023,Grand Rapids SMM Food,130
234
+ 0.0,0.0,0.0,0.023102384621302353,0.0,0.0,0.0,53.77,9/19/2022,Grand Rapids SMM Food,131
235
+ 0.0,0.0,0.0,0.0,0.001827226831674759,0.0,0.0,45.22,9/20/2021,Grand Rapids SMM Food,132
236
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08572844400396432,79.122,9/25/2023,Grand Rapids SMM Food,133
237
+ 0.0,0.0,0.0,0.02625158212085696,0.0,0.0,0.0,53.48,9/26/2022,Grand Rapids SMM Food,134
238
+ 0.0,0.0,0.0,0.0,0.0012488730443978803,0.0,0.0,45.61,9/27/2021,Grand Rapids SMM Food,135
239
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06689791873141725,97.272,9/4/2023,Grand Rapids SMM Food,136
240
+ 0.0,0.0,0.0,0.023187427795256017,0.0,0.0,0.0,79.71,9/5/2022,Grand Rapids SMM Food,137
241
+ 0.0,0.0,0.0,0.0,0.001495678564316035,0.0,0.0,69.21,9/6/2021,Grand Rapids SMM Food,138
242
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05847373637264618,34.23,8/7/2023,Greensboro SMM Food,124
243
+ 0.0,0.0,0.0,0.0,0.008662935605147259,0.0,0.0,41.28,8/8/2022,Greensboro SMM Food,125
244
+ 0.0,0.0,0.0,0.0,0.002148878135828745,0.0,0.0,33.05,8/9/2021,Greensboro SMM Food,126
245
+ 0.0,0.0,0.0,0.0,0.0,0.004162733342605559,0.05302279484638256,40.267,9/11/2023,Greensboro SMM Food,127
246
+ 0.0,0.0,0.0,0.01938722492394592,0.0,0.0,0.0,38.46,9/12/2022,Greensboro SMM Food,128
247
+ 0.0,0.0,0.0,0.0,0.0019855782429505676,0.0,0.0,34.42,9/13/2021,Greensboro SMM Food,129
248
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.059960356788899896,39.972,9/18/2023,Greensboro SMM Food,130
249
+ 0.0,0.0,0.0,0.02020919576536063,0.0,0.0,0.0,37.05,9/19/2022,Greensboro SMM Food,131
250
+ 0.0,0.0,0.0,0.0,0.0019132066995159206,0.0,0.0,29.9,9/20/2021,Greensboro SMM Food,132
251
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05698711595639247,58.21,9/25/2023,Greensboro SMM Food,133
252
+ 0.0,0.0,0.0,0.022964008737958168,0.0,0.0,0.0,31.18,9/26/2022,Greensboro SMM Food,134
253
+ 0.0,0.0,0.0,0.0,0.0017647522514448503,0.0,0.0,32.39,9/27/2021,Greensboro SMM Food,135
254
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05004955401387512,28.032,9/4/2023,Greensboro SMM Food,136
255
+ 0.0,0.0,0.0,0.020283588694575232,0.0,0.0,0.0,31.02,9/5/2022,Greensboro SMM Food,137
256
+ 0.0,0.0,0.0,0.0,0.0016861951060072422,0.0,0.0,55.3,9/6/2021,Greensboro SMM Food,138
257
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08622398414271557,34.307,8/7/2023,Harrisburg/Lancaster SMM Food,124
258
+ 0.0,0.00118647246994757,0.0,0.0,0.010951608346242928,0.0,0.0,37.54,8/8/2022,Harrisburg/Lancaster SMM Food,125
259
+ 0.0,0.0,0.0,0.0,0.0027989849063399744,0.0,0.0,31.88,8/9/2021,Harrisburg/Lancaster SMM Food,126
260
+ 0.0,0.0,0.009303514502060626,0.0,0.0,0.05938927543516645,0.06838453914767095,47.335,9/11/2023,Harrisburg/Lancaster SMM Food,127
261
+ 0.0,0.0,0.0,0.01722270730805324,0.0,0.0,0.0,47.54,9/12/2022,Harrisburg/Lancaster SMM Food,128
262
+ 0.0,0.0,0.0,0.0,0.0017567109688410004,0.0,0.0,37.65,9/13/2021,Harrisburg/Lancaster SMM Food,129
263
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06838453914767095,47.204,9/18/2023,Harrisburg/Lancaster SMM Food,130
264
+ 0.0,0.0,0.0,0.017952907903006455,0.0,0.0,0.0,47.12,9/19/2022,Harrisburg/Lancaster SMM Food,131
265
+ 0.0,0.0,0.0,0.0,0.0023622814049309086,0.0,0.0,39.6,9/20/2021,Harrisburg/Lancaster SMM Food,132
266
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06689791873141725,42.773,9/25/2023,Harrisburg/Lancaster SMM Food,133
267
+ 0.0,0.0,0.0,0.02040015539180732,0.0,0.0,0.0,39.34,9/26/2022,Harrisburg/Lancaster SMM Food,134
268
+ 0.0,0.0,0.0,0.0,0.0015365035375355792,0.0,0.0,36.2,9/27/2021,Harrisburg/Lancaster SMM Food,135
269
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06987115956392467,49.172,9/4/2023,Harrisburg/Lancaster SMM Food,136
270
+ 0.0,0.0,0.0,0.018018995117875386,0.0,0.0,0.0,46.11,9/5/2022,Harrisburg/Lancaster SMM Food,137
271
+ 0.0,0.0,0.0,0.0,0.0018253711510738705,0.0,0.0,41.15,9/6/2021,Harrisburg/Lancaster SMM Food,138
272
+ 0.0,0.0018337180408220845,0.0,0.0,0.010148098646058258,0.0,0.0,57.79,8/8/2022,Hartford/New Haven SMM Food,125
273
+ 0.0,0.0,0.0,0.0,0.0037509490545957138,0.0,0.0,69.72,8/9/2021,Hartford/New Haven SMM Food,126
274
+ 0.0,0.0,0.014994996886122389,0.0,0.0,0.08363767112400147,0.0882061446977205,74.813,9/11/2023,Hartford/New Haven SMM Food,127
275
+ 0.0,0.0,0.0,0.025926611998646588,0.0,0.0,0.0,80.45,9/12/2022,Hartford/New Haven SMM Food,128
276
+ 0.0,0.0,0.0,0.0,0.0030495017874599055,0.0,0.0,68.05,9/13/2021,Hartford/New Haven SMM Food,129
277
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10059464816650149,103.87,9/18/2023,Hartford/New Haven SMM Food,130
278
+ 0.0,0.0,0.0,0.027025836833104906,0.0,0.0,0.0,76.63,9/19/2022,Hartford/New Haven SMM Food,131
279
+ 0.0,0.0,0.0,0.0,0.0023901166139442343,0.0,0.0,59.62,9/20/2021,Hartford/New Haven SMM Food,132
280
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08721506442021804,89.9,9/25/2023,Hartford/New Haven SMM Food,133
281
+ 0.0,0.0,0.0,0.030709859033967845,0.0,0.0,0.0,79.63,9/26/2022,Hartford/New Haven SMM Food,134
282
+ 0.0,0.0,0.0,0.0,0.0023709412477350544,0.0,0.0,64.74,9/27/2021,Hartford/New Haven SMM Food,135
283
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09910802775024777,67.473,9/4/2023,Hartford/New Haven SMM Food,136
284
+ 0.0,0.0,0.0,0.027125322790759788,0.0,0.0,0.0,68.92,9/5/2022,Hartford/New Haven SMM Food,137
285
+ 0.0,0.0,0.0,0.0,0.0025515608262215235,0.0,0.0,67.33,9/6/2021,Hartford/New Haven SMM Food,138
286
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1962338949454906,133.105,8/7/2023,Houston SMM Food,124
287
+ 0.0,0.0046540451267612325,0.0,0.0,0.022832912673530933,0.0,0.0,118.76,8/8/2022,Houston SMM Food,125
288
+ 0.0,0.0,0.0,0.0,0.005281885550328628,0.0,0.0,103.5,8/9/2021,Houston SMM Food,126
289
+ 0.0,0.0,0.01913533089801548,0.0,0.0,0.21760885851354209,0.1684836471754212,140.942,9/11/2023,Houston SMM Food,127
290
+ 0.0,0.0,0.0,0.04769953315392536,0.0,0.0,0.0,140.87,9/12/2022,Houston SMM Food,128
291
+ 0.0,0.0,0.0,0.0,0.004650335585826283,0.0,0.0,105.88,9/13/2021,Houston SMM Food,129
292
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1620416253716551,129.531,9/18/2023,Houston SMM Food,130
293
+ 0.0,0.0,0.0,0.049721876494397986,0.0,0.0,0.0,145.85,9/19/2022,Houston SMM Food,131
294
+ 0.0,0.0,0.0,0.0,0.003903114863868561,0.0,0.0,111.54,9/20/2021,Houston SMM Food,132
295
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15510406342913777,135.992,9/25/2023,Houston SMM Food,133
296
+ 0.0,0.0,0.0,0.05649970535943224,0.0,0.0,0.0,150.89,9/26/2022,Houston SMM Food,134
297
+ 0.0,0.0,0.0,0.0,0.003332802359195532,0.0,0.0,100.18,9/27/2021,Houston SMM Food,135
298
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15857284440039643,134.53,9/4/2023,Houston SMM Food,136
299
+ 0.0,0.0,0.0,0.04990490981700915,0.0,0.0,0.0,130.92,9/5/2022,Houston SMM Food,137
300
+ 0.0,0.0,0.0,0.0,0.0032511524127564434,0.0,0.0,108.11,9/6/2021,Houston SMM Food,138
301
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14172447968285432,48.376,8/7/2023,Indianapolis SMM Food,124
302
+ 0.0,0.0024260878158616334,0.0,0.0,0.012808526067531899,0.0,0.0,46.59,8/8/2022,Indianapolis SMM Food,125
303
+ 0.0,0.0,0.0,0.0,0.003151564220508767,0.0,0.0,38.95,8/9/2021,Indianapolis SMM Food,126
304
+ 0.0,0.0,0.016644041455881685,0.0,0.0,0.11700205142709444,0.11446977205153618,49.036,9/11/2023,Indianapolis SMM Food,127
305
+ 0.0,0.0,0.0,0.023691657521331348,0.0,0.0,0.0,35.97,9/12/2022,Indianapolis SMM Food,128
306
+ 0.0,0.0,0.0,0.0,0.0022490848882767175,0.0,0.0,37.35,9/13/2021,Indianapolis SMM Food,129
307
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11645193260654113,51.603,9/18/2023,Indianapolis SMM Food,130
308
+ 0.0,0.0,0.0,0.0246961257538268,0.0,0.0,0.0,38.52,9/19/2022,Indianapolis SMM Food,131
309
+ 0.0,0.0,0.0,0.0,0.0029072329413917966,0.0,0.0,31.83,9/20/2021,Indianapolis SMM Food,132
310
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10009910802775024,53.418,9/25/2023,Indianapolis SMM Food,133
311
+ 0.0,0.0,0.0,0.028062573805723218,0.0,0.0,0.0,39.19,9/26/2022,Indianapolis SMM Food,134
312
+ 0.0,0.0,0.0,0.0,0.002647437657267423,0.0,0.0,31.38,9/27/2021,Indianapolis SMM Food,135
313
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10505450941526263,55.713,9/4/2023,Indianapolis SMM Food,136
314
+ 0.0,0.0,0.0,0.024787035718660904,0.0,0.0,0.0,46.84,9/5/2022,Indianapolis SMM Food,137
315
+ 0.0,0.0,0.0,0.0,0.0030024912122374,0.0,0.0,37.3,9/6/2021,Indianapolis SMM Food,138
316
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07383548067393458,96.535,8/7/2023,Jacksonville SMM Food,124
317
+ 0.0,0.0008658822942801401,0.0,0.0,0.007301484604295482,0.0,0.0,62.66,8/8/2022,Jacksonville SMM Food,125
318
+ 0.0,0.0,0.0,0.0,0.0019435161493304308,0.0,0.0,34.35,8/9/2021,Jacksonville SMM Food,126
319
+ 0.0,0.0,0.0069561155917302895,0.0,0.0,0.08053507618258654,0.059960356788899896,27.967,9/11/2023,Jacksonville SMM Food,127
320
+ 0.0,0.0,0.0,0.02082072414146757,0.0,0.0,0.0,27.95,9/12/2022,Jacksonville SMM Food,128
321
+ 0.0,0.0,0.0,0.0,0.0015767099505548275,0.0,0.0,32.77,9/13/2021,Jacksonville SMM Food,129
322
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06491575817641229,29.339,9/18/2023,Jacksonville SMM Food,130
323
+ 0.0,0.0,0.0,0.02170347183093534,0.0,0.0,0.0,26.19,9/19/2022,Jacksonville SMM Food,131
324
+ 0.0,0.0,0.0,0.0,0.001496297124516331,0.0,0.0,28.8,9/20/2021,Jacksonville SMM Food,132
325
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.049554013875123884,28.801,9/25/2023,Jacksonville SMM Food,133
326
+ 0.0,0.0,0.0,0.024661976783877985,0.0,0.0,0.0,25.24,9/26/2022,Jacksonville SMM Food,134
327
+ 0.0,0.0,0.0,0.0,0.0016119678819717068,0.0,0.0,25.69,9/27/2021,Jacksonville SMM Food,135
328
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07433102081268583,51.144,9/4/2023,Jacksonville SMM Food,136
329
+ 0.0,0.0,0.0,0.02178336541288693,0.0,0.0,0.0,43.45,9/5/2022,Jacksonville SMM Food,137
330
+ 0.0,0.0,0.0,0.0,0.0012927908186189051,0.0,0.0,31.77,9/6/2021,Jacksonville SMM Food,138
331
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11248761149653122,29.172,8/7/2023,Kansas City SMM Food,124
332
+ 0.0,0.0018331404008659269,0.0,0.0,0.0055076600234367145,0.0,0.0,35.15,8/8/2022,Kansas City SMM Food,125
333
+ 0.0,0.0,0.0,0.0,0.0016793909438039844,0.0,0.0,32.17,8/9/2021,Kansas City SMM Food,126
334
+ 0.0,0.0,0.0,0.0,0.0,0.08131822285155027,0.11050545094152626,33.379,9/11/2023,Kansas City SMM Food,127
335
+ 0.0,0.0,0.0,0.020919710852413544,0.0,0.0,0.0,31.54,9/12/2022,Kansas City SMM Food,128
336
+ 0.0,0.0,0.0,0.0,0.00130639914302542,0.0,0.0,35.16,9/13/2021,Kansas City SMM Food,129
337
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10555004955401387,30.958,9/18/2023,Kansas City SMM Food,130
338
+ 0.0,0.0,0.0,0.021806655337224045,0.0,0.0,0.0,30.39,9/19/2022,Kansas City SMM Food,131
339
+ 0.0,0.0,0.0,0.0,0.0012995949808221627,0.0,0.0,33.17,9/20/2021,Kansas City SMM Food,132
340
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10009910802775024,32.027,9/25/2023,Kansas City SMM Food,133
341
+ 0.0,0.0,0.0,0.024779225733846975,0.0,0.0,0.0,30.72,9/26/2022,Kansas City SMM Food,134
342
+ 0.0,0.0,0.0,0.0,0.0017282571996273786,0.0,0.0,30.48,9/27/2021,Kansas City SMM Food,135
343
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0882061446977205,31.622,9/4/2023,Kansas City SMM Food,136
344
+ 0.0,0.0,0.0,0.021886928747765332,0.0,0.0,0.0,33.43,9/5/2022,Kansas City SMM Food,137
345
+ 0.0,0.0,0.0,0.0,0.0012779453738117983,0.0,0.0,34.17,9/6/2021,Kansas City SMM Food,138
346
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.059960356788899896,28.985,8/7/2023,Knoxville SMM Food,124
347
+ 0.0,0.0009172922503781605,0.0,0.0,0.004641057182821841,0.0,0.0,24.48,8/8/2022,Knoxville SMM Food,125
348
+ 0.0,0.0,0.0,0.0,0.00217362054384059,0.0,0.0,22.62,8/9/2021,Knoxville SMM Food,126
349
+ 0.0,0.0,0.007657423696883808,0.0,0.0,0.05601546016597905,0.06095143706640238,34.993,9/11/2023,Knoxville SMM Food,127
350
+ 0.0,0.0,0.0,0.012082336514998791,0.0,0.0,0.0,21.57,9/12/2022,Knoxville SMM Food,128
351
+ 0.0,0.0,0.0,0.0,0.0016899064672090188,0.0,0.0,22.64,9/13/2021,Knoxville SMM Food,129
352
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05153617443012884,23.653,9/18/2023,Knoxville SMM Food,130
353
+ 0.0,0.0,0.0,0.012594597987226747,0.0,0.0,0.0,25.34,9/19/2022,Knoxville SMM Food,131
354
+ 0.0,0.0,0.0,0.0,0.0013614510008517755,0.0,0.0,23.4,9/20/2021,Knoxville SMM Food,132
355
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.055996035678889985,23.93,9/25/2023,Knoxville SMM Food,133
356
+ 0.0,0.0,0.0,0.014311428395501457,0.0,0.0,0.0,26.36,9/26/2022,Knoxville SMM Food,134
357
+ 0.0,0.0,0.0,0.0,0.0009154690964382679,0.0,0.0,25.75,9/27/2021,Knoxville SMM Food,135
358
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05302279484638256,27.206,9/4/2023,Knoxville SMM Food,136
359
+ 0.0,0.0,0.0,0.01264096049426039,0.0,0.0,0.0,23.09,9/5/2022,Knoxville SMM Food,137
360
+ 0.0,0.0,0.0,0.0,0.0013441313152434838,0.0,0.0,25.4,9/6/2021,Knoxville SMM Food,138
361
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05946481665014866,31.532,8/7/2023,Las Vegas SMM Food,124
362
+ 0.0,0.002099721240632628,0.0,0.0,0.003961259522696397,0.0,0.0,24.92,8/8/2022,Las Vegas SMM Food,125
363
+ 0.0,0.0,0.0,0.0,0.0010515523405034157,0.0,0.0,17.85,8/9/2021,Las Vegas SMM Food,126
364
+ 0.0,0.0,0.009369763221981868,0.0,0.0,0.08034252733962806,0.035678889990089196,34.959,9/11/2023,Las Vegas SMM Food,127
365
+ 0.0,0.0,0.0,0.0185917027305958,0.0,0.0,0.0,28.18,9/12/2022,Las Vegas SMM Food,128
366
+ 0.0,0.0,0.0,0.0,0.0012927908186189051,0.0,0.0,24.83,9/13/2021,Las Vegas SMM Food,129
367
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.048562933597621406,33.115,9/18/2023,Las Vegas SMM Food,130
368
+ 0.0,0.0,0.0,0.019379945382538788,0.0,0.0,0.0,26.13,9/19/2022,Las Vegas SMM Food,131
369
+ 0.0,0.0,0.0,0.0,0.001155470454153165,0.0,0.0,24.17,9/20/2021,Las Vegas SMM Food,132
370
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05302279484638256,30.334,9/25/2023,Las Vegas SMM Food,133
371
+ 0.0,0.0,0.0,0.022021719233974155,0.0,0.0,0.0,25.26,9/26/2022,Las Vegas SMM Food,134
372
+ 0.0,0.0,0.0,0.0,0.0013317601112375612,0.0,0.0,24.46,9/27/2021,Las Vegas SMM Food,135
373
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04707631318136769,30.934,9/4/2023,Las Vegas SMM Food,136
374
+ 0.0,0.0,0.0,0.019451285727142276,0.0,0.0,0.0,26.34,9/5/2022,Las Vegas SMM Food,137
375
+ 0.0,0.0,0.0,0.0,0.0016472258133885859,0.0,0.0,23.98,9/6/2021,Las Vegas SMM Food,138
376
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0639246778989098,10.063,8/7/2023,Little Rock/Pine Bluff SMM Food,124
377
+ 0.0,0.0014186837323228979,0.0,0.0,0.006373025743650996,0.0,0.0,8.89,8/8/2022,Little Rock/Pine Bluff SMM Food,125
378
+ 0.0,0.0,0.0,0.0,0.001933619186125693,0.0,0.0,10.01,8/9/2021,Little Rock/Pine Bluff SMM Food,126
379
+ 0.0,0.0,0.0067615890956558185,0.0,0.0,0.04907078091276023,0.055004955401387515,10.863,9/11/2023,Little Rock/Pine Bluff SMM Food,127
380
+ 0.0,0.0,0.0,0.015617921237149364,0.0,0.0,0.0,9.69,9/12/2022,Little Rock/Pine Bluff SMM Food,128
381
+ 0.0,0.0,0.0,0.0,0.0014356782248873107,0.0,0.0,11.67,9/13/2021,Little Rock/Pine Bluff SMM Food,129
382
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.062438057482656094,9.718,9/18/2023,Little Rock/Pine Bluff SMM Food,130
383
+ 0.0,0.0,0.0,0.01628008283607892,0.0,0.0,0.0,10.38,9/19/2022,Little Rock/Pine Bluff SMM Food,131
384
+ 0.0,0.0,0.0,0.0,0.0015482561813412057,0.0,0.0,9.39,9/20/2021,Little Rock/Pine Bluff SMM Food,132
385
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05252725470763132,9.803,9/25/2023,Little Rock/Pine Bluff SMM Food,133
386
+ 0.0,0.0,0.0,0.018499299465241616,0.0,0.0,0.0,9.19,9/26/2022,Little Rock/Pine Bluff SMM Food,134
387
+ 0.0,0.0,0.0,0.0,0.0015946481963634153,0.0,0.0,9.27,9/27/2021,Little Rock/Pine Bluff SMM Food,135
388
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04013875123885034,11.034,9/4/2023,Little Rock/Pine Bluff SMM Food,136
389
+ 0.0,0.0,0.0,0.016340012143976613,0.0,0.0,0.0,9.59,9/5/2022,Little Rock/Pine Bluff SMM Food,137
390
+ 0.0,0.0,0.0,0.0,0.0017777420156510687,0.0,0.0,11.85,9/6/2021,Little Rock/Pine Bluff SMM Food,138
391
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3062438057482656,114.624,8/7/2023,Los Angeles SMM Food,124
392
+ 0.0,0.019228478860571916,0.0,0.0,0.03378946950137623,0.0,0.0,106.07,8/8/2022,Los Angeles SMM Food,125
393
+ 0.0,0.0,0.0,0.0,0.010010778281592518,0.0,0.0,93.99,8/9/2021,Los Angeles SMM Food,126
394
+ 0.0,0.0,0.13303797876107476,0.0,0.0,0.3747884838535892,0.2522299306243806,131.228,9/11/2023,Los Angeles SMM Food,127
395
+ 0.0,0.0,0.0,0.10969678061239888,0.0,0.0,0.0,115.82,9/12/2022,Los Angeles SMM Food,128
396
+ 0.0,0.0,0.0,0.0,0.009888921922134182,0.0,0.0,119.97,9/13/2021,Los Angeles SMM Food,129
397
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.24727452923686818,119.603,9/18/2023,Los Angeles SMM Food,130
398
+ 0.0,0.0,0.0,0.11434765534026742,0.0,0.0,0.0,109.13,9/19/2022,Los Angeles SMM Food,131
399
+ 0.0,0.0,0.0,0.0,0.00820272681612694,0.0,0.0,99.09,9/20/2021,Los Angeles SMM Food,132
400
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.25966303270564917,114.482,9/25/2023,Los Angeles SMM Food,133
401
+ 0.0,0.0,0.0,0.12993493592533384,0.0,0.0,0.0,115.06,9/26/2022,Los Angeles SMM Food,134
402
+ 0.0,0.0,0.0,0.0,0.00794355009220286,0.0,0.0,98.9,9/27/2021,Los Angeles SMM Food,135
403
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2477700693756194,135.601,9/4/2023,Los Angeles SMM Food,136
404
+ 0.0,0.0,0.0,0.11476858539692965,0.0,0.0,0.0,107.08,9/5/2022,Los Angeles SMM Food,137
405
+ 0.0,0.0,0.0,0.0,0.008441491053441243,0.0,0.0,109.3,9/6/2021,Los Angeles SMM Food,138
406
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.049554013875123884,5.978,8/7/2023,Madison WI SMM Food,124
407
+ 0.0,0.000593236234973785,0.0,0.0,0.0031558941419108397,0.0,0.0,5.08,8/8/2022,Madison WI SMM Food,125
408
+ 0.0,0.0,0.0,0.0,0.0008400047520021403,0.0,0.0,5.58,8/9/2021,Madison WI SMM Food,126
409
+ 0.0,0.0,0.004571583640934544,0.0,0.0,0.034073713711936085,0.037165510406342916,7.98,9/11/2023,Madison WI SMM Food,127
410
+ 0.0,0.0,0.0,0.00930365997973997,0.0,0.0,0.0,6.03,9/12/2022,Madison WI SMM Food,128
411
+ 0.0,0.0,0.0,0.0,0.0004911367990351248,0.0,0.0,8.3,9/13/2021,Madison WI SMM Food,129
412
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.044598612487611496,7.618,9/18/2023,Madison WI SMM Food,130
413
+ 0.0,0.0,0.0,0.009698112368307879,0.0,0.0,0.0,6.79,9/19/2022,Madison WI SMM Food,131
414
+ 0.0,0.0,0.0,0.0,0.0004218580566019586,0.0,0.0,5.87,9/20/2021,Madison WI SMM Food,132
415
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.03815659068384539,7.501,9/25/2023,Madison WI SMM Food,133
416
+ 0.0,0.0,0.0,0.011020108853925868,0.0,0.0,0.0,6.51,9/26/2022,Madison WI SMM Food,134
417
+ 0.0,0.0,0.0,0.0,0.0006612408541165596,0.0,0.0,5.48,9/27/2021,Madison WI SMM Food,135
418
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04509415262636274,8.164,9/4/2023,Madison WI SMM Food,136
419
+ 0.0,0.0,0.0,0.009733812499659315,0.0,0.0,0.0,5.28,9/5/2022,Madison WI SMM Food,137
420
+ 0.0,0.0,0.0,0.0,0.00041381677399810894,0.0,0.0,5.27,9/6/2021,Madison WI SMM Food,138
421
+ 0.0,0.005007849599907721,0.0,0.0,0.011139032086932654,0.0,0.0,265.02,8/8/2022,Miami/West Palm Beach SMM Food,125
422
+ 0.0,0.0,0.0,0.0,0.0028466140417627763,0.0,0.0,109.22,8/9/2021,Miami/West Palm Beach SMM Food,126
423
+ 0.0,0.0,0.018040328170654842,0.0,0.0,0.135383570276492,0.0867195242814668,117.213,9/11/2023,Miami/West Palm Beach SMM Food,127
424
+ 0.0,0.0,0.0,0.040042460444501625,0.0,0.0,0.0,103.86,9/12/2022,Miami/West Palm Beach SMM Food,128
425
+ 0.0,0.0,0.0,0.0,0.0025509422660212277,0.0,0.0,106.45,9/13/2021,Miami/West Palm Beach SMM Food,129
426
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08225966303270565,115.904,9/18/2023,Miami/West Palm Beach SMM Food,130
427
+ 0.0,0.0,0.0,0.04174016266482536,0.0,0.0,0.0,95.09,9/19/2022,Miami/West Palm Beach SMM Food,131
428
+ 0.0,0.0,0.0,0.0,0.002568261951629519,0.0,0.0,104.62,9/20/2021,Miami/West Palm Beach SMM Food,132
429
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07036669970267592,103.499,9/25/2023,Miami/West Palm Beach SMM Food,133
430
+ 0.0,0.0,0.0,0.04742996560650661,0.0,0.0,0.0,111.66,9/26/2022,Miami/West Palm Beach SMM Food,134
431
+ 0.0,0.0,0.0,0.0,0.0022886727410956695,0.0,0.0,102.39,9/27/2021,Miami/West Palm Beach SMM Food,135
432
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10158572844400396,146.302,9/4/2023,Miami/West Palm Beach SMM Food,136
433
+ 0.0,0.0,0.0,0.04189381415960767,0.0,0.0,0.0,147.87,9/5/2022,Miami/West Palm Beach SMM Food,137
434
+ 0.0,0.0,0.0,0.0,0.0027909436237361245,0.0,0.0,104.06,9/6/2021,Miami/West Palm Beach SMM Food,138
435
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0931615460852329,24.866,8/7/2023,Milwaukee SMM Food,124
436
+ 0.0,0.001717034769678263,0.0,0.0,0.009219639785413772,0.0,0.0,23.28,8/8/2022,Milwaukee SMM Food,125
437
+ 0.0,0.0,0.0,0.0,0.0018352681142786086,0.0,0.0,19.3,8/9/2021,Milwaukee SMM Food,126
438
+ 0.0,0.0,0.01275815316445043,0.0,0.0,0.08156726192538118,0.062438057482656094,25.297,9/11/2023,Milwaukee SMM Food,127
439
+ 0.0,0.0,0.0,0.021252502340492276,0.0,0.0,0.0,18.62,9/12/2022,Milwaukee SMM Food,128
440
+ 0.0,0.0,0.0,0.0,0.0014635134339006364,0.0,0.0,20.78,9/13/2021,Milwaukee SMM Food,129
441
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06689791873141725,28.503,9/18/2023,Milwaukee SMM Food,130
442
+ 0.0,0.0,0.0,0.02215355637305754,0.0,0.0,0.0,20.56,9/19/2022,Milwaukee SMM Food,131
443
+ 0.0,0.0,0.0,0.0,0.001509905448922846,0.0,0.0,18.05,9/20/2021,Milwaukee SMM Food,132
444
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08275520317145689,24.272,9/25/2023,Milwaukee SMM Food,133
445
+ 0.0,0.0,0.0,0.02517341451994022,0.0,0.0,0.0,19.51,9/26/2022,Milwaukee SMM Food,134
446
+ 0.0,0.0,0.0,0.0,0.0013719665242568095,0.0,0.0,20.33,9/27/2021,Milwaukee SMM Food,135
447
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07284440039643211,28.938,9/4/2023,Milwaukee SMM Food,136
448
+ 0.0,0.0,0.0,0.02223510677772291,0.0,0.0,0.0,25.25,9/5/2022,Milwaukee SMM Food,137
449
+ 0.0,0.0,0.0,0.0,0.001925577903521843,0.0,0.0,24.08,9/6/2021,Milwaukee SMM Food,138
450
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1709613478691774,37.06,8/7/2023,Minneapolis/St. Paul SMM Food,124
451
+ 0.0,0.0038046255712315823,0.0,0.0,0.00971510650585097,0.0,0.0,46.84,8/8/2022,Minneapolis/St. Paul SMM Food,125
452
+ 0.0,0.0,0.0,0.0,0.002077125152594394,0.0,0.0,41.5,8/9/2021,Minneapolis/St. Paul SMM Food,126
453
+ 0.0,0.0,0.03094870136244261,0.0,0.0,0.1252957809638225,0.17393458870168482,38.324,9/11/2023,Minneapolis/St. Paul SMM Food,127
454
+ 0.0,0.0,0.0,0.038681592342424166,0.0,0.0,0.0,51.68,9/12/2022,Minneapolis/St. Paul SMM Food,128
455
+ 0.0,0.0,0.0,0.0,0.001091758753522664,0.0,0.0,45.98,9/13/2021,Minneapolis/St. Paul SMM Food,129
456
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1570862239841427,40.978,9/18/2023,Minneapolis/St. Paul SMM Food,130
457
+ 0.0,0.0,0.0,0.0403215970895781,0.0,0.0,0.0,40.48,9/19/2022,Minneapolis/St. Paul SMM Food,131
458
+ 0.0,0.0,0.0,0.0,0.002432178707564371,0.0,0.0,49.56,9/20/2021,Minneapolis/St. Paul SMM Food,132
459
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15262636273538155,38.141,9/25/2023,Minneapolis/St. Paul SMM Food,133
460
+ 0.0,0.0,0.0,0.04581802852379454,0.0,0.0,0.0,38.38,9/26/2022,Minneapolis/St. Paul SMM Food,134
461
+ 0.0,0.0,0.0,0.0,0.0014257812616825726,0.0,0.0,47.81,9/27/2021,Minneapolis/St. Paul SMM Food,135
462
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1645193260654113,40.776,9/4/2023,Minneapolis/St. Paul SMM Food,136
463
+ 0.0,0.0,0.0,0.04047002664468756,0.0,0.0,0.0,44.99,9/5/2022,Minneapolis/St. Paul SMM Food,137
464
+ 0.0,0.0,0.0,0.0,0.0022967140236995194,0.0,0.0,43.4,9/6/2021,Minneapolis/St. Paul SMM Food,138
465
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06194251734390485,48.944,8/7/2023,Mobile/Pensacola SMM Food,124
466
+ 0.0,0.0007766369210538014,0.0,0.0,0.006063745643502932,0.0,0.0,31.02,8/8/2022,Mobile/Pensacola SMM Food,125
467
+ 0.0,0.0,0.0,0.0,0.0015507304221423902,0.0,0.0,18.44,8/9/2021,Mobile/Pensacola SMM Food,126
468
+ 0.0,0.0,0.007016034816117654,0.0,0.0,0.06153590867568924,0.05153617443012884,18.764,9/11/2023,Mobile/Pensacola SMM Food,127
469
+ 0.0,0.0,0.0,0.016447031490323782,0.0,0.0,0.0,17.84,9/12/2022,Mobile/Pensacola SMM Food,128
470
+ 0.0,0.0,0.0,0.0,0.001671349661200135,0.0,0.0,18.48,9/13/2021,Mobile/Pensacola SMM Food,129
471
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05054509415262636,17.263,9/18/2023,Mobile/Pensacola SMM Food,130
472
+ 0.0,0.0,0.0,0.01714434533067197,0.0,0.0,0.0,15.41,9/19/2022,Mobile/Pensacola SMM Food,131
473
+ 0.0,0.0,0.0,0.0,0.0012228935159854428,0.0,0.0,17.3,9/20/2021,Mobile/Pensacola SMM Food,132
474
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.030723488602576808,16.84,9/25/2023,Mobile/Pensacola SMM Food,133
475
+ 0.0,0.0,0.0,0.019481373757693706,0.0,0.0,0.0,14.96,9/26/2022,Mobile/Pensacola SMM Food,134
476
+ 0.0,0.0,0.0,0.0,0.0012754711330106138,0.0,0.0,15.57,9/27/2021,Mobile/Pensacola SMM Food,135
477
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.053518334985133795,21.946,9/4/2023,Mobile/Pensacola SMM Food,136
478
+ 0.0,0.0,0.0,0.017207456111133626,0.0,0.0,0.0,23.31,9/5/2022,Mobile/Pensacola SMM Food,137
479
+ 0.0,0.0,0.0,0.0,0.0013367085928399302,0.0,0.0,17.9,9/6/2021,Mobile/Pensacola SMM Food,138
480
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08572844400396432,77.43,8/7/2023,Nashville SMM Food,124
481
+ 0.0,0.0024515039739325646,0.0,0.0,0.011818829747058097,0.0,0.0,56.6,8/8/2022,Nashville SMM Food,125
482
+ 0.0,0.0,0.0,0.0,0.002948676474811637,0.0,0.0,41.75,8/9/2021,Nashville SMM Food,126
483
+ 0.0,0.0,0.018863584556427716,0.0,0.0,0.1291559227775106,0.09613478691774033,54.687,9/11/2023,Nashville SMM Food,127
484
+ 0.0,0.0,0.0,0.023131705316610268,0.0,0.0,0.0,43.39,9/12/2022,Nashville SMM Food,128
485
+ 0.0,0.0,0.0,0.0,0.0023907351741445306,0.0,0.0,39.43,9/13/2021,Nashville SMM Food,129
486
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10951437066402378,55.368,9/18/2023,Nashville SMM Food,130
487
+ 0.0,0.0,0.0,0.02411243295492175,0.0,0.0,0.0,41.52,9/19/2022,Nashville SMM Food,131
488
+ 0.0,0.0,0.0,0.0,0.0027346546455091774,0.0,0.0,42.92,9/20/2021,Nashville SMM Food,132
489
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09217046580773042,58.347,9/25/2023,Nashville SMM Food,133
490
+ 0.0,0.0,0.0,0.0273993150200572,0.0,0.0,0.0,48.74,9/26/2022,Nashville SMM Food,134
491
+ 0.0,0.0,0.0,0.0,0.0031305331736986982,0.0,0.0,43.99,9/27/2021,Nashville SMM Food,135
492
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08225966303270565,54.91,9/4/2023,Nashville SMM Food,136
493
+ 0.0,0.0,0.0,0.024201194256313775,0.0,0.0,0.0,43.7,9/5/2022,Nashville SMM Food,137
494
+ 0.0,0.0,0.0,0.0,0.002930119668802753,0.0,0.0,44.1,9/6/2021,Nashville SMM Food,138
495
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05004955401387512,10.449,8/7/2023,New Orleans SMM Food,124
496
+ 0.0,0.0011893606697283578,0.0,0.0,0.006126220223732841,0.0,0.0,13.23,8/8/2022,New Orleans SMM Food,125
497
+ 0.0,0.0,0.0,0.0,0.0021148573248124577,0.0,0.0,14.12,8/9/2021,New Orleans SMM Food,126
498
+ 0.0,0.0,0.007795828665891241,0.0,0.0,0.0697753770970809,0.040634291377601585,12.088,9/11/2023,New Orleans SMM Food,127
499
+ 0.0,0.0,0.0,0.01804932909865379,0.0,0.0,0.0,9.64,9/12/2022,New Orleans SMM Food,128
500
+ 0.0,0.0,0.0,0.0,0.0012334090393904772,0.0,0.0,24.18,9/13/2021,New Orleans SMM Food,129
501
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05698711595639247,10.331,9/18/2023,New Orleans SMM Food,130
502
+ 0.0,0.0,0.0,0.01881457643298289,0.0,0.0,0.0,9.9,9/19/2022,New Orleans SMM Food,131
503
+ 0.0,0.0,0.0,0.0,0.001212996552780705,0.0,0.0,34.03,9/20/2021,New Orleans SMM Food,132
504
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04162537165510406,11.492,9/25/2023,New Orleans SMM Food,133
505
+ 0.0,0.0,0.0,0.02137928211724966,0.0,0.0,0.0,8.96,9/26/2022,New Orleans SMM Food,134
506
+ 0.0,0.0,0.0,0.0,0.0007688703289680858,0.0,0.0,17.31,9/27/2021,New Orleans SMM Food,135
507
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04162537165510406,18.667,9/4/2023,New Orleans SMM Food,136
508
+ 0.0,0.0,0.0,0.018883835570947957,0.0,0.0,0.0,19.88,9/5/2022,New Orleans SMM Food,137
509
+ 0.0,0.0,0.0,0.0,0.001574235709753643,0.0,0.0,7.57,9/6/2021,New Orleans SMM Food,138
510
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4534192269573835,246.856,8/7/2023,New York SMM Food,124
511
+ 0.0,0.039101892732193715,0.0,0.0,0.0494452281708712,0.0,0.0,205.05,8/8/2022,New York SMM Food,125
512
+ 0.0,0.0,0.0,0.0,0.015521531106030714,0.0,0.0,234.8,8/9/2021,New York SMM Food,126
513
+ 0.0,0.0,0.24068159947386805,0.0,0.0,0.520680218910273,0.410802775024777,288.514,9/11/2023,New York SMM Food,127
514
+ 0.0,0.0,0.0,0.17120571402939075,0.0,0.0,0.0,254.52,9/12/2022,New York SMM Food,128
515
+ 0.0,0.0,0.0,0.0,0.013122136089082036,0.0,0.0,230.57,9/13/2021,New York SMM Food,129
516
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.41873141724479684,509.862,9/18/2023,New York SMM Food,130
517
+ 0.0,0.0,0.0,0.1784644168917692,0.0,0.0,0.0,247.62,9/19/2022,New York SMM Food,131
518
+ 0.0,0.0,0.0,0.0,0.012023573173356115,0.0,0.0,230.26,9/20/2021,New York SMM Food,132
519
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.42913776015857286,303.344,9/25/2023,New York SMM Food,133
520
+ 0.0,0.0,0.0,0.20279176256454842,0.0,0.0,0.0,260.65,9/26/2022,New York SMM Food,134
521
+ 0.0,0.0,0.0,0.0,0.011220682033371742,0.0,0.0,237.2,9/27/2021,New York SMM Food,135
522
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4474727452923687,274.76,9/4/2023,New York SMM Food,136
523
+ 0.0,0.0,0.0,0.17912136984330115,0.0,0.0,0.0,223.46,9/5/2022,New York SMM Food,137
524
+ 0.0,0.0,0.0,0.0,0.01324461100874067,0.0,0.0,236.95,9/6/2021,New York SMM Food,138
525
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07482656095143707,53.749,8/7/2023,Norfolk/Portsmouth/Newport News SMM Food,124
526
+ 0.0,0.0011087798958443822,0.0,0.0,0.008415511525028807,0.0,0.0,62.84,8/8/2022,Norfolk/Portsmouth/Newport News SMM Food,125
527
+ 0.0,0.0,0.0,0.0,0.00208578499539854,0.0,0.0,53.72,8/9/2021,Norfolk/Portsmouth/Newport News SMM Food,126
528
+ 0.0,0.0,0.010047019244106654,0.0,0.0,0.08559141854246288,0.062438057482656094,66.739,9/11/2023,Norfolk/Portsmouth/Newport News SMM Food,127
529
+ 0.0,0.0,0.0,0.015531940702298817,0.0,0.0,0.0,56.23,9/12/2022,Norfolk/Portsmouth/Newport News SMM Food,128
530
+ 0.0,0.0,0.0,0.0,0.0010960886749247368,0.0,0.0,57.58,9/13/2021,Norfolk/Portsmouth/Newport News SMM Food,129
531
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06045589692765114,57.374,9/18/2023,Norfolk/Portsmouth/Newport News SMM Food,130
532
+ 0.0,0.0,0.0,0.016190456939540337,0.0,0.0,0.0,55.17,9/19/2022,Norfolk/Portsmouth/Newport News SMM Food,131
533
+ 0.0,0.0,0.0,0.0,0.0014499051094941215,0.0,0.0,47.98,9/20/2021,Norfolk/Portsmouth/Newport News SMM Food,132
534
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06442021803766104,71.472,9/25/2023,Norfolk/Portsmouth/Newport News SMM Food,133
535
+ 0.0,0.0,0.0,0.01839745623572133,0.0,0.0,0.0,47.55,9/26/2022,Norfolk/Portsmouth/Newport News SMM Food,134
536
+ 0.0,0.0,0.0,0.0,0.0011863984641679714,0.0,0.0,51.74,9/27/2021,Norfolk/Portsmouth/Newport News SMM Food,135
537
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05797819623389494,49.663,9/4/2023,Norfolk/Portsmouth/Newport News SMM Food,136
538
+ 0.0,0.0,0.0,0.01625005632294706,0.0,0.0,0.0,49.62,9/5/2022,Norfolk/Portsmouth/Newport News SMM Food,137
539
+ 0.0,0.0,0.0,0.0,0.0014202142198799074,0.0,0.0,80.86,9/6/2021,Norfolk/Portsmouth/Newport News SMM Food,138
540
+ 0.0,0.0012719631834588849,0.0,0.0,0.004641057182821841,0.0,0.0,2.43,8/8/2022,Oklahoma City SMM Food,125
541
+ 0.0,0.0,0.0,0.0,0.001920629421919474,0.0,0.0,2.79,8/9/2021,Oklahoma City SMM Food,126
542
+ 0.0,0.0,0.008075170402119658,0.0,0.0,0.05973936106606689,0.0639246778989098,5.321,9/11/2023,Oklahoma City SMM Food,127
543
+ 0.0,0.0,0.0,0.017613566913413724,0.0,0.0,0.0,4.4,9/12/2022,Oklahoma City SMM Food,128
544
+ 0.0,0.0,0.0,0.0,0.0016657826193974697,0.0,0.0,5.31,9/13/2021,Oklahoma City SMM Food,129
545
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06739345887016848,4.506,9/18/2023,Oklahoma City SMM Food,130
546
+ 0.0,0.0,0.0,0.01836033899387075,0.0,0.0,0.0,3.98,9/19/2022,Oklahoma City SMM Food,131
547
+ 0.0,0.0,0.0,0.0,0.0015340292967343948,0.0,0.0,3.66,9/20/2021,Oklahoma City SMM Food,132
548
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06095143706640238,6.145,9/25/2023,Oklahoma City SMM Food,133
549
+ 0.0,0.0,0.0,0.02086312538457761,0.0,0.0,0.0,3.72,9/26/2022,Oklahoma City SMM Food,134
550
+ 0.0,0.0,0.0,0.0,0.0010830989107185184,0.0,0.0,4.46,9/27/2021,Oklahoma City SMM Food,135
551
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06541129831516353,8.982,9/4/2023,Oklahoma City SMM Food,136
552
+ 0.0,0.0,0.0,0.018427926025991807,0.0,0.0,0.0,2.67,9/5/2022,Oklahoma City SMM Food,137
553
+ 0.0,0.0,0.0,0.0,0.002021454734567743,0.0,0.0,2.99,9/6/2021,Oklahoma City SMM Food,138
554
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04311199207135778,12.325,8/7/2023,Omaha SMM Food,124
555
+ 0.0,0.0009476183480764309,0.0,0.0,0.003898166382266192,0.0,0.0,15.49,8/8/2022,Omaha SMM Food,125
556
+ 0.0,0.0,0.0,0.0,0.000536291693656742,0.0,0.0,12.09,8/9/2021,Omaha SMM Food,126
557
+ 0.0,0.0,0.00745909950348901,0.0,0.0,0.04438741589312105,0.049554013875123884,13.324,9/11/2023,Omaha SMM Food,127
558
+ 0.0,0.0,0.0,0.009233480542505387,0.0,0.0,0.0,11.97,9/12/2022,Omaha SMM Food,128
559
+ 0.0,0.0,0.0,0.0,0.0005041265632413435,0.0,0.0,13.54,9/13/2021,Omaha SMM Food,129
560
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06045589692765114,12.73,9/18/2023,Omaha SMM Food,130
561
+ 0.0,0.0,0.0,0.0096249574987297,0.0,0.0,0.0,11.64,9/19/2022,Omaha SMM Food,131
562
+ 0.0,0.0,0.0,0.0,0.0006804162203257396,0.0,0.0,14.6,9/20/2021,Omaha SMM Food,132
563
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04558969276511397,13.377,9/25/2023,Omaha SMM Food,133
564
+ 0.0,0.0,0.0,0.010936981891184227,0.0,0.0,0.0,11.62,9/26/2022,Omaha SMM Food,134
565
+ 0.0,0.0,0.0,0.0,0.0004911367990351248,0.0,0.0,12.9,9/27/2021,Omaha SMM Food,135
566
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05004955401387512,14.921,9/4/2023,Omaha SMM Food,136
567
+ 0.0,0.0,0.0,0.00966038834039735,0.0,0.0,0.0,12.01,9/5/2022,Omaha SMM Food,137
568
+ 0.0,0.0,0.0,0.0,0.000555467059865922,0.0,0.0,13.82,9/6/2021,Omaha SMM Food,138
569
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15807730426164518,296.409,8/7/2023,Orlando/Daytona Beach/Melborne SMM Food,124
570
+ 0.0,0.0035978304669271864,0.0,0.0,0.014912249308739028,0.0,0.0,177.13,8/8/2022,Orlando/Daytona Beach/Melborne SMM Food,125
571
+ 0.0,0.0,0.0,0.0,0.005805187479779151,0.0,0.0,65.31,8/9/2021,Orlando/Daytona Beach/Melborne SMM Food,126
572
+ 0.0,0.0,0.024174453275719036,0.0,0.0,0.18581466537428856,0.1238850346878097,77.936,9/11/2023,Orlando/Daytona Beach/Melborne SMM Food,127
573
+ 0.0,0.0,0.0,0.04488872730475567,0.0,0.0,0.0,68.78,9/12/2022,Orlando/Daytona Beach/Melborne SMM Food,128
574
+ 0.0,0.0,0.0,0.0,0.003562906753705691,0.0,0.0,66.88,9/13/2021,Orlando/Daytona Beach/Melborne SMM Food,129
575
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13627353815659068,75.008,9/18/2023,Orlando/Daytona Beach/Melborne SMM Food,130
576
+ 0.0,0.0,0.0,0.046791899365486236,0.0,0.0,0.0,58.18,9/19/2022,Orlando/Daytona Beach/Melborne SMM Food,131
577
+ 0.0,0.0,0.0,0.0,0.003940847036086625,0.0,0.0,59.08,9/20/2021,Orlando/Daytona Beach/Melborne SMM Food,132
578
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11149653121902874,68.939,9/25/2023,Orlando/Daytona Beach/Melborne SMM Food,133
579
+ 0.0,0.0,0.0,0.053170328912353564,0.0,0.0,0.0,66.79,9/26/2022,Orlando/Daytona Beach/Melborne SMM Food,134
580
+ 0.0,0.0,0.0,0.0,0.004718377207858856,0.0,0.0,57.95,9/27/2021,Orlando/Daytona Beach/Melborne SMM Food,135
581
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17244796828543113,108.309,9/4/2023,Orlando/Daytona Beach/Melborne SMM Food,136
582
+ 0.0,0.0,0.0,0.0469641470254011,0.0,0.0,0.0,84.61,9/5/2022,Orlando/Daytona Beach/Melborne SMM Food,137
583
+ 0.0,0.0,0.0,0.0,0.004595902288200223,0.0,0.0,60.35,9/6/2021,Orlando/Daytona Beach/Melborne SMM Food,138
584
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.028245787908820614,6.148,8/7/2023,Paducah KY/Cape Girardeau MO SMM Food,124
585
+ 0.0,0.00036420199235732373,0.0,0.0,0.0035888862821181287,0.0,0.0,5.95,8/8/2022,Paducah KY/Cape Girardeau MO SMM Food,125
586
+ 0.0,0.0,0.0,0.0,0.0016602155775948047,0.0,0.0,6.97,8/9/2021,Paducah KY/Cape Girardeau MO SMM Food,126
587
+ 0.0,0.0,0.0033689794894980066,0.0,0.0,0.02940059048808853,0.036669970267591674,5.015,9/11/2023,Paducah KY/Cape Girardeau MO SMM Food,127
588
+ 0.0,0.0,0.0,0.008585794855104294,0.0,0.0,0.0,5.9,9/12/2022,Paducah KY/Cape Girardeau MO SMM Food,128
589
+ 0.0,0.0,0.0,0.0,0.0006470139695097488,0.0,0.0,5.93,9/13/2021,Paducah KY/Cape Girardeau MO SMM Food,129
590
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0421209117938553,5.725,9/18/2023,Paducah KY/Cape Girardeau MO SMM Food,130
591
+ 0.0,0.0,0.0,0.008949811523566999,0.0,0.0,0.0,4.53,9/19/2022,Paducah KY/Cape Girardeau MO SMM Food,131
592
+ 0.0,0.0,0.0,0.0,0.001383719168062436,0.0,0.0,5.28,9/20/2021,Paducah KY/Cape Girardeau MO SMM Food,132
593
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.03815659068384539,4.811,9/25/2023,Paducah KY/Cape Girardeau MO SMM Food,133
594
+ 0.0,0.0,0.0,0.010169803507137157,0.0,0.0,0.0,6.14,9/26/2022,Paducah KY/Cape Girardeau MO SMM Food,134
595
+ 0.0,0.0,0.0,0.0,0.0010738205077140764,0.0,0.0,5.48,9/27/2021,Paducah KY/Cape Girardeau MO SMM Food,135
596
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.024777006937561942,6.809,9/4/2023,Paducah KY/Cape Girardeau MO SMM Food,136
597
+ 0.0,0.0,0.0,0.008982757054847872,0.0,0.0,0.0,7.88,9/5/2022,Paducah KY/Cape Girardeau MO SMM Food,137
598
+ 0.0,0.0,0.0,0.0,0.0006903131835304776,0.0,0.0,7.07,9/6/2021,Paducah KY/Cape Girardeau MO SMM Food,138
599
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2522299306243806,136.614,8/7/2023,Philadelphia SMM Food,124
600
+ 0.0,0.006726039649498299,0.0,0.0,0.0256807638356943,0.0,0.0,135.86,8/8/2022,Philadelphia SMM Food,125
601
+ 0.0,0.0,0.0,0.0,0.007499423868390242,0.0,0.0,130.86,8/9/2021,Philadelphia SMM Food,126
602
+ 0.0,0.0,0.04194430100389289,0.0,0.0,0.2407575070389005,0.21754212091179384,175.883,9/11/2023,Philadelphia SMM Food,127
603
+ 0.0,0.0,0.0,0.06751901436081623,0.0,0.0,0.0,157.21,9/12/2022,Philadelphia SMM Food,128
604
+ 0.0,0.0,0.0,0.0,0.006012405146878353,0.0,0.0,149.83,9/13/2021,Philadelphia SMM Food,129
605
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.20416253716551042,235.367,9/18/2023,Philadelphia SMM Food,130
606
+ 0.0,0.0,0.0,0.07038165514606878,0.0,0.0,0.0,153.26,9/19/2022,Philadelphia SMM Food,131
607
+ 0.0,0.0,0.0,0.0,0.0061806535213589,0.0,0.0,146.17,9/20/2021,Philadelphia SMM Food,132
608
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2358771060455897,157.971,9/25/2023,Philadelphia SMM Food,133
609
+ 0.0,0.0,0.0,0.07997571812552183,0.0,0.0,0.0,135.14,9/26/2022,Philadelphia SMM Food,134
610
+ 0.0,0.0,0.0,0.0,0.00549714450003168,0.0,0.0,145.33,9/27/2021,Philadelphia SMM Food,135
611
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2309217046580773,165.02,9/4/2023,Philadelphia SMM Food,136
612
+ 0.0,0.0,0.0,0.07064074003892257,0.0,0.0,0.0,151.89,9/5/2022,Philadelphia SMM Food,137
613
+ 0.0,0.0,0.0,0.0,0.0056214751002912015,0.0,0.0,155.51,9/6/2021,Philadelphia SMM Food,138
614
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17195242814667988,79.849,8/7/2023,Phoenix/Prescott SMM Food,124
615
+ 0.0,0.0,0.0,0.0,0.014418019708702422,0.0,0.0,66.86,8/8/2022,Phoenix/Prescott SMM Food,125
616
+ 0.0,0.0,0.0,0.0,0.005271370026923594,0.0,0.0,46.12,8/9/2021,Phoenix/Prescott SMM Food,126
617
+ 0.0,0.0,0.0,0.0,0.0,0.001808959402470655,0.13627353815659068,80.322,9/11/2023,Phoenix/Prescott SMM Food,127
618
+ 0.0,0.0,0.0,0.036806299803701564,0.0,0.0,0.0,73.57,9/12/2022,Phoenix/Prescott SMM Food,128
619
+ 0.0,0.0,0.0,0.0,0.0034243492688393585,0.0,0.0,56.9,9/13/2021,Phoenix/Prescott SMM Food,129
620
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1630327056491576,72.968,9/18/2023,Phoenix/Prescott SMM Food,130
621
+ 0.0,0.0,0.0,0.0383667967368777,0.0,0.0,0.0,67.09,9/19/2022,Phoenix/Prescott SMM Food,131
622
+ 0.0,0.0,0.0,0.0,0.002687025510086375,0.0,0.0,54.17,9/20/2021,Phoenix/Prescott SMM Food,132
623
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1367690782953419,71.044,9/25/2023,Phoenix/Prescott SMM Food,133
624
+ 0.0,0.0,0.0,0.04359675990047249,0.0,0.0,0.0,75.15,9/26/2022,Phoenix/Prescott SMM Food,134
625
+ 0.0,0.0,0.0,0.0,0.0027371288863103616,0.0,0.0,54.23,9/27/2021,Phoenix/Prescott SMM Food,135
626
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14866204162537167,80.716,9/4/2023,Phoenix/Prescott SMM Food,136
627
+ 0.0,0.0,0.0,0.038508030393034846,0.0,0.0,0.0,67.72,9/5/2022,Phoenix/Prescott SMM Food,137
628
+ 0.0,0.0,0.0,0.0,0.0037181653639800187,0.0,0.0,56.91,9/6/2021,Phoenix/Prescott SMM Food,138
629
+ 0.0,0.0022663703679840757,0.0,0.0,0.00748705266438432,0.0,0.0,50.92,8/8/2022,Pittsburgh SMM Food,125
630
+ 0.0,0.0,0.0,0.0,0.003074244195471751,0.0,0.0,59.65,8/9/2021,Pittsburgh SMM Food,126
631
+ 0.0,0.0,0.009616613547803052,0.0,0.0,0.0779249674907126,0.11050545094152626,57.215,9/11/2023,Pittsburgh SMM Food,127
632
+ 0.0,0.0,0.0,0.025851136933559334,0.0,0.0,0.0,57.81,9/12/2022,Pittsburgh SMM Food,128
633
+ 0.0,0.0,0.0,0.0,0.002534859700813528,0.0,0.0,64.84,9/13/2021,Pittsburgh SMM Food,129
634
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10604558969276512,50.418,9/18/2023,Pittsburgh SMM Food,130
635
+ 0.0,0.0,0.0,0.026947161800410718,0.0,0.0,0.0,49.22,9/19/2022,Pittsburgh SMM Food,131
636
+ 0.0,0.0,0.0,0.0,0.002456921115576216,0.0,0.0,55.17,9/20/2021,Pittsburgh SMM Food,132
637
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10059464816650149,54.89,9/25/2023,Pittsburgh SMM Food,133
638
+ 0.0,0.0,0.0,0.030620459431281187,0.0,0.0,0.0,46.36,9/26/2022,Pittsburgh SMM Food,134
639
+ 0.0,0.0,0.0,0.0,0.002446405592171182,0.0,0.0,58.95,9/27/2021,Pittsburgh SMM Food,135
640
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.08870168483647176,59.663,9/4/2023,Pittsburgh SMM Food,136
641
+ 0.0,0.0,0.0,0.027046358148388426,0.0,0.0,0.0,56.47,9/5/2022,Pittsburgh SMM Food,137
642
+ 0.0,0.0,0.0,0.0,0.0023140337093078105,0.0,0.0,57.77,9/6/2021,Pittsburgh SMM Food,138
643
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10257680872150644,31.759,8/7/2023,Portland OR SMM Food,124
644
+ 0.0,0.002691513375716019,0.0,0.0,0.007488289784784913,0.0,0.0,32.69,8/8/2022,Portland OR SMM Food,125
645
+ 0.0,0.0,0.0,0.0,0.0017870204186555107,0.0,0.0,36.91,8/9/2021,Portland OR SMM Food,126
646
+ 0.0,0.0,0.020675086178223175,0.0,0.0,0.10859833173904791,0.09613478691774033,41.43,9/11/2023,Portland OR SMM Food,127
647
+ 0.0,0.0,0.0,0.025917320120911743,0.0,0.0,0.0,37.08,9/12/2022,Portland OR SMM Food,128
648
+ 0.0,0.0,0.0,0.0,0.0024290859065628904,0.0,0.0,40.37,9/13/2021,Portland OR SMM Food,129
649
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11050545094152626,36.716,9/18/2023,Portland OR SMM Food,130
650
+ 0.0,0.0,0.0,0.02701615099834603,0.0,0.0,0.0,34.13,9/19/2022,Portland OR SMM Food,131
651
+ 0.0,0.0,0.0,0.0,0.0006643336551180404,0.0,0.0,39.78,9/20/2021,Portland OR SMM Food,132
652
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.099603567888999,39.153,9/25/2023,Portland OR SMM Food,133
653
+ 0.0,0.0,0.0,0.030698852877443856,0.0,0.0,0.0,34.55,9/26/2022,Portland OR SMM Food,134
654
+ 0.0,0.0,0.0,0.0,0.0015080497683219573,0.0,0.0,36.01,9/27/2021,Portland OR SMM Food,135
655
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10356788899900891,45.084,9/4/2023,Portland OR SMM Food,136
656
+ 0.0,0.0,0.0,0.027115601306424007,0.0,0.0,0.0,32.45,9/5/2022,Portland OR SMM Food,137
657
+ 0.0,0.0,0.0,0.0,0.0023134151491075146,0.0,0.0,41.15,9/6/2021,Portland OR SMM Food,138
658
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05153617443012884,35.059,8/7/2023,Providence RI/New Bedford MA SMM Food,124
659
+ 0.0,0.0014989756862287948,0.0,0.0,0.006621068383969743,0.0,0.0,36.29,8/8/2022,Providence RI/New Bedford MA SMM Food,125
660
+ 0.0,0.0,0.0,0.0,0.0017084632732179026,0.0,0.0,35.9,8/9/2021,Providence RI/New Bedford MA SMM Food,126
661
+ 0.0,0.0,0.005980529346775456,0.0,0.0,0.05103785298168852,0.05004955401387512,39.575,9/11/2023,Providence RI/New Bedford MA SMM Food,127
662
+ 0.0,0.0,0.0,0.016572692519385028,0.0,0.0,0.0,47.61,9/12/2022,Providence RI/New Bedford MA SMM Food,128
663
+ 0.0,0.0,0.0,0.0,0.0012748525728103176,0.0,0.0,36.32,9/13/2021,Providence RI/New Bedford MA SMM Food,129
664
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.05450941526263627,46.736,9/18/2023,Providence RI/New Bedford MA SMM Food,130
665
+ 0.0,0.0,0.0,0.01727533407353234,0.0,0.0,0.0,43.68,9/19/2022,Providence RI/New Bedford MA SMM Food,131
666
+ 0.0,0.0,0.0,0.0,0.0017511439270383351,0.0,0.0,32.15,9/20/2021,Providence RI/New Bedford MA SMM Food,132
667
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.053518334985133795,44.89,9/25/2023,Providence RI/New Bedford MA SMM Food,133
668
+ 0.0,0.0,0.0,0.01963021820698563,0.0,0.0,0.0,43.55,9/26/2022,Providence RI/New Bedford MA SMM Food,134
669
+ 0.0,0.0,0.0,0.0,0.0016719682214004312,0.0,0.0,32.14,9/27/2021,Providence RI/New Bedford MA SMM Food,135
670
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.052031714568880075,36.566,9/4/2023,Providence RI/New Bedford MA SMM Food,136
671
+ 0.0,0.0,0.0,0.017338927045711716,0.0,0.0,0.0,40.72,9/5/2022,Providence RI/New Bedford MA SMM Food,137
672
+ 0.0,0.0,0.0,0.0,0.0022255796006654645,0.0,0.0,34.4,9/6/2021,Providence RI/New Bedford MA SMM Food,138
673
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10208126858275521,74.844,8/7/2023,Raleigh/Durham/Fayetteville SMM Food,124
674
+ 0.0,0.002229401410789994,0.0,0.0,0.014169977068383676,0.0,0.0,95.13,8/8/2022,Raleigh/Durham/Fayetteville SMM Food,125
675
+ 0.0,0.0,0.0,0.0,0.0034323905514432084,0.0,0.0,67.86,8/9/2021,Raleigh/Durham/Fayetteville SMM Food,126
676
+ 0.0,0.0,0.017138164073892976,0.0,0.0,0.12866985361914052,0.09217046580773042,92.348,9/11/2023,Raleigh/Durham/Fayetteville SMM Food,127
677
+ 0.0,0.0,0.0,0.03276343729674159,0.0,0.0,0.0,84.3,9/12/2022,Raleigh/Durham/Fayetteville SMM Food,128
678
+ 0.0,0.0,0.0,0.0,0.0024866120051904306,0.0,0.0,74.59,9/13/2021,Raleigh/Durham/Fayetteville SMM Food,129
679
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09464816650148662,87.201,9/18/2023,Raleigh/Durham/Fayetteville SMM Food,130
680
+ 0.0,0.0,0.0,0.034152526763903276,0.0,0.0,0.0,76.26,9/19/2022,Raleigh/Durham/Fayetteville SMM Food,131
681
+ 0.0,0.0,0.0,0.0,0.0025843445168372186,0.0,0.0,62.15,9/20/2021,Raleigh/Durham/Fayetteville SMM Food,132
682
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09266600594648167,108.314,9/25/2023,Raleigh/Durham/Fayetteville SMM Food,133
683
+ 0.0,0.0,0.0,0.03880802245868132,0.0,0.0,0.0,60.35,9/26/2022,Raleigh/Durham/Fayetteville SMM Food,134
684
+ 0.0,0.0,0.0,0.0,0.00243712718916674,0.0,0.0,64.26,9/27/2021,Raleigh/Durham/Fayetteville SMM Food,135
685
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07730426164519326,60.95,9/4/2023,Raleigh/Durham/Fayetteville SMM Food,136
686
+ 0.0,0.0,0.0,0.03427824709389885,0.0,0.0,0.0,65.5,9/5/2022,Raleigh/Durham/Fayetteville SMM Food,137
687
+ 0.0,0.0,0.0,0.0,0.0019868153633511593,0.0,0.0,98.44,9/6/2021,Raleigh/Durham/Fayetteville SMM Food,138
688
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.6694747274529237,288.005,8/7/2023,Rem US East North Central SMM Food,124
689
+ 0.0,0.010814575259181308,0.0,0.0,0.07214515040133847,0.0,0.0,308.06,8/8/2022,Rem US East North Central SMM Food,125
690
+ 0.0,0.0,0.0,0.0,0.02009021674541791,0.0,0.0,247.25,8/9/2021,Rem US East North Central SMM Food,126
691
+ 0.0,0.0,0.07424624851147829,0.0,0.0,0.5637364309077629,0.6283448959365708,263.553,9/11/2023,Rem US East North Central SMM Food,127
692
+ 0.0,0.0,0.0,0.1610144344327281,0.0,0.0,0.0,240.58,9/12/2022,Rem US East North Central SMM Food,128
693
+ 0.0,0.0,0.0,0.0,0.016926281320903215,0.0,0.0,240.68,9/13/2021,Rem US East North Central SMM Food,129
694
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5926660059464817,298.802,9/18/2023,Rem US East North Central SMM Food,130
695
+ 0.0,0.0,0.0,0.16784105194697213,0.0,0.0,0.0,230.68,9/19/2022,Rem US East North Central SMM Food,131
696
+ 0.0,0.0,0.0,0.0,0.016729579177209047,0.0,0.0,202.81,9/20/2021,Rem US East North Central SMM Food,132
697
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5812685827552032,297.755,9/25/2023,Rem US East North Central SMM Food,133
698
+ 0.0,0.0,0.0,0.1907202755058764,0.0,0.0,0.0,247.8,9/26/2022,Rem US East North Central SMM Food,134
699
+ 0.0,0.0,0.0,0.0,0.014327709919459187,0.0,0.0,202.26,9/27/2021,Rem US East North Central SMM Food,135
700
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5827552031714569,348.214,9/4/2023,Rem US East North Central SMM Food,136
701
+ 0.0,0.0,0.0,0.16845889879914241,0.0,0.0,0.0,298.88,9/5/2022,Rem US East North Central SMM Food,137
702
+ 0.0,0.0,0.0,0.0,0.015420087233182148,0.0,0.0,258.8,9/6/2021,Rem US East North Central SMM Food,138
703
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.28344895936570863,84.899,8/7/2023,Rem US Middle Atlantic SMM Food,124
704
+ 0.0,0.004143700225496054,0.0,0.0,0.0231415742134787,0.0,0.0,71.81,8/8/2022,Rem US Middle Atlantic SMM Food,125
705
+ 0.0,0.0,0.0,0.0,0.006617357022767966,0.0,0.0,78.23,8/9/2021,Rem US Middle Atlantic SMM Food,126
706
+ 0.0,0.0,0.028037555383228337,0.0,0.0,0.20463726833171583,0.267591674925669,91.266,9/11/2023,Rem US Middle Atlantic SMM Food,127
707
+ 0.0,0.0,0.0,0.05392961586570856,0.0,0.0,0.0,79.8,9/12/2022,Rem US Middle Atlantic SMM Food,128
708
+ 0.0,0.0,0.0,0.0,0.005358587015165347,0.0,0.0,82.84,9/13/2021,Rem US Middle Atlantic SMM Food,129
709
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2968285431119921,95.654,9/18/2023,Rem US Middle Atlantic SMM Food,130
710
+ 0.0,0.0,0.0,0.056216099457233604,0.0,0.0,0.0,79.34,9/19/2022,Rem US Middle Atlantic SMM Food,131
711
+ 0.0,0.0,0.0,0.0,0.005923332478035712,0.0,0.0,79.18,9/20/2021,Rem US Middle Atlantic SMM Food,132
712
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.288404360753221,92.07,9/25/2023,Rem US Middle Atlantic SMM Food,133
713
+ 0.0,0.0,0.0,0.06387918718332888,0.0,0.0,0.0,76.85,9/26/2022,Rem US Middle Atlantic SMM Food,134
714
+ 0.0,0.0,0.0,0.0,0.004886007022139106,0.0,0.0,78.62,9/27/2021,Rem US Middle Atlantic SMM Food,135
715
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.25421209117938554,92.244,9/4/2023,Rem US Middle Atlantic SMM Food,136
716
+ 0.0,0.0,0.0,0.05642303894016692,0.0,0.0,0.0,90.03,9/5/2022,Rem US Middle Atlantic SMM Food,137
717
+ 0.0,0.0,0.0,0.0,0.005541680834453002,0.0,0.0,88.71,9/6/2021,Rem US Middle Atlantic SMM Food,138
718
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3865213082259663,129.148,8/7/2023,Rem US Mountain SMM Food,124
719
+ 0.0,0.00753329148822845,0.0,0.0,0.02747273273595218,0.0,0.0,113.3,8/8/2022,Rem US Mountain SMM Food,125
720
+ 0.0,0.0,0.0,0.0,0.007616950306446507,0.0,0.0,115.63,8/9/2021,Rem US Mountain SMM Food,126
721
+ 0.0,0.0,0.023499729051807798,0.0,0.0,0.3230963384624684,0.3295341922695738,135.595,9/11/2023,Rem US Mountain SMM Food,127
722
+ 0.0,0.0,0.0,0.08969502904489553,0.0,0.0,0.0,124.27,9/12/2022,Rem US Mountain SMM Food,128
723
+ 0.0,0.0,0.0,0.0,0.005267040105521521,0.0,0.0,115.0,9/13/2021,Rem US Mountain SMM Food,129
724
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3637264618434093,137.112,9/18/2023,Rem US Mountain SMM Food,130
725
+ 0.0,0.0,0.0,0.09349787851239232,0.0,0.0,0.0,126.58,9/19/2022,Rem US Mountain SMM Food,131
726
+ 0.0,0.0,0.0,0.0,0.004318168758267262,0.0,0.0,118.66,9/20/2021,Rem US Mountain SMM Food,132
727
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.3399405351833498,137.733,9/25/2023,Rem US Mountain SMM Food,133
728
+ 0.0,0.0,0.0,0.10624302537960408,0.0,0.0,0.0,125.46,9/26/2022,Rem US Mountain SMM Food,134
729
+ 0.0,0.0,0.0,0.0,0.0057761151503652325,0.0,0.0,115.09,9/27/2021,Rem US Mountain SMM Food,135
730
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.31714568880079286,153.818,9/4/2023,Rem US Mountain SMM Food,136
731
+ 0.0,0.0,0.0,0.09384205752517928,0.0,0.0,0.0,123.49,9/5/2022,Rem US Mountain SMM Food,137
732
+ 0.0,0.0,0.0,0.0,0.005829929887790996,0.0,0.0,119.33,9/6/2021,Rem US Mountain SMM Food,138
733
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14816650148662042,95.632,8/7/2023,Rem US New England SMM Food,124
734
+ 0.0,0.0027053767346638,0.0,0.0,0.012870382087561513,0.0,0.0,92.11,8/8/2022,Rem US New England SMM Food,125
735
+ 0.0,0.0,0.0,0.0,0.0037107426415764655,0.0,0.0,93.54,8/9/2021,Rem US New England SMM Food,126
736
+ 0.0,0.0,0.016692145621939145,0.0,0.0,0.10162023020001978,0.14717542120911795,96.91,9/11/2023,Rem US New England SMM Food,127
737
+ 0.0,0.0,0.0,0.02729342543083433,0.0,0.0,0.0,108.12,9/12/2022,Rem US New England SMM Food,128
738
+ 0.0,0.0,0.0,0.0,0.003017336657044507,0.0,0.0,105.63,9/13/2021,Rem US New England SMM Food,129
739
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14568880079286423,104.654,9/18/2023,Rem US New England SMM Food,130
740
+ 0.0,0.0,0.0,0.028450599800614283,0.0,0.0,0.0,107.99,9/19/2022,Rem US New England SMM Food,131
741
+ 0.0,0.0,0.0,0.0,0.001866196124293415,0.0,0.0,103.16,9/20/2021,Rem US New England SMM Food,132
742
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1377601585728444,103.237,9/25/2023,Rem US New England SMM Food,133
743
+ 0.0,0.0,0.0,0.032328838321626044,0.0,0.0,0.0,110.46,9/26/2022,Rem US New England SMM Food,134
744
+ 0.0,0.0,0.0,0.0,0.002290528421696558,0.0,0.0,93.03,9/27/2021,Rem US New England SMM Food,135
745
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13181367690782952,95.746,9/4/2023,Rem US New England SMM Food,136
746
+ 0.0,0.0,0.0,0.028555330519776528,0.0,0.0,0.0,94.74,9/5/2022,Rem US New England SMM Food,137
747
+ 0.0,0.0,0.0,0.0,0.0022682602544858974,0.0,0.0,92.71,9/6/2021,Rem US New England SMM Food,138
748
+ 0.0,0.006359527097316345,0.0,0.0,0.02227744561366501,0.0,0.0,56.31,8/8/2022,Rem US Pacific SMM Food,125
749
+ 0.0,0.0,0.0,0.0,0.006462098412493638,0.0,0.0,52.58,8/9/2021,Rem US Pacific SMM Food,126
750
+ 0.0,0.0,0.04350177887159544,0.0,0.0,0.2505022822201761,0.26957383548067393,68.969,9/11/2023,Rem US Pacific SMM Food,127
751
+ 0.0,0.0,0.0,0.07303394106363369,0.0,0.0,0.0,64.99,9/12/2022,Rem US Pacific SMM Food,128
752
+ 0.0,0.0,0.0,0.0,0.005756939784156053,0.0,0.0,60.43,9/13/2021,Rem US Pacific SMM Food,129
753
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2755203171456888,59.672,9/18/2023,Rem US Pacific SMM Food,130
754
+ 0.0,0.0,0.0,0.07613040119907764,0.0,0.0,0.0,59.55,9/19/2022,Rem US Pacific SMM Food,131
755
+ 0.0,0.0,0.0,0.0,0.006201684568168969,0.0,0.0,50.8,9/20/2021,Rem US Pacific SMM Food,132
756
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.25173439048562934,59.2,9/25/2023,Rem US Pacific SMM Food,133
757
+ 0.0,0.0,0.0,0.08650810352908421,0.0,0.0,0.0,58.94,9/26/2022,Rem US Pacific SMM Food,134
758
+ 0.0,0.0,0.0,0.0,0.00586766206000906,0.0,0.0,56.23,9/27/2021,Rem US Pacific SMM Food,135
759
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.2512388503468781,68.417,9/4/2023,Rem US Pacific SMM Food,136
760
+ 0.0,0.0,0.0,0.07641064808426322,0.0,0.0,0.0,64.25,9/5/2022,Rem US Pacific SMM Food,137
761
+ 0.0,0.0,0.0,0.0,0.006398386711863137,0.0,0.0,56.78,9/6/2021,Rem US Pacific SMM Food,138
762
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.6902874132804757,361.601,8/7/2023,Rem US South Atlantic SMM Food,124
763
+ 0.0,0.012989967334070573,0.0,0.0,0.07146720842181392,0.0,0.0,306.04,8/8/2022,Rem US South Atlantic SMM Food,125
764
+ 0.0,0.0,0.0,0.0,0.021449812065668792,0.0,0.0,216.74,8/9/2021,Rem US South Atlantic SMM Food,126
765
+ 0.0,0.0,0.07827180767102376,0.0,0.0,0.7032422127774433,0.5802775024777007,251.083,9/11/2023,Rem US South Atlantic SMM Food,127
766
+ 0.0,0.0,0.0,0.17196903338655478,0.0,0.0,0.0,233.99,9/12/2022,Rem US South Atlantic SMM Food,128
767
+ 0.0,0.0,0.0,0.0,0.015825244164376112,0.0,0.0,221.21,9/13/2021,Rem US South Atlantic SMM Food,129
768
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.6040634291377601,232.236,9/18/2023,Rem US South Atlantic SMM Food,130
769
+ 0.0,0.0,0.0,0.17926009905695495,0.0,0.0,0.0,215.08,9/19/2022,Rem US South Atlantic SMM Food,131
770
+ 0.0,0.0,0.0,0.0,0.017987112064411077,0.0,0.0,197.7,9/20/2021,Rem US South Atlantic SMM Food,132
771
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5708622398414271,309.873,9/25/2023,Rem US South Atlantic SMM Food,133
772
+ 0.0,0.0,0.0,0.20369590803657825,0.0,0.0,0.0,210.58,9/26/2022,Rem US South Atlantic SMM Food,134
773
+ 0.0,0.0,0.0,0.0,0.014305441752248528,0.0,0.0,213.12,9/27/2021,Rem US South Atlantic SMM Food,135
774
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.5802775024777007,234.028,9/4/2023,Rem US South Atlantic SMM Food,136
775
+ 0.0,0.0,0.0,0.17991998108708984,0.0,0.0,0.0,215.63,9/5/2022,Rem US South Atlantic SMM Food,137
776
+ 0.0,0.0,0.0,0.0,0.01699123014193431,0.0,0.0,279.36,9/6/2021,Rem US South Atlantic SMM Food,138
777
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.9940535183349851,402.383,8/7/2023,Rem US South Central SMM Food,124
778
+ 0.0,0.014466126242031146,0.0,0.0,0.09628013229649275,0.0,0.0,349.19,8/8/2022,Rem US South Central SMM Food,125
779
+ 0.0,0.0,0.0,0.0,0.026810254761435028,0.0,0.0,321.57,8/9/2021,Rem US South Central SMM Food,126
780
+ 0.0,0.0,0.0887623135688707,0.0,0.0,0.8841922317358683,0.8275520317145688,406.505,9/11/2023,Rem US South Central SMM Food,127
781
+ 0.0,0.0,0.0,0.23375662511916412,0.0,0.0,0.0,389.86,9/12/2022,Rem US South Central SMM Food,128
782
+ 0.0,0.0,0.0,0.0,0.023796629465592297,0.0,0.0,338.41,9/13/2021,Rem US South Central SMM Food,129
783
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.9340931615460852,374.323,9/18/2023,Rem US South Central SMM Food,130
784
+ 0.0,0.0,0.0,0.24366733338763769,0.0,0.0,0.0,410.27,9/19/2022,Rem US South Central SMM Food,131
785
+ 0.0,0.0,0.0,0.0,0.023312915388960728,0.0,0.0,322.93,9/20/2021,Rem US South Central SMM Food,132
786
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.8875123885034688,376.732,9/25/2023,Rem US South Central SMM Food,133
787
+ 0.0,0.0,0.0,0.2768828031055804,0.0,0.0,0.0,415.53,9/26/2022,Rem US South Central SMM Food,134
788
+ 0.0,0.0,0.0,0.0,0.021042799453873943,0.0,0.0,312.75,9/27/2021,Rem US South Central SMM Food,135
789
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.7715559960356789,385.963,9/4/2023,Rem US South Central SMM Food,136
790
+ 0.0,0.0,0.0,0.24456430760086398,0.0,0.0,0.0,384.02,9/5/2022,Rem US South Central SMM Food,137
791
+ 0.0,0.0,0.0,0.0,0.021850639075460684,0.0,0.0,348.91,9/6/2021,Rem US South Central SMM Food,138
792
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4821605550049554,81.439,8/7/2023,Rem US West North Central SMM Food,124
793
+ 0.0,0.005221576383686008,0.0,0.0,0.032486163159352294,0.0,0.0,85.9,8/8/2022,Rem US West North Central SMM Food,125
794
+ 0.0,0.0,0.0,0.0,0.010447481783001583,0.0,0.0,67.85,8/9/2021,Rem US West North Central SMM Food,126
795
+ 0.0,0.0,0.04495249924795993,0.0,0.0,0.32640646345165913,0.42170465807730423,81.258,9/11/2023,Rem US West North Central SMM Food,127
796
+ 0.0,0.0,0.0,0.08643118883692774,0.0,0.0,0.0,90.01,9/12/2022,Rem US West North Central SMM Food,128
797
+ 0.0,0.0,0.0,0.0,0.006995915865349195,0.0,0.0,80.77,9/13/2021,Rem US West North Central SMM Food,129
798
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4405351833498513,77.838,9/18/2023,Rem US West North Central SMM Food,130
799
+ 0.0,0.0,0.0,0.09009565954761295,0.0,0.0,0.0,77.07,9/19/2022,Rem US West North Central SMM Food,131
800
+ 0.0,0.0,0.0,0.0,0.007515506433597942,0.0,0.0,73.56,9/20/2021,Rem US West North Central SMM Food,132
801
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.4400396432111001,78.46,9/25/2023,Rem US West North Central SMM Food,133
802
+ 0.0,0.0,0.0,0.10237703355668529,0.0,0.0,0.0,82.7,9/26/2022,Rem US West North Central SMM Food,134
803
+ 0.0,0.0,0.0,0.0,0.007104782460601314,0.0,0.0,74.24,9/27/2021,Rem US West North Central SMM Food,135
804
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.38503468780971256,87.813,9/4/2023,Rem US West North Central SMM Food,136
805
+ 0.0,0.0,0.0,0.09042731448975182,0.0,0.0,0.0,85.04,9/5/2022,Rem US West North Central SMM Food,137
806
+ 0.0,0.0,0.0,0.0,0.007015091231558375,0.0,0.0,87.6,9/6/2021,Rem US West North Central SMM Food,138
807
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04112983151635283,43.858,8/7/2023,Richmond/Petersburg SMM Food,124
808
+ 0.0,0.0009487736279887459,0.0,0.0,0.007115916544206644,0.0,0.0,41.87,8/8/2022,Richmond/Petersburg SMM Food,125
809
+ 0.0,0.0,0.0,0.0,0.0012606256882035066,0.0,0.0,34.56,8/9/2021,Richmond/Petersburg SMM Food,126
810
+ 0.0,0.0,0.005540418423986577,0.0,0.0,0.04781667750388989,0.03964321110009911,41.396,9/11/2023,Richmond/Petersburg SMM Food,127
811
+ 0.0,0.0,0.0,0.01266418225172223,0.0,0.0,0.0,36.0,9/12/2022,Richmond/Petersburg SMM Food,128
812
+ 0.0,0.0,0.0,0.0,0.0013101105042271969,0.0,0.0,35.96,9/13/2021,Richmond/Petersburg SMM Food,129
813
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04162537165510406,37.841,9/18/2023,Richmond/Petersburg SMM Food,130
814
+ 0.0,0.0,0.0,0.013201112554278954,0.0,0.0,0.0,34.82,9/19/2022,Richmond/Petersburg SMM Food,131
815
+ 0.0,0.0,0.0,0.0,0.00111155267993214,0.0,0.0,33.78,9/20/2021,Richmond/Petersburg SMM Food,132
816
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0421209117938553,52.209,9/25/2023,Richmond/Petersburg SMM Food,133
817
+ 0.0,0.0,0.0,0.015000619892522049,0.0,0.0,0.0,37.32,9/26/2022,Richmond/Petersburg SMM Food,134
818
+ 0.0,0.0,0.0,0.0,0.0012204192751842583,0.0,0.0,33.61,9/27/2021,Richmond/Petersburg SMM Food,135
819
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.03617443012884043,37.615,9/4/2023,Richmond/Petersburg SMM Food,136
820
+ 0.0,0.0,0.0,0.013249707732199589,0.0,0.0,0.0,38.38,9/5/2022,Richmond/Petersburg SMM Food,137
821
+ 0.0,0.0,0.0,0.0,0.0012822752952138712,0.0,0.0,47.08,9/6/2021,Richmond/Petersburg SMM Food,138
822
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11793855302279485,26.418,8/7/2023,Sacramento/Stockton/Modesto SMM Food,124
823
+ 0.0,0.0036908304998685493,0.0,0.0,0.006869111024288489,0.0,0.0,24.42,8/8/2022,Sacramento/Stockton/Modesto SMM Food,125
824
+ 0.0,0.0,0.0,0.0,0.00287321213037551,0.0,0.0,23.32,8/9/2021,Sacramento/Stockton/Modesto SMM Food,126
825
+ 0.0,0.0,0.017499367285692864,0.0,0.0,0.09899835674878281,0.08275520317145689,27.508,9/11/2023,Sacramento/Stockton/Modesto SMM Food,127
826
+ 0.0,0.0,0.0,0.029183182904838144,0.0,0.0,0.0,25.44,9/12/2022,Sacramento/Stockton/Modesto SMM Food,128
827
+ 0.0,0.0,0.0,0.0,0.0019026911761108865,0.0,0.0,24.91,9/13/2021,Sacramento/Stockton/Modesto SMM Food,129
828
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11298315163528246,22.085,9/18/2023,Sacramento/Stockton/Modesto SMM Food,130
829
+ 0.0,0.0,0.0,0.030420478364843156,0.0,0.0,0.0,24.71,9/19/2022,Sacramento/Stockton/Modesto SMM Food,131
830
+ 0.0,0.0,0.0,0.0,0.0023127965889072188,0.0,0.0,23.73,9/20/2021,Sacramento/Stockton/Modesto SMM Food,132
831
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.07879088206144698,27.12,9/25/2023,Sacramento/Stockton/Modesto SMM Food,133
832
+ 0.0,0.0,0.0,0.034567240528453246,0.0,0.0,0.0,26.42,9/26/2022,Sacramento/Stockton/Modesto SMM Food,134
833
+ 0.0,0.0,0.0,0.0,0.0016187720441749643,0.0,0.0,22.87,9/27/2021,Sacramento/Stockton/Modesto SMM Food,135
834
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10257680872150644,30.477,9/4/2023,Sacramento/Stockton/Modesto SMM Food,136
835
+ 0.0,0.0,0.0,0.030532460487995166,0.0,0.0,0.0,25.38,9/5/2022,Sacramento/Stockton/Modesto SMM Food,137
836
+ 0.0,0.0,0.0,0.0,0.0018699074854951917,0.0,0.0,25.66,9/6/2021,Sacramento/Stockton/Modesto SMM Food,138
837
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13280475718533202,31.866,8/7/2023,Salt Lake City SMM Food,124
838
+ 0.0,0.0,0.0,0.0,0.005755702663755461,0.0,0.0,30.89,8/8/2022,Salt Lake City SMM Food,125
839
+ 0.0,0.0,0.0,0.0,0.002216919757861319,0.0,0.0,30.55,8/9/2021,Salt Lake City SMM Food,126
840
+ 0.0,0.0,0.0,0.0,0.0,0.0020036799212335816,0.12338949454905847,35.521,9/11/2023,Salt Lake City SMM Food,127
841
+ 0.0,0.0,0.0,0.024569078193799245,0.0,0.0,0.0,28.16,9/12/2022,Salt Lake City SMM Food,128
842
+ 0.0,0.0,0.0,0.0,0.0018668146844937111,0.0,0.0,34.69,9/13/2021,Salt Lake City SMM Food,129
843
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12091179385530228,39.734,9/18/2023,Salt Lake City SMM Food,130
844
+ 0.0,0.0,0.0,0.0256107469124291,0.0,0.0,0.0,20.08,9/19/2022,Salt Lake City SMM Food,131
845
+ 0.0,0.0,0.0,0.0,0.002090114916800613,0.0,0.0,30.04,9/20/2021,Salt Lake City SMM Food,132
846
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.11446977205153618,36.76,9/25/2023,Salt Lake City SMM Food,133
847
+ 0.0,0.0,0.0,0.02910187138286449,0.0,0.0,0.0,28.2,9/26/2022,Salt Lake City SMM Food,134
848
+ 0.0,0.0,0.0,0.0,0.0013169146664304542,0.0,0.0,31.92,9/27/2021,Salt Lake City SMM Food,135
849
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.12933597621407333,38.673,9/4/2023,Salt Lake City SMM Food,136
850
+ 0.0,0.0,0.0,0.025705023731608795,0.0,0.0,0.0,29.76,9/5/2022,Salt Lake City SMM Food,137
851
+ 0.0,0.0,0.0,0.0,0.0014486679890935294,0.0,0.0,30.71,9/6/2021,Salt Lake City SMM Food,138
852
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06739345887016848,27.155,8/7/2023,San Diego SMM Food,124
853
+ 0.0,0.0020376249453456933,0.0,0.0,0.006930348484117806,0.0,0.0,23.05,8/8/2022,San Diego SMM Food,125
854
+ 0.0,0.0,0.0,0.0,0.0011183568421353973,0.0,0.0,18.52,8/9/2021,San Diego SMM Food,126
855
+ 0.0,0.0,0.008977334498881523,0.0,0.0,0.06158408920762952,0.058969276511397425,31.97,9/11/2023,San Diego SMM Food,127
856
+ 0.0,0.0,0.0,0.020400456588260608,0.0,0.0,0.0,26.77,9/12/2022,San Diego SMM Food,128
857
+ 0.0,0.0,0.0,0.0,0.0014214513402804997,0.0,0.0,22.06,9/13/2021,San Diego SMM Food,129
858
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.055996035678889985,29.921,9/18/2023,San Diego SMM Food,130
859
+ 0.0,0.0,0.0,0.021265385972826126,0.0,0.0,0.0,23.46,9/19/2022,San Diego SMM Food,131
860
+ 0.0,0.0,0.0,0.0,0.0010942329943238486,0.0,0.0,18.64,9/20/2021,San Diego SMM Food,132
861
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.059960356788899896,29.193,9/25/2023,San Diego SMM Food,133
862
+ 0.0,0.0,0.0,0.02416417332539202,0.0,0.0,0.0,27.29,9/26/2022,San Diego SMM Food,134
863
+ 0.0,0.0,0.0,0.0,0.001024335691690386,0.0,0.0,21.74,9/27/2021,San Diego SMM Food,135
864
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.06739345887016848,34.927,9/4/2023,San Diego SMM Food,136
865
+ 0.0,0.0,0.0,0.021343666889227886,0.0,0.0,0.0,24.65,9/5/2022,San Diego SMM Food,137
866
+ 0.0,0.0,0.0,0.0,0.0013292858704363766,0.0,0.0,22.7,9/6/2021,San Diego SMM Food,138
867
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.10852329038652131,37.539,8/7/2023,San Francisco/Oakland/San Jose SMM Food,124
868
+ 0.0,0.007054716784551935,0.0,0.0,0.010025623726399625,0.0,0.0,43.76,8/8/2022,San Francisco/Oakland/San Jose SMM Food,125
869
+ 0.0,0.0,0.0,0.0,0.0026325922124603163,0.0,0.0,35.86,8/9/2021,San Francisco/Oakland/San Jose SMM Food,126
870
+ 0.0,0.0,0.03269606409616145,0.0,0.0,0.08548204542111204,0.08919722497522299,39.91,9/11/2023,San Francisco/Oakland/San Jose SMM Food,127
871
+ 0.0,0.0,0.0,0.047694445908865776,0.0,0.0,0.0,39.0,9/12/2022,San Francisco/Oakland/San Jose SMM Food,128
872
+ 0.0,0.0,0.0,0.0,0.0020171248131656697,0.0,0.0,39.68,9/13/2021,San Francisco/Oakland/San Jose SMM Food,129
873
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09712586719524281,39.834,9/18/2023,San Francisco/Oakland/San Jose SMM Food,130
874
+ 0.0,0.0,0.0,0.04971657356674364,0.0,0.0,0.0,41.01,9/19/2022,San Francisco/Oakland/San Jose SMM Food,131
875
+ 0.0,0.0,0.0,0.0,0.002183517507045328,0.0,0.0,37.16,9/20/2021,San Francisco/Oakland/San Jose SMM Food,132
876
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.0817641228939544,38.973,9/25/2023,San Francisco/Oakland/San Jose SMM Food,133
877
+ 0.0,0.0,0.0,0.056493679565598955,0.0,0.0,0.0,40.14,9/26/2022,San Francisco/Oakland/San Jose SMM Food,134
878
+ 0.0,0.0,0.0,0.0,0.0021674349418376285,0.0,0.0,36.73,9/27/2021,San Francisco/Oakland/San Jose SMM Food,135
879
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09068384539147671,45.739,9/4/2023,San Francisco/Oakland/San Jose SMM Food,136
880
+ 0.0,0.0,0.0,0.049899587365703414,0.0,0.0,0.0,42.29,9/5/2022,San Francisco/Oakland/San Jose SMM Food,137
881
+ 0.0,0.0,0.0,0.0,0.0014294926228843492,0.0,0.0,39.55,9/6/2021,San Francisco/Oakland/San Jose SMM Food,138
882
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.176412289395441,54.498,8/7/2023,Seattle/Tacoma SMM Food,124
883
+ 0.0,0.006289632662621285,0.0,0.0,0.014541731748761649,0.0,0.0,38.02,8/8/2022,Seattle/Tacoma SMM Food,125
884
+ 0.0,0.0,0.0,0.0,0.0025020760101978337,0.0,0.0,44.59,8/9/2021,Seattle/Tacoma SMM Food,126
885
+ 0.0,0.0,0.04408198262886745,0.0,0.0,0.13501876631890186,0.14073339940535184,56.797,9/11/2023,Seattle/Tacoma SMM Food,127
886
+ 0.0,0.0,0.0,0.03795459470136038,0.0,0.0,0.0,45.0,9/12/2022,Seattle/Tacoma SMM Food,128
887
+ 0.0,0.0,0.0,0.0,0.0019701142379431645,0.0,0.0,47.26,9/13/2021,Seattle/Tacoma SMM Food,129
888
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.15163528245787908,53.988,9/18/2023,Seattle/Tacoma SMM Food,130
889
+ 0.0,0.0,0.0,0.03956377652701973,0.0,0.0,0.0,42.63,9/19/2022,Seattle/Tacoma SMM Food,131
890
+ 0.0,0.0,0.0,0.0,0.0010663977853105227,0.0,0.0,44.68,9/20/2021,Seattle/Tacoma SMM Food,132
891
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14767096134786917,57.516,9/25/2023,Seattle/Tacoma SMM Food,133
892
+ 0.0,0.0,0.0,0.04495690578008078,0.0,0.0,0.0,43.4,9/26/2022,Seattle/Tacoma SMM Food,134
893
+ 0.0,0.0,0.0,0.0,0.002235476563870203,0.0,0.0,47.9,9/27/2021,Seattle/Tacoma SMM Food,135
894
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13429137760158572,69.688,9/4/2023,Seattle/Tacoma SMM Food,136
895
+ 0.0,0.0,0.0,0.039709416436374406,0.0,0.0,0.0,41.17,9/5/2022,Seattle/Tacoma SMM Food,137
896
+ 0.0,0.0,0.0,0.0,0.0016051637197684492,0.0,0.0,42.94,9/6/2021,Seattle/Tacoma SMM Food,138
897
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13875123885034688,41.124,8/7/2023,St. Louis SMM Food,124
898
+ 0.0,0.0016459850550708866,0.0,0.0,0.010519234766235935,0.0,0.0,33.68,8/8/2022,St. Louis SMM Food,125
899
+ 0.0,0.0,0.0,0.0,0.0028880575751826162,0.0,0.0,35.24,8/9/2021,St. Louis SMM Food,126
900
+ 0.0,0.0,0.013647236303775618,0.0,0.0,0.11378140992305427,0.09266600594648167,41.021,9/11/2023,St. Louis SMM Food,127
901
+ 0.0,0.0,0.0,0.028725686548902455,0.0,0.0,0.0,46.76,9/12/2022,St. Louis SMM Food,128
902
+ 0.0,0.0,0.0,0.0,0.002591148679040476,0.0,0.0,37.37,9/13/2021,St. Louis SMM Food,129
903
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09266600594648167,38.672,9/18/2023,St. Louis SMM Food,130
904
+ 0.0,0.0,0.0,0.029943585281161426,0.0,0.0,0.0,41.99,9/19/2022,St. Louis SMM Food,131
905
+ 0.0,0.0,0.0,0.0,0.0026987781538920018,0.0,0.0,33.82,9/20/2021,St. Louis SMM Food,132
906
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09217046580773042,52.498,9/25/2023,St. Louis SMM Food,133
907
+ 0.0,0.0,0.0,0.034025339850661744,0.0,0.0,0.0,38.58,9/26/2022,St. Louis SMM Food,134
908
+ 0.0,0.0,0.0,0.0,0.003129296053298106,0.0,0.0,35.39,9/27/2021,St. Louis SMM Food,135
909
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.09514370664023786,44.922,9/4/2023,St. Louis SMM Food,136
910
+ 0.0,0.0,0.0,0.03005381188828102,0.0,0.0,0.0,51.7,9/5/2022,St. Louis SMM Food,137
911
+ 0.0,0.0,0.0,0.0,0.0020622797077872873,0.0,0.0,45.12,9/6/2021,St. Louis SMM Food,138
912
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.18434093161546083,392.534,8/7/2023,Tampa/Ft. Myers SMM Food,124
913
+ 0.0,0.002718951273633502,0.0,0.0,0.014108739608554358,0.0,0.0,249.67,8/8/2022,Tampa/Ft. Myers SMM Food,125
914
+ 0.0,0.0,0.0,0.0,0.005458175207413023,0.0,0.0,94.56,8/9/2021,Tampa/Ft. Myers SMM Food,126
915
+ 0.0,0.0,0.018081680874809502,0.0,0.0,0.19101996581778166,0.1377601585728444,112.223,9/11/2023,Tampa/Ft. Myers SMM Food,127
916
+ 0.0,0.0,0.0,0.05247086431152936,0.0,0.0,0.0,92.25,9/12/2022,Tampa/Ft. Myers SMM Food,128
917
+ 0.0,0.0,0.0,0.0,0.004128889336976647,0.0,0.0,93.22,9/13/2021,Tampa/Ft. Myers SMM Food,129
918
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13181367690782952,105.58,9/18/2023,Tampa/Ft. Myers SMM Food,130
919
+ 0.0,0.0,0.0,0.05469550040636205,0.0,0.0,0.0,85.97,9/19/2022,Tampa/Ft. Myers SMM Food,131
920
+ 0.0,0.0,0.0,0.0,0.004280436586049198,0.0,0.0,86.54,9/20/2021,Tampa/Ft. Myers SMM Food,132
921
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.13875123885034688,98.576,9/25/2023,Tampa/Ft. Myers SMM Food,133
922
+ 0.0,0.0,0.0,0.062151307947871305,0.0,0.0,0.0,92.27,9/26/2022,Tampa/Ft. Myers SMM Food,134
923
+ 0.0,0.0,0.0,0.0,0.004065796196546442,0.0,0.0,83.16,9/27/2021,Tampa/Ft. Myers SMM Food,135
924
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.18533201189296333,155.563,9/4/2023,Tampa/Ft. Myers SMM Food,136
925
+ 0.0,0.0,0.0,0.0548968423482816,0.0,0.0,0.0,131.88,9/5/2022,Tampa/Ft. Myers SMM Food,137
926
+ 0.0,0.0,0.0,0.0,0.004370127815092137,0.0,0.0,85.36,9/6/2021,Tampa/Ft. Myers SMM Food,138
927
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.033201189296333006,14.745,8/7/2023,Tucson/Sierra Vista SMM Food,124
928
+ 0.0,0.0008540406751789106,0.0,0.0,0.0032796061819700653,0.0,0.0,11.07,8/8/2022,Tucson/Sierra Vista SMM Food,125
929
+ 0.0,0.0,0.0,0.0,0.0014684619155030051,0.0,0.0,10.23,8/9/2021,Tucson/Sierra Vista SMM Food,126
930
+ 0.0,0.0,0.004325155281482285,0.0,0.0,0.03514997428852929,0.033201189296333006,13.086,9/11/2023,Tucson/Sierra Vista SMM Food,127
931
+ 0.0,0.0,0.0,0.008438669343202216,0.0,0.0,0.0,15.07,9/12/2022,Tucson/Sierra Vista SMM Food,128
932
+ 0.0,0.0,0.0,0.0,0.0005659825832709562,0.0,0.0,12.89,9/13/2021,Tucson/Sierra Vista SMM Food,129
933
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.04558969276511397,13.845,9/18/2023,Tucson/Sierra Vista SMM Food,130
934
+ 0.0,0.0,0.0,0.008796448244863359,0.0,0.0,0.0,12.4,9/19/2022,Tucson/Sierra Vista SMM Food,131
935
+ 0.0,0.0,0.0,0.0,0.0005641269026700677,0.0,0.0,11.2,9/20/2021,Tucson/Sierra Vista SMM Food,132
936
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.028741328047571853,14.286,9/25/2023,Tucson/Sierra Vista SMM Food,133
937
+ 0.0,0.0,0.0,0.009995534545410896,0.0,0.0,0.0,14.46,9/26/2022,Tucson/Sierra Vista SMM Food,134
938
+ 0.0,0.0,0.0,0.0,0.0005597969812679949,0.0,0.0,13.72,9/27/2021,Tucson/Sierra Vista SMM Food,135
939
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.036669970267591674,14.191,9/4/2023,Tucson/Sierra Vista SMM Food,136
940
+ 0.0,0.0,0.0,0.008828829229391247,0.0,0.0,0.0,13.52,9/5/2022,Tucson/Sierra Vista SMM Food,137
941
+ 0.0,0.0,0.0,0.0,0.0008028911399843727,0.0,0.0,12.27,9/6/2021,Tucson/Sierra Vista SMM Food,138
942
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.17443012884043607,117.859,8/7/2023,Washington DC/Hagerstown SMM Food,124
943
+ 0.0,0.008450294918628531,0.0,0.0,0.01769886301107308,0.0,0.0,121.38,8/8/2022,Washington DC/Hagerstown SMM Food,125
944
+ 0.0,0.0,0.0,0.0,0.005262091623919152,0.0,0.0,114.34,8/9/2021,Washington DC/Hagerstown SMM Food,126
945
+ 0.0,0.0,0.05609156745484475,0.0,0.0,0.19144403459184595,0.155599603567889,160.362,9/11/2023,Washington DC/Hagerstown SMM Food,127
946
+ 0.0,0.0,0.0,0.05177122745529417,0.0,0.0,0.0,144.07,9/12/2022,Washington DC/Hagerstown SMM Food,128
947
+ 0.0,0.0,0.0,0.0,0.0036185771717323423,0.0,0.0,123.88,9/13/2021,Washington DC/Hagerstown SMM Food,129
948
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.14519326065411298,165.895,9/18/2023,Washington DC/Hagerstown SMM Food,130
949
+ 0.0,0.0,0.0,0.05396620066002498,0.0,0.0,0.0,138.59,9/19/2022,Washington DC/Hagerstown SMM Food,131
950
+ 0.0,0.0,0.0,0.0,0.0035734222771107256,0.0,0.0,116.24,9/20/2021,Washington DC/Hagerstown SMM Food,132
951
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1620416253716551,159.074,9/25/2023,Washington DC/Hagerstown SMM Food,133
952
+ 0.0,0.0,0.0,0.06132259383502524,0.0,0.0,0.0,132.64,9/26/2022,Washington DC/Hagerstown SMM Food,134
953
+ 0.0,0.0,0.0,0.0,0.002285579940094189,0.0,0.0,113.16,9/27/2021,Washington DC/Hagerstown SMM Food,135
954
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.1337958374628345,117.933,9/4/2023,Washington DC/Hagerstown SMM Food,136
955
+ 0.0,0.0,0.0,0.054164857947246375,0.0,0.0,0.0,118.44,9/5/2022,Washington DC/Hagerstown SMM Food,137
956
+ 0.0,0.0,0.0,0.0,0.0032740391401673997,0.0,0.0,130.79,9/6/2021,Washington DC/Hagerstown SMM Food,138
957
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.024281466798810703,3.773,8/7/2023,Yakima/Pasco/Richland/Kennewick SMM Food,124
958
+ 0.0,0.00041792250827997425,0.0,0.0,0.0016707311009998389,0.0,0.0,3.86,8/8/2022,Yakima/Pasco/Richland/Kennewick SMM Food,125
959
+ 0.0,0.0,0.0,0.0,0.00020907334770009088,0.0,0.0,3.64,8/9/2021,Yakima/Pasco/Richland/Kennewick SMM Food,126
960
+ 0.0,0.0,0.0024254626885814802,0.0,0.0,0.023424539263820505,0.022794846382556987,4.202,9/11/2023,Yakima/Pasco/Richland/Kennewick SMM Food,127
961
+ 0.0,0.0,0.0,0.0051309930988511126,0.0,0.0,0.0,3.78,9/12/2022,Yakima/Pasco/Richland/Kennewick SMM Food,128
962
+ 0.0,0.0,0.0,0.0,0.00041010541279633213,0.0,0.0,3.71,9/13/2021,Yakima/Pasco/Richland/Kennewick SMM Food,129
963
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.018334985133795837,4.43,9/18/2023,Yakima/Pasco/Richland/Kennewick SMM Food,130
964
+ 0.0,0.0,0.0,0.005348534635223674,0.0,0.0,0.0,3.76,9/19/2022,Yakima/Pasco/Richland/Kennewick SMM Food,131
965
+ 0.0,0.0,0.0,0.0,0.0005270132906523001,0.0,0.0,3.12,9/20/2021,Yakima/Pasco/Richland/Kennewick SMM Food,132
966
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.02180376610505451,3.573,9/25/2023,Yakima/Pasco/Richland/Kennewick SMM Food,133
967
+ 0.0,0.0,0.0,0.006077619195352498,0.0,0.0,0.0,2.75,9/26/2022,Yakima/Pasco/Richland/Kennewick SMM Food,134
968
+ 0.0,0.0,0.0,0.0,0.000404538370993667,0.0,0.0,3.74,9/27/2021,Yakima/Pasco/Richland/Kennewick SMM Food,135
969
+ 0.0,0.0,0.0,0.0,0.0,0.0,0.015857284440039643,4.901,9/4/2023,Yakima/Pasco/Richland/Kennewick SMM Food,136
970
+ 0.0,0.0,0.0,0.005368223354373092,0.0,0.0,0.0,3.93,9/5/2022,Yakima/Pasco/Richland/Kennewick SMM Food,137
971
+ 0.0,0.0,0.0,0.0,0.0004614459094209107,0.0,0.0,3.81,9/6/2021,Yakima/Pasco/Richland/Kennewick SMM Food,138
Test/X_train_test_tuned_trend.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/X_train_tuned_trend.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/media_data.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/merged_df_contri.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/output_df.csv ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,paid_search,kwai,fb_level_achieved_tier_2,fb_level_achieved_tier_1,ga_app,digital_tactic_others,programmatic,f1,const
2
+ 2023-05-29,7.761772068985416,-0.11831412496677594,29.26262853674282,43.02259197416761,34.850430143372286,31.805310964227356,49.945005056325215,-151.2233076306245,3208.7414522702875
3
+ 2023-06-05,11.900777512763158,-0.2212240988214056,49.58946950913165,71.26050886089686,60.27543592613474,62.10940924204467,79.2264816017311,-286.5283723527622,4747.16623924949
4
+ 2023-06-12,12.282715596734517,-0.2048833704554769,48.252401507743485,70.09496805521223,70.9132464057077,62.522979876920985,81.71726972795152,-294.4874938070056,4755.355576471715
5
+ 2023-06-19,12.382302189764735,-0.2296347038287279,46.53951754306768,68.15735805665786,87.27506443802963,62.16527903772261,83.93193578834166,-310.40573671549237,4763.335036288525
6
+ 2023-06-26,11.696188946109924,-0.21004736562649393,44.41794375254801,67.67342484354124,95.3081258323134,61.04163282569863,84.24842600525427,-318.3648581697358,4756.71263706442
7
+ 2023-07-03,11.898849705377968,-0.21171921819363215,46.9589343899434,62.3806139692273,117.01657513265482,61.827996998986066,89.18225343091929,-334.28310107822256,4764.608039630399
8
+ 2023-07-10,11.400078866984943,-0.20451126846569176,51.51273512856333,62.14094623079805,119.16568176464439,58.064920572392516,85.76433103185752,-342.242222532466,4772.288544720711
9
+ 2023-07-17,12.240551031341669,-0.20879227519812163,53.406074306806204,66.62714284775411,120.08780443602339,53.92649980095306,84.74701307508934,-358.16046544095275,4765.362259286595
10
+ 2023-07-24,12.472994192760371,-0.20201100495743263,51.138519266662804,68.11537266284667,135.7641063558982,53.40467326346821,85.38679362668982,-374.0787083494395,4772.94893420709
11
+ 2023-07-31,12.216919598346994,-0.20118792897095253,52.36907023775602,69.38935909702018,136.58185949073408,51.25674449278376,81.80915243758835,-389.99695125792636,4780.3159616991115
12
+ 2023-08-07,11.68184289582116,-0.1900559572480093,51.7674320981761,66.6880448645572,132.68440248302835,49.73440953073621,81.53670989501589,-405.91519416641313,4758.683687475835
13
+ 2023-08-14,11.030712912279618,-0.18532033476535537,51.65737080344436,64.15587643429623,144.0217777883639,48.760065010063165,84.94872431432898,-421.8334370748999,4751.907827482204
14
+ 2023-08-21,12.174149234047514,-0.1788917290046374,49.945758769275564,63.42762001621204,139.79609107610307,49.58095128524336,79.62779039781014,-437.7516799833867,4745.263040561774
15
+ 2023-08-28,11.475760787789591,-0.17897129727260774,47.86484019659933,63.16888640925602,119.34747622797671,48.55511494884034,79.18275616309377,-437.7516799833867,4724.364689256547
16
+ 2023-09-04,10.784548681845763,-0.18107805565532287,48.09059891962533,64.08470600801677,120.9156275735582,49.37148058444818,76.67002062964586,-437.7516799833867,4718.339675367797
17
+ 2023-09-11,10.460607422586236,-0.1679667399423954,49.62711002315703,64.33927808054996,107.78396054011917,51.0983128811782,80.78429460638174,-429.7925585291433,4712.462435247174
18
+ 2023-09-18,11.01278154591493,-0.16178665522614283,50.42367669887675,59.83196612699692,87.95063414123518,50.83166592589223,81.26099096254094,-429.7925585291433,4692.348103995998
19
+ 2023-09-25,11.327684294221173,-0.16353545230736108,49.60486279452533,59.82025278209932,81.45747658861694,51.747401338722035,82.33301818385348,-405.91519416641313,4687.123351093481
20
+ 2023-10-02,11.231549544405924,-0.17486349329323414,46.85718784382516,63.95205633846565,84.89825241976841,50.33664960147841,80.98101404521579,-382.03782980368294,4682.062375756669
21
+ 2023-10-09,11.251590868928977,-0.1654682137284127,46.54594119804424,65.87573682348982,68.12094681690598,47.36954672121316,77.92215543618711,-366.11958689519616,4662.780071210013
22
+ 2023-10-16,11.913767940099804,-0.16718933892723858,47.525395858768135,66.68707816679074,62.77619484285204,46.98492917212639,74.39447439940525,-342.242222532466,4672.790714513497
23
+ 2023-10-23,12.751773182921884,-0.18943906693249418,47.705605391283164,62.03932213297635,63.08428259541279,46.647413021686255,74.8153365723307,-318.3648581697358,4682.632382943418
24
+ 2023-10-30,12.15172802085707,-0.19964377212864787,48.19404180459145,60.82548461564065,56.2821737810174,48.472255554281546,79.45239812058935,-302.446615261249,4692.300397179917
25
+ 2023-11-06,12.315626230257198,-0.22454915335644057,47.654754547692086,64.99799055542847,47.93842126614167,52.03374245039889,82.85114865344232,-286.5283723527622,4701.790129360621
26
+ 2023-11-13,12.057771016456664,-0.23114982148024918,47.25937342177303,65.78730201930323,48.68731998881546,52.66557624111979,82.51201963559883,-286.5283723527622,4711.097004451976
27
+ 2023-11-20,11.25530939574993,-0.21876701155401534,48.16411014600904,66.77377800218942,48.07060214377797,55.589681651747284,75.72366775862979,-278.5692508985188,4720.216501604931
28
+ 2023-11-27,11.831475124951874,-0.21899193223555222,50.12740561124711,68.71104581693022,52.39831796372385,61.59004202167329,80.66941943577457,-278.5692508985188,4729.144155494561
29
+ 2023-12-04,11.663983873121959,-0.21787078177757843,53.06860015718747,70.48587869707336,55.57760064435842,62.407241387586325,85.24225869415339,-286.5283723527622,4737.875557643242
Test/scenario_test_df.csv ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ other_contributions,correction,sales
2
+ 3092.2502606580683,0.018289272297352,161.77901932815132
3
+ 4520.6920787240415,12.691006151152578,261.39564057541395
4
+ 4531.576445699961,13.180430267972042,261.6899044965908
5
+ 4539.974729307233,11.415759970162071,261.7606326453921
6
+ 4533.445857361371,7.034293127891942,262.04332324526104
7
+ 4547.129794466638,10.55839324772478,261.6902552467294
8
+ 4549.007492684424,7.134844942079326,261.74816688851763
9
+ 4527.080806006467,10.047752584746377,260.89952847719786
10
+ 4534.432321208591,10.417247571706866,260.10110544072165
11
+ 4526.699682002948,5.6167603548483385,261.4244855086468
12
+ 4485.262839835202,0.6467608214952634,260.76167846281174
13
+ 4473.910847860902,-1.5698341209472346,262.12258359536
14
+ 4447.128559925485,-6.631915109862348,261.38818481245124
15
+ 4405.781514203864,-11.061565779265038,261.308924284844
16
+ 4401.322544902313,-13.048209237455922,262.0495640610377
17
+ 4390.285870518207,-5.424545971523912,261.7341489853767
18
+ 4350.344392952864,-8.48416165893741,261.8452429191589
19
+ 4362.502098063377,-6.76238707135326,261.59560646477416
20
+ 4384.747934879461,-7.684187682013544,261.0426450554038
21
+ 4364.615962917995,-12.088387690841955,261.05335873870496
22
+ 4393.1574974849555,-14.196460193362327,261.7021057305525
23
+ 4427.162368302163,-17.84564469086581,261.8050949920636
24
+ 4445.936311927557,-11.525826770700405,260.6217348866607
25
+ 4462.975629120644,-0.22793023673057178,260.08119267394966
26
+ 4473.024802266549,-1.1435299752947685,261.4255723095467
27
+ 4489.499085838636,-2.9266244485161224,260.43317140284114
28
+ 4502.754230627531,10.784780169006808,262.1446078415698
29
+ 4506.706915153061,21.076207874711145,261.7917549344106
Test/x_test_contribution.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/x_test_to_save.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/x_train_contribution.csv ADDED
The diff for this file is too large to render. See raw diff
 
Test/x_train_to_save.csv ADDED
The diff for this file is too large to render. See raw diff
 
Transformation_functions.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ from Eda_functions import format_numbers,line_plot,summary
6
+ import numpy as np
7
+ import re
8
+
9
+ def sanitize_key(key, prefix=""):
10
+ # Use regular expressions to remove non-alphanumeric characters and spaces
11
+ key = re.sub(r'[^a-zA-Z0-9]', '', key)
12
+ return f"{prefix}{key}"
13
+
14
+
15
+ def check_box(options, ad_stock_value,lag_value,num_columns=4, prefix=""):
16
+ num_rows = -(-len(options) // num_columns) # Ceiling division to calculate rows
17
+
18
+ selected_options = []
19
+ adstock_info = {} # Store adstock and lag info for each selected option
20
+ if ad_stock_value!=0:
21
+ for row in range(num_rows):
22
+ cols = st.columns(num_columns)
23
+ for col in cols:
24
+ if options:
25
+ option = options.pop(0)
26
+ key = sanitize_key(f"{option}_{row}", prefix=prefix)
27
+ selected = col.checkbox(option, key=key)
28
+ if selected:
29
+ selected_options.append(option)
30
+
31
+ # Input minimum and maximum adstock values
32
+ adstock = col.slider('Select Adstock Range', 0.0, 1.0, ad_stock_value, step=0.05, format="%.2f",key= f"adstock_{key}" )
33
+
34
+ # Input minimum and maximum lag values
35
+ lag = col.slider('Select Lag Range', 0, 7, lag_value, step=1,key=f"lag_{key}" )
36
+
37
+ # Create a dictionary to store adstock and lag info for the option
38
+ option_info = {
39
+ 'adstock': adstock,
40
+ 'lag': lag}
41
+ # Append the dictionary to the adstock_info list
42
+ adstock_info[option]=option_info
43
+
44
+ else:adstock_info[option]={
45
+ 'adstock': ad_stock_value,
46
+ 'lag': lag_value}
47
+
48
+ return selected_options, adstock_info
49
+ else:
50
+ for row in range(num_rows):
51
+ cols = st.columns(num_columns)
52
+ for col in cols:
53
+ if options:
54
+ option = options.pop(0)
55
+ key = sanitize_key(f"{option}_{row}", prefix=prefix)
56
+ selected = col.checkbox(option, key=key)
57
+ if selected:
58
+ selected_options.append(option)
59
+
60
+ # Input minimum and maximum lag values
61
+ lag = col.slider('Select Lag Range', 0, 7, lag_value, step=1,key=f"lag_{key}" )
62
+
63
+ # dictionary to store adstock and lag info for the option
64
+ option_info = {
65
+ 'lag': lag}
66
+ # Append the dictionary to the adstock_info list
67
+ adstock_info[option]=option_info
68
+
69
+ else:adstock_info[option]={
70
+ 'lag': lag_value}
71
+
72
+ return selected_options, adstock_info
73
+
74
+ def apply_lag(X, features,lag_dict):
75
+ #lag_data=pd.DataFrame()
76
+ for col in features:
77
+ for lag in range(lag_dict[col]['lag'][0], lag_dict[col]['lag'][1] + 1):
78
+ if lag>0:
79
+ X[f'{col}_lag{lag}'] = X[col].shift(periods=lag, fill_value=0)
80
+ return X
81
+
82
+ def apply_adstock(X, variable_name, decay):
83
+ values = X[variable_name].values
84
+ adstock = np.zeros(len(values))
85
+
86
+ for row in range(len(values)):
87
+ if row == 0:
88
+ adstock[row] = values[row]
89
+ else:
90
+ adstock[row] = values[row] + adstock[row - 1] * decay
91
+
92
+ return adstock
93
+
94
+ def top_correlated_features(df,target,media_data):
95
+ corr_df=df.drop(target,axis=1)
96
+ #corr_df[target]=df[target]
97
+ #st.dataframe(corr_df)
98
+ for i in media_data:
99
+ #st.write(media_data[2])
100
+ #st.dataframe(corr_df.filter(like=media_data[2]))
101
+ d=(pd.concat([corr_df.filter(like=i),df[target]],axis=1)).corr()[target]
102
+ d=d.sort_values(ascending=False)
103
+ d=d.drop(target,axis=0)
104
+ corr=pd.DataFrame({'Feature_name':d.index,"Correlation":d.values})
105
+ corr.columns = pd.MultiIndex.from_product([[i], ['Feature_name', 'Correlation']])
106
+
107
+ return corr
108
+
109
+ def top_correlated_features(df,variables,target):
110
+ correlation_df=pd.DataFrame()
111
+ for col in variables:
112
+ d=pd.concat([df.filter(like=col),df[target]],axis=1).corr()[target]
113
+ #st.dataframe(d)
114
+ d=d.sort_values(ascending=False).iloc[1:]
115
+ corr_df=pd.DataFrame({'Media_channel':d.index,'Correlation':d.values})
116
+ corr_df.columns=pd.MultiIndex.from_tuples([(col, 'Variable'), (col, 'Correlation')])
117
+ correlation_df=pd.concat([corr_df,correlation_df],axis=1)
118
+ return correlation_df
119
+
120
+ def top_correlated_feature(df,variable,target):
121
+ d=pd.concat([df.filter(like=variable),df[target]],axis=1).corr()[target]
122
+ # st.dataframe(d)
123
+ d=d.sort_values(ascending=False).iloc[1:]
124
+ # st.dataframe(d)
125
+ corr_df=pd.DataFrame({'Media_channel':d.index,'Correlation':d.values})
126
+ corr_df['Adstock']=corr_df['Media_channel'].map(lambda x:x.split('_adst')[1] if len(x.split('_adst'))>1 else '-')
127
+ corr_df['Lag']=corr_df['Media_channel'].map(lambda x:x.split('_lag')[1][0] if len(x.split('_lag'))>1 else '-' )
128
+ corr_df.drop(['Correlation'],axis=1,inplace=True)
129
+ corr_df['Correlation']=np.round(d.values,2)
130
+ sorted_corr_df= corr_df.loc[corr_df['Correlation'].abs().sort_values(ascending=False).index]
131
+ #corr_df.columns=pd.MultiIndex.from_tuples([(variable, 'Variable'), (variable, 'Correlation')])
132
+ #correlation_df=pd.concat([corr_df,correlation_df],axis=1)
133
+ return sorted_corr_df
Users/saved_scenarios.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b09928ce441321b24be8466d1d76e7bd4427a35d5ea9cf31e49fcdfc0f4e8454
3
+ size 13213
classes-gk.py ADDED
@@ -0,0 +1,541 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.optimize import minimize, LinearConstraint, NonlinearConstraint
3
+ from collections import OrderedDict
4
+ import pandas as pd
5
+ from numerize.numerize import numerize
6
+
7
+
8
+ def class_to_dict(class_instance):
9
+ attr_dict = {}
10
+ if isinstance(class_instance, Channel):
11
+ attr_dict["type"] = "Channel"
12
+ attr_dict["name"] = class_instance.name
13
+ attr_dict["dates"] = class_instance.dates
14
+ attr_dict["spends"] = class_instance.actual_spends
15
+ attr_dict["conversion_rate"] = class_instance.conversion_rate
16
+ attr_dict["modified_spends"] = class_instance.modified_spends
17
+ attr_dict["modified_sales"] = class_instance.modified_sales
18
+ attr_dict["response_curve_type"] = class_instance.response_curve_type
19
+ attr_dict["response_curve_params"] = (
20
+ class_instance.response_curve_params
21
+ )
22
+ attr_dict["penalty"] = class_instance.penalty
23
+ attr_dict["bounds"] = class_instance.bounds
24
+ attr_dict["actual_total_spends"] = class_instance.actual_total_spends
25
+ attr_dict["actual_total_sales"] = class_instance.actual_total_sales
26
+ attr_dict["modified_total_spends"] = (
27
+ class_instance.modified_total_spends
28
+ )
29
+ attr_dict["modified_total_sales"] = class_instance.modified_total_sales
30
+ attr_dict["actual_mroi"] = class_instance.get_marginal_roi("actual")
31
+ attr_dict["modified_mroi"] = class_instance.get_marginal_roi(
32
+ "modified"
33
+ )
34
+
35
+ elif isinstance(class_instance, Scenario):
36
+ attr_dict["type"] = "Scenario"
37
+ attr_dict["name"] = class_instance.name
38
+ channels = []
39
+ for channel in class_instance.channels.values():
40
+ channels.append(class_to_dict(channel))
41
+ attr_dict["channels"] = channels
42
+ attr_dict["constant"] = class_instance.constant
43
+ attr_dict["correction"] = class_instance.correction
44
+ attr_dict["actual_total_spends"] = class_instance.actual_total_spends
45
+ attr_dict["actual_total_sales"] = class_instance.actual_total_sales
46
+ attr_dict["modified_total_spends"] = (
47
+ class_instance.modified_total_spends
48
+ )
49
+ attr_dict["modified_total_sales"] = class_instance.modified_total_sales
50
+
51
+ return attr_dict
52
+
53
+
54
+ def class_from_dict(attr_dict):
55
+ if attr_dict["type"] == "Channel":
56
+ return Channel.from_dict(attr_dict)
57
+ elif attr_dict["type"] == "Scenario":
58
+ return Scenario.from_dict(attr_dict)
59
+
60
+
61
+ class Channel:
62
+ def __init__(
63
+ self,
64
+ name,
65
+ dates,
66
+ spends,
67
+ response_curve_type,
68
+ response_curve_params,
69
+ bounds,
70
+ conversion_rate=1,
71
+ modified_spends=None,
72
+ penalty=True,
73
+ ):
74
+ self.name = name
75
+ self.dates = dates
76
+ self.conversion_rate = conversion_rate
77
+ self.actual_spends = spends.copy()
78
+
79
+ if modified_spends is None:
80
+ self.modified_spends = self.actual_spends.copy()
81
+ else:
82
+ self.modified_spends = modified_spends
83
+
84
+ self.response_curve_type = response_curve_type
85
+ self.response_curve_params = response_curve_params
86
+ self.bounds = bounds
87
+ self.penalty = penalty
88
+
89
+ self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
90
+ self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
91
+ # self.actual_sales = None
92
+ # self.actual_sales = self.response_curve(self.actual_spends)
93
+ self.actual_total_spends = self.actual_spends.sum()
94
+ self.actual_total_sales = self.actual_sales.sum()
95
+ self.modified_sales = self.calculate_sales()
96
+ self.modified_total_spends = self.modified_spends.sum()
97
+ self.modified_total_sales = self.modified_sales.sum()
98
+ self.delta_spends = (
99
+ self.modified_total_spends - self.actual_total_spends
100
+ )
101
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
102
+
103
+ @property
104
+ def actual_sales(self):
105
+ return self.response_curve(self.actual_spends)
106
+
107
+ def update_penalty(self, penalty):
108
+ self.penalty = penalty
109
+
110
+ def _modify_spends(self, spends_array, total_spends):
111
+ return spends_array * total_spends / spends_array.sum()
112
+
113
+ def modify_spends(self, total_spends):
114
+ self.modified_spends = (
115
+ self.modified_spends * total_spends / self.modified_spends.sum()
116
+ )
117
+
118
+ def calculate_sales(self):
119
+ return self.response_curve(self.modified_spends)
120
+
121
+ def response_curve(self, x):
122
+ if self.penalty:
123
+ x = np.where(
124
+ x < self.upper_limit,
125
+ x,
126
+ self.upper_limit
127
+ + (x - self.upper_limit) * self.upper_limit / x,
128
+ )
129
+ if self.response_curve_type == "s-curve":
130
+ if self.power >= 0:
131
+ x = x / 10**self.power
132
+ x = x.astype("float64")
133
+ K = self.response_curve_params["K"]
134
+ b = self.response_curve_params["b"]
135
+ a = self.response_curve_params["a"]
136
+ x0 = self.response_curve_params["x0"]
137
+ sales = K / (1 + b * np.exp(-a * (x - x0)))
138
+ if self.response_curve_type == "linear":
139
+ beta = self.response_curve_params["beta"]
140
+ sales = beta * x
141
+
142
+ return sales
143
+
144
+ def get_marginal_roi(self, flag):
145
+ K = self.response_curve_params["K"]
146
+ a = self.response_curve_params["a"]
147
+ # x = self.modified_total_spends
148
+ # if self.power >= 0 :
149
+ # x = x / 10**self.power
150
+ # x = x.astype('float64')
151
+ # return K*b*a*np.exp(-a*(x-x0)) / (1 + b * np.exp(-a*(x - x0)))**2
152
+ if flag == "actual":
153
+ y = self.response_curve(self.actual_spends)
154
+ # spends_array = self.actual_spends
155
+ # total_spends = self.actual_total_spends
156
+ # total_sales = self.actual_total_sales
157
+
158
+ else:
159
+ y = self.response_curve(self.modified_spends)
160
+ # spends_array = self.modified_spends
161
+ # total_spends = self.modified_total_spends
162
+ # total_sales = self.modified_total_sales
163
+
164
+ # spends_inc_1 = self._modify_spends(spends_array, total_spends+1)
165
+ mroi = a * (y) * (1 - y / K)
166
+ return mroi.sum() / len(self.modified_spends)
167
+ # spends_inc_1 = self.spends_array + 1
168
+ # new_total_sales = self.response_curve(spends_inc_1).sum()
169
+ # return (new_total_sales - total_sales) / len(self.modified_spends)
170
+
171
+ def update(self, total_spends):
172
+ self.modify_spends(total_spends)
173
+ self.modified_sales = self.calculate_sales()
174
+ self.modified_total_spends = self.modified_spends.sum()
175
+ self.modified_total_sales = self.modified_sales.sum()
176
+ self.delta_spends = (
177
+ self.modified_total_spends - self.actual_total_spends
178
+ )
179
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
180
+
181
+ def intialize(self):
182
+ self.new_spends = self.old_spends
183
+
184
+ def __str__(self):
185
+ return f"{self.name},{self.actual_total_sales}, {self.modified_total_spends}"
186
+
187
+ @classmethod
188
+ def from_dict(cls, attr_dict):
189
+ return Channel(
190
+ name=attr_dict["name"],
191
+ dates=attr_dict["dates"],
192
+ spends=attr_dict["spends"],
193
+ bounds=attr_dict["bounds"],
194
+ modified_spends=attr_dict["modified_spends"],
195
+ response_curve_type=attr_dict["response_curve_type"],
196
+ response_curve_params=attr_dict["response_curve_params"],
197
+ penalty=attr_dict["penalty"],
198
+ )
199
+
200
+ def update_response_curves(self, response_curve_params):
201
+ self.response_curve_params = response_curve_params
202
+
203
+
204
+ class Scenario:
205
+ def __init__(self, name, channels, constant, correction):
206
+ self.name = name
207
+ self.channels = channels
208
+ self.constant = constant
209
+ self.correction = correction
210
+
211
+ self.actual_total_spends = self.calculate_modified_total_spends()
212
+ self.actual_total_sales = self.calculate_actual_total_sales()
213
+ self.modified_total_sales = self.calculate_modified_total_sales()
214
+ self.modified_total_spends = self.calculate_modified_total_spends()
215
+ self.delta_spends = (
216
+ self.modified_total_spends - self.actual_total_spends
217
+ )
218
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
219
+
220
+ def update_penalty(self, value):
221
+ for channel in self.channels.values():
222
+ channel.update_penalty(value)
223
+
224
+ def calculate_modified_total_spends(self):
225
+ total_actual_spends = 0.0
226
+ for channel in self.channels.values():
227
+ total_actual_spends += (
228
+ channel.actual_total_spends * channel.conversion_rate
229
+ )
230
+ return total_actual_spends
231
+
232
+ def calculate_modified_total_spends(self):
233
+ total_modified_spends = 0.0
234
+ for channel in self.channels.values():
235
+ # import streamlit as st
236
+ # st.write(channel.modified_total_spends )
237
+ total_modified_spends += (
238
+ channel.modified_total_spends * channel.conversion_rate
239
+ )
240
+ return total_modified_spends
241
+
242
+ def calculate_actual_total_sales(self):
243
+ total_actual_sales = self.constant.sum() + self.correction.sum()
244
+ for channel in self.channels.values():
245
+ total_actual_sales += channel.actual_total_sales
246
+ return total_actual_sales
247
+
248
+ def calculate_modified_total_sales(self):
249
+ total_modified_sales = self.constant.sum() + self.correction.sum()
250
+ for channel in self.channels.values():
251
+ total_modified_sales += channel.modified_total_sales
252
+ return total_modified_sales
253
+
254
+ def update(self, channel_name, modified_spends):
255
+ self.channels[channel_name].update(modified_spends)
256
+ self.modified_total_sales = self.calculate_modified_total_sales()
257
+ self.modified_total_spends = self.calculate_modified_total_spends()
258
+ self.delta_spends = (
259
+ self.modified_total_spends - self.actual_total_spends
260
+ )
261
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
262
+
263
+ # def optimize_spends(self, sales_percent, channels_list, algo="COBYLA"):
264
+ # desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
265
+
266
+ # def constraint(x):
267
+ # for ch, spends in zip(channels_list, x):
268
+ # self.update(ch, spends)
269
+ # return self.modified_total_sales - desired_sales
270
+
271
+ # bounds = []
272
+ # for ch in channels_list:
273
+ # bounds.append(
274
+ # (1 + np.array([-50.0, 100.0]) / 100.0)
275
+ # * self.channels[ch].actual_total_spends
276
+ # )
277
+
278
+ # initial_point = []
279
+ # for bound in bounds:
280
+ # initial_point.append(bound[0])
281
+
282
+ # power = np.ceil(np.log(sum(initial_point)) / np.log(10))
283
+
284
+ # constraints = [NonlinearConstraint(constraint, -1.0, 1.0)]
285
+
286
+ # res = minimize(
287
+ # lambda x: sum(x) / 10 ** (power),
288
+ # bounds=bounds,
289
+ # x0=initial_point,
290
+ # constraints=constraints,
291
+ # method=algo,
292
+ # options={"maxiter": int(2e7), "catol": 1},
293
+ # )
294
+
295
+ # for channel_name, modified_spends in zip(channels_list, res.x):
296
+ # self.update(channel_name, modified_spends)
297
+
298
+ # return zip(channels_list, res.x)
299
+
300
+ def optimize_spends(
301
+ self, sales_percent, channels_list, algo="trust-constr"
302
+ ):
303
+ desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
304
+
305
+ def constraint(x):
306
+ for ch, spends in zip(channels_list, x):
307
+ self.update(ch, spends)
308
+ return self.modified_total_sales - desired_sales
309
+
310
+ bounds = []
311
+ for ch in channels_list:
312
+ bounds.append(
313
+ (1 + np.array([-50.0, 100.0]) / 100.0)
314
+ * self.channels[ch].actual_total_spends
315
+ )
316
+
317
+ initial_point = []
318
+ for bound in bounds:
319
+ initial_point.append(bound[0])
320
+
321
+ power = np.ceil(np.log(sum(initial_point)) / np.log(10))
322
+
323
+ constraints = [NonlinearConstraint(constraint, -1.0, 1.0)]
324
+
325
+ res = minimize(
326
+ lambda x: sum(x) / 10 ** (power),
327
+ bounds=bounds,
328
+ x0=initial_point,
329
+ constraints=constraints,
330
+ method=algo,
331
+ options={"maxiter": int(2e7), "xtol": 100},
332
+ )
333
+
334
+ for channel_name, modified_spends in zip(channels_list, res.x):
335
+ self.update(channel_name, modified_spends)
336
+
337
+ return zip(channels_list, res.x)
338
+
339
+ def optimize(self, spends_percent, channels_list):
340
+ # channels_list = self.channels.keys()
341
+ num_channels = len(channels_list)
342
+ spends_constant = []
343
+ spends_constraint = 0.0
344
+ for channel_name in channels_list:
345
+ # spends_constraint += self.channels[channel_name].modified_total_spends
346
+ spends_constant.append(self.channels[channel_name].conversion_rate)
347
+ spends_constraint += (
348
+ self.channels[channel_name].actual_total_spends
349
+ * self.channels[channel_name].conversion_rate
350
+ )
351
+ spends_constraint = spends_constraint * (1 + spends_percent / 100)
352
+ # constraint= LinearConstraint(np.ones((num_channels,)), lb = spends_constraint, ub = spends_constraint)
353
+ constraint = LinearConstraint(
354
+ np.array(spends_constant),
355
+ lb=spends_constraint,
356
+ ub=spends_constraint,
357
+ )
358
+ bounds = []
359
+ old_spends = []
360
+ for channel_name in channels_list:
361
+ _channel_class = self.channels[channel_name]
362
+ channel_bounds = _channel_class.bounds
363
+ channel_actual_total_spends = (
364
+ _channel_class.actual_total_spends
365
+ * ((1 + spends_percent / 100))
366
+ )
367
+ old_spends.append(channel_actual_total_spends)
368
+ bounds.append(
369
+ (1 + channel_bounds / 100) * channel_actual_total_spends
370
+ )
371
+
372
+ def objective_function(x):
373
+ for channel_name, modified_spends in zip(channels_list, x):
374
+ self.update(channel_name, modified_spends)
375
+ return -1 * self.modified_total_sales
376
+
377
+ res = minimize(
378
+ lambda x: objective_function(x) / 1e8,
379
+ method="trust-constr",
380
+ x0=old_spends,
381
+ constraints=constraint,
382
+ bounds=bounds,
383
+ options={"maxiter": int(1e7), "xtol": 100},
384
+ )
385
+ # res = dual_annealing(
386
+ # objective_function,
387
+ # x0=old_spends,
388
+ # mi
389
+ # constraints=constraint,
390
+ # bounds=bounds,
391
+ # tol=1e-16
392
+ # )
393
+ print(res)
394
+ for channel_name, modified_spends in zip(channels_list, res.x):
395
+ self.update(channel_name, modified_spends)
396
+
397
+ return zip(channels_list, res.x)
398
+
399
+ def save(self):
400
+ details = {}
401
+ actual_list = []
402
+ modified_list = []
403
+ data = {}
404
+ channel_data = []
405
+
406
+ summary_rows = []
407
+ actual_list.append(
408
+ {
409
+ "name": "Total",
410
+ "Spends": self.actual_total_spends,
411
+ "Sales": self.actual_total_sales,
412
+ }
413
+ )
414
+ modified_list.append(
415
+ {
416
+ "name": "Total",
417
+ "Spends": self.modified_total_spends,
418
+ "Sales": self.modified_total_sales,
419
+ }
420
+ )
421
+ for channel in self.channels.values():
422
+ name_mod = channel.name.replace("_", " ")
423
+ if name_mod.lower().endswith(" imp"):
424
+ name_mod = name_mod.replace("Imp", " Impressions")
425
+ summary_rows.append(
426
+ [
427
+ name_mod,
428
+ channel.actual_total_spends,
429
+ channel.modified_total_spends,
430
+ channel.actual_total_sales,
431
+ channel.modified_total_sales,
432
+ round(
433
+ channel.actual_total_sales
434
+ / channel.actual_total_spends,
435
+ 2,
436
+ ),
437
+ round(
438
+ channel.modified_total_sales
439
+ / channel.modified_total_spends,
440
+ 2,
441
+ ),
442
+ channel.get_marginal_roi("actual"),
443
+ channel.get_marginal_roi("modified"),
444
+ ]
445
+ )
446
+ data[channel.name] = channel.modified_spends
447
+ data["Date"] = channel.dates
448
+ data["Sales"] = (
449
+ data.get("Sales", np.zeros((len(channel.dates),)))
450
+ + channel.modified_sales
451
+ )
452
+ actual_list.append(
453
+ {
454
+ "name": channel.name,
455
+ "Spends": channel.actual_total_spends,
456
+ "Sales": channel.actual_total_sales,
457
+ "ROI": round(
458
+ channel.actual_total_sales
459
+ / channel.actual_total_spends,
460
+ 2,
461
+ ),
462
+ }
463
+ )
464
+ modified_list.append(
465
+ {
466
+ "name": channel.name,
467
+ "Spends": channel.modified_total_spends,
468
+ "Sales": channel.modified_total_sales,
469
+ "ROI": round(
470
+ channel.modified_total_sales
471
+ / channel.modified_total_spends,
472
+ 2,
473
+ ),
474
+ "Marginal ROI": channel.get_marginal_roi("modified"),
475
+ }
476
+ )
477
+
478
+ channel_data.append(
479
+ {
480
+ "channel": channel.name,
481
+ "spends_act": channel.actual_total_spends,
482
+ "spends_mod": channel.modified_total_spends,
483
+ "sales_act": channel.actual_total_sales,
484
+ "sales_mod": channel.modified_total_sales,
485
+ }
486
+ )
487
+ summary_rows.append(
488
+ [
489
+ "Total",
490
+ self.actual_total_spends,
491
+ self.modified_total_spends,
492
+ self.actual_total_sales,
493
+ self.modified_total_sales,
494
+ round(self.actual_total_sales / self.actual_total_spends, 2),
495
+ round(
496
+ self.modified_total_sales / self.modified_total_spends, 2
497
+ ),
498
+ 0.0,
499
+ 0.0,
500
+ ]
501
+ )
502
+ details["Actual"] = actual_list
503
+ details["Modified"] = modified_list
504
+ columns_index = pd.MultiIndex.from_product(
505
+ [[""], ["Channel"]], names=["first", "second"]
506
+ )
507
+ columns_index = columns_index.append(
508
+ pd.MultiIndex.from_product(
509
+ [["Spends", "NRPU", "ROI", "MROI"], ["Actual", "Simulated"]],
510
+ names=["first", "second"],
511
+ )
512
+ )
513
+ details["Summary"] = pd.DataFrame(summary_rows, columns=columns_index)
514
+ data_df = pd.DataFrame(data)
515
+ channel_list = list(self.channels.keys())
516
+ data_df = data_df[["Date", *channel_list, "Sales"]]
517
+
518
+ details["download"] = {
519
+ "data_df": data_df,
520
+ "channels_df": pd.DataFrame(channel_data),
521
+ "total_spends_act": self.actual_total_spends,
522
+ "total_sales_act": self.actual_total_sales,
523
+ "total_spends_mod": self.modified_total_spends,
524
+ "total_sales_mod": self.modified_total_sales,
525
+ }
526
+
527
+ return details
528
+
529
+ @classmethod
530
+ def from_dict(cls, attr_dict):
531
+ channels_list = attr_dict["channels"]
532
+ channels = {
533
+ channel["name"]: class_from_dict(channel)
534
+ for channel in channels_list
535
+ }
536
+ return Scenario(
537
+ name=attr_dict["name"],
538
+ channels=channels,
539
+ constant=attr_dict["constant"],
540
+ correction=attr_dict["correction"],
541
+ )
classes.py ADDED
@@ -0,0 +1,541 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.optimize import minimize, LinearConstraint, NonlinearConstraint
3
+ from collections import OrderedDict
4
+ import pandas as pd
5
+ from numerize.numerize import numerize
6
+
7
+
8
+ def class_to_dict(class_instance):
9
+ attr_dict = {}
10
+ if isinstance(class_instance, Channel):
11
+ attr_dict["type"] = "Channel"
12
+ attr_dict["name"] = class_instance.name
13
+ attr_dict["dates"] = class_instance.dates
14
+ attr_dict["spends"] = class_instance.actual_spends
15
+ attr_dict["conversion_rate"] = class_instance.conversion_rate
16
+ attr_dict["modified_spends"] = class_instance.modified_spends
17
+ attr_dict["modified_sales"] = class_instance.modified_sales
18
+ attr_dict["response_curve_type"] = class_instance.response_curve_type
19
+ attr_dict["response_curve_params"] = (
20
+ class_instance.response_curve_params
21
+ )
22
+ attr_dict["penalty"] = class_instance.penalty
23
+ attr_dict["bounds"] = class_instance.bounds
24
+ attr_dict["actual_total_spends"] = class_instance.actual_total_spends
25
+ attr_dict["actual_total_sales"] = class_instance.actual_total_sales
26
+ attr_dict["modified_total_spends"] = (
27
+ class_instance.modified_total_spends
28
+ )
29
+ attr_dict["modified_total_sales"] = class_instance.modified_total_sales
30
+ attr_dict["actual_mroi"] = class_instance.get_marginal_roi("actual")
31
+ attr_dict["modified_mroi"] = class_instance.get_marginal_roi(
32
+ "modified"
33
+ )
34
+
35
+ elif isinstance(class_instance, Scenario):
36
+ attr_dict["type"] = "Scenario"
37
+ attr_dict["name"] = class_instance.name
38
+ channels = []
39
+ for channel in class_instance.channels.values():
40
+ channels.append(class_to_dict(channel))
41
+ attr_dict["channels"] = channels
42
+ attr_dict["constant"] = class_instance.constant
43
+ attr_dict["correction"] = class_instance.correction
44
+ attr_dict["actual_total_spends"] = class_instance.actual_total_spends
45
+ attr_dict["actual_total_sales"] = class_instance.actual_total_sales
46
+ attr_dict["modified_total_spends"] = (
47
+ class_instance.modified_total_spends
48
+ )
49
+ attr_dict["modified_total_sales"] = class_instance.modified_total_sales
50
+
51
+ return attr_dict
52
+
53
+
54
+ def class_from_dict(attr_dict):
55
+ if attr_dict["type"] == "Channel":
56
+ return Channel.from_dict(attr_dict)
57
+ elif attr_dict["type"] == "Scenario":
58
+ return Scenario.from_dict(attr_dict)
59
+
60
+
61
+ class Channel:
62
+ def __init__(
63
+ self,
64
+ name,
65
+ dates,
66
+ spends,
67
+ response_curve_type,
68
+ response_curve_params,
69
+ bounds,
70
+ conversion_rate=1,
71
+ modified_spends=None,
72
+ penalty=True,
73
+ ):
74
+ self.name = name
75
+ self.dates = dates
76
+ self.conversion_rate = conversion_rate
77
+ self.actual_spends = spends.copy()
78
+
79
+ if modified_spends is None:
80
+ self.modified_spends = self.actual_spends.copy()
81
+ else:
82
+ self.modified_spends = modified_spends
83
+
84
+ self.response_curve_type = response_curve_type
85
+ self.response_curve_params = response_curve_params
86
+ self.bounds = bounds
87
+ self.penalty = penalty
88
+
89
+ self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
90
+ self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
91
+ # self.actual_sales = None
92
+ # self.actual_sales = self.response_curve(self.actual_spends)
93
+ self.actual_total_spends = self.actual_spends.sum()
94
+ self.actual_total_sales = self.actual_sales.sum()
95
+ self.modified_sales = self.calculate_sales()
96
+ self.modified_total_spends = self.modified_spends.sum()
97
+ self.modified_total_sales = self.modified_sales.sum()
98
+ self.delta_spends = (
99
+ self.modified_total_spends - self.actual_total_spends
100
+ )
101
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
102
+
103
+ @property
104
+ def actual_sales(self):
105
+ return self.response_curve(self.actual_spends)
106
+
107
+ def update_penalty(self, penalty):
108
+ self.penalty = penalty
109
+
110
+ def _modify_spends(self, spends_array, total_spends):
111
+ return spends_array * total_spends / spends_array.sum()
112
+
113
+ def modify_spends(self, total_spends):
114
+ self.modified_spends = (
115
+ self.modified_spends * total_spends / self.modified_spends.sum()
116
+ )
117
+
118
+ def calculate_sales(self):
119
+ return self.response_curve(self.modified_spends)
120
+
121
+ def response_curve(self, x):
122
+ if self.penalty:
123
+ x = np.where(
124
+ x < self.upper_limit,
125
+ x,
126
+ self.upper_limit
127
+ + (x - self.upper_limit) * self.upper_limit / x,
128
+ )
129
+ if self.response_curve_type == "s-curve":
130
+ if self.power >= 0:
131
+ x = x / 10**self.power
132
+ x = x.astype("float64")
133
+ K = self.response_curve_params["K"]
134
+ b = self.response_curve_params["b"]
135
+ a = self.response_curve_params["a"]
136
+ x0 = self.response_curve_params["x0"]
137
+ sales = K / (1 + b * np.exp(-a * (x - x0)))
138
+ if self.response_curve_type == "linear":
139
+ beta = self.response_curve_params["beta"]
140
+ sales = beta * x
141
+
142
+ return sales
143
+
144
+ def get_marginal_roi(self, flag):
145
+ K = self.response_curve_params["K"]
146
+ a = self.response_curve_params["a"]
147
+ # x = self.modified_total_spends
148
+ # if self.power >= 0 :
149
+ # x = x / 10**self.power
150
+ # x = x.astype('float64')
151
+ # return K*b*a*np.exp(-a*(x-x0)) / (1 + b * np.exp(-a*(x - x0)))**2
152
+ if flag == "actual":
153
+ y = self.response_curve(self.actual_spends)
154
+ # spends_array = self.actual_spends
155
+ # total_spends = self.actual_total_spends
156
+ # total_sales = self.actual_total_sales
157
+
158
+ else:
159
+ y = self.response_curve(self.modified_spends)
160
+ # spends_array = self.modified_spends
161
+ # total_spends = self.modified_total_spends
162
+ # total_sales = self.modified_total_sales
163
+
164
+ # spends_inc_1 = self._modify_spends(spends_array, total_spends+1)
165
+ mroi = a * (y) * (1 - y / K)
166
+ return mroi.sum() / len(self.modified_spends)
167
+ # spends_inc_1 = self.spends_array + 1
168
+ # new_total_sales = self.response_curve(spends_inc_1).sum()
169
+ # return (new_total_sales - total_sales) / len(self.modified_spends)
170
+
171
+ def update(self, total_spends):
172
+ self.modify_spends(total_spends)
173
+ self.modified_sales = self.calculate_sales()
174
+ self.modified_total_spends = self.modified_spends.sum()
175
+ self.modified_total_sales = self.modified_sales.sum()
176
+ self.delta_spends = (
177
+ self.modified_total_spends - self.actual_total_spends
178
+ )
179
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
180
+
181
+ def intialize(self):
182
+ self.new_spends = self.old_spends
183
+
184
+ def __str__(self):
185
+ return f"{self.name},{self.actual_total_sales}, {self.modified_total_spends}"
186
+
187
+ @classmethod
188
+ def from_dict(cls, attr_dict):
189
+ return Channel(
190
+ name=attr_dict["name"],
191
+ dates=attr_dict["dates"],
192
+ spends=attr_dict["spends"],
193
+ bounds=attr_dict["bounds"],
194
+ modified_spends=attr_dict["modified_spends"],
195
+ response_curve_type=attr_dict["response_curve_type"],
196
+ response_curve_params=attr_dict["response_curve_params"],
197
+ penalty=attr_dict["penalty"],
198
+ )
199
+
200
+ def update_response_curves(self, response_curve_params):
201
+ self.response_curve_params = response_curve_params
202
+
203
+
204
+ class Scenario:
205
+ def __init__(self, name, channels, constant, correction):
206
+ self.name = name
207
+ self.channels = channels
208
+ self.constant = constant
209
+ self.correction = correction
210
+
211
+ self.actual_total_spends = self.calculate_modified_total_spends()
212
+ self.actual_total_sales = self.calculate_actual_total_sales()
213
+ self.modified_total_sales = self.calculate_modified_total_sales()
214
+ self.modified_total_spends = self.calculate_modified_total_spends()
215
+ self.delta_spends = (
216
+ self.modified_total_spends - self.actual_total_spends
217
+ )
218
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
219
+
220
+ def update_penalty(self, value):
221
+ for channel in self.channels.values():
222
+ channel.update_penalty(value)
223
+
224
+ def calculate_modified_total_spends(self):
225
+ total_actual_spends = 0.0
226
+ for channel in self.channels.values():
227
+ total_actual_spends += (
228
+ channel.actual_total_spends * channel.conversion_rate
229
+ )
230
+ return total_actual_spends
231
+
232
+ def calculate_modified_total_spends(self):
233
+ total_modified_spends = 0.0
234
+ for channel in self.channels.values():
235
+ # import streamlit as st
236
+ # st.write(channel.modified_total_spends )
237
+ total_modified_spends += (
238
+ channel.modified_total_spends * channel.conversion_rate
239
+ )
240
+ return total_modified_spends
241
+
242
+ def calculate_actual_total_sales(self):
243
+ total_actual_sales = self.constant.sum() + self.correction.sum()
244
+ for channel in self.channels.values():
245
+ total_actual_sales += channel.actual_total_sales
246
+ return total_actual_sales
247
+
248
+ def calculate_modified_total_sales(self):
249
+ total_modified_sales = self.constant.sum() + self.correction.sum()
250
+ for channel in self.channels.values():
251
+ total_modified_sales += channel.modified_total_sales
252
+ return total_modified_sales
253
+
254
+ def update(self, channel_name, modified_spends):
255
+ self.channels[channel_name].update(modified_spends)
256
+ self.modified_total_sales = self.calculate_modified_total_sales()
257
+ self.modified_total_spends = self.calculate_modified_total_spends()
258
+ self.delta_spends = (
259
+ self.modified_total_spends - self.actual_total_spends
260
+ )
261
+ self.delta_sales = self.modified_total_sales - self.actual_total_sales
262
+
263
+ # def optimize_spends(self, sales_percent, channels_list, algo="COBYLA"):
264
+ # desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
265
+
266
+ # def constraint(x):
267
+ # for ch, spends in zip(channels_list, x):
268
+ # self.update(ch, spends)
269
+ # return self.modified_total_sales - desired_sales
270
+
271
+ # bounds = []
272
+ # for ch in channels_list:
273
+ # bounds.append(
274
+ # (1 + np.array([-50.0, 100.0]) / 100.0)
275
+ # * self.channels[ch].actual_total_spends
276
+ # )
277
+
278
+ # initial_point = []
279
+ # for bound in bounds:
280
+ # initial_point.append(bound[0])
281
+
282
+ # power = np.ceil(np.log(sum(initial_point)) / np.log(10))
283
+
284
+ # constraints = [NonlinearConstraint(constraint, -1.0, 1.0)]
285
+
286
+ # res = minimize(
287
+ # lambda x: sum(x) / 10 ** (power),
288
+ # bounds=bounds,
289
+ # x0=initial_point,
290
+ # constraints=constraints,
291
+ # method=algo,
292
+ # options={"maxiter": int(2e7), "catol": 1},
293
+ # )
294
+
295
+ # for channel_name, modified_spends in zip(channels_list, res.x):
296
+ # self.update(channel_name, modified_spends)
297
+
298
+ # return zip(channels_list, res.x)
299
+
300
+ def optimize_spends(
301
+ self, sales_percent, channels_list, algo="trust-constr"
302
+ ):
303
+ desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
304
+
305
+ def constraint(x):
306
+ for ch, spends in zip(channels_list, x):
307
+ self.update(ch, spends)
308
+ return self.modified_total_sales - desired_sales
309
+
310
+ bounds = []
311
+ for ch in channels_list:
312
+ bounds.append(
313
+ (1 + np.array([-50.0, 100.0]) / 100.0)
314
+ * self.channels[ch].actual_total_spends
315
+ )
316
+
317
+ initial_point = []
318
+ for bound in bounds:
319
+ initial_point.append(bound[0])
320
+
321
+ power = np.ceil(np.log(sum(initial_point)) / np.log(10))
322
+
323
+ constraints = [NonlinearConstraint(constraint, -1.0, 1.0)]
324
+
325
+ res = minimize(
326
+ lambda x: sum(x) / 10 ** (power),
327
+ bounds=bounds,
328
+ x0=initial_point,
329
+ constraints=constraints,
330
+ method=algo,
331
+ options={"maxiter": int(2e7), "xtol": 100},
332
+ )
333
+
334
+ for channel_name, modified_spends in zip(channels_list, res.x):
335
+ self.update(channel_name, modified_spends)
336
+
337
+ return zip(channels_list, res.x)
338
+
339
+ def optimize(self, spends_percent, channels_list):
340
+ # channels_list = self.channels.keys()
341
+ num_channels = len(channels_list)
342
+ spends_constant = []
343
+ spends_constraint = 0.0
344
+ for channel_name in channels_list:
345
+ # spends_constraint += self.channels[channel_name].modified_total_spends
346
+ spends_constant.append(self.channels[channel_name].conversion_rate)
347
+ spends_constraint += (
348
+ self.channels[channel_name].actual_total_spends
349
+ * self.channels[channel_name].conversion_rate
350
+ )
351
+ spends_constraint = spends_constraint * (1 + spends_percent / 100)
352
+ # constraint= LinearConstraint(np.ones((num_channels,)), lb = spends_constraint, ub = spends_constraint)
353
+ constraint = LinearConstraint(
354
+ np.array(spends_constant),
355
+ lb=spends_constraint,
356
+ ub=spends_constraint,
357
+ )
358
+ bounds = []
359
+ old_spends = []
360
+ for channel_name in channels_list:
361
+ _channel_class = self.channels[channel_name]
362
+ channel_bounds = _channel_class.bounds
363
+ channel_actual_total_spends = (
364
+ _channel_class.actual_total_spends
365
+ * ((1 + spends_percent / 100))
366
+ )
367
+ old_spends.append(channel_actual_total_spends)
368
+ bounds.append(
369
+ (1 + channel_bounds / 100) * channel_actual_total_spends
370
+ )
371
+
372
+ def objective_function(x):
373
+ for channel_name, modified_spends in zip(channels_list, x):
374
+ self.update(channel_name, modified_spends)
375
+ return -1 * self.modified_total_sales
376
+
377
+ res = minimize(
378
+ lambda x: objective_function(x) / 1e8,
379
+ method="trust-constr",
380
+ x0=old_spends,
381
+ constraints=constraint,
382
+ bounds=bounds,
383
+ options={"maxiter": int(1e7), "xtol": 100},
384
+ )
385
+ # res = dual_annealing(
386
+ # objective_function,
387
+ # x0=old_spends,
388
+ # mi
389
+ # constraints=constraint,
390
+ # bounds=bounds,
391
+ # tol=1e-16
392
+ # )
393
+ print(res)
394
+ for channel_name, modified_spends in zip(channels_list, res.x):
395
+ self.update(channel_name, modified_spends)
396
+
397
+ return zip(channels_list, res.x)
398
+
399
+ def save(self):
400
+ details = {}
401
+ actual_list = []
402
+ modified_list = []
403
+ data = {}
404
+ channel_data = []
405
+
406
+ summary_rows = []
407
+ actual_list.append(
408
+ {
409
+ "name": "Total",
410
+ "Spends": self.actual_total_spends,
411
+ "Sales": self.actual_total_sales,
412
+ }
413
+ )
414
+ modified_list.append(
415
+ {
416
+ "name": "Total",
417
+ "Spends": self.modified_total_spends,
418
+ "Sales": self.modified_total_sales,
419
+ }
420
+ )
421
+ for channel in self.channels.values():
422
+ name_mod = channel.name.replace("_", " ")
423
+ if name_mod.lower().endswith(" imp"):
424
+ name_mod = name_mod.replace("Imp", " Impressions")
425
+ summary_rows.append(
426
+ [
427
+ name_mod,
428
+ channel.actual_total_spends,
429
+ channel.modified_total_spends,
430
+ channel.actual_total_sales,
431
+ channel.modified_total_sales,
432
+ round(
433
+ channel.actual_total_sales
434
+ / channel.actual_total_spends,
435
+ 2,
436
+ ),
437
+ round(
438
+ channel.modified_total_sales
439
+ / channel.modified_total_spends,
440
+ 2,
441
+ ),
442
+ channel.get_marginal_roi("actual"),
443
+ channel.get_marginal_roi("modified"),
444
+ ]
445
+ )
446
+ data[channel.name] = channel.modified_spends
447
+ data["Date"] = channel.dates
448
+ data["Sales"] = (
449
+ data.get("Sales", np.zeros((len(channel.dates),)))
450
+ + channel.modified_sales
451
+ )
452
+ actual_list.append(
453
+ {
454
+ "name": channel.name,
455
+ "Spends": channel.actual_total_spends,
456
+ "Sales": channel.actual_total_sales,
457
+ "ROI": round(
458
+ channel.actual_total_sales
459
+ / channel.actual_total_spends,
460
+ 2,
461
+ ),
462
+ }
463
+ )
464
+ modified_list.append(
465
+ {
466
+ "name": channel.name,
467
+ "Spends": channel.modified_total_spends,
468
+ "Sales": channel.modified_total_sales,
469
+ "ROI": round(
470
+ channel.modified_total_sales
471
+ / channel.modified_total_spends,
472
+ 2,
473
+ ),
474
+ "Marginal ROI": channel.get_marginal_roi("modified"),
475
+ }
476
+ )
477
+
478
+ channel_data.append(
479
+ {
480
+ "channel": channel.name,
481
+ "spends_act": channel.actual_total_spends,
482
+ "spends_mod": channel.modified_total_spends,
483
+ "sales_act": channel.actual_total_sales,
484
+ "sales_mod": channel.modified_total_sales,
485
+ }
486
+ )
487
+ summary_rows.append(
488
+ [
489
+ "Total",
490
+ self.actual_total_spends,
491
+ self.modified_total_spends,
492
+ self.actual_total_sales,
493
+ self.modified_total_sales,
494
+ round(self.actual_total_sales / self.actual_total_spends, 2),
495
+ round(
496
+ self.modified_total_sales / self.modified_total_spends, 2
497
+ ),
498
+ 0.0,
499
+ 0.0,
500
+ ]
501
+ )
502
+ details["Actual"] = actual_list
503
+ details["Modified"] = modified_list
504
+ columns_index = pd.MultiIndex.from_product(
505
+ [[""], ["Channel"]], names=["first", "second"]
506
+ )
507
+ columns_index = columns_index.append(
508
+ pd.MultiIndex.from_product(
509
+ [["Spends", "NRPU", "ROI", "MROI"], ["Actual", "Simulated"]],
510
+ names=["first", "second"],
511
+ )
512
+ )
513
+ details["Summary"] = pd.DataFrame(summary_rows, columns=columns_index)
514
+ data_df = pd.DataFrame(data)
515
+ channel_list = list(self.channels.keys())
516
+ data_df = data_df[["Date", *channel_list, "Sales"]]
517
+
518
+ details["download"] = {
519
+ "data_df": data_df,
520
+ "channels_df": pd.DataFrame(channel_data),
521
+ "total_spends_act": self.actual_total_spends,
522
+ "total_sales_act": self.actual_total_sales,
523
+ "total_spends_mod": self.modified_total_spends,
524
+ "total_sales_mod": self.modified_total_sales,
525
+ }
526
+
527
+ return details
528
+
529
+ @classmethod
530
+ def from_dict(cls, attr_dict):
531
+ channels_list = attr_dict["channels"]
532
+ channels = {
533
+ channel["name"]: class_from_dict(channel)
534
+ for channel in channels_list
535
+ }
536
+ return Scenario(
537
+ name=attr_dict["name"],
538
+ channels=channels,
539
+ constant=attr_dict["constant"],
540
+ correction=attr_dict["correction"],
541
+ )
config.yaml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ credentials:
2
+ usernames:
3
+ geetha:
4
+ email: geethu4444@gmail.com
5
+ name: Geetha Krishna
6
+ password: '$2b$12$r.KJDzrp6kFErWwh/n7vh.eSvXNU60HBDjrQrNQqkqOH8KSlVacMu'
7
+ manoj:
8
+ email: manojp1732@gmail.com
9
+ name: Manoj P
10
+ password: '$2b$12$r.KJDzrp6kFErWwh/n7vh.eSvXNU60HBDjrQrNQqkqOH8KSlVacMu'
11
+ samkeet:
12
+ email: samkeet.sangai@blend360.com
13
+ name: 'Samkeet Sangai'
14
+ password: '$2b$12$r.KJDzrp6kFErWwh/n7vh.eSvXNU60HBDjrQrNQqkqOH8KSlVacMu'
15
+ srishti:
16
+ email: srishti.verma@blend360.com
17
+ name: 'Srishti Verma'
18
+ password: '$2b$12$r.KJDzrp6kFErWwh/n7vh.eSvXNU60HBDjrQrNQqkqOH8KSlVacMu'
19
+ Ismail:
20
+ email: mohammed.ismail@blend360.com
21
+ name: 'Ismail mohammed'
22
+ password: '$2b$12$r.KJDzrp6kFErWwh/n7vh.eSvXNU60HBDjrQrNQqkqOH8KSlVacMu'
23
+
24
+ cookie:
25
+ expiry_days: 1
26
+ key: some_signature_key
27
+ name: some_cookie_name
28
+ preauthorized:
29
+ emails:
30
+ - geethu4444@gmail.com
31
+ - manojp1732@gmail.com
32
+ - samkeet@gmail.com
data_test_overview_panel_#total_approved_accounts_appsflyer.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:31cebbaf2ba1e644eb5cf98e537f5d01171be4d3ea6b7a298800d4be28da0b92
3
+ size 1634822
data_test_overview_panel_#total_approved_accounts_revenue.xlsx ADDED
Binary file (215 kB). View file
 
db_creation.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ import uuid
3
+ import json
4
+ import streamlit as st
5
+ from utilities import (
6
+ load_local_css,
7
+ set_header,
8
+ load_authenticator,
9
+ send_email,
10
+ )
11
+ import streamlit_authenticator as stauth
12
+ import yaml
13
+ from yaml import SafeLoader
14
+
15
+
16
+
17
+ # st.set_page_config(layout="wide")
18
+ # load_local_css("styles.css")
19
+ # set_header()
20
+ # for k, v in st.session_state.items():
21
+ # if k not in ["logout", "login", "config"] and not k.startswith(
22
+ # "FormSubmitter"
23
+ # ):
24
+ # st.session_state[k] = v
25
+ # with open("config.yaml") as file:
26
+ # config = yaml.load(file, Loader=SafeLoader)
27
+ # st.session_state["config"] = config
28
+ # authenticator = stauth.Authenticate(
29
+ # config["credentials"],
30
+ # config["cookie"]["name"],
31
+ # config["cookie"]["key"],
32
+ # config["cookie"]["expiry_days"],
33
+ # config["preauthorized"],
34
+ # )
35
+ # st.session_state["authenticator"] = authenticator
36
+ # name, authentication_status, username = authenticator.login("Login", "main")
37
+ # auth_status = st.session_state.get("authentication_status")
38
+ # if auth_status == True:
39
+ # authenticator.logout("Logout", "main")
40
+ # is_state_initiaized = st.session_state.get("initialized", False)
41
+ # if not is_state_initiaized:
42
+ database_file = r'C:\Users\ManojP\Documents\Mastercard\Build\DB_Sample\DB\User.db'
43
+
44
+ conn = sqlite3.connect(database_file)
45
+ c = conn.cursor()
46
+
47
+
48
+ #c.execute('DROP TABLE IF EXISTS users ')
49
+ # c.execute('DROP TABLE IF EXISTS sessions ')
50
+ # conn.commit()
51
+
52
+ #output = c.fetchall()
53
+
54
+ #st.write(output)
55
+
56
+ c.execute('''CREATE TABLE IF NOT EXISTS users
57
+ (user_id INTEGER PRIMARY KEY,
58
+ username TEXT,
59
+ email TEXT,
60
+ user_type TEXT )''')
61
+
62
+ c.execute('''CREATE TABLE IF NOT EXISTS sessions
63
+ (user_id INTEGER,
64
+ owner TEXT,
65
+ session_id INTEGER,
66
+ session_name TEXT,
67
+ status TEXT,
68
+ created_time TIMESTAMP,
69
+ updated_time TIMESTAMP,
70
+ allowed_users TEXT)''')
71
+
72
+ #c.execute("DELETE FROM sessions")
73
+
74
+
75
+
76
+ user_id = str(uuid.uuid4())
77
+
78
+
79
+
80
+
81
+ # c.executemany("INSERT INTO users (username, email,user_type) VALUES (?, ?,?)",
82
+ # [("Geetha Krishna", "geetha1732@gmail.com","technical"),
83
+ # ("Samkeet Sangai", "samkeet.sangai@blend360.com","technical"),
84
+ # ('Manoj P','manojp1732@gmail.com',"technical"),
85
+ # ('Srishti Verma','srishti.verma@blend360.com',"technical"),
86
+ # ('Ismail mohammed',"mohammed.ismail@blend360.com","technical"),
87
+ # ('Sharon Sheng','sharon.sheng@mastercard.com',"technical"),
88
+ # ('Ioannis Papadopoulos','ioannis.papadopoulos@mastercard.com',"business"),
89
+ # ('Herman Kwong',"herman.kwong@mastercard.com",'technical'),
90
+
91
+ # ])
92
+
93
+
94
+
95
+
96
+ conn.commit()
97
+
98
+
lime_img.png ADDED
mastercard_logo.png ADDED
metrics_level_data/Overview_data_test_panel@#app_installs.xlsx ADDED
Binary file (28.1 kB). View file
 
metrics_level_data/Overview_data_test_panel@#revenue.xlsx ADDED
Binary file (28.1 kB). View file
 
model_output.csv ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ ,Model_object,Model_iteration,Feature_set,MAPE,R2,ADJR2,pos_count
2
+ 0,Model/model_0.pkl,0,"['paid_search_clicks_lag_1_moving_average_1_saturation_20_power_2_adstock_0_7', 'kwai_clicks_lag_2_moving_average_1_saturation_10_power_4_adstock_0_7', 'fb_level_achieved_tier_2_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'fb_level_achieved_tier_1_impressions_lag_2_moving_average_2_saturation_10_power_2_adstock_0_7', 'ga_app_clicks', 'digital_tactic_others_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'programmatic_clicks_lag_2_moving_average_1_saturation_10_power_2_adstock_0_7']",0.2246671699826956,0.8695595237589726,0.8694321404813935,8
3
+ 1,Model/model_1.pkl,1,"['paid_search_clicks_lag_1_moving_average_1_saturation_20_power_2_adstock_0_7', 'kwai_clicks_lag_2_moving_average_1_saturation_10_power_4_adstock_0_7', 'fb_level_achieved_tier_2_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'fb_level_achieved_tier_1_impressions_lag_2_moving_average_2_saturation_10_power_2_adstock_0_7', 'ga_app_clicks', 'digital_tactic_others_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'programmatic_clicks_lag_2_moving_average_1_saturation_20_power_2_adstock_0_7']",0.2246671699826956,0.8695595237589726,0.8694321404813935,8
4
+ 2,Model/model_2.pkl,2,"['paid_search_clicks_lag_1_moving_average_1_saturation_20_power_2_adstock_0_7', 'kwai_clicks_lag_2_moving_average_1_saturation_10_power_4_adstock_0_7', 'fb_level_achieved_tier_2_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'fb_level_achieved_tier_1_impressions_lag_2_moving_average_2_saturation_10_power_2_adstock_0_7', 'ga_app_clicks', 'digital_tactic_others_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'programmatic_impressions_lag_2_moving_average_1_saturation_10_power_3_adstock_0_7']",0.23058715311257882,0.8699421089682134,0.8698150993090027,8
5
+ 3,Model/model_3.pkl,3,"['paid_search_clicks_lag_1_moving_average_1_saturation_20_power_2_adstock_0_7', 'kwai_clicks_lag_2_moving_average_1_saturation_10_power_4_adstock_0_7', 'fb_level_achieved_tier_2_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'fb_level_achieved_tier_1_impressions_lag_2_moving_average_2_saturation_10_power_2_adstock_0_7', 'ga_app_clicks', 'digital_tactic_others_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'programmatic_impressions_lag_2_moving_average_1_saturation_20_power_3_adstock_0_7']",0.23058715311257882,0.8699421089682134,0.8698150993090027,8
6
+ 4,Model/model_4.pkl,4,"['paid_search_clicks_lag_1_moving_average_1_saturation_20_power_2_adstock_0_7', 'kwai_clicks_lag_2_moving_average_1_saturation_10_power_4_adstock_0_7', 'fb_level_achieved_tier_2_clicks_lag_2_moving_average_2_saturation_20_power_2_adstock_0_7', 'fb_level_achieved_tier_1_impressions_lag_2_moving_average_2_saturation_10_power_2_adstock_0_7', 'ga_app_clicks', 'digital_tactic_others_clicks_lag_2_moving_average_2_saturation_10_power_2_adstock_0_7', 'programmatic_clicks_lag_2_moving_average_1_saturation_10_power_2_adstock_0_7']",0.22466716998074276,0.8695595237588377,0.8694321404812584,8