Pragya Jatav commited on
Commit
2d928fb
·
1 Parent(s): 4bae411
Streamlit_functions.py CHANGED
@@ -281,7 +281,7 @@ def waterfall(start_date,end_date,btn_chart):
281
  # Updating layout for black background and gray gridlines
282
  if btn_chart == "Month on Month":
283
  fig.update_layout(
284
- title=f"Change In MMM Estimated Prospect Contribution <br>{start_date_prev.strftime('%m-%d-%Y')} To {end_date_prev.strftime('%m-%d-%Y')} Vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}"
285
  ,showlegend=False,
286
  # plot_bgcolor='black',
287
  # paper_bgcolor='black',
@@ -293,11 +293,22 @@ def waterfall(start_date,end_date,btn_chart):
293
  yaxis=dict(
294
  title="Prospects",
295
  showgrid=True,
296
- gridcolor='gray', # Setting y-axis gridline color to gray
 
297
  zeroline=False, # Hiding the y-axis zero line
298
  # range=[18000, max(max(cumulative), max(values)) + 1000] # Setting the y-axis range from 19k to slightly above the maximum value
299
  )
300
  )
 
 
 
 
 
 
 
 
 
 
301
  # fig.update_xaxes(
302
  # tickmode="array",
303
  # # categoryorder="total ascending",
@@ -308,7 +319,7 @@ def waterfall(start_date,end_date,btn_chart):
308
  # )
309
  else :
310
  fig.update_layout(
311
- title=f"Change In MMM Estimated Prospect Contribution <br>{start_date_prev.strftime('%m-%d-%Y')} To {end_date_prev.strftime('%m-%d-%Y')} Vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}"
312
  ,showlegend=False,
313
  # plot_bgcolor='black',
314
  # paper_bgcolor='black',
@@ -320,12 +331,23 @@ def waterfall(start_date,end_date,btn_chart):
320
  yaxis=dict(
321
  title="Prospects",
322
  showgrid=True,
323
- gridcolor='gray', # Setting y-axis gridline color to gray
 
324
  zeroline=False, # Hiding the y-axis zero line
325
  # range=[10000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
326
  )
327
 
328
  )
 
 
 
 
 
 
 
 
 
 
329
  # print(cur_data)
330
  # print(prev_data)
331
  # fig.show()
@@ -431,7 +453,7 @@ def channel_contribution(start_date,end_date):
431
 
432
  # Updating layout for better visualization
433
  fig.update_layout(
434
- title=f"Media Contribution <br> {cur_data['Date'].min().strftime('%m-%d-%Y')} To {cur_data['Date'].max().strftime('%m-%d-%Y')}",
435
  # plot_bgcolor='black',
436
  # paper_bgcolor='black',
437
  # font=dict(color='white'), # Changing font color to white for better contrast
@@ -443,10 +465,21 @@ def channel_contribution(start_date,end_date):
443
  yaxis=dict(
444
  title="Prospect",
445
  showgrid=True,
446
- gridcolor='gray', # Setting y-axis gridline color to gray
 
447
  zeroline=False, # Hiding the y-axis zero line
448
  )
449
  )
 
 
 
 
 
 
 
 
 
 
450
 
451
  return fig
452
 
@@ -478,7 +511,7 @@ def chanel_spends(start_date,end_date):
478
 
479
  # Updating layout for better visualization
480
  fig.update_layout(
481
- title=f"Media Spends <br> {cur_data['Date'].min().strftime('%m-%d-%Y')} To {cur_data['Date'].max().strftime('%m-%d-%Y')}",
482
  # plot_bgcolor='black',
483
  # paper_bgcolor='black',
484
  # font=dict(color='white'), # Changing font color to white for better contrast
@@ -490,10 +523,21 @@ def chanel_spends(start_date,end_date):
490
  yaxis=dict(
491
  title="Spends ($)",
492
  showgrid=True,
493
- gridcolor='gray', # Setting y-axis gridline color to gray
 
494
  zeroline=False, # Hiding the y-axis zero line
495
  )
496
  )
 
 
 
 
 
 
 
 
 
 
497
 
498
  return fig
499
 
@@ -590,24 +634,36 @@ def cpp(start_date,end_date):
590
 
591
  # Update layout for better visualization
592
  fig.update_layout(
593
- title=f"CPP Distribution <br>{cur_data['Date'].min().strftime('%m-%d-%Y')} To {cur_data['Date'].max().strftime('%m-%d-%Y')}"
594
  ,
595
  # plot_bgcolor='black',
596
  # paper_bgcolor='black',
597
  # font=dict(color='white'), # Changing font color to white for better contrast
598
  xaxis=dict(
599
- showgrid=True,
600
- gridcolor='gray', # Setting x-axis gridline color to gray
 
601
  zeroline=False, # Hiding the x-axis zero line
602
  ),
603
  yaxis=dict(
604
  title="CPP",
605
  showgrid=True,
606
- gridcolor='gray', # Setting y-axis gridline color to gray
 
607
  zeroline=False, # Hiding the y-axis zero line
608
  ),
609
  hovermode='x' # Show hover info for all lines at a single point
610
  )
 
 
 
 
 
 
 
 
 
 
611
  return fig
612
 
613
  def base_decomp():
@@ -641,7 +697,8 @@ def base_decomp():
641
  yaxis=dict(
642
  title="Prospect",
643
  showgrid=True,
644
- gridcolor='gray', # Setting y-axis gridline color to gray
 
645
  zeroline=False, # Hiding the y-axis zero line
646
  ),
647
  hovermode='x' # Show hover info for all lines at a single point
@@ -731,7 +788,8 @@ def media_decomp():
731
  yaxis=dict(
732
  title="Prospect",
733
  showgrid=True,
734
- gridcolor='gray', # Setting y-axis gridline color to gray
 
735
  zeroline=False, # Hiding the y-axis zero line
736
  )
737
  )
@@ -749,7 +807,7 @@ def mmm_model_quality():
749
 
750
  # Update layout for better visualization
751
  fig.update_layout(
752
- title=f"Model Predicted V/S Actual Prospects"
753
  ,
754
  # plot_bgcolor='black',
755
  # paper_bgcolor='black',
@@ -762,7 +820,8 @@ def mmm_model_quality():
762
  yaxis=dict(
763
  title="Prospects",
764
  showgrid=True,
765
- gridcolor='gray', # Setting y-axis gridline color to gray
 
766
  zeroline=False, # Hiding the y-axis zero line
767
  ),
768
  hovermode='x' # Show hover info for all lines at a single point
@@ -819,7 +878,8 @@ def elasticity(media_df):
819
  xaxis=dict(
820
  title="Elasticity (coefficient)",
821
  showgrid=True,
822
- gridcolor='gray', # Setting x-axis gridline color to gray
 
823
  zeroline=False, # Hiding the x-axis zero line
824
  ),
825
  yaxis=dict(
@@ -858,7 +918,8 @@ def half_life(media_df):
858
  xaxis=dict(
859
  title="Weeks",
860
  showgrid=True,
861
- gridcolor='gray', # Setting x-axis gridline color to gray
 
862
  zeroline=False, # Hiding the x-axis zero line
863
  ),
864
  yaxis=dict(
@@ -1024,7 +1085,7 @@ def scenario_spend_forecasting2(delta_df,start_date,end_date):
1024
  cur_data = cur_data[spend_cols2]
1025
  cur_data.columns = channels2
1026
 
1027
- cur_data["Date2"] = cur_data["Date"]+ pd.Timedelta(days=5)
1028
  # cur_data["Date"] = delta_df["Date"]
1029
  cur_data["Date_diff"] = (cur_data["Date"]-start_date).dt.days
1030
  cur_data["Date_diff_months"] =(np.ceil(cur_data["Date_diff"] / 30))
 
281
  # Updating layout for black background and gray gridlines
282
  if btn_chart == "Month on Month":
283
  fig.update_layout(
284
+ title=f"Change In MMM Estimated Prospect Contribution"
285
  ,showlegend=False,
286
  # plot_bgcolor='black',
287
  # paper_bgcolor='black',
 
293
  yaxis=dict(
294
  title="Prospects",
295
  showgrid=True,
296
+ gridcolor='lightgray',
297
+ griddash='dot', # Setting y-axis gridline color to gray
298
  zeroline=False, # Hiding the y-axis zero line
299
  # range=[18000, max(max(cumulative), max(values)) + 1000] # Setting the y-axis range from 19k to slightly above the maximum value
300
  )
301
  )
302
+ fig.add_annotation(
303
+ text=f"{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}",
304
+ x=0,
305
+ y=1.15,
306
+ xref="x domain",
307
+ yref="y domain",
308
+ showarrow=False,
309
+ font=dict(size=16),
310
+ # align='left'
311
+ )
312
  # fig.update_xaxes(
313
  # tickmode="array",
314
  # # categoryorder="total ascending",
 
319
  # )
320
  else :
321
  fig.update_layout(
322
+ title="Change In MMM Estimated Prospect Contribution "
323
  ,showlegend=False,
324
  # plot_bgcolor='black',
325
  # paper_bgcolor='black',
 
331
  yaxis=dict(
332
  title="Prospects",
333
  showgrid=True,
334
+ gridcolor='lightgray',
335
+ griddash='dot', # Setting y-axis gridline color to gray
336
  zeroline=False, # Hiding the y-axis zero line
337
  # range=[10000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
338
  )
339
 
340
  )
341
+ fig.add_annotation(
342
+ text=f"{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} To {end_date.strftime('%m-%d-%Y')}",
343
+ x=0,
344
+ y=1.15,
345
+ xref="x domain",
346
+ yref="y domain",
347
+ showarrow=False,
348
+ font=dict(size=16),
349
+ # align='left'
350
+ )
351
  # print(cur_data)
352
  # print(prev_data)
353
  # fig.show()
 
453
 
454
  # Updating layout for better visualization
455
  fig.update_layout(
456
+ title=f"Media Contribution",
457
  # plot_bgcolor='black',
458
  # paper_bgcolor='black',
459
  # font=dict(color='white'), # Changing font color to white for better contrast
 
465
  yaxis=dict(
466
  title="Prospect",
467
  showgrid=True,
468
+ gridcolor='lightgray',
469
+ griddash='dot', # Setting y-axis gridline color to gray
470
  zeroline=False, # Hiding the y-axis zero line
471
  )
472
  )
473
+ fig.add_annotation(
474
+ text=f"{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
475
+ x=0,
476
+ y=1.15,
477
+ xref="x domain",
478
+ yref="y domain",
479
+ showarrow=False,
480
+ font=dict(size=16),
481
+ # align='left'
482
+ )
483
 
484
  return fig
485
 
 
511
 
512
  # Updating layout for better visualization
513
  fig.update_layout(
514
+ title=f"Media Spends",
515
  # plot_bgcolor='black',
516
  # paper_bgcolor='black',
517
  # font=dict(color='white'), # Changing font color to white for better contrast
 
523
  yaxis=dict(
524
  title="Spends ($)",
525
  showgrid=True,
526
+ gridcolor='lightgray',
527
+ griddash='dot', # Setting y-axis gridline color to gray
528
  zeroline=False, # Hiding the y-axis zero line
529
  )
530
  )
531
+ fig.add_annotation(
532
+ text=f"{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
533
+ x=0,
534
+ y=1.15,
535
+ xref="x domain",
536
+ yref="y domain",
537
+ showarrow=False,
538
+ font=dict(size=16),
539
+ # align='left'
540
+ )
541
 
542
  return fig
543
 
 
634
 
635
  # Update layout for better visualization
636
  fig.update_layout(
637
+ title=f"CPP Distribution"
638
  ,
639
  # plot_bgcolor='black',
640
  # paper_bgcolor='black',
641
  # font=dict(color='white'), # Changing font color to white for better contrast
642
  xaxis=dict(
643
+ showgrid=False,
644
+ gridcolor='lightgray',
645
+ griddash='dot', # Setting x-axis gridline color to gray
646
  zeroline=False, # Hiding the x-axis zero line
647
  ),
648
  yaxis=dict(
649
  title="CPP",
650
  showgrid=True,
651
+ gridcolor='lightgray',
652
+ griddash='dot', # Setting y-axis gridline color to gray
653
  zeroline=False, # Hiding the y-axis zero line
654
  ),
655
  hovermode='x' # Show hover info for all lines at a single point
656
  )
657
+ fig.add_annotation(
658
+ text=f"{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
659
+ x=0,
660
+ y=1.15,
661
+ xref="x domain",
662
+ yref="y domain",
663
+ showarrow=False,
664
+ font=dict(size=16),
665
+ # align='left'
666
+ )
667
  return fig
668
 
669
  def base_decomp():
 
697
  yaxis=dict(
698
  title="Prospect",
699
  showgrid=True,
700
+ gridcolor='lightgray',
701
+ griddash='dot', # Setting y-axis gridline color to gray
702
  zeroline=False, # Hiding the y-axis zero line
703
  ),
704
  hovermode='x' # Show hover info for all lines at a single point
 
788
  yaxis=dict(
789
  title="Prospect",
790
  showgrid=True,
791
+ gridcolor='lightgray',
792
+ griddash='dot', # Setting y-axis gridline color to gray
793
  zeroline=False, # Hiding the y-axis zero line
794
  )
795
  )
 
807
 
808
  # Update layout for better visualization
809
  fig.update_layout(
810
+ title=f"Model Predicted v/s Actual Prospects"
811
  ,
812
  # plot_bgcolor='black',
813
  # paper_bgcolor='black',
 
820
  yaxis=dict(
821
  title="Prospects",
822
  showgrid=True,
823
+ gridcolor='lightgray',
824
+ griddash='dot', # Setting y-axis gridline color to gray
825
  zeroline=False, # Hiding the y-axis zero line
826
  ),
827
  hovermode='x' # Show hover info for all lines at a single point
 
878
  xaxis=dict(
879
  title="Elasticity (coefficient)",
880
  showgrid=True,
881
+ gridcolor='lightgray',
882
+ griddash='dot', # Setting x-axis gridline color to gray
883
  zeroline=False, # Hiding the x-axis zero line
884
  ),
885
  yaxis=dict(
 
918
  xaxis=dict(
919
  title="Weeks",
920
  showgrid=True,
921
+ gridcolor='lightgray',
922
+ griddash='dot', # Setting x-axis gridline color to gray
923
  zeroline=False, # Hiding the x-axis zero line
924
  ),
925
  yaxis=dict(
 
1085
  cur_data = cur_data[spend_cols2]
1086
  cur_data.columns = channels2
1087
 
1088
+ cur_data["Date2"] = cur_data["Date"]+ pd.Timedelta(days=6)
1089
  # cur_data["Date"] = delta_df["Date"]
1090
  cur_data["Date_diff"] = (cur_data["Date"]-start_date).dt.days
1091
  cur_data["Date_diff_months"] =(np.ceil(cur_data["Date_diff"] / 30))
__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__/response_curves_model_quality.cpython-310.pyc CHANGED
Binary files a/__pycache__/response_curves_model_quality.cpython-310.pyc and b/__pycache__/response_curves_model_quality.cpython-310.pyc differ
 
__pycache__/response_curves_model_quality_base.cpython-310.pyc CHANGED
Binary files a/__pycache__/response_curves_model_quality_base.cpython-310.pyc and b/__pycache__/response_curves_model_quality_base.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
@@ -3,7 +3,7 @@ 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 = {}
@@ -23,8 +23,8 @@ def class_to_dict(class_instance):
23
  attr_dict["actual_total_sales"] = class_instance.actual_total_sales
24
  attr_dict["modified_total_spends"] = class_instance.modified_total_spends
25
  attr_dict["modified_total_sales"] = class_instance.modified_total_sales
26
- attr_dict["actual_mroi"] = class_instance.get_marginal_roi("actual")
27
- attr_dict["modified_mroi"] = class_instance.get_marginal_roi("modified")
28
 
29
  elif isinstance(class_instance, Scenario):
30
  attr_dict["type"] = "Scenario"
@@ -56,6 +56,7 @@ class Channel:
56
  name,
57
  dates,
58
  spends,
 
59
  response_curve_type,
60
  response_curve_params,
61
  bounds,channel_bounds_min,channel_bounds_max,
@@ -67,6 +68,7 @@ class Channel:
67
  self.dates = dates
68
  self.conversion_rate = conversion_rate
69
  self.actual_spends = spends.copy()
 
70
 
71
  if modified_spends is None:
72
  self.modified_spends = self.actual_spends.copy()
@@ -83,7 +85,7 @@ class Channel:
83
  self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
84
  self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
85
  self.actual_sales = None
86
- self.actual_sales = self.response_curve(self.actual_spends)
87
  self.actual_total_spends = self.actual_spends.sum()
88
  self.actual_total_sales = self.actual_sales.sum()
89
  self.modified_sales = self.calculate_sales()
@@ -104,8 +106,11 @@ class Channel:
104
  )
105
 
106
  def calculate_sales(self):
 
107
  return self.response_curve(self.modified_spends)
108
 
 
 
109
  def response_curve(self, x):
110
  if self.penalty:
111
  x = np.where(
@@ -113,11 +118,33 @@ class Channel:
113
  x,
114
  self.upper_limit + (x - self.upper_limit) * self.upper_limit / x,
115
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  if self.response_curve_type == "s-curve":
117
  if self.power >= 0:
118
  x = x / 10**self.power
119
  x = x.astype("float64")
120
- K = self.response_curve_params["K"]
121
  b = self.response_curve_params["b"]
122
  a = self.response_curve_params["a"]
123
  x0 = self.response_curve_params["x0"]
@@ -247,7 +274,7 @@ class Scenario:
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)
@@ -290,6 +317,20 @@ class Scenario:
290
 
291
  # return zip(channels_list, res.x)
292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  def optimize_spends(self, sales_percent, channels_list, algo="trust-constr"):
294
  print("%"*100)
295
  desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
@@ -327,6 +368,8 @@ class Scenario:
327
  self.update(channel_name, modified_spends)
328
 
329
  return zip(channels_list, res.x)
 
 
330
 
331
  def optimize(self, spends_percent, channels_list):
332
  # channels_list = self.channels.keys()
@@ -386,6 +429,69 @@ class Scenario:
386
  self.update(channel_name, modified_spends)
387
 
388
  return zip(channels_list, res.x)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
  def save(self):
391
  details = {}
 
3
  from collections import OrderedDict
4
  import pandas as pd
5
  from numerize.numerize import numerize
6
+ from gekko import GEKKO
7
 
8
  def class_to_dict(class_instance):
9
  attr_dict = {}
 
23
  attr_dict["actual_total_sales"] = class_instance.actual_total_sales
24
  attr_dict["modified_total_spends"] = class_instance.modified_total_spends
25
  attr_dict["modified_total_sales"] = class_instance.modified_total_sales
26
+ # attr_dict["actual_mroi"] = class_instance.get_marginal_roi("actual")
27
+ # attr_dict["modified_mroi"] = class_instance.get_marginal_roi("modified")
28
 
29
  elif isinstance(class_instance, Scenario):
30
  attr_dict["type"] = "Scenario"
 
56
  name,
57
  dates,
58
  spends,
59
+ sales,
60
  response_curve_type,
61
  response_curve_params,
62
  bounds,channel_bounds_min,channel_bounds_max,
 
68
  self.dates = dates
69
  self.conversion_rate = conversion_rate
70
  self.actual_spends = spends.copy()
71
+ # self.actual_sales = sales.copy()
72
 
73
  if modified_spends is None:
74
  self.modified_spends = self.actual_spends.copy()
 
85
  self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
86
  self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
87
  self.actual_sales = None
88
+ self.actual_sales = self.response_curve(self.actual_spends)#sales.copy()#
89
  self.actual_total_spends = self.actual_spends.sum()
90
  self.actual_total_sales = self.actual_sales.sum()
91
  self.modified_sales = self.calculate_sales()
 
106
  )
107
 
108
  def calculate_sales(self):
109
+ print("in calc_sales")
110
  return self.response_curve(self.modified_spends)
111
 
112
+ def hill_equation(x, Kd, n):
113
+ return x**n / (Kd**n + x**n)
114
  def response_curve(self, x):
115
  if self.penalty:
116
  x = np.where(
 
118
  x,
119
  self.upper_limit + (x - self.upper_limit) * self.upper_limit / x,
120
  )
121
+ if self.response_curve_type == "hill-eq":
122
+ print("lalala")
123
+ print(self.name)
124
+ Kd= self.response_curve_params["Kd"]
125
+ n= self.response_curve_params["n"]
126
+ x_min= self.response_curve_params["x_min"]
127
+ x_max= self.response_curve_params["x_max"]
128
+ y_min= self.response_curve_params["y_min"]
129
+ y_max= self.response_curve_params['y_max']
130
+ # print(x_min)
131
+ # print(Kd,n,x_min,x_max,y_min,y_max)
132
+ print(np.sum(x)/104)
133
+ x_inp = ( x- x_min) / (x_max - x_min)
134
+ # print(x_inp)
135
+ x_out = x_inp**n / (Kd**n + x_inp**n) #self.hill_equation(x_inp,Kd, n)
136
+ print(x_out)
137
+
138
+ sales = (y_max - y_min)*x_out + y_min
139
+ sales[np.isnan(sales)] = 0
140
+ print(sales)
141
+ print(np.sum(sales))
142
+ # print(sales)
143
  if self.response_curve_type == "s-curve":
144
  if self.power >= 0:
145
  x = x / 10**self.power
146
  x = x.astype("float64")
147
+ K = self.response_curve_params["Kd"]
148
  b = self.response_curve_params["b"]
149
  a = self.response_curve_params["a"]
150
  x0 = self.response_curve_params["x0"]
 
274
 
275
  def update_bounds_min(self, channel_name,modified_bound):
276
  # self.modify_spends(total_spends)
277
+ self.channels[channel_name].update_bounds_min(modified_bound)
278
 
279
  def update_bounds_max(self, channel_name,modified_bound):
280
  # self.modify_spends(total_spends)
 
317
 
318
  # return zip(channels_list, res.x)
319
 
320
+ def hill_equation(x, Kd, n):
321
+ return x**n / (Kd**n + x**n)
322
+
323
+ def cost_func(channel,x):
324
+ x_inp = (x/104 - param_dicts["x_min"][channel]) / (param_dicts["x_max"][channel] - param_dicts["x_min"][channel])
325
+ # print(x_inp)
326
+ x_out = hill_equation(x_inp, param_dicts["Kd"][channel], param_dicts["n"][channel])
327
+ # print(x_out)
328
+ #
329
+ return (param_dicts["y_max"][channel] - param_dicts["y_min"][channel])*(x_out + param_dicts["y_min"][channel])*104
330
+
331
+
332
+
333
+
334
  def optimize_spends(self, sales_percent, channels_list, algo="trust-constr"):
335
  print("%"*100)
336
  desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
 
368
  self.update(channel_name, modified_spends)
369
 
370
  return zip(channels_list, res.x)
371
+
372
+
373
 
374
  def optimize(self, spends_percent, channels_list):
375
  # channels_list = self.channels.keys()
 
429
  self.update(channel_name, modified_spends)
430
 
431
  return zip(channels_list, res.x)
432
+
433
+
434
+ def hill_equation(self,x, Kd, n):
435
+ return x**n / (Kd**n + x**n)
436
+
437
+ def cost_func(self ,channel,x):
438
+
439
+ response_curve_params = pd.read_excel(r"C:\Users\PragyaJatav\Downloads\Untitled Folder 2\simulator uploaded - Copy\Simulator-UOPX\response_curves_parameters.xlsx",index_col = "channel")
440
+ param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
441
+
442
+ x_inp = (x/104 - param_dicts["x_min"][channel]) / (param_dicts["x_max"][channel] - param_dicts["x_min"][channel])
443
+ # print(x_inp)
444
+ x_out = self.hill_equation(x_inp, param_dicts["Kd"][channel], param_dicts["n"][channel])
445
+ # print(x_out)
446
+ #
447
+ return (param_dicts["y_max"][channel] - param_dicts["y_min"][channel])*(x_out + param_dicts["y_min"][channel])*104
448
+
449
+
450
+ def spends_optimisation(self, spends_percent,channels_list):
451
+ m = GEKKO(remote=False)
452
+ # Define variables
453
+ # Initialize 13 variables with specific bounds
454
+ response_curve_params = pd.read_excel(r"C:\Users\PragyaJatav\Downloads\Untitled Folder 2\simulator uploaded - Copy\Simulator-UOPX\response_curves_parameters.xlsx",index_col = "channel")
455
+ param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
456
+
457
+ initial_values = list(param_dicts["x_min"].values())
458
+ current_spends = list(param_dicts["current_spends"].values())
459
+ lower_bounds = list(param_dicts["x_min"].values())
460
+
461
+ num_channels = len(channels_list)
462
+
463
+ x_vars=[]
464
+ x_vars = [m.Var(value=param_dicts["current_spends"][_], lb=param_dicts["x_min"][_]*104, ub=5*param_dicts["current_spends"][_]) for _ in channels_list]
465
+ print(x_vars)
466
+ # x_vars,lower_bounds
467
+
468
+ # Define the objective function to minimize
469
+ cost = 0
470
+ spends = 0
471
+ i = 0
472
+ for i,c in enumerate(channels_list):
473
+ # print(c)
474
+ # print(x_vars[i])
475
+ cost = cost + (self.cost_func(c, x_vars[i]))
476
+ spends = spends +x_vars[i]
477
+
478
+
479
+ m.Maximize(cost)
480
+
481
+ # Define constraints
482
+ m.Equation(spends == sum(current_spends)*(1 + spends_percent / 100))
483
+ m.Equation(spends <= sum(current_spends)*0.5)
484
+ m.Equation(spends >= sum(current_spends)*1.5)
485
+
486
+ m.solve(disp=True)
487
+
488
+ for i, var in enumerate(x_vars):
489
+ print(f"x{i+1} = {var.value[0]}")
490
+
491
+ for channel_name, modified_spends in zip(channels_list, x_vars):
492
+ self.update(channel_name, modified_spends.value[0])
493
+
494
+ return zip(channels_list, x_vars)
495
 
496
  def save(self):
497
  details = {}
pages/2_Scenario_Planner.py CHANGED
@@ -62,9 +62,15 @@ def optimize(key, status_placeholder):
62
  if key.lower() == "media spends":
63
  with status_placeholder:
64
  with st.spinner("Optimizing"):
 
 
65
  result = st.session_state["scenario"].optimize(
66
  st.session_state["total_spends_change"], channel_list
 
 
67
  )
 
 
68
  # elif key.lower() == "revenue":
69
  else:
70
  with status_placeholder:
@@ -565,117 +571,6 @@ def plot_response_curves(summary_df_sorted):
565
  with col:
566
  st.plotly_chart(fig, use_container_width=True)
567
 
568
- # cols = st.columns(3)
569
- # for i in range(0, len(channels_list)):
570
-
571
- # col = channels_list[i]
572
- # if col == "Panel":
573
- # continue
574
- # st.write(col)
575
- # x_modified = summary_df_sorted["Optimized_spend"][col]/104
576
- # y_modified = summary_df_sorted["New_sales"][col]/104
577
- # st.plotly_chart(rc.response_curves(col,x_modified,y_modified))
578
-
579
-
580
- # @st.cache
581
- # def plot_response_curves():
582
- # cols = 4
583
- # rcs = st.session_state["rcs"]
584
- # shapes = []
585
- # fig = make_subplots(rows=6, cols=cols, subplot_titles=channels_list)
586
- # for i in range(0, len(channels_list)):
587
- # col = channels_list[i]
588
- # x = st.session_state["actual_df"][col].values
589
- # spends = x.sum()
590
- # power = np.ceil(np.log(x.max()) / np.log(10)) - 3
591
- # x = np.linspace(0, 3 * x.max(), 200)
592
-
593
- # K = rcs[col]["K"]
594
- # b = rcs[col]["b"]
595
- # a = rcs[col]["a"]
596
- # x0 = rcs[col]["x0"]
597
-
598
- # y = s_curve(x / 10**power, K, b, a, x0)
599
- # roi = y / x
600
- # marginal_roi = a * (y) * (1 - y / K)
601
- # fig.add_trace(
602
- # go.Scatter(
603
- # x=52
604
- # * x
605
- # * st.session_state["scenario"].channels[col].conversion_rate,
606
- # y=52 * y,
607
- # name=col,
608
- # customdata=np.stack((roi, marginal_roi), axis=-1),
609
- # hovertemplate="Spend:%{x:$.2s}<br>Sale:%{y:$.2s}<br>ROI:%{customdata[0]:.3f}<br>MROI:%{customdata[1]:.3f}",
610
- # ),
611
- # row=1 + (i) // cols,
612
- # col=i % cols + 1,
613
- # )
614
-
615
- # fig.add_trace(
616
- # go.Scatter(
617
- # x=[
618
- # spends
619
- # * st.session_state["scenario"]
620
- # .channels[col]
621
- # .conversion_rate
622
- # ],
623
- # y=[52 * s_curve(spends / (10**power * 52), K, b, a, x0)],
624
- # name=col,
625
- # legendgroup=col,
626
- # showlegend=False,
627
- # marker=dict(color=["black"]),
628
- # ),
629
- # row=1 + (i) // cols,
630
- # col=i % cols + 1,
631
- # )
632
-
633
- # shapes.append(
634
- # go.layout.Shape(
635
- # type="line",
636
- # x0=0,
637
- # y0=52 * s_curve(spends / (10**power * 52), K, b, a, x0),
638
- # x1=spends
639
- # * st.session_state["scenario"].channels[col].conversion_rate,
640
- # y1=52 * s_curve(spends / (10**power * 52), K, b, a, x0),
641
- # line_width=1,
642
- # line_dash="dash",
643
- # line_color="black",
644
- # xref=f"x{i+1}",
645
- # yref=f"y{i+1}",
646
- # )
647
- # )
648
-
649
- # shapes.append(
650
- # go.layout.Shape(
651
- # type="line",
652
- # x0=spends
653
- # * st.session_state["scenario"].channels[col].conversion_rate,
654
- # y0=0,
655
- # x1=spends
656
- # * st.session_state["scenario"].channels[col].conversion_rate,
657
- # y1=52 * s_curve(spends / (10**power * 52), K, b, a, x0),
658
- # line_width=1,
659
- # line_dash="dash",
660
- # line_color="black",
661
- # xref=f"x{i+1}",
662
- # yref=f"y{i+1}",
663
- # )
664
- # )
665
-
666
- # fig.update_layout(
667
- # height=1500,
668
- # width=1000,
669
- # title_text="Response Curves",
670
- # showlegend=False,
671
- # shapes=shapes,
672
- # )
673
- # fig.update_annotations(font_size=10)
674
- # fig.update_xaxes(title="Spends")
675
- # fig.update_yaxes(title=target)
676
- # return fig
677
-
678
-
679
  # ======================================================== #
680
  # ==================== HTML Components =================== #
681
  # ======================================================== #
@@ -683,7 +578,7 @@ def plot_response_curves(summary_df_sorted):
683
 
684
  def generate_spending_header(heading):
685
  return st.markdown(
686
- f"""<h2 class="spends-header">{heading}</h2>""", unsafe_allow_html=True
687
  )
688
 
689
 
@@ -776,6 +671,7 @@ def reset_inputs():
776
  del st.session_state.total_sales_change_abs_slider
777
 
778
  st.session_state["initialized"] = False
 
779
  def scenario_planner_plots():
780
  with st.expander('Optimized Spends Overview'):
781
  # if st.button('Refresh'):
@@ -818,59 +714,6 @@ def scenario_planner_plots():
818
  light_red = 'rgba(250, 110, 10, 0.7)'
819
  light_purple = 'rgba(255, 191, 69, 0.7)'
820
 
821
-
822
- # # Create subplots with one row and two columns
823
- # fig = make_subplots(rows=3, cols=1, subplot_titles=("Actual vs. Optimized Spend", "Actual vs. Optimized Contribution", "Actual vs. Optimized ROI"))
824
- # # Add actual vs optimized spend bars
825
-
826
-
827
- # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['Actual_spend'], name='Actual',
828
- # text=summary_df_sorted['Actual_spend'].apply(format_number) + ' '+' (' + actual_spend_percentage.round(2).astype(str) + '%)',
829
- # marker_color=light_blue, orientation='h'),
830
- # row=1,
831
- # col=1)
832
-
833
-
834
- # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['Optimized_spend'], name='Optimized',
835
- # text=summary_df_sorted['Optimized_spend'].apply(format_number) + ' (' + optimized_spend_percentage.round(2).astype(str) + '%)',
836
- # marker_color=light_orange,
837
- # orientation='h'),
838
- # row=1,
839
- # col=1)
840
-
841
- # fig.update_xaxes(title_text="Amount", row=1, col=1)
842
-
843
- # # Add actual vs optimized Contribution
844
- # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['New_sales'],
845
- # name='Optimized Contribution',text=summary_df_sorted['New_sales'].apply(format_number),
846
- # marker_color=light_orange, orientation='h',showlegend=False), row=2, col=1)
847
-
848
- # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['Old_sales'],
849
- # name='Actual Contribution',text=summary_df_sorted['Old_sales'].apply(format_number),
850
- # marker_color=light_blue, orientation='h',showlegend=False), row=2, col=1)
851
-
852
-
853
- # fig.update_xaxes(title_text="Contribution", row=2, col=1)
854
-
855
- # # Add actual vs optimized ROI bars
856
-
857
- # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['new_roi'],
858
- # name='Optimized ROI',text=summary_df_sorted['new_roi'].apply(format_number) ,
859
- # marker_color=light_orange, orientation='h',showlegend=False), row=3, col=1)
860
-
861
- # fig.add_trace(go.Bar(y=summary_df_sorted['Channel_name'], x=summary_df_sorted['old_roi'],
862
- # name='Actual ROI', text=summary_df_sorted['old_roi'].apply(format_number) ,
863
- # marker_color=light_blue, orientation='h',showlegend=False), row=3, col=1)
864
-
865
- # fig.update_xaxes(title_text="ROI", row=3, col=1)
866
-
867
- # # Update layout
868
- # fig.update_layout(title_text="Actual vs. Optimized Metrics for Media Channels",
869
- # showlegend=True, yaxis=dict(title='Media Channels', autorange="reversed"))
870
-
871
- # st.plotly_chart(fig,use_container_width=True)
872
-
873
- # Create subplots with one row and two columns
874
  fig = go.Figure()
875
  # Add actual vs optimized spend bars
876
 
@@ -993,17 +836,7 @@ if auth_status == True:
993
  # Check if state is initiaized
994
  is_state_initiaized = st.session_state.get("initialized", False)
995
  if not is_state_initiaized or st.session_state["first_time"]:
996
- # initialize_data()
997
- if panel_selected == "Total Market":
998
- initialize_data(
999
- panel=panel_selected,
1000
- target_file=file_selected,
1001
- updated_rcs=updated_rcs,
1002
- metrics=metrics_selected,
1003
- )
1004
- panel = None
1005
- else:
1006
- initialize_data(
1007
  panel=panel_selected,
1008
  target_file=file_selected,
1009
  updated_rcs=updated_rcs,
@@ -1044,6 +877,7 @@ if auth_status == True:
1044
  _scenario.actual_total_spends, 1
1045
  )
1046
 
 
1047
  if "total_sales_change_abs" not in st.session_state:
1048
  st.session_state["total_sales_change_abs"] = numerize(
1049
  _scenario.actual_total_sales, 1
@@ -1065,7 +899,7 @@ if auth_status == True:
1065
  if "upper_bound_key" not in st.session_state:
1066
  st.session_state["upper_bound_key"] = 10
1067
 
1068
-
1069
  header_df = pd.DataFrame(index=["Actual","Simulated","Change","Percent Change"],columns=["Spends","Prospects"])
1070
  header_df["Spends"]["Actual"] = format_numbers(_scenario.actual_total_spends)
1071
  header_df["Spends"]["Simulated"] = format_numbers(_scenario.modified_total_spends)
@@ -1083,7 +917,7 @@ if auth_status == True:
1083
  """
1084
  <style>
1085
  .custom-text_head {
1086
- font-size: 36px; /* Adjust font size */
1087
  color: 'blue' ; /* Adjust text color */
1088
 
1089
  font-weight: bold;
@@ -1111,93 +945,85 @@ if auth_status == True:
1111
 
1112
  _columns = st.columns((1, 1, 1, 1, 1))
1113
  with _columns[0]:
1114
- st.header("Spends")
 
1115
  with _columns[1]:
1116
- st.metric(label="", value=header_df["Spends"]["Actual"])
 
1117
  with _columns[2]:
1118
- st.metric(label="", value=header_df["Spends"]["Simulated"])
1119
- with _columns[3]:
1120
- if _scenario.delta_spends >= 0:
1121
  st.markdown(
1122
  """
1123
  <style>
1124
  .custom-text {
1125
- font-size: 36px; /* Adjust font size */
1126
  color: #6bbf6b ; /* Adjust text color */
1127
  }
1128
  </style>
1129
  """,
1130
  unsafe_allow_html=True
1131
  )
1132
- else:
1133
  st.markdown(
1134
  """
1135
  <style>
1136
  .custom-text {
1137
- font-size: 36px; /* Adjust font size */
1138
  color: #ff6868; /* Adjust text color */
1139
  }
1140
  </style>
1141
  """,
1142
  unsafe_allow_html=True
1143
  )
 
 
1144
 
1145
-
1146
  # Apply custom styles to text
1147
- st.markdown(f'<p class="custom-text">{header_df["Spends"]["Change"]}</p>', unsafe_allow_html=True)
1148
  with _columns[4]:
1149
  # Apply custom styles to text
1150
- st.markdown(f'<p></hr></p>', unsafe_allow_html=True)
1151
- st.markdown(f'<p class="custom-text">{header_df["Spends"]["Percent Change"]}</p>', unsafe_allow_html=True)
1152
-
1153
-
1154
  st.markdown(
1155
  """<hr class="spends-child-seperator">""",
1156
  unsafe_allow_html=True,
1157
  )
1158
  _columns = st.columns((1, 1, 1, 1, 1))
1159
  with _columns[0]:
1160
- st.header("Prospects")
 
1161
  with _columns[1]:
1162
- st.metric(label="", value=header_df["Prospects"]["Actual"])
 
1163
  with _columns[2]:
1164
- st.metric(label="", value=header_df["Prospects"]["Simulated"])
1165
- with _columns[3]:
1166
-
1167
- if _scenario.delta_sales >= 0:
1168
  st.markdown(
1169
  """
1170
  <style>
1171
  .custom-text {
1172
- font-size: 36px; /* Adjust font size */
1173
  color:#6bbf6b ; /* Adjust text color */
1174
  }
1175
  </style>
1176
  """,
1177
  unsafe_allow_html=True
1178
  )
1179
- else:
1180
- st.markdown(
1181
- """
1182
- <style>
1183
- .custom-text {
1184
- font-size: 36px; /* Adjust font size */
1185
- color: #ff6868; /* Adjust text color */
1186
- }
1187
- </style>
1188
- """,
1189
- unsafe_allow_html=True
1190
- )
1191
-
1192
  # Apply custom styles to text
1193
- st.markdown(f'<p class="custom-text">{header_df["Prospects"]["Change"]}</p>', unsafe_allow_html=True)
1194
  # st.markdown(f'<p style="color: red;">{st.metric(label="", value=header_df["Prospects"]["Change"])}</p>', unsafe_allow_html=True)
1195
  # st.markdown(f'<p style="color: red;">{header_df["Prospects"]["Change"]}</p>', unsafe_allow_html=True)
1196
 
1197
  with _columns[4]:
1198
- st.markdown(f'<p></hr></p>', unsafe_allow_html=True)
1199
  # Apply custom styles to text
1200
- st.markdown(f'<p class="custom-text">{header_df["Prospects"]["Percent Change"]}</p>', unsafe_allow_html=True)
1201
  st.markdown(
1202
  """<hr class="spends-child-seperator">""",
1203
  unsafe_allow_html=True,
@@ -1207,31 +1033,33 @@ if auth_status == True:
1207
  ef1 = (_scenario.actual_total_spends/_scenario.actual_total_sales)
1208
  ef2 = (_scenario.modified_total_spends/_scenario.modified_total_sales)
1209
  with _columns[0]:
1210
- st.header("Cost Per Prospect")
 
1211
  with _columns[1]:
1212
- st.metric(label="", value='$ '+numerize(ef1,0))
 
1213
  with _columns[2]:
1214
- st.metric(label="", value='$ '+numerize(ef2,0))
1215
- with _columns[3]:
1216
-
1217
- if ef2 >= ef1:
1218
  st.markdown(
1219
  """
1220
  <style>
1221
  .custom-text1 {
1222
- font-size: 36px; /* Adjust font size */
1223
  color:#6bbf6b ; /* Adjust text color */
1224
  }
1225
  </style>
1226
  """,
1227
  unsafe_allow_html=True
1228
  )
1229
- else:
1230
  st.markdown(
1231
  """
1232
  <style>
1233
  .custom-text1 {
1234
- font-size: 36px; /* Adjust font size */
1235
  color: #ff6868; /* Adjust text color */
1236
  }
1237
  </style>
@@ -1239,19 +1067,19 @@ if auth_status == True:
1239
  unsafe_allow_html=True
1240
  )
1241
 
 
 
 
1242
  # Apply custom styles to text
1243
- st.markdown(f'<p class="custom-text1">{"$ "+numerize(ef2-ef1,0)}</p>', unsafe_allow_html=True)
1244
  # st.markdown(f'<p style="color: red;">{st.metric(label="", value=header_df["Prospects"]["Change"])}</p>', unsafe_allow_html=True)
1245
  # st.markdown(f'<p style="color: red;">{header_df["Prospects"]["Change"]}</p>', unsafe_allow_html=True)
1246
 
1247
  with _columns[4]:
1248
- st.markdown(f'<p></hr></p>', unsafe_allow_html=True)
1249
  # Apply custom styles to text
1250
- st.markdown(f'<p class="custom-text1">{round((ef2-ef1)/ef1*100,2)}%</p>', unsafe_allow_html=True)
1251
- st.markdown(
1252
- """<hr class="spends-child-seperator">""",
1253
- unsafe_allow_html=True,
1254
- )
1255
 
1256
  # st.markdown("""<hr class="spends-heading-seperator">""", unsafe_allow_html=True)
1257
 
@@ -1431,11 +1259,8 @@ if auth_status == True:
1431
  # on_change=partial(update_data_bound_max_overall)
1432
  )
1433
 
1434
-
1435
-
1436
-
1437
- min_value = round(_scenario.actual_total_spends * 0.5)
1438
- max_value = round(_scenario.actual_total_spends * 1.5)
1439
  st.session_state["total_spends_change_abs_slider_options"] = [
1440
  numerize(value, 1)
1441
  for value in range(min_value, max_value + 1, int(1e4))
@@ -1486,10 +1311,10 @@ if auth_status == True:
1486
  # st.write(max_value)
1487
  # for value in range(min_value, max_value + 1, int(100)):
1488
  # st.write(numerize(value, 1))
1489
- st.session_state["total_sales_change_abs_slider_options"] = [
1490
- numerize(value, 1)
1491
- for value in range(min_value, max_value + 1, int(100))
1492
- ]
1493
 
1494
  # st.select_slider(
1495
  # "Absolute Slider",
@@ -1642,33 +1467,41 @@ if auth_status == True:
1642
  st.session_state["acutual_predicted"]["Delta"].append(spends_delta)
1643
  _spend_cols = st.columns(2)
1644
  with _spend_cols[0]:
1645
- st.metric(
1646
- label="Actual Spends",
1647
- value=format_numbers(actual_channel_spends),
1648
- # delta=numerize(spends_delta, 1),
1649
- # label_visibility="collapsed",
1650
- )
1651
-
1652
- st.metric(
1653
- label="Change",
1654
- value= format_numbers_f(spends_delta),
1655
- delta=numerize(spends_delta, 1),
1656
- # label_visibility="collapsed",
1657
- )
 
 
 
 
 
 
1658
  with _spend_cols[1]:
1659
- st.metric(
1660
- label="Simulated Spends",
1661
- value=format_numbers(current_channel_spends),
1662
- # delta=numerize(spends_delta, 1),
1663
- # label_visibility="collapsed",
1664
- )
1665
-
1666
- st.metric(
1667
- label="Percent Change",
1668
- value= numerize(( spends_delta/actual_channel_spends)*100,0) +"%",
1669
- delta=numerize(spends_delta, 1),
1670
- # label_visibility="collapsed",
1671
- )
 
 
1672
 
1673
 
1674
  with _columns[3]:
@@ -1682,33 +1515,40 @@ if auth_status == True:
1682
 
1683
  _prospect_cols = st.columns(2)
1684
  with _prospect_cols[0]:
1685
- st.metric(
1686
- # target,
1687
- label="Actual Prospects",
1688
- value= format_numbers_f(actual_channel_sales),
1689
- # delta=numerize(sales_delta, 1),
1690
- # label_visibility="collapsed",
1691
- )
1692
- st.metric(
1693
- label="Change",
1694
- value= format_numbers_f(_channel_class.delta_sales),
1695
- delta=numerize(sales_delta, 1),
1696
- # label_visibility="collapsed",
1697
- )
 
 
 
 
1698
  with _prospect_cols[1]:
1699
- st.metric(
1700
- label="Simulated Prospects",
1701
- value= format_numbers_f(current_channel_sales),
1702
- # delta=numerize(sales_delta, 1),
1703
- # label_visibility="collapsed",
1704
- )
1705
-
1706
- st.metric(
1707
- label="Percent Change",
1708
- value= numerize((_channel_class.delta_sales/actual_channel_sales)*100,0) +"%",
1709
- delta=numerize(sales_delta, 1),
1710
- # label_visibility="collapsed",
1711
- )
 
 
 
1712
 
1713
 
1714
 
@@ -1752,77 +1592,77 @@ if auth_status == True:
1752
 
1753
  updated_rcs_key = f"{metrics_selected}#@{panel_selected}#@{channel_name}"
1754
 
1755
- if updated_rcs and updated_rcs_key in list(updated_rcs.keys()):
1756
- K = updated_rcs[updated_rcs_key]["K"]
1757
- b = updated_rcs[updated_rcs_key]["b"]
1758
- a = updated_rcs[updated_rcs_key]["a"]
1759
- x0 = updated_rcs[updated_rcs_key]["x0"]
1760
- else:
1761
- K = st.session_state["rcs"][col]["K"]
1762
- b = st.session_state["rcs"][col]["b"]
1763
- a = st.session_state["rcs"][col]["a"]
1764
- x0 = st.session_state["rcs"][col]["x0"]
1765
-
1766
- x_plot = np.linspace(0, 5 * x_actual.sum(), 200)
1767
-
1768
- # Append current_channel_spends to the end of x_plot
1769
- x_plot = np.append(x_plot, current_channel_spends)
1770
-
1771
- x, y, marginal_roi = [], [], []
1772
- for x_p in x_plot:
1773
- x.append(x_p * x_actual / x_actual.sum())
1774
-
1775
- for index in range(len(x_plot)):
1776
- y.append(s_curve(x[index] / 10**power, K, b, a, x0))
1777
-
1778
- for index in range(len(x_plot)):
1779
- marginal_roi.append(
1780
- a * y[index] * (1 - y[index] / np.maximum(K, np.finfo(float).eps))
1781
- )
1782
-
1783
- x = (
1784
- np.sum(x, axis=1)
1785
- * st.session_state["scenario"].channels[col].conversion_rate
1786
- )
1787
- y = np.sum(y, axis=1)
1788
- marginal_roi = (
1789
- np.average(marginal_roi, axis=1)
1790
- / st.session_state["scenario"].channels[col].conversion_rate
1791
- )
1792
 
1793
- roi = y / np.maximum(x, np.finfo(float).eps)
1794
- # roi = (y/np.sum(y))/(x/np.sum(x))
1795
- # st.write(x)
1796
- # st.write(y)
1797
- # st.write(roi)
1798
 
1799
- # st.write(roi[-1])
1800
 
1801
- roi_current, marginal_roi_current = roi[-1], marginal_roi[-1]
1802
- x, y, roi, marginal_roi = (
1803
- x[:-1],
1804
- y[:-1],
1805
- roi[:-1],
1806
- marginal_roi[:-1],
1807
- ) # Drop data for current spends
1808
-
1809
- # roi_current =
1810
-
1811
- start_value, end_value, left_value, right_value = find_segment_value(
1812
- x,
1813
- roi,
1814
- marginal_roi,
1815
- )
1816
 
1817
  #st.write(roi_current)
1818
 
1819
- rgba = calculate_rgba(
1820
- start_value,
1821
- end_value,
1822
- left_value,
1823
- right_value,
1824
- current_channel_spends,
1825
- )
1826
 
1827
  summary_df = pd.DataFrame(st.session_state["acutual_predicted"])
1828
  # st.dataframe(summary_df)
@@ -1860,12 +1700,14 @@ if auth_status == True:
1860
  text-align: center;
1861
  color: {'black'};
1862
  ">
1863
- <p style="margin: 0; font-size: 20px;">Simulated Efficiency: {round(a,2)} </br> Actual Efficiency: {round(b,2)} </p>
1864
- <!--<p style="margin: 0; font-size: 20px;">Marginal ROI: {round(marginal_roi_current,1)}</p>-->
1865
  </div>
1866
  """,
1867
  unsafe_allow_html=True,
1868
  )
 
 
1869
 
1870
  with st.expander("See Response Curves", expanded=True):
1871
  fig = plot_response_curves(summary_df_sorted)
 
62
  if key.lower() == "media spends":
63
  with status_placeholder:
64
  with st.spinner("Optimizing"):
65
+ print(channel_list)
66
+ print(st.session_state["total_spends_change"])
67
  result = st.session_state["scenario"].optimize(
68
  st.session_state["total_spends_change"], channel_list
69
+ # result = st.session_state["scenario"].spends_optimisation(
70
+ # st.session_state["total_spends_change"], channel_list
71
  )
72
+
73
+
74
  # elif key.lower() == "revenue":
75
  else:
76
  with status_placeholder:
 
571
  with col:
572
  st.plotly_chart(fig, use_container_width=True)
573
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  # ======================================================== #
575
  # ==================== HTML Components =================== #
576
  # ======================================================== #
 
578
 
579
  def generate_spending_header(heading):
580
  return st.markdown(
581
+ f"""<h4 class="spends-header"><bold>{heading}<bold></h4>""", unsafe_allow_html=True
582
  )
583
 
584
 
 
671
  del st.session_state.total_sales_change_abs_slider
672
 
673
  st.session_state["initialized"] = False
674
+
675
  def scenario_planner_plots():
676
  with st.expander('Optimized Spends Overview'):
677
  # if st.button('Refresh'):
 
714
  light_red = 'rgba(250, 110, 10, 0.7)'
715
  light_purple = 'rgba(255, 191, 69, 0.7)'
716
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717
  fig = go.Figure()
718
  # Add actual vs optimized spend bars
719
 
 
836
  # Check if state is initiaized
837
  is_state_initiaized = st.session_state.get("initialized", False)
838
  if not is_state_initiaized or st.session_state["first_time"]:
839
+ initialize_data(
 
 
 
 
 
 
 
 
 
 
840
  panel=panel_selected,
841
  target_file=file_selected,
842
  updated_rcs=updated_rcs,
 
877
  _scenario.actual_total_spends, 1
878
  )
879
 
880
+ st.write(_scenario.actual_total_sales)
881
  if "total_sales_change_abs" not in st.session_state:
882
  st.session_state["total_sales_change_abs"] = numerize(
883
  _scenario.actual_total_sales, 1
 
899
  if "upper_bound_key" not in st.session_state:
900
  st.session_state["upper_bound_key"] = 10
901
 
902
+ st.write(_scenario.modified_total_sales)
903
  header_df = pd.DataFrame(index=["Actual","Simulated","Change","Percent Change"],columns=["Spends","Prospects"])
904
  header_df["Spends"]["Actual"] = format_numbers(_scenario.actual_total_spends)
905
  header_df["Spends"]["Simulated"] = format_numbers(_scenario.modified_total_spends)
 
917
  """
918
  <style>
919
  .custom-text_head {
920
+ font-size: 24px; /* Adjust font size */
921
  color: 'blue' ; /* Adjust text color */
922
 
923
  font-weight: bold;
 
945
 
946
  _columns = st.columns((1, 1, 1, 1, 1))
947
  with _columns[0]:
948
+ st.markdown("""<h4> Spends</h4>""",unsafe_allow_html=True)
949
+ # st.write("Spends")
950
  with _columns[1]:
951
+ st.markdown(f"""<h4>{header_df["Spends"]["Actual"]}</h4>""",unsafe_allow_html=True)
952
+ # st.metric(label="", value=header_df["Spends"]["Actual"])
953
  with _columns[2]:
954
+ st.markdown(f"""<h4>{header_df["Spends"]["Simulated"]}</h4>""",unsafe_allow_html=True)
955
+ if _scenario.delta_spends < 0:
 
956
  st.markdown(
957
  """
958
  <style>
959
  .custom-text {
960
+ font-size: 24px; /* Adjust font size */
961
  color: #6bbf6b ; /* Adjust text color */
962
  }
963
  </style>
964
  """,
965
  unsafe_allow_html=True
966
  )
967
+ else:
968
  st.markdown(
969
  """
970
  <style>
971
  .custom-text {
972
+ font-size: 24px; /* Adjust font size */
973
  color: #ff6868; /* Adjust text color */
974
  }
975
  </style>
976
  """,
977
  unsafe_allow_html=True
978
  )
979
+ # st.metric(label="", value=header_df["Spends"]["Simulated"])
980
+ with _columns[3]:
981
 
 
982
  # Apply custom styles to text
983
+ st.markdown(f'<h4 class="custom-text">{header_df["Spends"]["Change"]}</h4>', unsafe_allow_html=True)
984
  with _columns[4]:
985
  # Apply custom styles to text
986
+ # st.markdown(f'<p></hr></p>', unsafe_allow_html=True)
987
+ st.markdown(f'<h4 class="custom-text">{header_df["Spends"]["Percent Change"]}</h4>', unsafe_allow_html=True)
 
 
988
  st.markdown(
989
  """<hr class="spends-child-seperator">""",
990
  unsafe_allow_html=True,
991
  )
992
  _columns = st.columns((1, 1, 1, 1, 1))
993
  with _columns[0]:
994
+ # st.header("Prospects")
995
+ st.markdown("""<h4> Prospects</h4>""",unsafe_allow_html=True)
996
  with _columns[1]:
997
+ st.markdown(f"""<h4>{header_df["Prospects"]["Actual"]}</h4>""",unsafe_allow_html=True)
998
+ # st.metric(label="", value=header_df["Prospects"]["Actual"])
999
  with _columns[2]:
1000
+ st.markdown(f"""<h4>{header_df["Prospects"]["Simulated"]}</h4>""",unsafe_allow_html=True)
1001
+ # st.metric(label="", value=header_df["Prospects"]["Simulated"])
1002
+
1003
+ if _scenario.delta_sales >= 0:
1004
  st.markdown(
1005
  """
1006
  <style>
1007
  .custom-text {
1008
+ font-size: 24px; /* Adjust font size */
1009
  color:#6bbf6b ; /* Adjust text color */
1010
  }
1011
  </style>
1012
  """,
1013
  unsafe_allow_html=True
1014
  )
1015
+ else:
1016
+ st.markdown("""<style>.custom-text {font-size: 24px; /* Adjust font size */color: #ff6868; /* Adjust text color */}</style>""",unsafe_allow_html=True)
1017
+ with _columns[3]:
 
 
 
 
 
 
 
 
 
 
1018
  # Apply custom styles to text
1019
+ st.markdown(f'<h4 class="custom-text">{header_df["Prospects"]["Change"]}</h4>', unsafe_allow_html=True)
1020
  # st.markdown(f'<p style="color: red;">{st.metric(label="", value=header_df["Prospects"]["Change"])}</p>', unsafe_allow_html=True)
1021
  # st.markdown(f'<p style="color: red;">{header_df["Prospects"]["Change"]}</p>', unsafe_allow_html=True)
1022
 
1023
  with _columns[4]:
1024
+ # st.markdown(f'<p></hr></p>', unsafe_allow_html=True)
1025
  # Apply custom styles to text
1026
+ st.markdown(f'<h4 class="custom-text">{header_df["Prospects"]["Percent Change"]}</h4>', unsafe_allow_html=True)
1027
  st.markdown(
1028
  """<hr class="spends-child-seperator">""",
1029
  unsafe_allow_html=True,
 
1033
  ef1 = (_scenario.actual_total_spends/_scenario.actual_total_sales)
1034
  ef2 = (_scenario.modified_total_spends/_scenario.modified_total_sales)
1035
  with _columns[0]:
1036
+ st.markdown("""<h4>Cost Per Prospect</h4>""",unsafe_allow_html=True)
1037
+ # st.header("Cost Per Prospect")
1038
  with _columns[1]:
1039
+ st.markdown(f"""<h4>{'$ '+numerize(ef1,0)}</h4>""",unsafe_allow_html=True)
1040
+ # st.metric(label="", value='$ '+numerize(ef1,0))
1041
  with _columns[2]:
1042
+ st.markdown(f"""<h4>{'$ '+numerize(ef2,0)}</h4>""",unsafe_allow_html=True)
1043
+ # st.metric(label="", value='$ '+numerize(ef2,0))
1044
+
1045
+ if ef2 <= ef1:
1046
  st.markdown(
1047
  """
1048
  <style>
1049
  .custom-text1 {
1050
+ font-size: 24px; /* Adjust font size */
1051
  color:#6bbf6b ; /* Adjust text color */
1052
  }
1053
  </style>
1054
  """,
1055
  unsafe_allow_html=True
1056
  )
1057
+ else:
1058
  st.markdown(
1059
  """
1060
  <style>
1061
  .custom-text1 {
1062
+ font-size: 24px; /* Adjust font size */
1063
  color: #ff6868; /* Adjust text color */
1064
  }
1065
  </style>
 
1067
  unsafe_allow_html=True
1068
  )
1069
 
1070
+ with _columns[3]:
1071
+
1072
+
1073
  # Apply custom styles to text
1074
+ st.markdown(f'<h4 class="custom-text1">{"$ "+numerize(ef2-ef1,0)}</h4>', unsafe_allow_html=True)
1075
  # st.markdown(f'<p style="color: red;">{st.metric(label="", value=header_df["Prospects"]["Change"])}</p>', unsafe_allow_html=True)
1076
  # st.markdown(f'<p style="color: red;">{header_df["Prospects"]["Change"]}</p>', unsafe_allow_html=True)
1077
 
1078
  with _columns[4]:
1079
+ # st.markdown(f'<p></hr></p>', unsafe_allow_html=True)
1080
  # Apply custom styles to text
1081
+ st.markdown(f'<h4 class="custom-text1">{round((ef2-ef1)/ef1*100,2)}%</h4>', unsafe_allow_html=True)
1082
+ st.markdown("""<hr class="spends-child-seperator">""",unsafe_allow_html=True)
 
 
 
1083
 
1084
  # st.markdown("""<hr class="spends-heading-seperator">""", unsafe_allow_html=True)
1085
 
 
1259
  # on_change=partial(update_data_bound_max_overall)
1260
  )
1261
 
1262
+ min_value = round(_scenario.actual_total_spends * (1-overall_lower_bound/100))
1263
+ max_value = round(_scenario.actual_total_spends * (1-overall_upper_bound/100))
 
 
 
1264
  st.session_state["total_spends_change_abs_slider_options"] = [
1265
  numerize(value, 1)
1266
  for value in range(min_value, max_value + 1, int(1e4))
 
1311
  # st.write(max_value)
1312
  # for value in range(min_value, max_value + 1, int(100)):
1313
  # st.write(numerize(value, 1))
1314
+ # st.session_state["total_sales_change_abs_slider_options"] = [
1315
+ # numerize(value, 1)
1316
+ # for value in range(min_value, max_value + 1, int(100))
1317
+ # ]
1318
 
1319
  # st.select_slider(
1320
  # "Absolute Slider",
 
1467
  st.session_state["acutual_predicted"]["Delta"].append(spends_delta)
1468
  _spend_cols = st.columns(2)
1469
  with _spend_cols[0]:
1470
+ # st.write("Actual")
1471
+ st.markdown(f'<p> Actual <h5>{format_numbers(actual_channel_spends)}</h5> </p>', unsafe_allow_html=True)
1472
+ # st.metric(
1473
+ # label="Actual Spends",
1474
+ # value=format_numbers(actual_channel_spends),
1475
+ # # delta=numerize(spends_delta, 1),
1476
+ # # label_visibility="collapsed",
1477
+ # )
1478
+
1479
+ # st.write("Actual")
1480
+ st.markdown(f'<p> Change <h5>{format_numbers(spends_delta)}</h5> </p>', unsafe_allow_html=True)
1481
+ # st.markdown(f'<h4 class="custom-text1">{format_numbers(spends_delta)}%</h4>', unsafe_allow_html=True)
1482
+
1483
+ # st.metric(
1484
+ # label="Change",
1485
+ # value= format_numbers_f(spends_delta),
1486
+ # delta=numerize(spends_delta, 1),
1487
+ # # label_visibility="collapsed",
1488
+ # )
1489
  with _spend_cols[1]:
1490
+ st.markdown(f'<p> Simulated <h5>{format_numbers(current_channel_spends)}</h5> </p>', unsafe_allow_html=True)
1491
+ st.markdown(f'<p>Percent<h5>{numerize(( spends_delta/actual_channel_spends)*100,0) +"%"}</h5> </p>', unsafe_allow_html=True)
1492
+ # st.metric(
1493
+ # label="Simulated Spends",
1494
+ # value=format_numbers(current_channel_spends),
1495
+ # # delta=numerize(spends_delta, 1),
1496
+ # # label_visibility="collapsed",
1497
+ # )
1498
+
1499
+ # st.metric(
1500
+ # label="Percent Change",
1501
+ # value= numerize(( spends_delta/actual_channel_spends)*100,0) +"%",
1502
+ # delta=numerize(spends_delta, 1),
1503
+ # # label_visibility="collapsed",
1504
+ # )
1505
 
1506
 
1507
  with _columns[3]:
 
1515
 
1516
  _prospect_cols = st.columns(2)
1517
  with _prospect_cols[0]:
1518
+ # st.write("Actual")
1519
+ st.markdown(f'<p> Actual <h5>{format_numbers(actual_channel_sales)}</h5> </p>', unsafe_allow_html=True)
1520
+ st.markdown(f'<p> Change <h5>{format_numbers(sales_delta)}</h5> </p>', unsafe_allow_html=True)
1521
+
1522
+ # st.metric(
1523
+ # # target,
1524
+ # label="Actual Prospects",
1525
+ # value= format_numbers_f(actual_channel_sales),
1526
+ # # delta=numerize(sales_delta, 1),
1527
+ # # label_visibility="collapsed",
1528
+ # )
1529
+ # st.metric(
1530
+ # label="Change",
1531
+ # value= format_numbers_f(_channel_class.delta_sales),
1532
+ # delta=numerize(sales_delta, 1),
1533
+ # # label_visibility="collapsed",
1534
+ # )
1535
  with _prospect_cols[1]:
1536
+ st.markdown(f'<p> Simulated <h5>{format_numbers(current_channel_sales)}</h5> </p>', unsafe_allow_html=True)
1537
+ st.markdown(f'<p>Percent<h5>{numerize(( _channel_class.delta_sales/actual_channel_sales)*100,0) +"%"}</h5> </p>', unsafe_allow_html=True)
1538
+
1539
+ # st.metric(
1540
+ # label="Simulated Prospects",
1541
+ # value= format_numbers_f(current_channel_sales),
1542
+ # # delta=numerize(sales_delta, 1),
1543
+ # # label_visibility="collapsed",
1544
+ # )
1545
+
1546
+ # st.metric(
1547
+ # label="Percent Change",
1548
+ # value= numerize((_channel_class.delta_sales/actual_channel_sales)*100,0) +"%",
1549
+ # delta=numerize(sales_delta, 1),
1550
+ # # label_visibility="collapsed",
1551
+ # )
1552
 
1553
 
1554
 
 
1592
 
1593
  updated_rcs_key = f"{metrics_selected}#@{panel_selected}#@{channel_name}"
1594
 
1595
+ # if updated_rcs and updated_rcs_key in list(updated_rcs.keys()):
1596
+ # K = updated_rcs[updated_rcs_key]["K"]
1597
+ # b = updated_rcs[updated_rcs_key]["b"]
1598
+ # a = updated_rcs[updated_rcs_key]["a"]
1599
+ # x0 = updated_rcs[updated_rcs_key]["x0"]
1600
+ # else:
1601
+ # K = st.session_state["rcs"][col]["K"]
1602
+ # b = st.session_state["rcs"][col]["b"]
1603
+ # a = st.session_state["rcs"][col]["a"]
1604
+ # x0 = st.session_state["rcs"][col]["x0"]
1605
+
1606
+ # x_plot = np.linspace(0, 5 * x_actual.sum(), 200)
1607
+
1608
+ # # Append current_channel_spends to the end of x_plot
1609
+ # x_plot = np.append(x_plot, current_channel_spends)
1610
+
1611
+ # x, y, marginal_roi = [], [], []
1612
+ # for x_p in x_plot:
1613
+ # x.append(x_p * x_actual / x_actual.sum())
1614
+
1615
+ # for index in range(len(x_plot)):
1616
+ # y.append(s_curve(x[index] / 10**power, K, b, a, x0))
1617
+
1618
+ # for index in range(len(x_plot)):
1619
+ # marginal_roi.append(
1620
+ # a * y[index] * (1 - y[index] / np.maximum(K, np.finfo(float).eps))
1621
+ # )
1622
+
1623
+ # x = (
1624
+ # np.sum(x, axis=1)
1625
+ # * st.session_state["scenario"].channels[col].conversion_rate
1626
+ # )
1627
+ # y = np.sum(y, axis=1)
1628
+ # marginal_roi = (
1629
+ # np.average(marginal_roi, axis=1)
1630
+ # / st.session_state["scenario"].channels[col].conversion_rate
1631
+ # )
1632
 
1633
+ # roi = y / np.maximum(x, np.finfo(float).eps)
1634
+ # # roi = (y/np.sum(y))/(x/np.sum(x))
1635
+ # # st.write(x)
1636
+ # # st.write(y)
1637
+ # # st.write(roi)
1638
 
1639
+ # # st.write(roi[-1])
1640
 
1641
+ # roi_current, marginal_roi_current = roi[-1], marginal_roi[-1]
1642
+ # x, y, roi, marginal_roi = (
1643
+ # x[:-1],
1644
+ # y[:-1],
1645
+ # roi[:-1],
1646
+ # marginal_roi[:-1],
1647
+ # ) # Drop data for current spends
1648
+
1649
+ # # roi_current =
1650
+
1651
+ # start_value, end_value, left_value, right_value = find_segment_value(
1652
+ # x,
1653
+ # roi,
1654
+ # marginal_roi,
1655
+ # )
1656
 
1657
  #st.write(roi_current)
1658
 
1659
+ # rgba = calculate_rgba(
1660
+ # start_value,
1661
+ # end_value,
1662
+ # left_value,
1663
+ # right_value,
1664
+ # current_channel_spends,
1665
+ # )
1666
 
1667
  summary_df = pd.DataFrame(st.session_state["acutual_predicted"])
1668
  # st.dataframe(summary_df)
 
1700
  text-align: center;
1701
  color: {'black'};
1702
  ">
1703
+ <p style="margin: 0; font-size: 16px;">Simulated Efficiency: {round(a,2)} </br> Actual Efficiency: {round(b,2)} </p>
1704
+ <!--<p style="margin: 0; font-size: 16px;">Marginal ROI: {round(b,1)}</p>-->
1705
  </div>
1706
  """,
1707
  unsafe_allow_html=True,
1708
  )
1709
+ # <p style="margin: 0; font-size: 16px;">Simulated Efficiency: {round(a,2)} </br> Actual Efficiency: {round(b,2)} </p>
1710
+ # <!--<p style="margin: 0; font-size: 16px;">Marginal ROI: {round(b,1)}</p>-->
1711
 
1712
  with st.expander("See Response Curves", expanded=True):
1713
  fig = plot_response_curves(summary_df_sorted)
pages/3_Saved_Scenarios.py CHANGED
@@ -405,6 +405,7 @@ if auth_status == True:
405
  # 'Pick a scenario to view details',
406
  # list(saved_scenarios.keys())
407
  # )
 
408
  with st.expander('Download Scenario'):
409
  st.markdown("""<hr>""", unsafe_allow_html=True)
410
  scenarios_to_download = st.multiselect('Select scenarios to download',
@@ -429,8 +430,9 @@ if auth_status == True:
429
  column_1, column_2,column_3 = st.columns((6,1,1))
430
  with column_1:
431
  st.header(selected_scenario)
432
- with column_3:
433
- st.button('Delete scenarios', on_click=delete_scenario)
 
434
  # with column_3:
435
  # st.button('Load Scenario', on_click=load_scenario)
436
 
 
405
  # 'Pick a scenario to view details',
406
  # list(saved_scenarios.keys())
407
  # )
408
+ st.button('Delete scenario', on_click=delete_scenario)
409
  with st.expander('Download Scenario'):
410
  st.markdown("""<hr>""", unsafe_allow_html=True)
411
  scenarios_to_download = st.multiselect('Select scenarios to download',
 
430
  column_1, column_2,column_3 = st.columns((6,1,1))
431
  with column_1:
432
  st.header(selected_scenario)
433
+ # with column_3:
434
+ # st.write("")
435
+ # st.button('Delete scenario', on_click=delete_scenario)
436
  # with column_3:
437
  # st.button('Load Scenario', on_click=load_scenario)
438
 
response_curves_model_quality.py CHANGED
@@ -125,7 +125,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
125
 
126
  ext_df['MAT'] = ["ext","ext","ext"]
127
 
128
- print(ext_df)
129
  plot_df= plot_df.append(ext_df)
130
  return plot_df
131
 
@@ -148,7 +148,7 @@ def input_data(df,spend_col,prospect_col):
148
  return X,y,x_data,y_data,x_minmax,y_minmax
149
 
150
  def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
151
- print(x_max)
152
  x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
153
  # x_ext_data = [1500000,2000000,2500000]
154
  # x_ext_data = [x_max+100,x_max+200,x_max+5000]
@@ -157,7 +157,7 @@ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
157
  for i in range(len(x_scaled)):
158
  x_data.append(x_scaled[i][0])
159
 
160
- print(x_data)
161
  y_fit = hill_equation(x_data, Kd_fit, n_fit)
162
  y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
163
 
@@ -170,8 +170,8 @@ def fit_data(spend_col,prospect_col,channel):
170
 
171
  X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
172
  y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
173
- print('k: ',Kd_fit)
174
- print('n: ', n_fit)
175
 
176
  ##### extend_s_curve
177
  x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
@@ -183,7 +183,7 @@ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
183
  plotly_data.tail()
184
 
185
  for i in range(1,13):
186
- print(i)
187
  pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
188
  plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
189
 
@@ -223,8 +223,8 @@ def response_curves(channel,x_modified,y_modified):
223
  ))
224
 
225
  fig.add_trace(go.Scatter(
226
- x=[x_modified],
227
- y=[y_modified],
228
  mode='markers',
229
  marker=dict(
230
  size=13 # Adjust the size value to make the markers larger or smaller
@@ -369,7 +369,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
369
 
370
  ext_df['MAT'] = ["ext","ext","ext"]
371
 
372
- print(ext_df)
373
  plot_df= plot_df.append(ext_df)
374
  return plot_df
375
 
@@ -392,7 +392,7 @@ def input_data(df,spend_col,prospect_col):
392
  return X,y,x_data,y_data,x_minmax,y_minmax
393
 
394
  def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
395
- print(x_max)
396
  x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
397
  # x_ext_data = [1500000,2000000,2500000]
398
  # x_ext_data = [x_max+100,x_max+200,x_max+5000]
@@ -401,7 +401,7 @@ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
401
  for i in range(len(x_scaled)):
402
  x_data.append(x_scaled[i][0])
403
 
404
- print(x_data)
405
  y_fit = hill_equation(x_data, Kd_fit, n_fit)
406
  y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
407
 
@@ -414,8 +414,8 @@ def fit_data(spend_col,prospect_col,channel):
414
 
415
  X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
416
  y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
417
- print('k: ',Kd_fit)
418
- print('n: ', n_fit)
419
 
420
  ##### extend_s_curve
421
  x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
@@ -427,7 +427,7 @@ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
427
  plotly_data.tail()
428
 
429
  for i in range(1,13):
430
- print(i)
431
  pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
432
  plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
433
 
 
125
 
126
  ext_df['MAT'] = ["ext","ext","ext"]
127
 
128
+ # print(ext_df)
129
  plot_df= plot_df.append(ext_df)
130
  return plot_df
131
 
 
148
  return X,y,x_data,y_data,x_minmax,y_minmax
149
 
150
  def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
151
+ # print(x_max)
152
  x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
153
  # x_ext_data = [1500000,2000000,2500000]
154
  # x_ext_data = [x_max+100,x_max+200,x_max+5000]
 
157
  for i in range(len(x_scaled)):
158
  x_data.append(x_scaled[i][0])
159
 
160
+ # print(x_data)
161
  y_fit = hill_equation(x_data, Kd_fit, n_fit)
162
  y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
163
 
 
170
 
171
  X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
172
  y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
173
+ # print('k: ',Kd_fit)
174
+ # print('n: ', n_fit)
175
 
176
  ##### extend_s_curve
177
  x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
 
183
  plotly_data.tail()
184
 
185
  for i in range(1,13):
186
+ # print(i)
187
  pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
188
  plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
189
 
 
223
  ))
224
 
225
  fig.add_trace(go.Scatter(
226
+ x=[x_modified/104],
227
+ y=[y_modified/104],
228
  mode='markers',
229
  marker=dict(
230
  size=13 # Adjust the size value to make the markers larger or smaller
 
369
 
370
  ext_df['MAT'] = ["ext","ext","ext"]
371
 
372
+ # print(ext_df)
373
  plot_df= plot_df.append(ext_df)
374
  return plot_df
375
 
 
392
  return X,y,x_data,y_data,x_minmax,y_minmax
393
 
394
  def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
395
+ # print(x_max)
396
  x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
397
  # x_ext_data = [1500000,2000000,2500000]
398
  # x_ext_data = [x_max+100,x_max+200,x_max+5000]
 
401
  for i in range(len(x_scaled)):
402
  x_data.append(x_scaled[i][0])
403
 
404
+ # print(x_data)
405
  y_fit = hill_equation(x_data, Kd_fit, n_fit)
406
  y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
407
 
 
414
 
415
  X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
416
  y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
417
+ # print('k: ',Kd_fit)
418
+ # print('n: ', n_fit)
419
 
420
  ##### extend_s_curve
421
  x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
 
427
  plotly_data.tail()
428
 
429
  for i in range(1,13):
430
+ # print(i)
431
  pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
432
  plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
433
 
response_curves_model_quality_base.py CHANGED
@@ -125,7 +125,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
125
 
126
  ext_df['MAT'] = ["ext","ext","ext"]
127
 
128
- print(ext_df.columns)
129
  plot_df= plot_df.append(ext_df)
130
  return plot_df
131
 
@@ -148,7 +148,7 @@ def input_data(df,spend_col,prospect_col):
148
  return X,y,x_data,y_data,x_minmax,y_minmax
149
 
150
  def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
151
- print(x_max)
152
  x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
153
  # x_ext_data = [1500000,2000000,2500000]
154
  # x_ext_data = [x_max+100,x_max+200,x_max+5000]
@@ -157,7 +157,7 @@ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
157
  for i in range(len(x_scaled)):
158
  x_data.append(x_scaled[i][0])
159
 
160
- print(x_data)
161
  y_fit = hill_equation(x_data, Kd_fit, n_fit)
162
  y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
163
 
@@ -170,8 +170,8 @@ def fit_data(spend_col,prospect_col,channel):
170
 
171
  X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
172
  y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
173
- print('k: ',Kd_fit)
174
- print('n: ', n_fit)
175
 
176
  ##### extend_s_curve
177
  x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
@@ -190,23 +190,59 @@ for i in range(1,13):
190
  def response_curves(channel,chart_typ):
191
  if chart_typ == 'View Scattered Plot':
192
  mode_f1 = "markers"
 
 
 
 
 
 
 
 
 
 
 
193
  elif chart_typ == 'View Line Plot':
194
  mode_f1 = "lines"
 
 
 
 
 
 
 
 
 
 
 
195
  else:
196
- mode_f1 = "lines+markers"
197
-
 
 
 
 
 
 
 
 
 
 
198
 
199
- # Initialize the Plotly figure
200
- fig = go.Figure()
 
 
 
 
 
 
 
 
 
 
 
201
 
202
- x_col = channel+"_Spends"
203
- y_col = "Fit_Data_"+channel
204
- fig.add_trace(go.Scatter(
205
- x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
206
- y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
207
- mode=mode_f1,
208
- name=x_col.replace('_Spends', '')
209
- ))
210
  plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
211
  # import steamlit as st
212
  # st.dataframe()
 
125
 
126
  ext_df['MAT'] = ["ext","ext","ext"]
127
 
128
+ # print(ext_df.columns)
129
  plot_df= plot_df.append(ext_df)
130
  return plot_df
131
 
 
148
  return X,y,x_data,y_data,x_minmax,y_minmax
149
 
150
  def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
151
+ # print(x_max)
152
  x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
153
  # x_ext_data = [1500000,2000000,2500000]
154
  # x_ext_data = [x_max+100,x_max+200,x_max+5000]
 
157
  for i in range(len(x_scaled)):
158
  x_data.append(x_scaled[i][0])
159
 
160
+ # print(x_data)
161
  y_fit = hill_equation(x_data, Kd_fit, n_fit)
162
  y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
163
 
 
170
 
171
  X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
172
  y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
173
+ # print('k: ',Kd_fit)
174
+ # print('n: ', n_fit)
175
 
176
  ##### extend_s_curve
177
  x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
 
190
  def response_curves(channel,chart_typ):
191
  if chart_typ == 'View Scattered Plot':
192
  mode_f1 = "markers"
193
+ # Initialize the Plotly figure
194
+ fig = go.Figure()
195
+
196
+ x_col = channel+"_Spends"
197
+ y_col = channel+"_Prospects"
198
+ fig.add_trace(go.Scatter(
199
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
200
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
201
+ mode=mode_f1,
202
+ name=x_col.replace('_Spends', '')
203
+ ))
204
  elif chart_typ == 'View Line Plot':
205
  mode_f1 = "lines"
206
+ # Initialize the Plotly figure
207
+ fig = go.Figure()
208
+
209
+ x_col = channel+"_Spends"
210
+ y_col = 'Fit_Data_'+channel
211
+ fig.add_trace(go.Scatter(
212
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
213
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
214
+ mode=mode_f1,
215
+ name=x_col.replace('_Spends', '')
216
+ ))
217
  else:
218
+ mode_f1 = "markers"
219
+ # Initialize the Plotly figure
220
+ fig = go.Figure()
221
+
222
+ x_col = channel+"_Spends"
223
+ y_col = channel+"_Prospects"
224
+ fig.add_trace(go.Scatter(
225
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
226
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
227
+ mode=mode_f1,
228
+ name=x_col.replace('_Spends', '')
229
+ ))
230
 
231
+ # mode_f1 = "lines+markers"
232
+ mode_f1 = "lines"
233
+ # Initialize the Plotly figure
234
+ # fig = go.Figure()
235
+
236
+ x_col = channel+"_Spends"
237
+ y_col = 'Fit_Data_'+channel
238
+ fig.add_trace(go.Scatter(
239
+ x=plotly_data.sort_values(by=x_col, ascending=True)[x_col],
240
+ y=plotly_data.sort_values(by=x_col, ascending=True)[y_col],
241
+ mode=mode_f1,
242
+ name=x_col.replace('_Spends', '')
243
+ ))
244
 
245
+
 
 
 
 
 
 
 
246
  plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
247
  # import steamlit as st
248
  # st.dataframe()
summary_df.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:ef1d30472601a41557559d3fe1b39fe0a08bfa581a66af23a210e9dc459b750c
3
  size 1822
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bbfe530ac30a045842611782bde814043862ff721a910f19cfbb8525f1dfb82a
3
  size 1822
utilities.py CHANGED
@@ -221,14 +221,10 @@ def initialize_data(
221
  contri_df = excel["CONTRIBUTION MMM"]
222
 
223
  # Check if the panel is not None
224
- if panel is not None and panel != "Total Market":
225
- raw_df = raw_df[raw_df["Panel"] == panel].drop(columns=["Panel"])
226
- spend_df = spend_df[spend_df["Panel"] == panel].drop(columns=["Panel"])
227
- contri_df = contri_df[contri_df["Panel"] == panel].drop(columns=["Panel"])
228
- elif panel == "Total Market":
229
- raw_df = panel_level(raw_df, date_column="Date")
230
- spend_df = panel_level(spend_df, date_column="Week")
231
- contri_df = panel_level(contri_df, date_column="Date")
232
 
233
  # Revenue_df = excel['Revenue']
234
 
@@ -294,48 +290,21 @@ def initialize_data(
294
  ##output cols aggregation
295
  output_cols.append(out_col)
296
 
297
- ## scale the input
298
- power = np.ceil(np.log(x.max()) / np.log(10)) - 3
299
- if power >= 0:
300
- x = x / 10**power
301
-
302
- x = x.astype("float64")
303
- y = y.astype("float64")
304
- # print('#printing yyyyyyyyy')
305
- # print(inp_col)
306
- # print(x.max())
307
- # print(y.max())
308
- bounds = ((0, 0, 0, 0), (3 * y.max(), 1000, 1, x.max()))
309
-
310
- # bounds = ((y.max(), 3*y.max()),(0,1000),(0,1),(0,x.max()))
311
- params, _ = curve_fit(
312
- s_curve,
313
- x,
314
- y,
315
- p0=(2 * y.max(), 0.01, 1e-5, x.max()),
316
- bounds=bounds,
317
- maxfev=int(1e5),
318
- )
319
- mape = (100 * abs(1 - s_curve(x, *params) / y.clip(min=1))).mean()
320
- rmse = np.sqrt(((y - s_curve(x, *params)) ** 2).mean())
321
- r2_ = r2_score(y, s_curve(x, *params))
322
-
323
  response_curves[inp_col] = {
324
- "K": params[0],
325
- "b": params[1],
326
- "a": params[2],
327
- "x0": params[3],
 
 
328
  }
329
 
330
  updated_rcs_key = f"{metrics}#@{panel}#@{inp_col}"
331
  if updated_rcs is not None and updated_rcs_key in list(updated_rcs.keys()):
332
  response_curves[inp_col] = updated_rcs[updated_rcs_key]
333
 
334
- mapes[inp_col] = mape
335
- rmses[inp_col] = rmse
336
- r2[inp_col] = r2_
337
- powers[inp_col] = power
338
-
339
  ## conversion rates
340
  spend_col = [
341
  _col
@@ -362,14 +331,17 @@ def initialize_data(
362
  name=inp_col,
363
  dates=dates,
364
  spends=spends,
 
365
  # conversion_rate = np.mean(list(conv_rates[inp_col].values())),
366
  conversion_rate=conv_rates[inp_col],
367
- response_curve_type="s-curve",
368
  response_curve_params={
369
- "K": params[0],
370
- "b": params[1],
371
- "a": params[2],
372
- "x0": params[3],
 
 
373
  },
374
  bounds=np.array([-10, 10]),
375
  channel_bounds_min = 10,
@@ -430,94 +402,6 @@ def initialize_data(
430
  st.session_state["disable_download_button"] = True
431
 
432
 
433
- # def initialize_data():
434
- # # fetch data from excel
435
- # output = pd.read_excel('data.xlsx',sheet_name=None)
436
- # raw_df = output['RAW DATA MMM']
437
- # contribution_df = output['CONTRIBUTION MMM']
438
- # Revenue_df = output['Revenue']
439
-
440
- # ## channels to be shows
441
- # channel_list = []
442
- # for col in raw_df.columns:
443
- # if 'click' in col.lower() or 'spend' in col.lower() or 'imp' in col.lower():
444
- # ##print(col)
445
- # channel_list.append(col)
446
- # else:
447
- # pass
448
-
449
- # ## NOTE : Considered only Desktop spends for all calculations
450
- # acutal_df = raw_df[raw_df.Region == 'Desktop'].copy()
451
- # ## NOTE : Considered one year of data
452
- # acutal_df = acutal_df[acutal_df.Date>'2020-12-31']
453
- # actual_df = acutal_df.drop('Region',axis=1).sort_values(by='Date')[[*channel_list,'Date']]
454
-
455
- # ##load response curves
456
- # with open('./grammarly_response_curves.json','r') as f:
457
- # response_curves = json.load(f)
458
-
459
- # ## create channel dict for scenario creation
460
- # dates = actual_df.Date.values
461
- # channels = {}
462
- # rcs = {}
463
- # constant = 0.
464
- # for i,info_dict in enumerate(response_curves):
465
- # name = info_dict.get('name')
466
- # response_curve_type = info_dict.get('response_curve')
467
- # response_curve_params = info_dict.get('params')
468
- # rcs[name] = response_curve_params
469
- # if name != 'constant':
470
- # spends = actual_df[name].values
471
- # channel = Channel(name=name,dates=dates,
472
- # spends=spends,
473
- # response_curve_type=response_curve_type,
474
- # response_curve_params=response_curve_params,
475
- # bounds=np.array([-30,30]))
476
-
477
- # channels[name] = channel
478
- # else:
479
- # constant = info_dict.get('value',0.) * len(dates)
480
-
481
- # ## create scenario
482
- # scenario = Scenario(name='default', channels=channels, constant=constant)
483
- # default_scenario_dict = class_to_dict(scenario)
484
-
485
-
486
- # ## setting session variables
487
- # st.session_state['initialized'] = True
488
- # st.session_state['actual_df'] = actual_df
489
- # st.session_state['raw_df'] = raw_df
490
- # st.session_state['default_scenario_dict'] = default_scenario_dict
491
- # st.session_state['scenario'] = scenario
492
- # st.session_state['channels_list'] = channel_list
493
- # st.session_state['optimization_channels'] = {channel_name : False for channel_name in channel_list}
494
- # st.session_state['rcs'] = rcs
495
- # for channel in channels.values():
496
- # if channel.name not in st.session_state:
497
- # st.session_state[channel.name] = float(channel.actual_total_spends)
498
-
499
- # if 'xlsx_buffer' not in st.session_state:
500
- # st.session_state['xlsx_buffer'] = io.BytesIO()
501
-
502
- # ## for saving scenarios
503
- # if 'saved_scenarios' not in st.session_state:
504
- # if Path('../saved_scenarios.pkl').exists():
505
- # with open('../saved_scenarios.pkl','rb') as f:
506
- # st.session_state['saved_scenarios'] = pickle.load(f)
507
-
508
- # else:
509
- # st.session_state['saved_scenarios'] = OrderedDict()
510
-
511
- # if 'total_spends_change' not in st.session_state:
512
- # st.session_state['total_spends_change'] = 0
513
-
514
- # if 'optimization_channels' not in st.session_state:
515
- # st.session_state['optimization_channels'] = {channel_name : False for channel_name in channel_list}
516
-
517
- # if 'disable_download_button' not in st.session_state:
518
- # st.session_state['disable_download_button'] = True
519
-
520
-
521
  def create_channel_summary(scenario):
522
 
523
  # Provided data
@@ -618,90 +502,6 @@ def create_channel_summary(scenario):
618
  return df
619
 
620
 
621
- # @st.cache(allow_output_mutation=True)
622
- # def create_contribution_pie(scenario):
623
- # #c1f7dc
624
- # colors_map = {col:color for col,color in zip(st.session_state['channels_list'],plotly.colors.n_colors(plotly.colors.hex_to_rgb('#BE6468'), plotly.colors.hex_to_rgb('#E7B8B7'),23))}
625
- # total_contribution_fig = make_subplots(rows=1, cols=2,subplot_titles=['Spends','Revenue'],specs=[[{"type": "pie"}, {"type": "pie"}]])
626
- # total_contribution_fig.add_trace(
627
- # go.Pie(labels=[channel_name_formating(channel_name) for channel_name in st.session_state['channels_list']] + ['Non Media'],
628
- # values= [round(scenario.channels[channel_name].actual_total_spends * scenario.channels[channel_name].conversion_rate,1) for channel_name in st.session_state['channels_list']] + [0],
629
- # marker=dict(colors = [plotly.colors.label_rgb(colors_map[channel_name]) for channel_name in st.session_state['channels_list']] + ['#F0F0F0']),
630
- # hole=0.3),
631
- # row=1, col=1)
632
-
633
- # total_contribution_fig.add_trace(
634
- # go.Pie(labels=[channel_name_formating(channel_name) for channel_name in st.session_state['channels_list']] + ['Non Media'],
635
- # values= [scenario.channels[channel_name].actual_total_sales for channel_name in st.session_state['channels_list']] + [scenario.correction.sum() + scenario.constant.sum()],
636
- # hole=0.3),
637
- # row=1, col=2)
638
-
639
- # total_contribution_fig.update_traces(textposition='inside',texttemplate='%{percent:.1%}')
640
- # total_contribution_fig.update_layout(uniformtext_minsize=12,title='Channel contribution', uniformtext_mode='hide')
641
- # return total_contribution_fig
642
-
643
- # @st.cache(allow_output_mutation=True)
644
-
645
- # def create_contribuion_stacked_plot(scenario):
646
- # weekly_contribution_fig = make_subplots(rows=1, cols=2,subplot_titles=['Spends','Revenue'],specs=[[{"type": "bar"}, {"type": "bar"}]])
647
- # raw_df = st.session_state['raw_df']
648
- # df = raw_df.sort_values(by='Date')
649
- # x = df.Date
650
- # weekly_spends_data = []
651
- # weekly_sales_data = []
652
- # for channel_name in st.session_state['channels_list']:
653
- # weekly_spends_data.append((go.Bar(x=x,
654
- # y=scenario.channels[channel_name].actual_spends * scenario.channels[channel_name].conversion_rate,
655
- # name=channel_name_formating(channel_name),
656
- # hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}",
657
- # legendgroup=channel_name)))
658
- # weekly_sales_data.append((go.Bar(x=x,
659
- # y=scenario.channels[channel_name].actual_sales,
660
- # name=channel_name_formating(channel_name),
661
- # hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}",
662
- # legendgroup=channel_name, showlegend=False)))
663
- # for _d in weekly_spends_data:
664
- # weekly_contribution_fig.add_trace(_d, row=1, col=1)
665
- # for _d in weekly_sales_data:
666
- # weekly_contribution_fig.add_trace(_d, row=1, col=2)
667
- # weekly_contribution_fig.add_trace(go.Bar(x=x,
668
- # y=scenario.constant + scenario.correction,
669
- # name='Non Media',
670
- # hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}"), row=1, col=2)
671
- # weekly_contribution_fig.update_layout(barmode='stack', title='Channel contribuion by week', xaxis_title='Date')
672
- # weekly_contribution_fig.update_xaxes(showgrid=False)
673
- # weekly_contribution_fig.update_yaxes(showgrid=False)
674
- # return weekly_contribution_fig
675
-
676
- # @st.cache(allow_output_mutation=True)
677
- # def create_channel_spends_sales_plot(channel):
678
- # if channel is not None:
679
- # x = channel.dates
680
- # _spends = channel.actual_spends * channel.conversion_rate
681
- # _sales = channel.actual_sales
682
- # channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
683
- # channel_sales_spends_fig.add_trace(go.Bar(x=x, y=_sales,marker_color='#c1f7dc',name='Revenue', hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}"), secondary_y = False)
684
- # channel_sales_spends_fig.add_trace(go.Scatter(x=x, y=_spends,line=dict(color='#005b96'),name='Spends',hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}"), secondary_y = True)
685
- # channel_sales_spends_fig.update_layout(xaxis_title='Date',yaxis_title='Revenue',yaxis2_title='Spends ($)',title='Channel spends and Revenue week wise')
686
- # channel_sales_spends_fig.update_xaxes(showgrid=False)
687
- # channel_sales_spends_fig.update_yaxes(showgrid=False)
688
- # else:
689
- # raw_df = st.session_state['raw_df']
690
- # df = raw_df.sort_values(by='Date')
691
- # x = df.Date
692
- # scenario = class_from_dict(st.session_state['default_scenario_dict'])
693
- # _sales = scenario.constant + scenario.correction
694
- # channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
695
- # channel_sales_spends_fig.add_trace(go.Bar(x=x, y=_sales,marker_color='#c1f7dc',name='Revenue', hovertemplate="Date:%{x}<br>Revenue:%{y:$.2s}"), secondary_y = False)
696
- # # channel_sales_spends_fig.add_trace(go.Scatter(x=x, y=_spends,line=dict(color='#15C39A'),name='Spends',hovertemplate="Date:%{x}<br>Spend:%{y:$.2s}"), secondary_y = True)
697
- # channel_sales_spends_fig.update_layout(xaxis_title='Date',yaxis_title='Revenue',yaxis2_title='Spends ($)',title='Channel spends and Revenue week wise')
698
- # channel_sales_spends_fig.update_xaxes(showgrid=False)
699
- # channel_sales_spends_fig.update_yaxes(showgrid=False)
700
- # return channel_sales_spends_fig
701
-
702
-
703
- # Define a shared color palette
704
-
705
 
706
  def create_contribution_pie():
707
  color_palette = [
 
221
  contri_df = excel["CONTRIBUTION MMM"]
222
 
223
  # Check if the panel is not None
224
+
225
+ raw_df = panel_level(raw_df, date_column="Date")
226
+ spend_df = panel_level(spend_df, date_column="Week")
227
+ contri_df = panel_level(contri_df, date_column="Date")
 
 
 
 
228
 
229
  # Revenue_df = excel['Revenue']
230
 
 
290
  ##output cols aggregation
291
  output_cols.append(out_col)
292
 
293
+ params = pd.read_excel(r"C:\Users\PragyaJatav\Downloads\Untitled Folder 2\simulator uploaded - Copy\Simulator-UOPX\response_curves_parameters.xlsx",index_col = "channel")
294
+ param_dicts = {col: params[col].to_dict() for col in params.columns}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  response_curves[inp_col] = {
296
+ "Kd": param_dicts["Kd"][inp_col],
297
+ "n": param_dicts["n"][inp_col],
298
+ "x_min": param_dicts["x_min"][inp_col],
299
+ "x_max": param_dicts["x_max"][inp_col],
300
+ "y_min": param_dicts["y_min"][inp_col],
301
+ "y_max": param_dicts["y_max"][inp_col]
302
  }
303
 
304
  updated_rcs_key = f"{metrics}#@{panel}#@{inp_col}"
305
  if updated_rcs is not None and updated_rcs_key in list(updated_rcs.keys()):
306
  response_curves[inp_col] = updated_rcs[updated_rcs_key]
307
 
 
 
 
 
 
308
  ## conversion rates
309
  spend_col = [
310
  _col
 
331
  name=inp_col,
332
  dates=dates,
333
  spends=spends,
334
+ sales= y.copy(),
335
  # conversion_rate = np.mean(list(conv_rates[inp_col].values())),
336
  conversion_rate=conv_rates[inp_col],
337
+ response_curve_type="hill-eq",
338
  response_curve_params={
339
+ "Kd": param_dicts["Kd"][inp_col],
340
+ "n": param_dicts["n"][inp_col],
341
+ "x_min": param_dicts["x_min"][inp_col],
342
+ "x_max": param_dicts["x_max"][inp_col],
343
+ "y_min": param_dicts["y_min"][inp_col],
344
+ "y_max": param_dicts["y_max"][inp_col]
345
  },
346
  bounds=np.array([-10, 10]),
347
  channel_bounds_min = 10,
 
402
  st.session_state["disable_download_button"] = True
403
 
404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
405
  def create_channel_summary(scenario):
406
 
407
  # Provided data
 
502
  return df
503
 
504
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
 
506
  def create_contribution_pie():
507
  color_palette = [