Pragya Jatav commited on
Commit
a7b3ed8
·
1 Parent(s): c60e469

version changes

Browse files
Model_Result_Overview.py CHANGED
@@ -112,7 +112,7 @@ if auth_status:
112
 
113
  # Create two columns for start date and end date input
114
  col1, col2 = st.columns(2)
115
-
116
  with col1:
117
  default_date = datetime(2024, 1, 28)
118
  start_date = st.date_input("Start Date: ",value=default_date)
@@ -121,6 +121,17 @@ if auth_status:
121
  default_date = datetime(2024, 2, 24)
122
  end_date = st.date_input("End Date: ",value=default_date)
123
 
 
 
 
 
 
 
 
 
 
 
 
124
  # Dropdown menu options
125
  options = [
126
  "Month on Month",
@@ -128,7 +139,7 @@ if auth_status:
128
  col1, col2 = st.columns(2)
129
  # Create a dropdown menu
130
  with col1:
131
- selected_option = st.selectbox('Select a comparision', options)
132
  with col2:
133
  st.write("")
134
  # Waterfall chart
@@ -162,10 +173,10 @@ if auth_status:
162
 
163
  ### Media decomp CHART
164
  st.plotly_chart(sf.media_decomp(),use_container_width=True)
165
-
166
- # fig = sf.pie1(start_date,end_date)
167
- # st.plotly_chart(fig,use_container_width=True)
168
- # # st.dataframe(fig)
169
 
170
  # def panel_fetch(file_selected):
171
  # raw_data_mmm_df = pd.read_excel(file_selected, sheet_name="RAW DATA MMM")
@@ -282,7 +293,7 @@ if auth_status:
282
  # col1, col2 = st.columns(2)
283
  # # Create a dropdown menu
284
  # with col1:
285
- # selected_option = st.selectbox('Select a comparision', options)
286
  # with col2:
287
  # st.write("")
288
  # # Waterfall chart
 
112
 
113
  # Create two columns for start date and end date input
114
  col1, col2 = st.columns(2)
115
+
116
  with col1:
117
  default_date = datetime(2024, 1, 28)
118
  start_date = st.date_input("Start Date: ",value=default_date)
 
121
  default_date = datetime(2024, 2, 24)
122
  end_date = st.date_input("End Date: ",value=default_date)
123
 
124
+ # col1, col2 = st.columns(2)
125
+ # with col1:
126
+ # fig = sf.pie_spend(start_date,end_date)
127
+ # st.plotly_chart(fig,use_container_width=True)
128
+ # with col2:
129
+ # fig = sf.pie_contributions(start_date,end_date)
130
+ # st.plotly_chart(fig,use_container_width=True)
131
+ # st.header("Distribution of Spends and Contributions")
132
+ fig = sf.pie_charts(start_date,end_date)
133
+ st.plotly_chart(fig,use_container_width=True)
134
+
135
  # Dropdown menu options
136
  options = [
137
  "Month on Month",
 
139
  col1, col2 = st.columns(2)
140
  # Create a dropdown menu
141
  with col1:
142
+ selected_option = st.selectbox('Select a comparison', options)
143
  with col2:
144
  st.write("")
145
  # Waterfall chart
 
173
 
174
  ### Media decomp CHART
175
  st.plotly_chart(sf.media_decomp(),use_container_width=True)
176
+
177
+
178
+ # st.write(fig.columns)
179
+ # st.dataframe(fig)
180
 
181
  # def panel_fetch(file_selected):
182
  # raw_data_mmm_df = pd.read_excel(file_selected, sheet_name="RAW DATA MMM")
 
293
  # col1, col2 = st.columns(2)
294
  # # Create a dropdown menu
295
  # with col1:
296
+ # selected_option = st.selectbox('Select a comparison', options)
297
  # with col2:
298
  # st.write("")
299
  # # Waterfall chart
Streamlit_functions.py CHANGED
@@ -12,8 +12,7 @@ from datetime import datetime,timedelta
12
  from plotly.subplots import make_subplots
13
  import pandas as pd
14
  import json
15
-
16
-
17
 
18
  # working_directory = r"C:\Users\PragyaJatav\Downloads\Deliverables\Deliverables\Response Curves 09_07_24\Response Curves Resources"
19
  # os.chdir(working_directory)
@@ -80,19 +79,62 @@ contribution_cols = [
80
  'Audio_Prospects',
81
  'Email_Prospects']
82
 
83
- def pie1(start_date,end_date):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  start_date = pd.to_datetime(start_date)
85
  end_date = pd.to_datetime(end_date)
86
  cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
87
- data = cur_data[spend_cols].sum().transpose()
88
  data.index = channels
89
  data.columns = ["p"]
90
  # Create a pie chart with custom options
91
  fig = go.Figure(data=[go.Pie(
92
  labels=channels,
93
- values=data["p"],
94
  hoverinfo='label+percent',
95
- # textinfo='value',
 
 
96
 
97
  )])
98
 
@@ -102,7 +144,36 @@ def pie1(start_date,end_date):
102
  )
103
 
104
  # Show the figure
105
- return data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
  def waterfall(start_date,end_date,btn_chart):
108
  # if pd.isnull(start_date) == True :
@@ -762,3 +833,58 @@ def model_metrics_table_func():
762
  return model_metrics_df.round(2)
763
 
764
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  from plotly.subplots import make_subplots
13
  import pandas as pd
14
  import json
15
+ from numerize.numerize import numerize
 
16
 
17
  # working_directory = r"C:\Users\PragyaJatav\Downloads\Deliverables\Deliverables\Response Curves 09_07_24\Response Curves Resources"
18
  # os.chdir(working_directory)
 
79
  'Audio_Prospects',
80
  'Email_Prospects']
81
 
82
+ def pie_charts(start_date,end_date):
83
+ start_date = pd.to_datetime(start_date)
84
+ end_date = pd.to_datetime(end_date)
85
+ import plotly.graph_objects as go
86
+ from plotly.subplots import make_subplots
87
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
88
+ data1 = pd.DataFrame(cur_data[spend_cols].sum().transpose())
89
+ data2 = pd.DataFrame(cur_data[contribution_cols].sum().transpose())
90
+
91
+ data1.index = channels
92
+ data1.columns = ["p"]
93
+
94
+ data2.index = channels
95
+ data2.columns = ["p"]
96
+
97
+ fig = make_subplots(rows=1, cols=2, specs=[[{'type':'domain'}, {'type':'domain'}]])
98
+
99
+ fig.add_trace(go.Pie(labels=channels,
100
+ values=data1["p"],
101
+ name="t2",
102
+ hoverinfo='label+percent',
103
+ textinfo= 'label+percent',
104
+ showlegend= False,textfont=dict(size =10),
105
+ # title="Distribution of Spends"
106
+ ), 1, 1)
107
+
108
+ fig.add_trace(go.Pie(labels=channels,
109
+ values=data2["p"],
110
+ name="t2",
111
+ hoverinfo='label+percent',
112
+ textinfo= 'label+percent',
113
+ showlegend= False,
114
+ textfont=dict(size = 10),
115
+ # title = "Distribution of Contributions"
116
+ ), 1, 2)
117
+ fig.update_layout(
118
+ title="Distribution of Spends and Contributions"
119
+ )
120
+
121
+ return fig
122
+
123
+ def pie_spend(start_date,end_date):
124
  start_date = pd.to_datetime(start_date)
125
  end_date = pd.to_datetime(end_date)
126
  cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
127
+ data = pd.DataFrame(cur_data[spend_cols].sum().transpose())
128
  data.index = channels
129
  data.columns = ["p"]
130
  # Create a pie chart with custom options
131
  fig = go.Figure(data=[go.Pie(
132
  labels=channels,
133
+ values=data["p"],#ype(str)+'<br>'+data.index,
134
  hoverinfo='label+percent',
135
+ textinfo= 'label+percent',
136
+ showlegend= False,
137
+ textfont=dict(size = 10)
138
 
139
  )])
140
 
 
144
  )
145
 
146
  # Show the figure
147
+ return fig
148
+ def pie_contributions(start_date,end_date):
149
+ start_date = pd.to_datetime(start_date)
150
+ end_date = pd.to_datetime(end_date)
151
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
152
+ data = pd.DataFrame(cur_data[contribution_cols].sum().transpose())
153
+ data.index = channels
154
+ data.columns = ["p"]
155
+ # Create a pie chart with custom options
156
+ fig = go.Figure(data=[go.Pie(
157
+ labels=channels,
158
+ values=data["p"],#ype(str)+'<br>'+data.index,
159
+ hoverinfo='label+percent',
160
+ textinfo= 'label+percent',
161
+ textposition='auto',
162
+ showlegend= False,
163
+ textfont=dict(size = 10)
164
+
165
+ )])
166
+
167
+ # fig.add_annotation(showarrow=False)
168
+ # Customize the layout
169
+ fig.update_layout(
170
+ title="Distribution of Contributions",
171
+ # margin=dict(t=0, b=0, l=0, r=0)
172
+ )
173
+
174
+
175
+ # Show the figure
176
+ return fig
177
 
178
  def waterfall(start_date,end_date,btn_chart):
179
  # if pd.isnull(start_date) == True :
 
833
  return model_metrics_df.round(2)
834
 
835
 
836
+ def scenario_spend_forecasting(delta_df,start_date,end_date):
837
+
838
+ key_df = pd.DataFrame()
839
+ key_df["Channel_name"] = ["Email",
840
+ "DisplayRetargeting",
841
+ "\xa0Video",
842
+ "BroadcastTV",
843
+ "SocialRetargeting",
844
+ "Connected&OTTTV",
845
+ "SearchBrand",
846
+ "Audio",
847
+ "SocialProspecting",
848
+ "CableTV",
849
+ "DisplayProspecting",
850
+ "SearchNon-brand",
851
+ "DigitalPartners"]
852
+ key_df["Channels"] = [
853
+ "EMAIL",
854
+ "DISPLAY RETARGETING",
855
+ "VIDEO",
856
+ "BROADCAST TV",
857
+ "SOCIAL RETARGETING",
858
+ "CONNECTED & OTT TV",
859
+ "SEARCH BRAND",
860
+ "AUDIO",
861
+ "SOCIAL PROSPECTING",
862
+ "CABLE TV",
863
+ "DISPLAY PROSPECTING",
864
+ "SEARCH NON-BRAND",
865
+ "DIGITAL PARTNERS"
866
+ ]
867
+
868
+
869
+ start_date = pd.to_datetime(start_date)
870
+ end_date = pd.to_datetime(end_date)
871
+
872
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
873
+ cur_data = cur_data[spend_cols]
874
+ cur_data.columns = channels
875
+ data1 = pd.DataFrame(cur_data[channels].sum().transpose()).reset_index()
876
+ data1.columns = ["Channels","last_year_spends"]
877
+
878
+ df_modified = delta_df.merge(key_df,on = "Channel_name",how = "inner")
879
+ df_modified2 = df_modified.merge(data1,on = "Channels",how ="outer")
880
+ df_modified2["Forecasted Spends"] =( df_modified2["last_year_spends"]*(1+df_modified2["Delta_percent"]/100)).apply(numerize)
881
+ df_modified2.index = df_modified2["Channels"]
882
+ df_modified2["Spend Change"] = df_modified2["Delta_percent"]
883
+ df_modified2["Last Year Spends"] = df_modified2["last_year_spends"].apply(numerize)
884
+ df_modified3 = df_modified2[["Last Year Spends","Forecasted Spends","Spend Change"]].transpose()
885
+ # df_modified2["forecasted_spends"] =
886
+ # # df_modified = delta_percent
887
+ # # df_modified["Optimised Spends"] = df_modified["Current Spends"]*
888
+ return df_modified3
889
+
890
+
__pycache__/Streamlit_functions.cpython-310.pyc CHANGED
Binary files a/__pycache__/Streamlit_functions.cpython-310.pyc and b/__pycache__/Streamlit_functions.cpython-310.pyc differ
 
__pycache__/classes.cpython-310.pyc CHANGED
Binary files a/__pycache__/classes.cpython-310.pyc and b/__pycache__/classes.cpython-310.pyc differ
 
__pycache__/utilities.cpython-310.pyc CHANGED
Binary files a/__pycache__/utilities.cpython-310.pyc and b/__pycache__/utilities.cpython-310.pyc differ
 
classes.py CHANGED
@@ -58,7 +58,7 @@ class Channel:
58
  spends,
59
  response_curve_type,
60
  response_curve_params,
61
- bounds,
62
  conversion_rate=1,
63
  modified_spends=None,
64
  penalty=True,
@@ -76,6 +76,8 @@ class Channel:
76
  self.response_curve_type = response_curve_type
77
  self.response_curve_params = response_curve_params
78
  self.bounds = bounds
 
 
79
  self.penalty = penalty
80
 
81
  self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
@@ -160,6 +162,12 @@ class Channel:
160
  self.modified_total_sales = self.modified_sales.sum()
161
  self.delta_spends = self.modified_total_spends - self.actual_total_spends
162
  self.delta_sales = self.modified_total_sales - self.actual_total_sales
 
 
 
 
 
 
163
 
164
  def intialize(self):
165
  self.new_spends = self.old_spends
@@ -237,6 +245,14 @@ class Scenario:
237
  self.delta_spends = self.modified_total_spends - self.actual_total_spends
238
  self.delta_sales = self.modified_total_sales - self.actual_total_sales
239
 
 
 
 
 
 
 
 
 
240
  # def optimize_spends(self, sales_percent, channels_list, algo="COBYLA"):
241
  # desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
242
 
 
58
  spends,
59
  response_curve_type,
60
  response_curve_params,
61
+ bounds,channel_bounds_min,channel_bounds_max,
62
  conversion_rate=1,
63
  modified_spends=None,
64
  penalty=True,
 
76
  self.response_curve_type = response_curve_type
77
  self.response_curve_params = response_curve_params
78
  self.bounds = bounds
79
+ self.channel_bounds_min = channel_bounds_min
80
+ self.channel_bounds_max = channel_bounds_max
81
  self.penalty = penalty
82
 
83
  self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
 
162
  self.modified_total_sales = self.modified_sales.sum()
163
  self.delta_spends = self.modified_total_spends - self.actual_total_spends
164
  self.delta_sales = self.modified_total_sales - self.actual_total_sales
165
+
166
+ def update_bounds_min(self, modified_bound):
167
+ self.channel_bounds_min = modified_bound
168
+
169
+ def update_bounds_max(self, modified_bound):
170
+ self.channel_bounds_max = modified_bound
171
 
172
  def intialize(self):
173
  self.new_spends = self.old_spends
 
245
  self.delta_spends = self.modified_total_spends - self.actual_total_spends
246
  self.delta_sales = self.modified_total_sales - self.actual_total_sales
247
 
248
+ def update_bounds_min(self, channel_name,modified_bound):
249
+ # self.modify_spends(total_spends)
250
+ self.channels[channel_name].update_bounds_min(modified_bound)
251
+
252
+ def update_bounds_max(self, channel_name,modified_bound):
253
+ # self.modify_spends(total_spends)
254
+ self.channels[channel_name].update_bounds_max(modified_bound)
255
+
256
  # def optimize_spends(self, sales_percent, channels_list, algo="COBYLA"):
257
  # desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
258
 
pages/2_Scenario_Planner.py CHANGED
@@ -5,6 +5,10 @@ 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 (
9
  format_numbers,format_numbers_f,
10
  load_local_css,
@@ -263,7 +267,28 @@ def validate_input(string_input):
263
  return False
264
  return True
265
 
266
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  def update_data_by_percent(channel_name):
268
  prev_spends = (
269
  st.session_state["scenario"].channels[channel_name].actual_total_spends
@@ -299,6 +324,7 @@ def update_data(channel_name):
299
  modified_spends
300
  / st.session_state["scenario"].channels[channel_name].conversion_rate,
301
  )
 
302
  # st.session_state['scenario'].update(channel_name, modified_spends)
303
  # else:
304
  # try:
@@ -311,6 +337,8 @@ def update_data(channel_name):
311
  # st.write('Invalid input')
312
 
313
 
 
 
314
  def select_channel_for_optimization(channel_name):
315
  """
316
  Marks the given channel for optimization
@@ -519,6 +547,8 @@ def plot_response_curves(summary_df_sorted):
519
  'Email']
520
  summary_df_sorted.index = summary_df_sorted["Channel_name"]
521
  figures = [rc.response_curves(channels_list[i], summary_df_sorted["Optimized_spend"][channels_list[i]]/104, summary_df_sorted["New_sales"][channels_list[i]]/104) for i in range(13)]
 
 
522
 
523
  # Display figures in a grid layout
524
  cols = st.columns(3) # 4 columns for the grid
@@ -739,59 +769,52 @@ def reset_inputs():
739
  del st.session_state.total_sales_change_abs_slider
740
 
741
  st.session_state["initialized"] = False
 
 
 
 
742
 
 
 
743
 
744
- if auth_status == True:
745
- authenticator.logout("Logout", "main")
746
- st.header("Scenario Planner")
747
- def scenario_planner_plots():
748
-
749
- with st.expander('Optimized Spends Overview'):
750
- # if st.button('Refresh'):
751
- # st.experimental_rerun()
752
-
753
- import plotly.graph_objects as go
754
- from plotly.subplots import make_subplots
755
 
756
- # Define light colors for bars
757
- import plotly.graph_objects as go
758
- from plotly.subplots import make_subplots
759
 
760
- st.empty()
761
- #st.header('Model Result Analysis')
762
- spends_data=pd.read_excel('Overview_data_test.xlsx')
763
-
764
- with open('summary_df.pkl', 'rb') as file:
765
- summary_df_sorted = pickle.load(file)
766
  #st.write(summary_df_sorted)
 
 
 
 
 
767
 
768
- # selected_scenario= st.selectbox('Select Saved Scenarios',['S1','S2'])
769
- summary_df_sorted=summary_df_sorted.sort_values(by=['Optimized_spend'],ascending=False)
770
- summary_df_sorted['old_efficiency']=(summary_df_sorted['Old_sales']/summary_df_sorted['Old_sales'].sum())/(summary_df_sorted['Actual_spend']/summary_df_sorted['Actual_spend'].sum())
771
- summary_df_sorted['new_efficiency']=(summary_df_sorted['New_sales']/summary_df_sorted['New_sales'].sum())/(summary_df_sorted['Optimized_spend']/summary_df_sorted['Optimized_spend'].sum())
772
-
773
- summary_df_sorted['old_roi']=summary_df_sorted['Old_sales']/summary_df_sorted['Actual_spend']
774
- summary_df_sorted['new_roi']=summary_df_sorted['New_sales']/summary_df_sorted['Optimized_spend']
775
-
776
- total_actual_spend = summary_df_sorted['Actual_spend'].sum()
777
- total_optimized_spend = summary_df_sorted['Optimized_spend'].sum()
778
 
779
- actual_spend_percentage = (summary_df_sorted['Actual_spend'] / total_actual_spend) * 100
780
- optimized_spend_percentage = (summary_df_sorted['Optimized_spend'] / total_optimized_spend) * 100
781
 
 
 
782
 
783
 
784
- light_blue = 'rgba(0, 31, 120, 0.7)'
785
- light_orange = 'rgba(0, 181, 219, 0.7)'
786
- light_green = 'rgba(240, 61, 20, 0.7)'
787
- light_red = 'rgba(250, 110, 10, 0.7)'
788
- light_purple = 'rgba(255, 191, 69, 0.7)'
789
 
 
 
 
 
 
790
 
791
- # # Create subplots with one row and two columns
792
- # fig = make_subplots(rows=3, cols=1, subplot_titles=("Actual vs. Optimized Spend", "Actual vs. Optimized Contribution", "Actual vs. Optimized ROI"))
793
 
794
- # # Add actual vs optimized spend bars
 
 
795
 
796
 
797
  # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['Actual_spend'], name='Actual',
@@ -841,11 +864,11 @@ if auth_status == True:
841
  # st.plotly_chart(fig,use_container_width=True)
842
 
843
  # Create subplots with one row and two columns
844
- fig = go.Figure()
845
- # Add actual vs optimized spend bars
846
 
847
 
848
- fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['Actual_spend'], name='Actual',
849
  text=summary_df_sorted['Actual_spend'].apply(format_number) + ' '
850
  # +
851
  # ' '+
@@ -854,62 +877,67 @@ if auth_status == True:
854
  marker_color=light_blue))
855
 
856
 
857
- fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['Optimized_spend'], name='Optimized',
858
  text=summary_df_sorted['Optimized_spend'].apply(format_number) + ' '
859
  # +
860
  # '</br> (' + optimized_spend_percentage.astype(int).astype(str) + '%)'
861
  ,textposition='outside',#textfont=dict(size=30),
862
  marker_color=light_orange))
863
 
864
- fig.update_xaxes(title_text="Channels")
865
- fig.update_yaxes(title_text="Spends ($)")
866
- fig.update_layout(
867
- title = "Actual vs. Optimized Spends",
868
  margin=dict(t=40, b=40, l=40, r=40)
869
  )
870
 
871
- st.plotly_chart(fig,use_container_width=True)
872
 
873
  # Add actual vs optimized Contribution
874
- fig = go.Figure()
875
- fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['Old_sales'],
876
  name='Actual Contribution',text=summary_df_sorted['Old_sales'].apply(format_number),textposition='outside',
877
  marker_color=light_blue,showlegend=True))
878
 
879
- fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['New_sales'],
880
  name='Optimized Contribution',text=summary_df_sorted['New_sales'].apply(format_number),textposition='outside',
881
  marker_color=light_orange, showlegend=True))
882
 
883
 
884
 
885
- fig.update_yaxes(title_text="Contribution")
886
- fig.update_xaxes(title_text="Channels")
887
- fig.update_layout(
888
- title = "Actual vs. Optimized Contributions",
889
  margin=dict(t=40, b=40, l=40, r=40)
890
  # yaxis=dict(range=[0, 0.002]),
891
  )
892
- st.plotly_chart(fig,use_container_width=True)
893
 
894
- # Add actual vs optimized Efficiency bars
895
- fig = go.Figure()
896
- summary_df_sorted_p = summary_df_sorted[summary_df_sorted['Channel_name']!="Panel"]
897
- fig.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'], y=summary_df_sorted_p['old_efficiency'],
898
  name='Actual Efficiency', text=summary_df_sorted_p['old_efficiency'].apply(format_number) ,textposition='outside',
899
  marker_color=light_blue,showlegend=True))
900
- fig.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'], y=summary_df_sorted_p['new_efficiency'],
901
  name='Optimized Efficiency',text=summary_df_sorted_p['new_efficiency'].apply(format_number),textposition='outside' ,
902
  marker_color=light_orange,showlegend=True))
903
 
904
- fig.update_xaxes(title_text="Channels")
905
- fig.update_yaxes(title_text="Efficiency")
906
- fig.update_layout(
907
  title = "Actual vs. Optimized Efficiency",
908
  margin=dict(t=40, b=40, l=40, r=40),
909
  # yaxis=dict(range=[0, 0.002]),
910
  )
911
 
912
- st.plotly_chart(fig,use_container_width=True)
 
 
 
 
 
913
 
914
 
915
  # Response Metrics
@@ -1023,39 +1051,119 @@ if auth_status == True:
1023
  st.session_state.total_sales_change_abs_slider = numerize(
1024
  _scenario.actual_total_sales, 1
1025
  )
 
 
 
 
 
 
1026
 
1027
- with main_header[0]:
1028
- st.subheader("Actual")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1029
 
1030
- with main_header[-1]:
1031
- st.subheader("Simulated")
1032
 
1033
- with sub_header[0]:
1034
- st.metric(label="Spends", value=format_numbers(_scenario.actual_total_spends))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1035
 
1036
- with sub_header[1]:
1037
- st.metric(
1038
- label=target,
1039
- value=format_numbers_f(
1040
- float(_scenario.actual_total_sales)
1041
- ),
1042
- )
1043
 
1044
- with sub_header[2]:
1045
- st.metric(
1046
- label="Spends",
1047
- value=format_numbers(_scenario.modified_total_spends),
1048
- delta=numerize(_scenario.delta_spends, 1),
1049
- )
1050
 
1051
- with sub_header[3]:
1052
- st.metric(
1053
- label=target,
1054
- value=format_numbers_f(
1055
- float(_scenario.modified_total_sales)
1056
- ),
1057
- delta=numerize(_scenario.delta_sales, 1),
1058
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1059
 
1060
  with st.expander("Channel Spends Simulator", expanded=True):
1061
  _columns1 = st.columns((2, 2, 1, 1))
@@ -1159,8 +1267,8 @@ if auth_status == True:
1159
  with _columns2[2]:
1160
  min_value = round(_scenario.actual_total_sales * 0.5)
1161
  max_value = round(_scenario.actual_total_sales * 1.5)
1162
- st.write(min_value)
1163
- st.write(max_value)
1164
  # for value in range(min_value, max_value + 1, int(100)):
1165
  # st.write(numerize(value, 1))
1166
  st.session_state["total_sales_change_abs_slider_options"] = [
@@ -1202,7 +1310,7 @@ if auth_status == True:
1202
  )
1203
 
1204
  st.markdown("""<hr class="spends-heading-seperator">""", unsafe_allow_html=True)
1205
- _columns = st.columns((2.5, 2, 1.5, 1.5, 1))
1206
  with _columns[0]:
1207
  generate_spending_header("Channel")
1208
  with _columns[1]:
@@ -1228,34 +1336,60 @@ if auth_status == True:
1228
  for i, channel_name in enumerate(channels_list):
1229
  # st.write(channel_name)
1230
  _channel_class = st.session_state["scenario"].channels[channel_name]
1231
- _columns = st.columns((2.5, 1.5, 1.5, 1.5, 1))
 
 
 
 
 
 
 
1232
  with _columns[0]:
1233
  st.write(channel_name_formating(channel_name))
1234
  bin_placeholder = st.container()
1235
 
1236
  with _columns[1]:
1237
  channel_bounds = _channel_class.bounds
 
1238
  channel_spends = float(_channel_class.actual_total_spends)
1239
- min_value = float((1 + channel_bounds[0] / 100) * channel_spends)
1240
- max_value = float((1 + channel_bounds[1] / 100) * channel_spends)
 
 
 
 
1241
  ##print(st.session_state[channel_name])
1242
- spend_input = st.text_input(
1243
- channel_name,
1244
- key=channel_name,
1245
- label_visibility="collapsed",
1246
- on_change=partial(update_data, channel_name),
1247
- )
1248
- if not validate_input(spend_input):
1249
- st.error("Invalid input")
 
 
 
 
 
 
 
 
1250
 
1251
  channel_name_current = f"{channel_name}_change"
1252
-
1253
- st.number_input(
1254
- "Percent Change",
1255
- key=channel_name_current,
1256
- step=1,
1257
- on_change=partial(update_data_by_percent, channel_name),
1258
- )
 
 
 
 
 
 
1259
 
1260
  with _columns[2]:
1261
  # spends
@@ -1474,6 +1608,8 @@ if auth_status == True:
1474
  2,
1475
  )
1476
 
 
 
1477
 
1478
 
1479
 
@@ -1494,6 +1630,99 @@ if auth_status == True:
1494
 
1495
  scenario_planner_plots()
1496
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1497
  _columns = st.columns(2)
1498
  # with _columns[0]:
1499
  st.subheader("Save Scenario")
@@ -1507,7 +1736,9 @@ if auth_status == True:
1507
  "Save",
1508
  on_click=lambda: save_scenario(scenario_name),
1509
  disabled=len(st.session_state["scenario_input"]) == 0,#use_container_width=True
 
1510
  )
 
1511
 
1512
 
1513
 
 
5
  from collections import OrderedDict
6
  from plotly.subplots import make_subplots
7
  import plotly.graph_objects as go
8
+ from datetime import datetime, timedelta
9
+ from dateutil.relativedelta import relativedelta
10
+ import time
11
+ import Streamlit_functions as sf
12
  from utilities import (
13
  format_numbers,format_numbers_f,
14
  load_local_css,
 
267
  return False
268
  return True
269
 
270
+ def update_data_bound_min(channel_name):
271
+ """
272
+ Updates the bounds for the given channel
273
+ """
274
+ modified_bounds = st.session_state[f"{channel_name}_lower_bound"]
275
+
276
+ # st.session_state['scenario']['channels'][channel_name].channel_bounds_min = st.session_state[f"{channel_name}_lower_bound"]
277
+ st.session_state['scenario'].update_bounds_min(channel_name,modified_bounds)
278
+ st.write(st.session_state["scenario"].channels[channel_name].channel_bounds_min)
279
+ # st.write(st.session_state["scenario"].channels[channel_name])
280
+
281
+ def update_data_bound_max(channel_name):
282
+ """
283
+ Updates the bounds for the given channel
284
+ """
285
+ modified_bounds = st.session_state[f"{channel_name}_upper_bound"]
286
+
287
+ # st.session_state['scenario']['channels'][channel_name].channel_bounds_min = st.session_state[f"{channel_name}_lower_bound"]
288
+ st.session_state['scenario'].update_bounds_max(channel_name,modified_bounds)
289
+ # st.write(st.session_state["scenario"].channels[channel_name].channel_bounds_max)
290
+ # st.write(st.session_state["scenario"].channels[channel_name])
291
+
292
  def update_data_by_percent(channel_name):
293
  prev_spends = (
294
  st.session_state["scenario"].channels[channel_name].actual_total_spends
 
324
  modified_spends
325
  / st.session_state["scenario"].channels[channel_name].conversion_rate,
326
  )
327
+ # st.write(hasattr(st.session_state["scenario"], 'update_bounds_min'))
328
  # st.session_state['scenario'].update(channel_name, modified_spends)
329
  # else:
330
  # try:
 
337
  # st.write('Invalid input')
338
 
339
 
340
+
341
+
342
  def select_channel_for_optimization(channel_name):
343
  """
344
  Marks the given channel for optimization
 
547
  'Email']
548
  summary_df_sorted.index = summary_df_sorted["Channel_name"]
549
  figures = [rc.response_curves(channels_list[i], summary_df_sorted["Optimized_spend"][channels_list[i]]/104, summary_df_sorted["New_sales"][channels_list[i]]/104) for i in range(13)]
550
+
551
+ # for i in range()
552
 
553
  # Display figures in a grid layout
554
  cols = st.columns(3) # 4 columns for the grid
 
769
  del st.session_state.total_sales_change_abs_slider
770
 
771
  st.session_state["initialized"] = False
772
+ def scenario_planner_plots():
773
+ with st.expander('Optimized Spends Overview'):
774
+ # if st.button('Refresh'):
775
+ # st.experimental_rerun()
776
 
777
+ import plotly.graph_objects as go
778
+ from plotly.subplots import make_subplots
779
 
780
+ # Define light colors for bars
781
+ import plotly.graph_objects as go
782
+ from plotly.subplots import make_subplots
 
 
 
 
 
 
 
 
783
 
784
+ st.empty()
785
+ #st.header('Model Result Analysis')
786
+ spends_data=pd.read_excel('Overview_data_test.xlsx')
787
 
788
+ with open('summary_df.pkl', 'rb') as file:
789
+ summary_df_sorted = pickle.load(file)
 
 
 
 
790
  #st.write(summary_df_sorted)
791
+
792
+ # selected_scenario= st.selectbox('Select Saved Scenarios',['S1','S2'])
793
+ summary_df_sorted=summary_df_sorted.sort_values(by=['Optimized_spend'],ascending=False)
794
+ summary_df_sorted['old_efficiency']=(summary_df_sorted['Old_sales']/summary_df_sorted['Old_sales'].sum())/(summary_df_sorted['Actual_spend']/summary_df_sorted['Actual_spend'].sum())
795
+ summary_df_sorted['new_efficiency']=(summary_df_sorted['New_sales']/summary_df_sorted['New_sales'].sum())/(summary_df_sorted['Optimized_spend']/summary_df_sorted['Optimized_spend'].sum())
796
 
797
+ summary_df_sorted['old_roi']=summary_df_sorted['Old_sales']/summary_df_sorted['Actual_spend']
798
+ summary_df_sorted['new_roi']=summary_df_sorted['New_sales']/summary_df_sorted['Optimized_spend']
 
 
 
 
 
 
 
 
799
 
800
+ total_actual_spend = summary_df_sorted['Actual_spend'].sum()
801
+ total_optimized_spend = summary_df_sorted['Optimized_spend'].sum()
802
 
803
+ actual_spend_percentage = (summary_df_sorted['Actual_spend'] / total_actual_spend) * 100
804
+ optimized_spend_percentage = (summary_df_sorted['Optimized_spend'] / total_optimized_spend) * 100
805
 
806
 
 
 
 
 
 
807
 
808
+ light_blue = 'rgba(0, 31, 120, 0.7)'
809
+ light_orange = 'rgba(0, 181, 219, 0.7)'
810
+ light_green = 'rgba(240, 61, 20, 0.7)'
811
+ light_red = 'rgba(250, 110, 10, 0.7)'
812
+ light_purple = 'rgba(255, 191, 69, 0.7)'
813
 
 
 
814
 
815
+ # # Create subplots with one row and two columns
816
+ # fig = make_subplots(rows=3, cols=1, subplot_titles=("Actual vs. Optimized Spend", "Actual vs. Optimized Contribution", "Actual vs. Optimized ROI"))
817
+ # # Add actual vs optimized spend bars
818
 
819
 
820
  # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['Actual_spend'], name='Actual',
 
864
  # st.plotly_chart(fig,use_container_width=True)
865
 
866
  # Create subplots with one row and two columns
867
+ fig = go.Figure()
868
+ # Add actual vs optimized spend bars
869
 
870
 
871
+ fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['Actual_spend'], name='Actual',
872
  text=summary_df_sorted['Actual_spend'].apply(format_number) + ' '
873
  # +
874
  # ' '+
 
877
  marker_color=light_blue))
878
 
879
 
880
+ fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['Optimized_spend'], name='Optimized',
881
  text=summary_df_sorted['Optimized_spend'].apply(format_number) + ' '
882
  # +
883
  # '</br> (' + optimized_spend_percentage.astype(int).astype(str) + '%)'
884
  ,textposition='outside',#textfont=dict(size=30),
885
  marker_color=light_orange))
886
 
887
+ fig.update_xaxes(title_text="Channels")
888
+ fig.update_yaxes(title_text="Spends ($)")
889
+ fig.update_layout(
890
+ title = "Actual vs. Optimized Spends",
891
  margin=dict(t=40, b=40, l=40, r=40)
892
  )
893
 
894
+ st.plotly_chart(fig,use_container_width=True)
895
 
896
  # Add actual vs optimized Contribution
897
+ fig = go.Figure()
898
+ fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['Old_sales'],
899
  name='Actual Contribution',text=summary_df_sorted['Old_sales'].apply(format_number),textposition='outside',
900
  marker_color=light_blue,showlegend=True))
901
 
902
+ fig.add_trace(go.Bar(x=summary_df_sorted['Channel_name'], y=summary_df_sorted['New_sales'],
903
  name='Optimized Contribution',text=summary_df_sorted['New_sales'].apply(format_number),textposition='outside',
904
  marker_color=light_orange, showlegend=True))
905
 
906
 
907
 
908
+ fig.update_yaxes(title_text="Contribution")
909
+ fig.update_xaxes(title_text="Channels")
910
+ fig.update_layout(
911
+ title = "Actual vs. Optimized Contributions",
912
  margin=dict(t=40, b=40, l=40, r=40)
913
  # yaxis=dict(range=[0, 0.002]),
914
  )
915
+ st.plotly_chart(fig,use_container_width=True)
916
 
917
+ # Add actual vs optimized Efficiency bars
918
+ fig = go.Figure()
919
+ summary_df_sorted_p = summary_df_sorted[summary_df_sorted['Channel_name']!="Panel"]
920
+ fig.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'], y=summary_df_sorted_p['old_efficiency'],
921
  name='Actual Efficiency', text=summary_df_sorted_p['old_efficiency'].apply(format_number) ,textposition='outside',
922
  marker_color=light_blue,showlegend=True))
923
+ fig.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'], y=summary_df_sorted_p['new_efficiency'],
924
  name='Optimized Efficiency',text=summary_df_sorted_p['new_efficiency'].apply(format_number),textposition='outside' ,
925
  marker_color=light_orange,showlegend=True))
926
 
927
+ fig.update_xaxes(title_text="Channels")
928
+ fig.update_yaxes(title_text="Efficiency")
929
+ fig.update_layout(
930
  title = "Actual vs. Optimized Efficiency",
931
  margin=dict(t=40, b=40, l=40, r=40),
932
  # yaxis=dict(range=[0, 0.002]),
933
  )
934
 
935
+ st.plotly_chart(fig,use_container_width=True)
936
+
937
+ if auth_status == True:
938
+ authenticator.logout("Logout", "main")
939
+ st.header("Scenario Planner")
940
+
941
 
942
 
943
  # Response Metrics
 
1051
  st.session_state.total_sales_change_abs_slider = numerize(
1052
  _scenario.actual_total_sales, 1
1053
  )
1054
+
1055
+ if "lower_bound_key" not in st.session_state:
1056
+ st.session_state["lower_bound_key"] = 10
1057
+
1058
+ if "upper_bound_key" not in st.session_state:
1059
+ st.session_state["upper_bound_key"] = 10
1060
 
1061
+
1062
+ header_df = pd.DataFrame(index=["Actual","Simulated","Change","Percent Change"],columns=["Spends","Prospects"])
1063
+ header_df["Spends"]["Actual"] = format_numbers(_scenario.actual_total_spends)
1064
+ header_df["Spends"]["Simulated"] = format_numbers(_scenario.modified_total_spends)
1065
+ header_df["Spends"]["Change"] = format_numbers(_scenario.delta_spends) #_scenario.modified_total_spends -_scenario.actual_total_spends
1066
+ header_df["Spends"]["Percent Change"] = numerize(100*(_scenario.delta_spends/_scenario.actual_total_spends))+'%'
1067
+
1068
+ header_df["Prospects"]["Actual"] = format_numbers_f(float(_scenario.actual_total_sales))
1069
+ header_df["Prospects"]["Simulated"] = format_numbers_f(float(_scenario.modified_total_sales))
1070
+ header_df["Prospects"]["Change"] = format_numbers_f(_scenario.delta_sales)
1071
+ header_df["Prospects"]["Percent Change"] = numerize(100*(_scenario.delta_sales/_scenario.actual_total_sales),1)+'%'
1072
+
1073
+ # header_df.reset_index(inplace=True)
1074
+ # # Function to color the index
1075
+ # def highlight_index(s):
1076
+ # return ['background-color: lightblue' for _ in s]
1077
+
1078
+ # # Function to color the header
1079
+ # def highlight_header(s):
1080
+ # return ['background-color: lightgreen' for _ in s]
1081
+
1082
+ # # Applying the styles
1083
+ # styled_df = header_df.style \
1084
+ # .apply(highlight_index, axis=0, subset=pd.IndexSlice[:, :]) \
1085
+ # .set_table_styles({
1086
+ # 'A': [{'selector': 'th', 'props': [('background-color', 'lightgreen')]}],
1087
+ # 'B': [{'selector': 'th', 'props': [('background-color', 'lightgreen')]}],
1088
+ # 'C': [{'selector': 'th', 'props': [('background-color', 'lightgreen')]}]
1089
+ # })
1090
+
1091
+ # # Function to apply arrows based on value
1092
+ # def format_arrows(val):
1093
+ # if val > 0:
1094
+ # return '<span style="color: green;">&#9650;</span>' # Green up arrow
1095
+ # elif val < 0:
1096
+ # return '<span style="color: red;">&#9660;</span>' # Red down arrow
1097
+ # return '' # No arrow for zero
1098
+
1099
+ # # Function to format specific rows and exclude the first column
1100
+ # def apply_row_formatting(df, rows):
1101
+ # def format_cell(val, row_idx, col_idx):
1102
+ # if row_idx in rows and col_idx > 0: # Exclude the first column (col_idx > 0)
1103
+ # return format_arrows(val)
1104
+ # return '' # No formatting for other cells
1105
+
1106
+ # return df.style.apply(lambda x: [format_cell(val, i, col) for i, (val, col) in enumerate(zip(x, range(len(x))))], axis=1)
1107
 
1108
+ # # Apply formatting to 3rd and 4th rows (index 2 and 3)
1109
+ # styled_df = apply_row_formatting(header_df, [2, 3])
1110
 
1111
+ # st.markdown(styled_df.to_html(escape=False), unsafe_allow_html=True)
1112
+
1113
+ st.markdown(header_df.style.set_table_styles
1114
+ ([{'selector': 'th',
1115
+ 'props': [('background-color', '#D3D3D3'),
1116
+ ('font-size', '25px')]},
1117
+ {
1118
+ 'selector' : 'td:first-child',
1119
+ 'props' : [('background-color', '#D3D3D3'),
1120
+ ('font-size', '25px')]
1121
+ }
1122
+ ,
1123
+ {'selector': 'tbody td',
1124
+ 'props': [('font-size', '20px')]}
1125
+
1126
+ ]).to_html(),unsafe_allow_html=True)
1127
+
1128
 
 
 
 
 
 
 
 
1129
 
1130
+ # styled_df = header_df.style.apply(highlight_first_col, axis=1)
 
 
 
 
 
1131
 
1132
+ # st.table(styled_df)
1133
+
1134
+
1135
+ # with main_header[0]:
1136
+ # st.subheader("Actual")
1137
+
1138
+ # with main_header[-1]:
1139
+ # st.subheader("Simulated")
1140
+
1141
+ # with sub_header[0]:
1142
+ # st.metric(label="Spends", value=format_numbers(_scenario.actual_total_spends))
1143
+
1144
+ # with sub_header[1]:
1145
+ # st.metric(
1146
+ # label=target,
1147
+ # value=format_numbers_f(
1148
+ # float(_scenario.actual_total_sales)
1149
+ # ),
1150
+ # )
1151
+
1152
+ # with sub_header[2]:
1153
+ # st.metric(
1154
+ # label="Spends",
1155
+ # value=format_numbers(_scenario.modified_total_spends),
1156
+ # delta=numerize(_scenario.delta_spends, 1),
1157
+ # )
1158
+
1159
+ # with sub_header[3]:
1160
+ # st.metric(
1161
+ # label=target,
1162
+ # value=format_numbers_f(
1163
+ # float(_scenario.modified_total_sales)
1164
+ # ),
1165
+ # delta=numerize(_scenario.delta_sales, 1),
1166
+ # )
1167
 
1168
  with st.expander("Channel Spends Simulator", expanded=True):
1169
  _columns1 = st.columns((2, 2, 1, 1))
 
1267
  with _columns2[2]:
1268
  min_value = round(_scenario.actual_total_sales * 0.5)
1269
  max_value = round(_scenario.actual_total_sales * 1.5)
1270
+ # st.write(min_value)
1271
+ # st.write(max_value)
1272
  # for value in range(min_value, max_value + 1, int(100)):
1273
  # st.write(numerize(value, 1))
1274
  st.session_state["total_sales_change_abs_slider_options"] = [
 
1310
  )
1311
 
1312
  st.markdown("""<hr class="spends-heading-seperator">""", unsafe_allow_html=True)
1313
+ _columns = st.columns((2, 2.5, 1.5, 1.5, 0.5))
1314
  with _columns[0]:
1315
  generate_spending_header("Channel")
1316
  with _columns[1]:
 
1336
  for i, channel_name in enumerate(channels_list):
1337
  # st.write(channel_name)
1338
  _channel_class = st.session_state["scenario"].channels[channel_name]
1339
+ # st.write(st.session_state["scenario"].channels[channel_name])
1340
+ # st.write(st.session_state["scenario"].channels[channel_name].actual_total_sales)
1341
+ # st.write(st.session_state["scenario"].channels[channel_name].actual_total_spends)
1342
+ # st.write(st.session_state["scenario"].channels[channel_name].modified_total_sales)
1343
+ # st.write(st.session_state["scenario"].channels[channel_name].modified_total_spends)
1344
+ # st.write(st.session_state["scenario"].channels[channel_name].bounds)
1345
+ # st.write(st.session_state["scenario"].channels[channel_name].channel_bounds_min)
1346
+ _columns = st.columns((2, 2.5, 1.5, 1.5, 0.5))
1347
  with _columns[0]:
1348
  st.write(channel_name_formating(channel_name))
1349
  bin_placeholder = st.container()
1350
 
1351
  with _columns[1]:
1352
  channel_bounds = _channel_class.bounds
1353
+ # st.write(channel_bounds)
1354
  channel_spends = float(_channel_class.actual_total_spends)
1355
+ channel_bounds_min = float(_channel_class.channel_bounds_min)
1356
+ channel_bounds_max = float(_channel_class.channel_bounds_max)
1357
+ min_value = float((1 - channel_bounds_min / 100) * channel_spends)
1358
+ max_value = float((1 + channel_bounds_max / 100) * channel_spends)
1359
+ # st.write(min_value)
1360
+ # st.write(max_value)
1361
  ##print(st.session_state[channel_name])
1362
+ _columns_min = st.columns(2)
1363
+ with _columns_min[0]:
1364
+ spend_input = st.text_input(
1365
+ "Absolute",
1366
+ key=channel_name,
1367
+ # label_visibility="collapsed",
1368
+ on_change=partial(update_data, channel_name),
1369
+ )
1370
+ channel_name_lower_bound = f"{channel_name}_lower_bound"
1371
+ channel_bounds_min = st.text_input(
1372
+ "Lower Bound Percentage",
1373
+ key = channel_name_lower_bound,
1374
+ on_change=partial(update_data_bound_min,channel_name),value=10
1375
+ )
1376
+ if not validate_input(spend_input):
1377
+ st.error("Invalid input")
1378
 
1379
  channel_name_current = f"{channel_name}_change"
1380
+ with _columns_min[1]:
1381
+ st.number_input(
1382
+ "Percent Change",
1383
+ key=channel_name_current,
1384
+ step=1,
1385
+ on_change=partial(update_data_by_percent, channel_name),
1386
+ )
1387
+ channel_name_upper_bound = f"{channel_name}_upper_bound"
1388
+ channel_bounds_max = st.text_input(
1389
+ "Upper Bound Percentage",
1390
+ key = channel_name_upper_bound,
1391
+ on_change=partial(update_data_bound_max,channel_name),value=10
1392
+ )
1393
 
1394
  with _columns[2]:
1395
  # spends
 
1608
  2,
1609
  )
1610
 
1611
+
1612
+
1613
 
1614
 
1615
 
 
1630
 
1631
  scenario_planner_plots()
1632
 
1633
+ with st.expander ("View Forecasted spends"):
1634
+ col1, col2, col3 = st.columns(3)
1635
+ with col1:
1636
+ default_date = datetime(2024, 1, 28)
1637
+ start_date1 = st.date_input("Select Start Date: ",value=default_date) - relativedelta(years=1)
1638
+
1639
+ with col2:
1640
+ default_date = datetime(2024, 2, 24)
1641
+ end_date1 = st.date_input("Select End Date: ",value=default_date)- relativedelta(years=1)
1642
+
1643
+ with col3:
1644
+ current_date = datetime(2024, 2, 24)
1645
+ c1, c2, c3 = st.columns(3)
1646
+ with c1:
1647
+ if st.button('Next Month'):
1648
+ start_date1 = current_date- relativedelta(years=1)
1649
+ end_date1 = current_date + relativedelta(months=1)- relativedelta(years=1)
1650
+ with c2:
1651
+ if st.button('Next Quarter'):
1652
+ start_date1 = current_date- relativedelta(years=1)
1653
+ end_date1 = current_date + relativedelta(months = 3)- relativedelta(years=1)
1654
+ with c3:
1655
+ if st.button('Next Year'):
1656
+ start_date1 = current_date- relativedelta(years=1)
1657
+ end_date1 = current_date + relativedelta(months = 12)- relativedelta(years=1)
1658
+
1659
+ forecasted_table_df = sf.scenario_spend_forecasting(summary_df_sorted,start_date1,end_date1)
1660
+ st.table(forecasted_table_df)
1661
+
1662
+ st.markdown("""
1663
+ <style>
1664
+ .yellow-container {
1665
+ background-color: #FFFF99;
1666
+ border: 1px solid #FFD700;
1667
+ padding: 10px;
1668
+ border-radius: 5px;
1669
+ margin-bottom: 10px;
1670
+ }
1671
+ </style>
1672
+ """, unsafe_allow_html=True)
1673
+
1674
+ def save_report_forecast(forecasted_table_df):
1675
+ from io import BytesIO
1676
+ # excel_file_path = filename+ '.xlsx'
1677
+ # forecasted_table_df.to_excel(excel_file_path, index=False)
1678
+
1679
+ # Convert the DataFrame to an Excel file in memory
1680
+ excel_file = BytesIO()
1681
+ with pd.ExcelWriter(excel_file, engine='openpyxl') as writer:
1682
+ forecasted_table_df.to_excel(writer, index=False, sheet_name='Sheet1')
1683
+
1684
+ # Seek to the beginning of the BytesIO buffer
1685
+ excel_file.seek(0)
1686
+ return excel_file
1687
+ # message_container = st.empty()
1688
+ # with message_container:
1689
+ # st.write(f'<div class="yellow-container">{"Report Saved!"}</div>', unsafe_allow_html=True)
1690
+ # time.sleep(5)
1691
+ # st.empty()
1692
+
1693
+ st.subheader("Download Report")
1694
+ report_name = st.text_input(
1695
+ "Report name",
1696
+ key="report_input",
1697
+ placeholder="Report name",
1698
+ label_visibility="collapsed",
1699
+ )
1700
+
1701
+
1702
+ st.download_button(
1703
+ "Download Report",
1704
+ data = save_report_forecast(forecasted_table_df),
1705
+ file_name = report_name+".xlsx",
1706
+ mime="application/vnd.ms-excel",
1707
+ # on_click=lambda: save_report_forecast(forecasted_table_df,report_name),
1708
+ disabled=len(st.session_state["report_input"]) == 0,#use_container_width=True
1709
+ )
1710
+
1711
+ # filename = st.text_input("Save Report: ",placeholder="Report name")
1712
+ # if st.button("Download Report",disabled= (filename != "Report name")):
1713
+ # excel_file_path = filename+ '.xlsx'
1714
+ # forecasted_table_df.to_excel(excel_file_path, index=False)
1715
+ # message_container = st.empty()
1716
+
1717
+
1718
+ # with message_container:
1719
+ # st.write(f'<div class="yellow-container">{"Report Saved!"}</div>', unsafe_allow_html=True)
1720
+ # time.sleep(0.5)
1721
+ # st.empty()
1722
+
1723
+ # on_click=lambda: save_scenario(scenario_name),
1724
+ # disabled=len(st.session_state["scenario_input"]) == 0,#use_container_width=True
1725
+
1726
  _columns = st.columns(2)
1727
  # with _columns[0]:
1728
  st.subheader("Save Scenario")
 
1736
  "Save",
1737
  on_click=lambda: save_scenario(scenario_name),
1738
  disabled=len(st.session_state["scenario_input"]) == 0,#use_container_width=True
1739
+
1740
  )
1741
+
1742
 
1743
 
1744
 
pages/3_Saved_Scenarios.py CHANGED
@@ -23,7 +23,7 @@ set_header()
23
  # for k, v in st.session_state.items():
24
  # if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
25
  # st.session_state[k] = v
26
- def comparision_scenarios_df():
27
 
28
  ## create summary page
29
  if len(scenarios_to_compare) == 0:
@@ -91,7 +91,7 @@ def comparision_scenarios_df():
91
 
92
 
93
 
94
- def plot_comparision_chart(df,metric):
95
 
96
  # Create traces for each column
97
  traces = []
@@ -107,7 +107,7 @@ def plot_comparision_chart(df,metric):
107
 
108
  # Create the layout
109
  layout = go.Layout(
110
- title='Scenario Comparision '+ metric,
111
  xaxis_title="Channels",
112
  yaxis_title=metric,
113
  barmode='group'
@@ -118,12 +118,12 @@ def plot_comparision_chart(df,metric):
118
 
119
  return fig
120
 
121
- def create_comparision_plots():
122
- comparision_scenarios_df()
123
- spends_df, prospects_df = comparision_scenarios_df()
124
 
125
- st.plotly_chart(plot_comparision_chart(spends_df,"Spends"),use_container_width=True)
126
- st.plotly_chart(plot_comparision_chart(prospects_df,"Contributions"),use_container_width=True)
127
 
128
  def create_scenario_summary(scenario_dict):
129
  summary_rows = []
@@ -397,12 +397,12 @@ if auth_status == True:
397
  ]).to_html(),unsafe_allow_html=True)
398
  st.markdown("<br><br>", unsafe_allow_html=True)
399
 
400
- with st.expander('Scenario Comparision'):
401
- st.header("Scenario Comparision")
402
  if len(scenarios_to_compare)== 0:
403
  st.write("")
404
  else:
405
- create_comparision_plots()
406
 
407
  elif auth_status == False:
408
  st.error('Username/Password is incorrect')
@@ -422,4 +422,4 @@ if auth_status != True:
422
 
423
 
424
 
425
- # create_comparision_plots()
 
23
  # for k, v in st.session_state.items():
24
  # if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
25
  # st.session_state[k] = v
26
+ def comparison_scenarios_df():
27
 
28
  ## create summary page
29
  if len(scenarios_to_compare) == 0:
 
91
 
92
 
93
 
94
+ def plot_comparison_chart(df,metric):
95
 
96
  # Create traces for each column
97
  traces = []
 
107
 
108
  # Create the layout
109
  layout = go.Layout(
110
+ title='Scenario comparison '+ metric,
111
  xaxis_title="Channels",
112
  yaxis_title=metric,
113
  barmode='group'
 
118
 
119
  return fig
120
 
121
+ def create_comparison_plots():
122
+ comparison_scenarios_df()
123
+ spends_df, prospects_df = comparison_scenarios_df()
124
 
125
+ st.plotly_chart(plot_comparison_chart(spends_df,"Spends"),use_container_width=True)
126
+ st.plotly_chart(plot_comparison_chart(prospects_df,"Contributions"),use_container_width=True)
127
 
128
  def create_scenario_summary(scenario_dict):
129
  summary_rows = []
 
397
  ]).to_html(),unsafe_allow_html=True)
398
  st.markdown("<br><br>", unsafe_allow_html=True)
399
 
400
+ with st.expander('Scenario comparison'):
401
+ st.header("Scenario comparison")
402
  if len(scenarios_to_compare)== 0:
403
  st.write("")
404
  else:
405
+ create_comparison_plots()
406
 
407
  elif auth_status == False:
408
  st.error('Username/Password is incorrect')
 
422
 
423
 
424
 
425
+ # create_comparison_plots()
pages/4_Model Quality.py DELETED
@@ -1,57 +0,0 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import numpy as np
4
- import plotly.express as px
5
- import Streamlit_functions as sf
6
- import response_curves_model_quality_base as rc1
7
- st.set_page_config(
8
- layout="wide"
9
- )
10
-
11
-
12
- st.header("Model Quality")
13
- st.write("MMM Model Quality")
14
-
15
- st.plotly_chart(sf.mmm_model_quality(),use_container_width=True)
16
-
17
- media_df = sf.media_data()
18
- # Create two columns for start date and end date input
19
- col1, col2 = st.columns(2)
20
-
21
- st.table(sf.model_metrics_table_func())
22
-
23
- with col1:
24
- st.plotly_chart(sf.elasticity(media_df))
25
- with col2:
26
- st.plotly_chart(sf.half_life(media_df))
27
-
28
-
29
- # Dropdown menu options
30
- options = [
31
- 'Broadcast TV',
32
- 'Cable TV',
33
- 'Connected & OTT TV',
34
- 'Display Prospecting',
35
- 'Display Retargeting',
36
- 'Video',
37
- 'Social Prospecting',
38
- 'Social Retargeting',
39
- 'Search Brand',
40
- 'Search Non-brand',
41
- 'Digital Partners',
42
- 'Audio',
43
- 'Email']
44
- options1 = [
45
- 'View Line Plot',
46
- 'View Scattered Plot',
47
- "View Both"]
48
- col1, col2 = st.columns(2)
49
- # Create a dropdown menu
50
- with col1:
51
- selected_option = st.selectbox('Select a media channel:', options)
52
- selected_option2 = st.selectbox('Select a Chart Type', options1)
53
- # Display the selected option
54
- st.plotly_chart(rc1.response_curves(selected_option,selected_option2))
55
- with col2:
56
- st.write("")
57
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
summary_df.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:6e33a4c4ff46b7f8107d89facbd624828fae4b25965ede19b314805579134823
3
  size 1822
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6b3fa465194a44ba02e73683524c7c7af94c746e1cba16191d686109b932270e
3
  size 1822
utilities.py CHANGED
@@ -372,6 +372,8 @@ def initialize_data(
372
  "x0": params[3],
373
  },
374
  bounds=np.array([-10, 10]),
 
 
375
  )
376
  channels[inp_col] = channel
377
  if sales is None:
 
372
  "x0": params[3],
373
  },
374
  bounds=np.array([-10, 10]),
375
+ channel_bounds_min = 10,
376
+ channel_bounds_max = 10
377
  )
378
  channels[inp_col] = channel
379
  if sales is None: