diff --git "a/pages/2_Scenario_Planner.py" "b/pages/2_Scenario_Planner.py"
--- "a/pages/2_Scenario_Planner.py"
+++ "b/pages/2_Scenario_Planner.py"
@@ -10,7 +10,8 @@ from dateutil.relativedelta import relativedelta
import time
import Streamlit_functions as sf
from utilities import (
- format_numbers,format_numbers_f,
+ format_numbers,
+ format_numbers_f,
load_local_css,
set_header,
initialize_data,
@@ -19,13 +20,15 @@ from utilities import (
channel_name_formating,
)
from io import BytesIO
+
# import xlsxwriter
import warnings
+
# Suppress specific warnings if necessary
-warnings.filterwarnings("ignore")
+warnings.filterwarnings("ignore")
warnings.filterwarnings("ignore", category=UserWarning, message="The widget with key")
# for i in :
- # warnings.filterwarnings("ignore",)
+# warnings.filterwarnings("ignore",)
from classes import class_from_dict, class_to_dict
import pickle
import streamlit_authenticator as stauth
@@ -53,111 +56,135 @@ for k, v in st.session_state.items():
# ======================= Functions ====================== #
# ======================================================== #
-def save_report_forecast(forecasted_table_df,forecasted_table_df2):
+
+def save_report_forecast(forecasted_table_df, forecasted_table_df2):
# Convert the DataFrame to an Excel file in memory
excel_file = BytesIO()
- with pd.ExcelWriter(excel_file, engine='openpyxl') as writer:
- forecasted_table_df.to_excel(writer, index=True, sheet_name='Forecasted Spends')
- forecasted_table_df2.to_excel(writer, sheet_name='Monthly Breakdown',index = True)
+ with pd.ExcelWriter(excel_file, engine="openpyxl") as writer:
+ forecasted_table_df.to_excel(writer, index=True, sheet_name="Forecasted Spends")
+ forecasted_table_df2.to_excel(
+ writer, sheet_name="Monthly Breakdown", index=True
+ )
# Seek to the beginning of the BytesIO buffer
excel_file.seek(0)
return excel_file
-
-def save_ppt_file(summary_df_sorted,fig1,fig2,fig3):
+
+
+def save_ppt_file(summary_df_sorted, fig1, fig2, fig3):
summary_df_sorted.index = summary_df_sorted["Channel_name"]
# Initialize PowerPoint presentation
prs = Presentation()
+
# Helper function to add Plotly figure to slide
def add_plotly_chart_to_slide(slide, fig, left, top, width, height):
img_stream = BytesIO()
- pio.write_image(fig, img_stream, format='png')
+ pio.write_image(fig, img_stream, format="png")
slide.shapes.add_picture(img_stream, left, top, width, height)
- for i in range(0,len(channels_list)):
+ for i in range(0, len(channels_list)):
# # print(channels_list[i])
slide_1 = prs.slides.add_slide(prs.slide_layouts[6])
- fig = rc.response_curves(channels_list[i], summary_df_sorted["Optimized_spend"][channels_list[i]], summary_df_sorted["New_sales"][channels_list[i]])
- add_plotly_chart_to_slide(slide_1, fig, Inches(0.1), Inches(0.1), width=Inches(9), height=Inches(7))
+ fig = rc.response_curves(
+ channels_list[i],
+ summary_df_sorted["Optimized_spend"][channels_list[i]],
+ summary_df_sorted["New_sales"][channels_list[i]],
+ )
+ add_plotly_chart_to_slide(
+ slide_1, fig, Inches(0.1), Inches(0.1), width=Inches(9), height=Inches(7)
+ )
# Update layout
fig1.update_layout(
legend=dict(
orientation="h", # Horizontal orientation
- yanchor="top", # Anchor the legend at the top
- y=-0.4, # Position the legend below the plot area
- xanchor="center", # Center the legend horizontally
- x=0.5 # Center the legend on the x-axis
+ yanchor="top", # Anchor the legend at the top
+ y=-0.4, # Position the legend below the plot area
+ xanchor="center", # Center the legend horizontally
+ x=0.5, # Center the legend on the x-axis
)
)
# Update layout
fig2.update_layout(
- legend=dict(
+ legend=dict(
orientation="h", # Horizontal orientation
- yanchor="top", # Anchor the legend at the top
- y=-0.4, # Position the legend below the plot area
- xanchor="center", # Center the legend horizontally
- x=0.5 # Center the legend on the x-axis
+ yanchor="top", # Anchor the legend at the top
+ y=-0.4, # Position the legend below the plot area
+ xanchor="center", # Center the legend horizontally
+ x=0.5, # Center the legend on the x-axis
)
)
# Update layout
fig3.update_layout(
legend=dict(
orientation="h", # Horizontal orientation
- yanchor="top", # Anchor the legend at the top
- y=-0.4, # Position the legend below the plot area
- xanchor="center", # Center the legend horizontally
- x=0.5 # Center the legend on the x-axis
+ yanchor="top", # Anchor the legend at the top
+ y=-0.4, # Position the legend below the plot area
+ xanchor="center", # Center the legend horizontally
+ x=0.5, # Center the legend on the x-axis
)
)
-
-
slide_1 = prs.slides.add_slide(prs.slide_layouts[6])
- add_plotly_chart_to_slide(slide_1, fig1, Inches(0.1), Inches(1), width=Inches(9.5), height=Inches(6))
+ add_plotly_chart_to_slide(
+ slide_1, fig1, Inches(0.1), Inches(1), width=Inches(9.5), height=Inches(6)
+ )
slide_1 = prs.slides.add_slide(prs.slide_layouts[6])
- add_plotly_chart_to_slide(slide_1, fig2, Inches(0.1), Inches(1), width=Inches(9.5), height=Inches(6))
+ add_plotly_chart_to_slide(
+ slide_1, fig2, Inches(0.1), Inches(1), width=Inches(9.5), height=Inches(6)
+ )
slide_1 = prs.slides.add_slide(prs.slide_layouts[6])
- add_plotly_chart_to_slide(slide_1, fig3, Inches(0.1), Inches(1), width=Inches(9.5), height=Inches(6))
-
-
+ add_plotly_chart_to_slide(
+ slide_1, fig3, Inches(0.1), Inches(1), width=Inches(9.5), height=Inches(6)
+ )
# Save to a BytesIO object
ppt_stream = BytesIO()
prs.save(ppt_stream)
ppt_stream.seek(0)
-
+
return ppt_stream.getvalue()
+
def first_day_of_next_year(date):
next_year = date.year + 1
first_day = datetime(next_year, 1, 1).date()
-
+
# Calculate the last day of the next year
- last_day = (first_day + relativedelta(years=1, days=-1))
-
+ last_day = first_day + relativedelta(years=1, days=-1)
+
return first_day, last_day
+
def first_day_of_next_quarter(date):
current_quarter = (date.month - 1) // 3 + 1
next_quarter_first_month = ((current_quarter % 4) * 3) + 1
next_quarter_year = date.year if next_quarter_first_month > 1 else date.year + 1
# Ensure month is within valid range
if next_quarter_first_month < 1 or next_quarter_first_month > 12:
- raise ValueError("Calculated month is out of range: {}".format(next_quarter_first_month))
+ raise ValueError(
+ "Calculated month is out of range: {}".format(next_quarter_first_month)
+ )
# st.write(next_quarter_first_month)
- first_day_next_quarter = datetime(next_quarter_year, next_quarter_first_month, 1).date()
- last_day_next_quarter = (first_day_next_quarter + relativedelta(months=3)) - relativedelta(days=1)
-
+ first_day_next_quarter = datetime(
+ next_quarter_year, next_quarter_first_month, 1
+ ).date()
+ last_day_next_quarter = (
+ first_day_next_quarter + relativedelta(months=3)
+ ) - relativedelta(days=1)
+
return first_day_next_quarter, last_day_next_quarter
def first_day_of_next_month(date):
next_month_date = date + relativedelta(months=1)
first_day_next_month = next_month_date.replace(day=1)
- last_day_next_month = (first_day_next_month + relativedelta(months=1)) - relativedelta(days=1)
+ last_day_next_month = (
+ first_day_next_month + relativedelta(months=1)
+ ) - relativedelta(days=1)
return first_day_next_month, last_day_next_month
+
def optimize(key, status_placeholder):
"""
Optimize the spends for the sales
@@ -175,15 +202,14 @@ def optimize(key, status_placeholder):
# # # # print(channel_list)
# # # # print(st.session_state["total_spends_change"])
result = st.session_state["scenario"].optimize(
- st.session_state["total_spends_change"], channel_list
+ st.session_state["total_spends_change"],
+ channel_list,
# result = st.session_state["scenario"].spends_optimisation(
# st.session_state["total_spends_change"], channel_list
)
# # print("")
# # print(list(zip(*result)))
-
-
# elif key.lower() == "revenue":
else:
with status_placeholder:
@@ -223,6 +249,7 @@ def save_scenario(scenario_name):
st.session_state["scenario"]
)
st.session_state["scenario_input"] = ""
+
# # # # print(type(st.session_state['saved_scenarios']))
with open("../saved_scenarios.pkl", "wb") as f:
pickle.dump(st.session_state["saved_scenarios"], f)
@@ -262,11 +289,11 @@ def update_sales_abs():
# and st.session_state["allow_sales_update"]
# ):
modified_sales = extract_number_for_string(
- st.session_state["total_sales_change_abs"]
- )
+ st.session_state["total_sales_change_abs"]
+ )
st.session_state["total_sales_change"] = round(
- ((modified_sales / actual_sales) - 1) * 100
- )
+ ((modified_sales / actual_sales) - 1) * 100
+ )
st.session_state["total_sales_change_abs_slider"] = numerize(modified_sales, 1)
@@ -397,42 +424,54 @@ def validate_input(string_input):
return False
return True
+
def validate_input_lb(string_input):
pattern = r"\d+\.?\d*[K|M|B]$"
match = re.match(pattern, string_input)
if match is None:
return False
- response_curve_params = pd.read_excel("response_curves_parameters.xlsx",index_col = "channel")
- param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
- if float(string_input) < round(param_dicts["x_min"][channel_name]*10400/param_dicts["current_spends"][channel_name]):
+ response_curve_params = pd.read_excel(
+ "response_curves_parameters.xlsx", index_col="channel"
+ )
+ param_dicts = {
+ col: response_curve_params[col].to_dict()
+ for col in response_curve_params.columns
+ }
+ if float(string_input) < round(
+ param_dicts["x_min"][channel_name]
+ * 10400
+ / param_dicts["current_spends"][channel_name]
+ ):
return False
return True
+
def update_data_bound_min(channel_name):
"""
Updates the bounds for the given channel
"""
if validate_input_lb(st.session_state[f"{channel_name}_lower_bound"]):
modified_bounds = st.session_state[f"{channel_name}_lower_bound"]
-
+
# st.session_state['scenario']['channels'][channel_name].channel_bounds_min = st.session_state[f"{channel_name}_lower_bound"]
- st.session_state['scenario'].update_bounds_min(channel_name,modified_bounds)
+ st.session_state["scenario"].update_bounds_min(channel_name, modified_bounds)
st.write(st.session_state["scenario"].channels[channel_name].channel_bounds_min)
# st.write(st.session_state["scenario"].channels[channel_name]
-
+
def update_data_bound_max(channel_name):
"""
Updates the bounds for the given channel
"""
modified_bounds = st.session_state[f"{channel_name}_upper_bound"]
-
+
# st.session_state['scenario']['channels'][channel_name].channel_bounds_min = st.session_state[f"{channel_name}_lower_bound"]
- st.session_state['scenario'].update_bounds_max(channel_name,modified_bounds)
+ st.session_state["scenario"].update_bounds_max(channel_name, modified_bounds)
# st.write(st.session_state["scenario"].channels[channel_name].channel_bounds_max)
# st.write(st.session_state["scenario"].channels[channel_name])
-
+
+
def update_data_by_percent(channel_name):
prev_spends = (
st.session_state["scenario"].channels[channel_name].actual_total_spends
@@ -468,19 +507,19 @@ def update_data(channel_name):
modified_spends
/ st.session_state["scenario"].channels[channel_name].conversion_rate,
)
-# st.write(hasattr(st.session_state["scenario"], 'update_bounds_min'))
- # st.session_state['scenario'].update(channel_name, modified_spends)
- # else:
- # try:
- # modified_spends = float(st.session_state[channel_name])
- # prev_spends = st.session_state['scenario'].channels[channel_name].actual_total_spends * st.session_state['scenario'].channels[channel_name].conversion_rate
- # st.session_state[f'{channel_name}_change'] = round(100*(modified_spends - prev_spends) / prev_spends,2)
- # st.session_state['scenario'].update(channel_name, modified_spends/st.session_state['scenario'].channels[channel_name].conversion_rate)
- # st.session_state[f'{channel_name}'] = numerize(modified_spends,1)
- # except ValueError:
- # st.write('Invalid input')
+# st.write(hasattr(st.session_state["scenario"], 'update_bounds_min'))
+# st.session_state['scenario'].update(channel_name, modified_spends)
+# else:
+# try:
+# modified_spends = float(st.session_state[channel_name])
+# prev_spends = st.session_state['scenario'].channels[channel_name].actual_total_spends * st.session_state['scenario'].channels[channel_name].conversion_rate
+# st.session_state[f'{channel_name}_change'] = round(100*(modified_spends - prev_spends) / prev_spends,2)
+# st.session_state['scenario'].update(channel_name, modified_spends/st.session_state['scenario'].channels[channel_name].conversion_rate)
+# st.session_state[f'{channel_name}'] = numerize(modified_spends,1)
+# except ValueError:
+# st.write('Invalid input')
def select_channel_for_optimization(channel_name):
@@ -494,6 +533,7 @@ def select_channel_for_optimization(channel_name):
# if not all(st.session_state["optimization_channels"].values()):
# st.session_state["optimize_all_channels"] = False
+
def select_all_channels_for_optimization():
"""
Marks all the channel for optimization
@@ -505,7 +545,6 @@ def select_all_channels_for_optimization():
st.session_state["optimization_channels"][channel_name] = st.session_state[
"optimze_all_channels"
]
-
def update_penalty():
@@ -524,7 +563,6 @@ def reset_scenario(panel_selected, file_selected, updated_rcs):
if panel_selected == "Total Market":
initialize_data(
-
target_file=file_selected,
panel=panel_selected,
updated_rcs=updated_rcs,
@@ -533,7 +571,6 @@ def reset_scenario(panel_selected, file_selected, updated_rcs):
panel = None
else:
initialize_data(
-
target_file=file_selected,
panel=panel_selected,
updated_rcs=updated_rcs,
@@ -681,32 +718,47 @@ def plot_response_curves(summary_df_sorted):
# shapes = []
# fig = make_subplots(rows=rows, cols=cols, subplot_titles=channels_list)
channel_cols = [
- 'BroadcastTV',
- 'CableTV',
- 'Connected&OTTTV',
- 'DisplayProspecting',
- 'DisplayRetargeting',
- 'Video',
- 'SocialProspecting',
- 'SocialRetargeting',
- 'SearchBrand',
- 'SearchNon-brand',
- 'DigitalPartners',
- 'Audio',
- 'Email']
+ "BroadcastTV",
+ "CableTV",
+ "Connected&OTTTV",
+ "DisplayProspecting",
+ "DisplayRetargeting",
+ "Video",
+ "SocialProspecting",
+ "SocialRetargeting",
+ "SearchBrand",
+ "SearchNon-brand",
+ "DigitalPartners",
+ "Audio",
+ "Email",
+ ]
summary_df_sorted.index = summary_df_sorted["Channel_name"]
- figures = [rc.response_curves(channels_list[i], summary_df_sorted["Optimized_spend"][channels_list[i]], summary_df_sorted["New_sales"][channels_list[i]]) for i in range(13)]
+ figures = [
+ rc.response_curves(
+ channels_list[i],
+ summary_df_sorted["Optimized_spend"][channels_list[i]],
+ summary_df_sorted["New_sales"][channels_list[i]],
+ )
+ for i in range(13)
+ ]
# for i in range()
-
+
# Display figures in a grid layout
- cols = st.columns(3) # 4 columns for the grid
+ col_num = 3
+ cols = st.columns(col_num) # 4 columns for the grid
for idx, fig in enumerate(figures):
- col = cols[idx % 3]
+ col = cols[idx % col_num]
with col:
+ # Get the current title and replace 'Response Curve' with a space
+ current_title = fig.layout.title.text if fig.layout.title else ""
+ updated_title = current_title.replace("Response Curve", "").strip().replace("Connected & OTTTV", "Connected & OTT TV")
+
+ fig.update_layout(height=350, width=350, yaxis_title="Revenue", title=updated_title)
st.plotly_chart(fig, use_container_width=True)
+
# ======================================================== #
# ==================== HTML Components =================== #
# ======================================================== #
@@ -714,7 +766,8 @@ def plot_response_curves(summary_df_sorted):
def generate_spending_header(heading):
return st.markdown(
- f"""
""", unsafe_allow_html=True
+ f"""""",
+ unsafe_allow_html=True,
)
@@ -740,25 +793,34 @@ auth_status = st.session_state.get("authentication_status")
import os
import glob
+
def upload_file_prospects_calc(df):
df["Prospects"] = 0
- params = pd.read_excel(r"response_curves_parameters.xlsx",index_col = "channel")
+ params = pd.read_excel(r"response_curves_parameters.xlsx", index_col="channel")
param_dicts = {col: params[col].to_dict() for col in params.columns}
df.index = df.channel
-# # # # print(param_dicts)
+ # # # # print(param_dicts)
for col in df.channel:
x = df["Spends"][col]
dividing_rate = 104
# st.write(x)
- x_inp = ( x/dividing_rate- param_dicts["x_min"][col]) / (param_dicts["x_max"][col] - param_dicts["x_min"][col])
- x_out = x_inp**param_dicts["n"][col] / (param_dicts["Kd"][col]**param_dicts["n"][col] + x_inp**param_dicts["n"][col]) #self.hill_equation(x_inp,Kd, n)
- # # # # print("x_out",x_out)
-
-
- x_val_inv = (x_out*param_dicts["x_max"][col] + (1 - x_out) * param_dicts["x_min"][col])
- sales = (x_val_inv*param_dicts["y_min"][col]/param_dicts["y_max"][col])*dividing_rate
- # sales = ((x_max - x_min)*x_out + x_min)*dividing_rate
+ x_inp = (x / dividing_rate - param_dicts["x_min"][col]) / (
+ param_dicts["x_max"][col] - param_dicts["x_min"][col]
+ )
+ x_out = x_inp ** param_dicts["n"][col] / (
+ param_dicts["Kd"][col] ** param_dicts["n"][col]
+ + x_inp ** param_dicts["n"][col]
+ ) # self.hill_equation(x_inp,Kd, n)
+ # # # # print("x_out",x_out)
+
+ x_val_inv = (
+ x_out * param_dicts["x_max"][col] + (1 - x_out) * param_dicts["x_min"][col]
+ )
+ sales = (
+ x_val_inv * param_dicts["y_min"][col] / param_dicts["y_max"][col]
+ ) * dividing_rate
+ # sales = ((x_max - x_min)*x_out + x_min)*dividing_rate
# x = (df["Spends"][col]/104 - param_dicts["x_min"][col])/(param_dicts["x_max"][col]-param_dicts["x_min"][col])
# x_out = x**param_dicts["n"][col]/(param_dicts["Kd"][col]**param_dicts["n"][col]+ x**param_dicts["n"][col])
@@ -766,7 +828,7 @@ def upload_file_prospects_calc(df):
df["Prospects"][col] = sales
# # # # print(df)
return df
-
+
def upload_file_format(df):
# key_df = pd.DataFrame()
@@ -777,42 +839,44 @@ def upload_file_format(df):
# # st.dataframe(df)
# df["channel"] = df["channels"]
# df.drop(columns = ["channel"])
-
+
df1 = df.transpose()
- df1.reset_index(inplace = True)
- df1.columns = df1.iloc[0]
+ df1.reset_index(inplace=True)
+ df1.columns = df1.iloc[0]
df1 = df1[1:]
- df1["channel"] = pd.to_datetime('1999-08-06').date()
- df1.rename(columns = {"channel":"Date"},inplace = True)
-
- df2 = df1.rename(columns = {"Date":"Week"})
+ df1["channel"] = pd.to_datetime("1999-08-06").date()
+ df1.rename(columns={"channel": "Date"}, inplace=True)
+
+ df2 = df1.rename(columns={"Date": "Week"})
- df3 =upload_file_prospects_calc(df)
+ df3 = upload_file_prospects_calc(df)
df3 = df3[["Prospects"]].transpose().reset_index()
- df3["index"] = pd.to_datetime('1999-08-06').date()
- df3.rename(columns = {"index":"Date"},inplace = True)
- df3.insert(1, 'const', [0])
-
+ df3["index"] = pd.to_datetime("1999-08-06").date()
+ df3.rename(columns={"index": "Date"}, inplace=True)
+ df3.insert(1, "const", [0])
+
# st.dataframe(df3)
# Create a buffer to hold the Excel file
import io
+
output = io.BytesIO()
# Write the dataframes to an Excel file
- with pd.ExcelWriter(output, engine='openpyxl') as writer:
- df1.to_excel(writer, index=False, sheet_name='RAW DATA MMM')
- df2.to_excel(writer, index=False, sheet_name='SPEND INPUT')
- df3.to_excel(writer, index=False, sheet_name='CONTRIBUTION MMM')
+ with pd.ExcelWriter(output, engine="openpyxl") as writer:
+ df1.to_excel(writer, index=False, sheet_name="RAW DATA MMM")
+ df2.to_excel(writer, index=False, sheet_name="SPEND INPUT")
+ df3.to_excel(writer, index=False, sheet_name="CONTRIBUTION MMM")
# Seek to the beginning of the stream
output.seek(0)
- with open('Overview_data_uploaded.xlsx', 'wb') as f:
+ with open("Overview_data_uploaded.xlsx", "wb") as f:
f.write(output.getvalue())
return
+
def get_excel_names(directory):
# Create a list to hold the final parts of the filenames
last_portions = []
@@ -880,109 +944,169 @@ def reset_inputs():
st.session_state["initialized"] = False
+
def scenario_planner_plots2():
import plotly.graph_objects as go
from plotly.subplots import make_subplots
-
- with open('summary_df.pkl', 'rb') as file:
- summary_df_sorted = pickle.load(file)
- #st.write(summary_df_sorted)
-
- # selected_scenario= st.selectbox('Select Saved Scenarios',['S1','S2'])
- summary_df_sorted=summary_df_sorted.sort_values(by=['Optimized_spend'],ascending=False)
- 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())
- 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())
- summary_df_sorted['old_roi']=summary_df_sorted['Old_sales']/summary_df_sorted['Actual_spend']
- summary_df_sorted['new_roi']=summary_df_sorted['New_sales']/summary_df_sorted['Optimized_spend']
-
- total_actual_spend = summary_df_sorted['Actual_spend'].sum()
- total_optimized_spend = summary_df_sorted['Optimized_spend'].sum()
- actual_spend_percentage = (summary_df_sorted['Actual_spend'] / total_actual_spend) * 100
- optimized_spend_percentage = (summary_df_sorted['Optimized_spend'] / total_optimized_spend) * 100
-
+ with open("summary_df.pkl", "rb") as file:
+ summary_df_sorted = pickle.load(file)
+ # st.write(summary_df_sorted)
+ # selected_scenario= st.selectbox('Select Saved Scenarios',['S1','S2'])
+ summary_df_sorted = summary_df_sorted.sort_values(
+ by=["Optimized_spend"], ascending=False
+ )
+ 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())
+ 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()
+ )
+ summary_df_sorted["old_roi"] = (
+ summary_df_sorted["Old_sales"] / summary_df_sorted["Actual_spend"]
+ )
+ summary_df_sorted["new_roi"] = (
+ summary_df_sorted["New_sales"] / summary_df_sorted["Optimized_spend"]
+ )
- light_blue = 'rgba(0, 31, 120, 0.7)'
- light_orange = 'rgba(0, 181, 219, 0.7)'
- light_green = 'rgba(240, 61, 20, 0.7)'
- light_red = 'rgba(250, 110, 10, 0.7)'
- light_purple = 'rgba(255, 191, 69, 0.7)'
+ total_actual_spend = summary_df_sorted["Actual_spend"].sum()
+ total_optimized_spend = summary_df_sorted["Optimized_spend"].sum()
+ actual_spend_percentage = (
+ summary_df_sorted["Actual_spend"] / total_actual_spend
+ ) * 100
+ optimized_spend_percentage = (
+ summary_df_sorted["Optimized_spend"] / total_optimized_spend
+ ) * 100
+
+ light_blue = "rgba(0, 31, 120, 0.7)"
+ light_orange = "rgba(0, 181, 219, 0.7)"
+ light_green = "rgba(240, 61, 20, 0.7)"
+ light_red = "rgba(250, 110, 10, 0.7)"
+ light_purple = "rgba(255, 191, 69, 0.7)"
fig1 = go.Figure()
- # Add actual vs optimized spend bars
+ # Add actual vs optimized spend bars
+
+ fig1.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["Actual_spend"],
+ name="Actual",
+ text=summary_df_sorted["Actual_spend"].apply(format_number) + " "
+ # +
+ # ' '+
+ # ' (' + actual_spend_percentage.astype(int).astype(str) + '%)'
+ ,
+ textposition="outside", # textfont=dict(size=30),
+ marker_color=light_blue,
+ )
+ )
+
+ fig1.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["Optimized_spend"],
+ name="Optimized",
+ text=summary_df_sorted["Optimized_spend"].apply(format_number) + " "
+ # +
+ # ' (' + optimized_spend_percentage.astype(int).astype(str) + '%)'
+ ,
+ textposition="outside", # textfont=dict(size=30),
+ marker_color=light_orange,
+ )
+ )
-
- fig1.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['Actual_spend'], name='Actual',
- text=summary_df_sorted['Actual_spend'].apply(format_number) + ' '
- # +
- # ' '+
- # ' (' + actual_spend_percentage.astype(int).astype(str) + '%)'
- ,textposition='outside',#textfont=dict(size=30),
- marker_color=light_blue))
-
-
- fig1.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['Optimized_spend'], name='Optimized',
- text=summary_df_sorted['Optimized_spend'].apply(format_number) + ' '
- # +
- # ' (' + optimized_spend_percentage.astype(int).astype(str) + '%)'
- ,textposition='outside',#textfont=dict(size=30),
- marker_color=light_orange))
-
fig1.update_xaxes(title_text="Channels")
fig1.update_yaxes(title_text="Spends ($)")
fig1.update_layout(
- title = "Actual vs. Optimized Spends",
- margin=dict(t=40, b=40, l=40, r=40)
- )
-
- # st.plotly_chart(fig1,use_container_width=True)
+ title="Actual vs. Optimized Spends", margin=dict(t=40, b=40, l=40, r=40)
+ )
+
+ # st.plotly_chart(fig1,use_container_width=True)
- # Add actual vs optimized Contribution
+ # Add actual vs optimized Contribution
fig2 = go.Figure()
- fig2.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['Old_sales'],
- name='Actual Contribution',text=summary_df_sorted['Old_sales'].apply(format_number),textposition='outside',
- marker_color=light_blue,showlegend=True))
-
- fig2.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['New_sales'],
- name='Optimized Contribution',text=summary_df_sorted['New_sales'].apply(format_number),textposition='outside',
- marker_color=light_orange, showlegend=True))
-
-
-
+ fig2.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["Old_sales"],
+ name="Actual Contribution",
+ text=summary_df_sorted["Old_sales"].apply(format_number),
+ textposition="outside",
+ marker_color=light_blue,
+ showlegend=True,
+ )
+ )
+
+ fig2.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["New_sales"],
+ name="Optimized Contribution",
+ text=summary_df_sorted["New_sales"].apply(format_number),
+ textposition="outside",
+ marker_color=light_orange,
+ showlegend=True,
+ )
+ )
+
fig2.update_yaxes(title_text="Contribution")
- fig2.update_xaxes(title_text="Channels")
+ fig2.update_xaxes(title_text="Channels")
fig2.update_layout(
- title = "Actual vs. Optimized Contributions",
- margin=dict(t=40, b=40, l=40, r=40)
- # yaxis=dict(range=[0, 0.002]),
- )
- # st.plotly_chart(fig2,use_container_width=True)
+ title="Actual vs. Optimized Contributions",
+ margin=dict(t=40, b=40, l=40, r=40),
+ # yaxis=dict(range=[0, 0.002]),
+ )
+ # st.plotly_chart(fig2,use_container_width=True)
- # Add actual vs optimized Efficiency bars
+ # Add actual vs optimized Efficiency bars
fig3 = go.Figure()
- summary_df_sorted_p = summary_df_sorted[summary_df_sorted['Channel_name']!="Panel"]
- fig3.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'].apply(channel_name_formating), y=summary_df_sorted_p['old_efficiency'],
- name='Actual Efficiency', text=summary_df_sorted_p['old_efficiency'].apply(format_number) ,textposition='outside',
- marker_color=light_blue,showlegend=True))
- fig3.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'].apply(channel_name_formating), y=summary_df_sorted_p['new_efficiency'],
- name='Optimized Efficiency',text=summary_df_sorted_p['new_efficiency'].apply(format_number),textposition='outside' ,
- marker_color=light_orange,showlegend=True))
-
+ summary_df_sorted_p = summary_df_sorted[
+ summary_df_sorted["Channel_name"] != "Panel"
+ ]
+ fig3.add_trace(
+ go.Bar(
+ x=summary_df_sorted_p["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted_p["old_efficiency"],
+ name="Actual Efficiency",
+ text=summary_df_sorted_p["old_efficiency"].apply(format_number),
+ textposition="outside",
+ marker_color=light_blue,
+ showlegend=True,
+ )
+ )
+ fig3.add_trace(
+ go.Bar(
+ x=summary_df_sorted_p["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted_p["new_efficiency"],
+ name="Optimized Efficiency",
+ text=summary_df_sorted_p["new_efficiency"].apply(format_number),
+ textposition="outside",
+ marker_color=light_orange,
+ showlegend=True,
+ )
+ )
+
fig3.update_xaxes(title_text="Channels")
fig3.update_yaxes(title_text="Efficiency")
fig3.update_layout(
- title = "Actual vs. Optimized Efficiency",
- margin=dict(t=40, b=40, l=40, r=40),
- # yaxis=dict(range=[0, 0.002]),
- )
-
- # st.plotly_chart(fig3,use_container_width=True)
- return fig1,fig2,fig3
+ title="Actual vs. Optimized Efficiency",
+ margin=dict(t=40, b=40, l=40, r=40),
+ # yaxis=dict(range=[0, 0.002]),
+ )
+
+ # st.plotly_chart(fig3,use_container_width=True)
+ return fig1, fig2, fig3
+
+
def scenario_planner_plots():
- with st.expander('Optimized Spends Overview'):
- # if st.button('Refresh'):
- # st.experimental_rerun()
+ with st.expander("Actual vs. Optimized Comparison"):
+ # if st.button('Refresh'):
+ # st.experimental_rerun()
import plotly.graph_objects as go
from plotly.subplots import make_subplots
@@ -992,137 +1116,210 @@ def scenario_planner_plots():
from plotly.subplots import make_subplots
st.empty()
- #st.header('Model Result Analysis')
- spends_data=pd.read_excel('Overview_data_test.xlsx')
-
- with open('summary_df.pkl', 'rb') as file:
- summary_df_sorted = pickle.load(file)
- #st.write(summary_df_sorted)
-
- # selected_scenario= st.selectbox('Select Saved Scenarios',['S1','S2'])
- summary_df_sorted=summary_df_sorted.sort_values(by=['Optimized_spend'],ascending=False)
- 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())
- 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())
+ # st.header('Model Result Analysis')
+ spends_data = pd.read_excel("Overview_data_test.xlsx")
- summary_df_sorted['old_roi']=summary_df_sorted['Old_sales']/summary_df_sorted['Actual_spend']
- summary_df_sorted['new_roi']=summary_df_sorted['New_sales']/summary_df_sorted['Optimized_spend']
+ with open("summary_df.pkl", "rb") as file:
+ summary_df_sorted = pickle.load(file).copy()
+ # st.write(summary_df_sorted)
- total_actual_spend = summary_df_sorted['Actual_spend'].sum()
- total_optimized_spend = summary_df_sorted['Optimized_spend'].sum()
+ # selected_scenario= st.selectbox('Select Saved Scenarios',['S1','S2'])
+ summary_df_sorted = summary_df_sorted.sort_values(
+ by=["Optimized_spend"], ascending=False
+ )
+ 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()
+ )
+ 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()
+ )
- actual_spend_percentage = (summary_df_sorted['Actual_spend'] / total_actual_spend) * 100
- optimized_spend_percentage = (summary_df_sorted['Optimized_spend'] / total_optimized_spend) * 100
+ summary_df_sorted["old_roi"] = (
+ summary_df_sorted["Old_sales"] / summary_df_sorted["Actual_spend"]
+ )
+ summary_df_sorted["new_roi"] = (
+ summary_df_sorted["New_sales"] / summary_df_sorted["Optimized_spend"]
+ )
+ total_actual_spend = summary_df_sorted["Actual_spend"].sum()
+ total_optimized_spend = summary_df_sorted["Optimized_spend"].sum()
+ actual_spend_percentage = (
+ summary_df_sorted["Actual_spend"] / total_actual_spend
+ ) * 100
+ optimized_spend_percentage = (
+ summary_df_sorted["Optimized_spend"] / total_optimized_spend
+ ) * 100
- light_blue = 'rgba(0, 31, 120, 0.7)'
- light_orange = 'rgba(0, 181, 219, 0.7)'
- light_green = 'rgba(240, 61, 20, 0.7)'
- light_red = 'rgba(250, 110, 10, 0.7)'
- light_purple = 'rgba(255, 191, 69, 0.7)'
+ light_blue = "rgba(0, 31, 120, 0.7)"
+ light_orange = "rgba(0, 181, 219, 0.7)"
+ light_green = "rgba(240, 61, 20, 0.7)"
+ light_red = "rgba(250, 110, 10, 0.7)"
+ light_purple = "rgba(255, 191, 69, 0.7)"
fig1 = go.Figure()
# Add actual vs optimized spend bars
-
- fig1.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['Actual_spend'], name='Actual',
- text=summary_df_sorted['Actual_spend'].apply(format_number) + ' '
- # +
- # ' '+
- # ' (' + actual_spend_percentage.astype(int).astype(str) + '%)'
- ,textposition='outside',#textfont=dict(size=30),
- marker_color=light_blue))
-
-
- fig1.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['Optimized_spend'], name='Optimized',
- text=summary_df_sorted['Optimized_spend'].apply(format_number) + ' '
- # +
- # ' (' + optimized_spend_percentage.astype(int).astype(str) + '%)'
- ,textposition='outside',#textfont=dict(size=30),
- marker_color=light_orange))
-
+ fig1.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["Actual_spend"],
+ name="Actual",
+ text=summary_df_sorted["Actual_spend"].apply(format_number) + " "
+ # +
+ # ' '+
+ # ' (' + actual_spend_percentage.astype(int).astype(str) + '%)'
+ ,
+ textposition="outside", # textfont=dict(size=30),
+ marker_color=light_blue,
+ )
+ )
+
+ fig1.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["Optimized_spend"],
+ name="Optimized",
+ text=summary_df_sorted["Optimized_spend"].apply(format_number) + " "
+ # +
+ # ' (' + optimized_spend_percentage.astype(int).astype(str) + '%)'
+ ,
+ textposition="outside", # textfont=dict(size=30),
+ marker_color=light_orange,
+ )
+ )
+
fig1.update_xaxes(title_text="Channels")
fig1.update_yaxes(title_text="Spends ($)")
fig1.update_layout(
- title = "Actual vs. Optimized Spends",
- margin=dict(t=40, b=40, l=40, r=40)
- )
-
- st.plotly_chart(fig1,use_container_width=True)
+ title="Spends", margin=dict(t=40, b=40, l=40, r=40)
+ )
+
+ st.plotly_chart(fig1, use_container_width=True)
- # Add actual vs optimized Contribution
+ # Add actual vs optimized Contribution
fig2 = go.Figure()
- fig2.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['Old_sales'],
- name='Actual Contribution',text=summary_df_sorted['Old_sales'].apply(format_number),textposition='outside',
- marker_color=light_blue,showlegend=True))
-
- fig2.add_trace(go.Bar(x=summary_df_sorted['Channel_name'].apply(channel_name_formating), y=summary_df_sorted['New_sales'],
- name='Optimized Contribution',text=summary_df_sorted['New_sales'].apply(format_number),textposition='outside',
- marker_color=light_orange, showlegend=True))
-
-
-
- fig2.update_yaxes(title_text="Contribution")
- fig2.update_xaxes(title_text="Channels")
+ fig2.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["Old_sales"],
+ name="Actual Contribution",
+ text=summary_df_sorted["Old_sales"].apply(format_number),
+ textposition="outside",
+ marker_color=light_blue,
+ showlegend=True,
+ )
+ )
+
+ fig2.add_trace(
+ go.Bar(
+ x=summary_df_sorted["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted["New_sales"],
+ name="Optimized Contribution",
+ text=summary_df_sorted["New_sales"].apply(format_number),
+ textposition="outside",
+ marker_color=light_orange,
+ showlegend=True,
+ )
+ )
+
+ fig2.update_yaxes(title_text="Revenue ($)")
+ fig2.update_xaxes(title_text="Channels")
fig2.update_layout(
- title = "Actual vs. Optimized Contributions",
- margin=dict(t=40, b=40, l=40, r=40)
- # yaxis=dict(range=[0, 0.002]),
- )
- st.plotly_chart(fig2,use_container_width=True)
+ title="Revenue",
+ margin=dict(t=40, b=40, l=40, r=40),
+ # yaxis=dict(range=[0, 0.002]),
+ )
+ st.plotly_chart(fig2, use_container_width=True)
# Add actual vs optimized Efficiency bars
fig3 = go.Figure()
- summary_df_sorted_p = summary_df_sorted[summary_df_sorted['Channel_name']!="Panel"]
- fig3.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'].apply(channel_name_formating), y=summary_df_sorted_p['old_efficiency'],
- name='Actual Efficiency', text=summary_df_sorted_p['old_efficiency'].apply(format_number) ,textposition='outside',
- marker_color=light_blue,showlegend=True))
- fig3.add_trace(go.Bar(x=summary_df_sorted_p['Channel_name'].apply(channel_name_formating), y=summary_df_sorted_p['new_efficiency'],
- name='Optimized Efficiency',text=summary_df_sorted_p['new_efficiency'].apply(format_number),textposition='outside' ,
- marker_color=light_orange,showlegend=True))
-
+ summary_df_sorted_p = summary_df_sorted[
+ summary_df_sorted["Channel_name"] != "Panel"
+ ]
+
+ # Ensure there are no division-by-zero errors
+ summary_df_sorted_p["Actual_spend"].replace(0, np.nan, inplace=True)
+ summary_df_sorted_p["Optimized_spend"].replace(0, np.nan, inplace=True)
+
+ summary_df_sorted_p["old_roi"] = summary_df_sorted_p["Old_sales"] / summary_df_sorted_p["Actual_spend"]
+ summary_df_sorted_p["new_roi"] = summary_df_sorted_p["New_sales"] / summary_df_sorted_p["Optimized_spend"]
+
+
+ fig3.add_trace(
+ go.Bar(
+ x=summary_df_sorted_p["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted_p["old_roi"],
+ name="Actual ROI",
+ text=summary_df_sorted_p["old_roi"].apply(format_number),
+ textposition="outside",
+ marker_color=light_blue,
+ showlegend=True,
+ )
+ )
+
+ fig3.add_trace(
+ go.Bar(
+ x=summary_df_sorted_p["Channel_name"].apply(channel_name_formating),
+ y=summary_df_sorted_p["new_roi"],
+ name="Optimized ROI",
+ text=summary_df_sorted_p["new_roi"].apply(format_number),
+ textposition="outside",
+ marker_color=light_orange,
+ showlegend=True,
+ )
+ )
+
fig3.update_xaxes(title_text="Channels")
- fig3.update_yaxes(title_text="Efficiency")
+ fig3.update_yaxes(title_text="ROI")
fig3.update_layout(
- title = "Actual vs. Optimized Efficiency",
- margin=dict(t=40, b=40, l=40, r=40),
- # yaxis=dict(range=[0, 0.002]),
- )
-
- st.plotly_chart(fig3,use_container_width=True)
- return fig1,fig2,fig3
+ title="ROI",
+ margin=dict(t=40, b=40, l=40, r=40),
+ # yaxis=dict(range=[0, 0.002]),
+ )
+
+ st.plotly_chart(fig3, use_container_width=True)
+ return fig1, fig2, fig3
+
def give_demo():
def get_file_bytes(file_path):
- with open(file_path, 'rb') as file:
+ with open(file_path, "rb") as file:
return file.read()
# Path to the existing Excel file
- file_path = 'input_data_example.xlsx'
+ file_path = "input_data_example.xlsx"
# Create a download button
st.download_button(
label="Download Input File Format",
data=get_file_bytes(file_path),
file_name=file_path,
- mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
- )
+ mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ )
+
+
if auth_status == True:
authenticator.logout("Logout", "main")
st.header("Scenario Planner")
-
+
data_selected = st.selectbox(
- "Select base data for optimisation", options=["Optimise Actual Spends", "Optimise Uploaded Spends"],
- key = "data_upload_key",index = 1)
+ "Select base data for optimisation",
+ options=["Optimise Actual Spends", "Optimise Uploaded Spends"],
+ key="data_upload_key",
+ index=1,
+ )
# st.text_input("")
-
-
-
# Response Metrics
directory = "metrics_level_data"
metrics_list = get_excel_names(directory)
-
+
# metrics_selected = col1.selectbox(
# "Response Metrics",
# metrics_list,
@@ -1131,7 +1328,7 @@ if auth_status == True:
# on_change=reset_inputs,
# )
- metrics_selected='prospects'
+ metrics_selected = "prospects"
# Target
target = name_formating(metrics_selected)
@@ -1139,21 +1336,21 @@ if auth_status == True:
# f"Overview_data_test_panel@#{metrics_selected}.xlsx"
# )
file_selected = None
- if data_selected == "Optimise Uploaded Spends":
+ if data_selected == "Optimise Uploaded Spends":
give_demo()
st.write("Select a file to upload")
-
+
uploaded_file = st.file_uploader("Choose an Excel file", type=["xlsx", "xls"])
# give_demo()
if uploaded_file:
try:
# Read the Excel file using pandas
- df = pd.read_excel(uploaded_file, engine='openpyxl')
+ df = pd.read_excel(uploaded_file, engine="openpyxl")
upload_file_format(df)
file_selected = "Overview_data_uploaded.xlsx"
# initialize_data(
-
+
# target_file=file_selected,
# panel="Total Market",
# updated_rcs=None,
@@ -1161,24 +1358,22 @@ if auth_status == True:
# )
except Exception as e:
st.error(f"Error reading the file: {e}")
-
- elif data_selected == "Optimise Actual Spends":
- file_selected = (
- f"Overview_data_test_panel@#{metrics_selected}.xlsx"
- )
+
+ elif data_selected == "Optimise Actual Spends":
+ file_selected = f"Overview_data_test_panel@#{metrics_selected}.xlsx"
# initialize_data(
-
+
# target_file=file_selected,
# panel="Total Market",
# updated_rcs=None,
# metrics=metrics_selected,
# )
-
- else :
+
+ else:
st.write("")
if file_selected:
- st.session_state['file_selected']=file_selected
+ st.session_state["file_selected"] = file_selected
# Panel List
panel_list = panel_fetch(file_selected)
@@ -1189,10 +1384,10 @@ if auth_status == True:
# index=0,
# on_change=reset_inputs,
# )
-
+
# st.write(panel_selected)
panel_selected = "Total Market"
- st.session_state['selected_markets']=panel_selected
+ st.session_state["selected_markets"] = panel_selected
if "update_rcs" in st.session_state:
updated_rcs = st.session_state["update_rcs"]
@@ -1206,18 +1401,15 @@ if auth_status == True:
is_state_initiaized = st.session_state.get("initialized", False)
if not is_state_initiaized or st.session_state["first_time"]:
initialize_data(
-
- target_file=file_selected,
- panel=panel_selected,
- updated_rcs=updated_rcs,
- metrics=metrics_selected,
- )
+ target_file=file_selected,
+ panel=panel_selected,
+ updated_rcs=updated_rcs,
+ metrics=metrics_selected,
+ )
st.session_state["initialized"] = True
st.session_state["first_time"] = False
save_scenario("current scenario")
-
-
# initialize_data(
# panel=panel_selected,
# target_file=file_selected,
@@ -1265,29 +1457,46 @@ if auth_status == True:
st.session_state.total_sales_change_abs_slider = numerize(
_scenario.actual_total_sales, 1
)
-
+
if "lower_bound_key" not in st.session_state:
st.session_state["lower_bound_key"] = 10
-
+
if "upper_bound_key" not in st.session_state:
st.session_state["upper_bound_key"] = 100
# st.write(_scenario.modified_total_sales)
- header_df = pd.DataFrame(index=["Actual","Simulated","Change","Percent Change"],columns=["Spends","Prospects"])
+ header_df = pd.DataFrame(
+ index=["Actual", "Simulated", "Change", "Percent Change"],
+ columns=["Spends", "Prospects"],
+ )
header_df["Spends"]["Actual"] = format_numbers(_scenario.actual_total_spends)
- header_df["Spends"]["Simulated"] = format_numbers(_scenario.modified_total_spends)
- header_df["Spends"]["Change"] = format_numbers(_scenario.delta_spends) #_scenario.modified_total_spends -_scenario.actual_total_spends
- header_df["Spends"]["Percent Change"] = numerize(100*(_scenario.delta_spends/_scenario.actual_total_spends))+'%'
-
- header_df["Prospects"]["Actual"] = format_numbers_f(float(_scenario.actual_total_sales))
- header_df["Prospects"]["Simulated"] = format_numbers_f(float(_scenario.modified_total_sales))
+ header_df["Spends"]["Simulated"] = format_numbers(
+ _scenario.modified_total_spends
+ )
+ header_df["Spends"]["Change"] = format_numbers(
+ _scenario.delta_spends
+ ) # _scenario.modified_total_spends -_scenario.actual_total_spends
+ header_df["Spends"]["Percent Change"] = (
+ numerize(100 * (_scenario.delta_spends / _scenario.actual_total_spends))
+ + "%"
+ )
+
+ header_df["Prospects"]["Actual"] = format_numbers_f(
+ float(_scenario.actual_total_sales)
+ )
+ header_df["Prospects"]["Simulated"] = format_numbers_f(
+ float(_scenario.modified_total_sales)
+ )
header_df["Prospects"]["Change"] = format_numbers_f(_scenario.delta_sales)
- header_df["Prospects"]["Percent Change"] = numerize(100*(_scenario.delta_sales/_scenario.actual_total_sales),1)+'%'
-
+ header_df["Prospects"]["Percent Change"] = (
+ numerize(100 * (_scenario.delta_sales / _scenario.actual_total_sales), 1)
+ + "%"
+ )
+
st.markdown("""
""", unsafe_allow_html=True)
_columns = st.columns((1, 1, 1, 1, 1))
st.markdown(
- """
+ """
""",
- unsafe_allow_html=True
- )
+ unsafe_allow_html=True,
+ )
with _columns[0]:
- st.markdown(f'{"Metrics"}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{"Metrics"}
', unsafe_allow_html=True
+ )
# generate_spending_header("Metric")
with _columns[1]:
- st.markdown(f'{"Actual"}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{"Actual"}
', unsafe_allow_html=True
+ )
# generate_spending_header("Actual")
with _columns[2]:
- st.markdown(f'{"Simulated"}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{"Simulated"}
', unsafe_allow_html=True
+ )
# generate_spending_header("Optimised")
with _columns[3]:
- st.markdown(f'{"Change"}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{"Change"}
', unsafe_allow_html=True
+ )
# generate_spending_header("Change")
with _columns[4]:
- st.markdown(f'{"Change Percent"}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{"Change Percent"}
',
+ unsafe_allow_html=True,
+ )
# generate_spending_header("Change Percent")
st.markdown("""
""", unsafe_allow_html=True)
_columns = st.columns((1, 1, 1, 1, 1))
with _columns[0]:
- st.markdown(""" Spends
""",unsafe_allow_html=True)
+ st.markdown("""Spends
""", unsafe_allow_html=True)
# st.write("Spends")
with _columns[1]:
- st.markdown(f"""{header_df["Spends"]["Actual"]}
""",unsafe_allow_html=True)
+ st.markdown(
+ f"""{header_df["Spends"]["Actual"]}
""", unsafe_allow_html=True
+ )
# st.metric(label="", value=header_df["Spends"]["Actual"])
with _columns[2]:
- st.markdown(f"""{header_df["Spends"]["Simulated"]}
""",unsafe_allow_html=True)
+ st.markdown(
+ f"""{header_df["Spends"]["Simulated"]}
""",
+ unsafe_allow_html=True,
+ )
if _scenario.delta_spends < 0:
- st.markdown(
+ st.markdown(
"""
""",
- unsafe_allow_html=True
+ unsafe_allow_html=True,
)
else:
- st.markdown(
+ st.markdown(
"""
""",
- unsafe_allow_html=True
+ unsafe_allow_html=True,
)
- # st.metric(label="", value=header_df["Spends"]["Simulated"])
+ # st.metric(label="", value=header_df["Spends"]["Simulated"])
with _columns[3]:
-
+
# Apply custom styles to text
- st.markdown(f'{header_df["Spends"]["Change"]}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{header_df["Spends"]["Change"]}
',
+ unsafe_allow_html=True,
+ )
with _columns[4]:
# Apply custom styles to text
# st.markdown(f'', unsafe_allow_html=True)
- st.markdown(f'{header_df["Spends"]["Percent Change"]}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{header_df["Spends"]["Percent Change"]}
',
+ unsafe_allow_html=True,
+ )
st.markdown(
- """
""",
- unsafe_allow_html=True,
- )
+ """
""",
+ unsafe_allow_html=True,
+ )
_columns = st.columns((1, 1, 1, 1, 1))
with _columns[0]:
# st.header("Prospects")
- st.markdown(""" Prospects
""",unsafe_allow_html=True)
+ st.markdown(""" Revenue
""", unsafe_allow_html=True)
with _columns[1]:
- st.markdown(f"""{header_df["Prospects"]["Actual"]}
""",unsafe_allow_html=True)
+ st.markdown(
+ f"""$ {header_df["Prospects"]["Actual"]}
""",
+ unsafe_allow_html=True,
+ )
# st.metric(label="", value=header_df["Prospects"]["Actual"])
with _columns[2]:
- st.markdown(f"""{header_df["Prospects"]["Simulated"]}
""",unsafe_allow_html=True)
+ st.markdown(
+ f"""$ {header_df["Prospects"]["Simulated"]}
""",
+ unsafe_allow_html=True,
+ )
# st.metric(label="", value=header_df["Prospects"]["Simulated"])
-
+
if _scenario.delta_sales >= 0:
- st.markdown(
+ st.markdown(
"""
""",
- unsafe_allow_html=True
+ unsafe_allow_html=True,
)
else:
- st.markdown("""""",unsafe_allow_html=True)
+ st.markdown(
+ """""",
+ unsafe_allow_html=True,
+ )
with _columns[3]:
# Apply custom styles to text
- st.markdown(f'{header_df["Prospects"]["Change"]}
', unsafe_allow_html=True)
- # st.markdown(f'{st.metric(label="", value=header_df["Prospects"]["Change"])}
', unsafe_allow_html=True)
- # st.markdown(f'{header_df["Prospects"]["Change"]}
', unsafe_allow_html=True)
+ st.markdown(
+ f'$ {header_df["Prospects"]["Change"]}
',
+ unsafe_allow_html=True,
+ )
+ # st.markdown(f'{st.metric(label="", value=header_df["Prospects"]["Change"])}
', unsafe_allow_html=True)
+ # st.markdown(f'{header_df["Prospects"]["Change"]}
', unsafe_allow_html=True)
with _columns[4]:
# st.markdown(f'', unsafe_allow_html=True)
# Apply custom styles to text
- st.markdown(f'{header_df["Prospects"]["Percent Change"]}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{header_df["Prospects"]["Percent Change"]}
',
+ unsafe_allow_html=True,
+ )
st.markdown(
- """
""",
- unsafe_allow_html=True,
- )
-
+ """
""",
+ unsafe_allow_html=True,
+ )
+
_columns = st.columns((1, 1, 1, 1, 1))
- ef1 = (_scenario.actual_total_spends/_scenario.actual_total_sales)
- ef2 = (_scenario.modified_total_spends/_scenario.modified_total_sales)
+
+ ef1 = _scenario.actual_total_sales/ _scenario.actual_total_spends
+ ef2 = _scenario.modified_total_sales/ _scenario.modified_total_spends
with _columns[0]:
- st.markdown("""Cost Per Prospect
""",unsafe_allow_html=True)
+ st.markdown("""ROI
""", unsafe_allow_html=True)
# st.header("Cost Per Prospect")
with _columns[1]:
- st.markdown(f"""{'$ '+numerize(ef1,0)}
""",unsafe_allow_html=True)
+ st.markdown(f"""{numerize(ef1,0)}
""", unsafe_allow_html=True)
# st.metric(label="", value='$ '+numerize(ef1,0))
with _columns[2]:
- st.markdown(f"""{'$ '+numerize(ef2,0)}
""",unsafe_allow_html=True)
+ st.markdown(f"""{numerize(ef2,0)}
""", unsafe_allow_html=True)
# st.metric(label="", value='$ '+numerize(ef2,0))
if ef2 <= ef1:
- st.markdown(
+ st.markdown(
"""
""",
- unsafe_allow_html=True
+ unsafe_allow_html=True,
)
else:
- st.markdown(
+ st.markdown(
"""
""",
- unsafe_allow_html=True
+ unsafe_allow_html=True,
)
with _columns[3]:
-
-
+
# Apply custom styles to text
- st.markdown(f'{"$ "+numerize(ef2-ef1,0)}
', unsafe_allow_html=True)
- # st.markdown(f'{st.metric(label="", value=header_df["Prospects"]["Change"])}
', unsafe_allow_html=True)
- # st.markdown(f'{header_df["Prospects"]["Change"]}
', unsafe_allow_html=True)
+ st.markdown(
+ f'{numerize(ef2-ef1,0)}
',
+ unsafe_allow_html=True,
+ )
+ # st.markdown(f'{st.metric(label="", value=header_df["Prospects"]["Change"])}
', unsafe_allow_html=True)
+ # st.markdown(f'{header_df["Prospects"]["Change"]}
', unsafe_allow_html=True)
with _columns[4]:
# st.markdown(f'', unsafe_allow_html=True)
# Apply custom styles to text
- st.markdown(f'{round((ef2-ef1)/ef1*100,2)}%
', unsafe_allow_html=True)
- st.markdown("""
""",unsafe_allow_html=True)
+ st.markdown(
+ f'{round((ef2-ef1)/ef1*100,2)}%
',
+ unsafe_allow_html=True,
+ )
+ st.markdown("""
""", unsafe_allow_html=True)
# st.markdown("""
""", unsafe_allow_html=True)
@@ -1488,14 +1740,14 @@ if auth_status == True:
# if row_idx in rows and col_idx > 0: # Exclude the first column (col_idx > 0)
# return format_arrows(val)
# return '' # No formatting for other cells
-
+
# return df.style.apply(lambda x: [format_cell(val, i, col) for i, (val, col) in enumerate(zip(x, range(len(x))))], axis=1)
# # Apply formatting to 3rd and 4th rows (index 2 and 3)
# styled_df = apply_row_formatting(header_df, [2, 3])
# st.markdown(styled_df.to_html(escape=False), unsafe_allow_html=True)
-
+
# st.markdown(header_df.style.set_table_styles
# ([{'selector': 'th',
# 'props': [('background-color', '#D3D3D3'),
@@ -1507,17 +1759,14 @@ if auth_status == True:
# }
# ,
# {'selector': 'tbody td',
- # 'props': [('font-size', '20px')]}
+ # 'props': [('font-size', '20px')]}
- # ]).to_html(),unsafe_allow_html=True)
-
+ # ]).to_html(),unsafe_allow_html=True)
-
- # styled_df = header_df.style.apply(highlight_first_col, axis=1)
+ # styled_df = header_df.style.apply(highlight_first_col, axis=1)
# st.table(styled_df)
-
# with main_header[0]:
# st.subheader("Actual")
@@ -1552,7 +1801,7 @@ if auth_status == True:
# )
with st.expander("Channel Spends Simulator", expanded=True):
- _columns1 = st.columns((1.5, 1.5, 1,1))
+ _columns1 = st.columns((1, 1, 1, 1))
with _columns1[0]:
optimization_selection = st.selectbox(
"Optimize", options=["Media Spends", target], key="optimization_key"
@@ -1567,7 +1816,7 @@ if auth_status == True:
# # on_change=select_all_channels_for_optimization,
# ):
# select_all_channels_for_optimization()
-
+ st.write("#")
st.checkbox(
label="Optimize all Channels",
key="optimze_all_channels",
@@ -1576,43 +1825,43 @@ if auth_status == True:
)
with _columns1[2]:
- #
-
-
-
+ st.write("####")
optimize_placeholder = st.empty()
with _columns1[3]:
- # st.markdown("#")
+ st.write("####")
st.button(
"Reset",
on_click=reset_scenario,
args=(panel_selected, file_selected, updated_rcs),
- # use_container_width=True,
+ use_container_width=True,
)
# st.write(target)
-
- _columns2 = st.columns((2, 2, 2,2))
+ _columns2 = st.columns((2, 2, 2, 2))
if st.session_state["optimization_key"] == "Media Spends":
# st.write(overall_lower_bound,overall_upper_bound)
-
+
with _columns2[2]:
overall_lower_bound = st.number_input(
- "Overall Lower Bound for Spends",
- value = 50.0,
- key = "overall_lower_bound",
- # on_change=partial(update_data_bound_min_overall)
- )
+ "Overall Lower Bound for Spends",
+ value=50.0,
+ key="overall_lower_bound",
+ # on_change=partial(update_data_bound_min_overall)
+ )
with _columns2[3]:
overall_upper_bound = st.number_input(
- "Overall Upper Bound for Spends",
- value = 50.0,
- key = "overall_upper_bound",
- # on_change=partial(update_data_bound_max_overall)
- )
- min_value = round(_scenario.actual_total_spends * (1-overall_lower_bound/100))
- max_value = round(_scenario.actual_total_spends * (1-overall_upper_bound/100))
+ "Overall Upper Bound for Spends",
+ value=50.0,
+ key="overall_upper_bound",
+ # on_change=partial(update_data_bound_max_overall)
+ )
+ min_value = round(
+ _scenario.actual_total_spends * (1 - overall_lower_bound / 100)
+ )
+ max_value = round(
+ _scenario.actual_total_spends * (1 - overall_upper_bound / 100)
+ )
with _columns2[0]:
spend_input = st.text_input(
"Absolute",
@@ -1627,15 +1876,13 @@ if auth_status == True:
st.number_input(
"Percent Change",
key="total_spends_change",
- min_value= -1*overall_lower_bound,
- max_value= overall_upper_bound,
+ min_value=-1 * overall_lower_bound,
+ max_value=overall_upper_bound,
step=0.01,
value=0.00,
on_change=update_spends,
)
-
-
st.session_state["total_spends_change_abs_slider_options"] = [
numerize(value, 1)
for value in range(min_value, max_value + 1, int(1e4))
@@ -1647,7 +1894,7 @@ if auth_status == True:
# key="total_spends_change_abs_slider",
# on_change=update_all_spends_abs_slider,
# )
-
+
elif st.session_state["optimization_key"] == target:
# st.write(target)
with _columns2[0]:
@@ -1664,24 +1911,25 @@ if auth_status == True:
min_value=-50.00,
max_value=50.00,
step=0.01,
-
value=0.00,
on_change=update_sales,
)
with _columns2[2]:
- overall_lower_bound = st.number_input(
- "Overall Lower Bound for Spends",
- value = 50
+ overall_lower_bound = st.number_input(
+ "Overall Lower Bound for Spends", value=50
)
with _columns2[3]:
-
+
overall_upper_bound = st.number_input(
- "Overall Upper Bound for Spends",
- value = 50
+ "Overall Upper Bound for Spends", value=50
)
- min_value = round(_scenario.actual_total_sales * (1-overall_lower_bound/100))
- max_value = round(_scenario.actual_total_sales * (1+overall_upper_bound/100))
+ min_value = round(
+ _scenario.actual_total_sales * (1 - overall_lower_bound / 100)
+ )
+ max_value = round(
+ _scenario.actual_total_sales * (1 + overall_upper_bound / 100)
+ )
# st.write(min_value)
# st.write(max_value)
# for value in range(min_value, max_value + 1, int(100)):
@@ -1711,7 +1959,6 @@ if auth_status == True:
):
st.warning("Invalid Input")
-
status_placeholder = st.empty()
# if optimize_placeholder.button("Optimize", use_container_width=True):
@@ -1722,11 +1969,13 @@ if auth_status == True:
"Optimize",
on_click=optimize,
args=(st.session_state["optimization_key"], status_placeholder),
- # use_container_width=True,
+ use_container_width=True,
)
- st.markdown("""
""", unsafe_allow_html=True)
- _columns = st.columns((1.5,2.5,2,2, 1))
+ st.markdown(
+ """
""", unsafe_allow_html=True
+ )
+ _columns = st.columns((1.5, 2.5, 2, 2, 1))
with _columns[0]:
generate_spending_header("Channel")
with _columns[1]:
@@ -1734,11 +1983,13 @@ if auth_status == True:
with _columns[2]:
generate_spending_header("Spends")
with _columns[3]:
- generate_spending_header(target)
+ generate_spending_header("Revenue" if target == "Prospects" else target)
with _columns[4]:
generate_spending_header("Optimize")
- st.markdown("""
""", unsafe_allow_html=True)
+ st.markdown(
+ """
""", unsafe_allow_html=True
+ )
if "acutual_predicted" not in st.session_state:
st.session_state["acutual_predicted"] = {
@@ -1746,8 +1997,8 @@ if auth_status == True:
"Actual_spend": [],
"Optimized_spend": [],
"Delta": [],
- "New_sales":[],
- "Old_sales":[]
+ "New_sales": [],
+ "Old_sales": [],
}
for i, channel_name in enumerate(channels_list):
# st.write(channel_name)
@@ -1759,13 +2010,22 @@ if auth_status == True:
# st.write(st.session_state["scenario"].channels[channel_name].modified_total_spends)
# st.write(st.session_state["scenario"].channels[channel_name].bounds)
# st.write(st.session_state["scenario"].channels[channel_name].channel_bounds_min)
-
- _columns = st.columns((1.5,2.5,2,2, 1))
- response_curve_params = pd.read_excel("response_curves_parameters.xlsx",index_col = "channel")
- param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
-
+
+ _columns = st.columns((1.5, 2.5, 2, 2, 1))
+ response_curve_params = pd.read_excel(
+ "response_curves_parameters.xlsx", index_col="channel"
+ )
+ param_dicts = {
+ col: response_curve_params[col].to_dict()
+ for col in response_curve_params.columns
+ }
+
with _columns[0]:
- st.write(channel_name_formating(channel_name))
+ st.write(
+ channel_name_formating(channel_name).replace(
+ "Connected & OTTTV", "Connected & OTT TV"
+ )
+ )
bin_placeholder = st.container()
with _columns[1]:
@@ -1789,25 +2049,32 @@ if auth_status == True:
key=channel_name,
# label_visibility="collapsed",
on_change=partial(update_data, channel_name),
-
)
channel_name_lower_bound = f"{channel_name}_lower_bound"
-
+
if channel_name_lower_bound not in st.session_state:
- st.session_state[channel_name_lower_bound] = str(round(param_dicts["x_min"][channel_name]*10400/param_dicts["current_spends"][channel_name]))
+ st.session_state[channel_name_lower_bound] = str(
+ round(
+ param_dicts["x_min"][channel_name]
+ * 10400
+ / param_dicts["current_spends"][channel_name]
+ )
+ )
# st.write(st.session_state[channel_name_lower_bound])
channel_bounds_min = st.text_input(
"Lower Bound Percentage",
- key = channel_name_lower_bound,
- on_change=partial(update_data_bound_min,channel_name)
+ key=channel_name_lower_bound,
+ on_change=partial(update_data_bound_min, channel_name),
)
# st.write(st.session_state[channel_name_lower_bound])
# if not validate_input_lb(str(channel_bounds_min)):
# st.error("Invalid input")
if not validate_input(spend_input):
st.error("Invalid input")
+
def calc_min_value():
return float(st.session_state[channel_name_upper_bound])
+
channel_name_current = f"{channel_name}_change"
with _columns_min[1]:
channel_name_upper_bound = f"{channel_name}_upper_bound"
@@ -1817,17 +2084,18 @@ if auth_status == True:
st.number_input(
"Percent Change",
key=channel_name_current,
- step=1.00,value=0.00,
+ step=1.00,
+ value=0.00,
on_change=partial(update_data_by_percent, channel_name),
- max_value = calc_min_value(),
- min_value = -1*float(st.session_state[channel_name_lower_bound])
-
+ max_value=calc_min_value(),
+ min_value=-1
+ * float(st.session_state[channel_name_lower_bound]),
)
-
+
channel_bounds_max = st.text_input(
"Upper Bound Percentage",
- key = channel_name_upper_bound,
- on_change=partial(update_data_bound_max,channel_name)
+ key=channel_name_upper_bound,
+ on_change=partial(update_data_bound_max, channel_name),
)
# if not validate_input(channel_bounds_max):
# st.error("Invalid input")
@@ -1838,7 +2106,8 @@ if auth_status == True:
* _channel_class.conversion_rate
)
actual_channel_spends = float(
- _channel_class.actual_total_spends * _channel_class.conversion_rate
+ _channel_class.actual_total_spends
+ * _channel_class.conversion_rate
)
spends_delta = float(
_channel_class.delta_spends * _channel_class.conversion_rate
@@ -1856,7 +2125,10 @@ if auth_status == True:
_spend_cols = st.columns(2)
with _spend_cols[0]:
# st.write("Actual")
- st.markdown(f' Actual
{format_numbers(actual_channel_spends)}
', unsafe_allow_html=True)
+ st.markdown(
+ f" Actual
{format_numbers(actual_channel_spends)}
",
+ unsafe_allow_html=True,
+ )
# st.metric(
# label="Actual Spends",
# value=format_numbers(actual_channel_spends),
@@ -1865,7 +2137,10 @@ if auth_status == True:
# )
# st.write("Actual")
- st.markdown(f' Change
{format_numbers(spends_delta)}
', unsafe_allow_html=True)
+ st.markdown(
+ f" Change
{format_numbers(spends_delta)}
",
+ unsafe_allow_html=True,
+ )
# st.markdown(f'{format_numbers(spends_delta)}%
', unsafe_allow_html=True)
# st.metric(
@@ -1875,8 +2150,14 @@ if auth_status == True:
# # label_visibility="collapsed",
# )
with _spend_cols[1]:
- st.markdown(f' Simulated
{format_numbers(current_channel_spends)}
', unsafe_allow_html=True)
- st.markdown(f'Percent
{numerize(( spends_delta/actual_channel_spends)*100,0) +"%"}
', unsafe_allow_html=True)
+ st.markdown(
+ f" Simulated
{format_numbers(current_channel_spends)}
",
+ unsafe_allow_html=True,
+ )
+ st.markdown(
+ f'Percent
{numerize(( spends_delta/actual_channel_spends)*100,0) +"%"}
',
+ unsafe_allow_html=True,
+ )
# st.metric(
# label="Simulated Spends",
# value=format_numbers(current_channel_spends),
@@ -1891,21 +2172,30 @@ if auth_status == True:
# # label_visibility="collapsed",
# )
-
with _columns[3]:
# sales
current_channel_sales = float(_channel_class.modified_total_sales)
actual_channel_sales = float(_channel_class.actual_total_sales)
sales_delta = float(_channel_class.delta_sales)
- st.session_state["acutual_predicted"]["Old_sales"].append(actual_channel_sales)
- st.session_state["acutual_predicted"]["New_sales"].append(current_channel_sales)
- #st.write(actual_channel_sales)
-
+ st.session_state["acutual_predicted"]["Old_sales"].append(
+ actual_channel_sales
+ )
+ st.session_state["acutual_predicted"]["New_sales"].append(
+ current_channel_sales
+ )
+ # st.write(actual_channel_sales)
+
_prospect_cols = st.columns(2)
with _prospect_cols[0]:
# st.write("Actual")
- st.markdown(f' Actual
{format_numbers_f(actual_channel_sales)}
', unsafe_allow_html=True)
- st.markdown(f' Change
{format_numbers_f(sales_delta)}
', unsafe_allow_html=True)
+ st.markdown(
+ f" Actual
{format_numbers_f(actual_channel_sales)}
",
+ unsafe_allow_html=True,
+ )
+ st.markdown(
+ f" Change
{format_numbers_f(sales_delta)}
",
+ unsafe_allow_html=True,
+ )
# st.metric(
# # target,
@@ -1921,8 +2211,14 @@ if auth_status == True:
# # label_visibility="collapsed",
# )
with _prospect_cols[1]:
- st.markdown(f' Simulated
{format_numbers_f(current_channel_sales)}
', unsafe_allow_html=True)
- st.markdown(f'Percent
{numerize(( _channel_class.delta_sales/actual_channel_sales)*100,0) +"%"}
', unsafe_allow_html=True)
+ st.markdown(
+ f" Simulated
{format_numbers_f(current_channel_sales)}
",
+ unsafe_allow_html=True,
+ )
+ st.markdown(
+ f'Percent
{numerize(( _channel_class.delta_sales/actual_channel_sales)*100,0) +"%"}
',
+ unsafe_allow_html=True,
+ )
# st.metric(
# label="Simulated Prospects",
@@ -1938,8 +2234,6 @@ if auth_status == True:
# # label_visibility="collapsed",
# )
-
-
with _columns[4]:
# if st.checkbox(
@@ -1955,7 +2249,9 @@ if auth_status == True:
label="select for optimization",
key=f"{channel_name}_selected",
value=False,
- on_change=partial(select_channel_for_optimization, channel_name),
+ on_change=partial(
+ select_channel_for_optimization, channel_name
+ ),
label_visibility="collapsed",
)
@@ -1968,17 +2264,19 @@ if auth_status == True:
col = channels_list[i]
x_actual = st.session_state["scenario"].channels[col].actual_spends
x_modified = st.session_state["scenario"].channels[col].modified_spends
- # x_modified_total = 0
+ # x_modified_total = 0
# for c in channels_list:
# # st.write(c)
# # st.write(st.session_state["scenario"].channels[c].modified_spends)
# x_modified_total = x_modified_total + st.session_state["scenario"].channels[c].modified_spends.sum()
# st.write(x_modified_total)
-
+
x_total = x_modified.sum()
power = np.ceil(np.log(x_actual.max()) / np.log(10)) - 3
- updated_rcs_key = f"{metrics_selected}#@{panel_selected}#@{channel_name}"
+ updated_rcs_key = (
+ f"{metrics_selected}#@{panel_selected}#@{channel_name}"
+ )
# if updated_rcs and updated_rcs_key in list(updated_rcs.keys()):
# K = updated_rcs[updated_rcs_key]["K"]
@@ -2025,7 +2323,7 @@ if auth_status == True:
# # st.write(roi)
# # st.write(roi[-1])
-
+
# roi_current, marginal_roi_current = roi[-1], marginal_roi[-1]
# x, y, roi, marginal_roi = (
# x[:-1],
@@ -2034,7 +2332,7 @@ if auth_status == True:
# marginal_roi[:-1],
# ) # Drop data for current spends
- # # roi_current =
+ # # roi_current =
# start_value, end_value, left_value, right_value = find_segment_value(
# x,
@@ -2042,7 +2340,7 @@ if auth_status == True:
# marginal_roi,
# )
- #st.write(roi_current)
+ # st.write(roi_current)
# rgba = calculate_rgba(
# start_value,
@@ -2056,23 +2354,48 @@ if auth_status == True:
summary_df = pd.DataFrame(st.session_state["acutual_predicted"])
# (pd.DataFrame(st.session_state["acutual_predicted"])).to_excel("test.xlsx")
# st.dataframe(summary_df)
- summary_df.drop_duplicates(subset="Channel_name", keep="last", inplace=True)
+ summary_df.drop_duplicates(
+ subset="Channel_name", keep="last", inplace=True
+ )
# st.dataframe(summary_df)
-
summary_df_sorted = summary_df.sort_values(by="Delta", ascending=False)
summary_df_sorted["Delta_percent"] = np.round(
- ((summary_df_sorted["Optimized_spend"] / summary_df_sorted["Actual_spend"]) - 1)
+ (
+ (
+ summary_df_sorted["Optimized_spend"]
+ / summary_df_sorted["Actual_spend"]
+ )
+ - 1
+ )
* 100,
2,
)
-
- summary_df_sorted=summary_df_sorted.sort_values(by=['Optimized_spend'],ascending=False)
- 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())
- 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())
-
- a = (summary_df_sorted[summary_df_sorted['Channel_name']== col]).reset_index()['new_efficiency'][0]
- b = (summary_df_sorted[summary_df_sorted['Channel_name']== col]).reset_index()['old_efficiency'][0]
+
+ summary_df_sorted = summary_df_sorted.sort_values(
+ by=["Optimized_spend"], ascending=False
+ )
+ summary_df_sorted["old_efficiency"] = (
+ summary_df_sorted["Old_sales"]
+ / summary_df_sorted["Actual_spend"].sum()
+ ) / (
+ summary_df_sorted["Actual_spend"]
+ / summary_df_sorted["Actual_spend"].sum()
+ )
+ summary_df_sorted["new_efficiency"] = (
+ summary_df_sorted["New_sales"]
+ / summary_df_sorted["Optimized_spend"].sum()
+ ) / (
+ summary_df_sorted["Optimized_spend"]
+ / summary_df_sorted["Optimized_spend"].sum()
+ )
+
+ a = (
+ summary_df_sorted[summary_df_sorted["Channel_name"] == col]
+ ).reset_index()["new_efficiency"][0]
+ b = (
+ summary_df_sorted[summary_df_sorted["Channel_name"] == col]
+ ).reset_index()["old_efficiency"][0]
# st.write(a)
# # print(a)
# # print(summary_df_sorted['Actual_spend'].sum())
@@ -2081,11 +2404,11 @@ if auth_status == True:
# # print(summary_df_sorted['Old_sales'])
# # print(col, "old efficiency ", a)
with bin_placeholder:
- if a> 1:
+ if a > 1.2:
fill_color_box = "#6bbf6b"
- elif a <1:
+ elif a <= 1.2:
fill_color_box = "#ff6868"
- else:
+ else:
fill_color_box = "#ff6868"
st.markdown(
f"""
@@ -2096,7 +2419,7 @@ if auth_status == True:
text-align: center;
color: {'black'};
">
- Simulated Efficiency: {round(a,2)} Actual Efficiency: {round(b,2)}
+ Simulated ROI: {round(a,2)} Actual ROI: {round(b,2)}
""",
@@ -2117,17 +2440,17 @@ if auth_status == True:
summary_df_sorted = summary_df.sort_values(by="Delta", ascending=False)
summary_df_sorted["Delta_percent"] = np.round(
- ((summary_df_sorted["Optimized_spend"] / summary_df_sorted["Actual_spend"]) - 1)
+ (
+ (
+ summary_df_sorted["Optimized_spend"]
+ / summary_df_sorted["Actual_spend"]
+ )
+ - 1
+ )
* 100,
2,
)
-
-
-
-
-
-
with open("summary_df.pkl", "wb") as f:
pickle.dump(summary_df_sorted, f)
# st.dataframe(summary_df_sorted)
@@ -2144,145 +2467,132 @@ if auth_status == True:
scenario_planner_plots()
- with st.expander ("View Forecasted spends"):
- # st.write("Select Time Period")
-
- options = ["Next Month","Next Quarter","Next Year","Custom Time Period"]
-
- # # Create the radio button
- forecast_btn_op = st.radio("Select Time Period", options)
-
-
- # List of 12 months
- months_start = ["January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"]
- years_start = range(2022,2025)
- months_end = ["January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"]
- years_end = range(2022,2025)
-
- if forecast_btn_op == "Custom Time Period":
- col1, col2, col3 = st.columns([1,1,0.75])
-
- with col1:
- from datetime import date
- st.write ("Select Start Time Period")
- sc1,sc2 = st.columns([1,1])
-
- with sc1:
- # Create a dropdown (selectbox) for months
- start_date_mon = st.selectbox("Select Start Month:", months_start)
- with sc2:
- start_date_year = st.selectbox("Select Start Year:", years_start,index=2)
- start_date1 = date(start_date_year, months_start.index(start_date_mon)+1, 1)
- # - relativedelta(years=1)
- # st.write(start_date1)
- # default_Month = "January"
- # start_date_mon = st.text_input("Select Start Month: ",value=default_Month)
-
- # default_Year = 2024
- # start_date_year = st.number_input("Select Start Year: ",value=default_Year)
-
- with col2:
- st.write ("Select End Time Period")
- ec1,ec2 = st.columns([1,1])
- with ec1:
- end_date_mon = st.selectbox("Select End Month:", months_end,index=1)
- with ec2:
- end_date_year = st.selectbox("Select End Year:", years_end,index=2)
- end_date1 = date(end_date_year, months_end.index(end_date_mon)+1, 1)+ relativedelta(months=1) - relativedelta(days=1)
- # - relativedelta(years=1)
- # st.write(end_date1)
- # default_Month = "February"
- # end_date_mon = st.text_input("Select End Month: ",value=default_Month)
-
- # default_Year = 2024
- # end_date_year = st.number_input("Select End Year: ",value=default_Year)
- # end_date1 = st.date_input("Select End Date: ",value=default_date) - relativedelta(years=1)
- elif forecast_btn_op == 'Next Month':
- # current_date = datetime.now()
- # start_date1 = current_date- relativedelta(years=1)
- # end_date1 = current_date + relativedelta(months=1)- relativedelta(years=1)
- start_date1,end_date1 = first_day_of_next_month(datetime.now())
- # start_date1 = start_date1- relativedelta(years=1)
- # end_date1 = end_date1 - relativedelta(years=1)
- elif forecast_btn_op == 'Next Quarter':
- # current_date = datetime.now()
- # start_date1 = current_date- relativedelta(years=1)
- # end_date1 = current_date + relativedelta(months = 3)- relativedelta(years=1)
- start_date1,end_date1 = first_day_of_next_quarter(datetime.now())
- # start_date1 = start_date1- relativedelta(years=1)
- # end_date1 = end_date1 - relativedelta(years=1)
- elif forecast_btn_op == 'Next Year':
- # current_date = datetime.now()
- # start_date1 = current_date- relativedelta(years=1)
- # end_date1 = current_date + relativedelta(months = 12)- relativedelta(years=1)
- start_date1,end_date1 = first_day_of_next_year(datetime.now())
- # start_date1 = start_date1- relativedelta(years=1)
- # end_date1 = end_date1 - relativedelta(years=1)
- if st.button('Generate Forecasts'):
- st.write(f"Forecasted Spends Time Period : {start_date1.strftime('%m-%d-%Y')} to {end_date1.strftime('%m-%d-%Y')}")
- if end_date1 < start_date1 :
- st.error("End date cannot be less than start date")
- forecasted_table_df2 = pd.DataFrame()
- try:
-
- st.write("Forecasted Spends wrt. Channels ")
- output_df1, output_df2 = sf.scenario_spend_forecasting(summary_df_sorted,start_date1- relativedelta(years=1),end_date1- relativedelta(years=1))
- forecasted_table_df = output_df1.copy()
- # forecasted_table_df.iloc[:2] = forecasted_table_df.iloc[:2].applymap(lambda x: "{:,.0f}".format(x))
- # forecasted_table_df.iloc[-1] = forecasted_table_df.iloc[-1].apply(lambda x: "{:.1f}%".format(x))
- st.dataframe(forecasted_table_df)
-
- st.write("Monthly Breakdown Of Forecasted Spends wrt. Channels ")
- # forecasted_table_df2 = output_df2.applymap(lambda x: "{:,.0f}".format(x))
- st.dataframe(output_df2)
-
- st.subheader("Download Report")
- report_name = st.text_input(
- "Report name",
- key="report_input",
- placeholder="Report name",
- label_visibility="collapsed",
- )
- st.download_button(
- "Download Report",
- data = save_report_forecast(output_df1,output_df2),
- file_name = report_name+".xlsx",
- mime="application/vnd.ms-excel",
- # on_click=lambda: save_report_forecast(forecasted_table_df,report_name),
- disabled=len(st.session_state["report_input"]) == 0,#use_container_width=True
- )
-
- except:
- st.warning("Please make sure the base data is updated")
-
-
-
-
-
-
-
-
-
-
-
-
- # filename = st.text_input("Save Report: ",placeholder="Report name")
- # if st.button("Download Report",disabled= (filename != "Report name")):
- # excel_file_path = filename+ '.xlsx'
- # forecasted_table_df.to_excel(excel_file_path, index=False)
- # message_container = st.empty()
+ # with st.expander ("View Forecasted spends"):
+ # # st.write("Select Time Period")
+
+ # options = ["Next Month","Next Quarter","Next Year","Custom Time Period"]
+
+ # # # Create the radio button
+ # forecast_btn_op = st.radio("Select Time Period", options)
+
+ # # List of 12 months
+ # months_start = ["January", "February", "March", "April", "May", "June",
+ # "July", "August", "September", "October", "November", "December"]
+ # years_start = range(2022,2025)
+ # months_end = ["January", "February", "March", "April", "May", "June",
+ # "July", "August", "September", "October", "November", "December"]
+ # years_end = range(2022,2025)
+
+ # if forecast_btn_op == "Custom Time Period":
+ # col1, col2, col3 = st.columns([1,1,0.75])
+
+ # with col1:
+ # from datetime import date
+ # st.write ("Select Start Time Period")
+ # sc1,sc2 = st.columns([1,1])
+
+ # with sc1:
+ # # Create a dropdown (selectbox) for months
+ # start_date_mon = st.selectbox("Select Start Month:", months_start)
+ # with sc2:
+ # start_date_year = st.selectbox("Select Start Year:", years_start,index=2)
+ # start_date1 = date(start_date_year, months_start.index(start_date_mon)+1, 1)
+ # # - relativedelta(years=1)
+ # # st.write(start_date1)
+ # # default_Month = "January"
+ # # start_date_mon = st.text_input("Select Start Month: ",value=default_Month)
+
+ # # default_Year = 2024
+ # # start_date_year = st.number_input("Select Start Year: ",value=default_Year)
+
+ # with col2:
+ # st.write ("Select End Time Period")
+ # ec1,ec2 = st.columns([1,1])
+ # with ec1:
+ # end_date_mon = st.selectbox("Select End Month:", months_end,index=1)
+ # with ec2:
+ # end_date_year = st.selectbox("Select End Year:", years_end,index=2)
+ # end_date1 = date(end_date_year, months_end.index(end_date_mon)+1, 1)+ relativedelta(months=1) - relativedelta(days=1)
+ # # - relativedelta(years=1)
+ # # st.write(end_date1)
+ # # default_Month = "February"
+ # # end_date_mon = st.text_input("Select End Month: ",value=default_Month)
+
+ # # default_Year = 2024
+ # # end_date_year = st.number_input("Select End Year: ",value=default_Year)
+ # # end_date1 = st.date_input("Select End Date: ",value=default_date) - relativedelta(years=1)
+ # elif forecast_btn_op == 'Next Month':
+ # # current_date = datetime.now()
+ # # start_date1 = current_date- relativedelta(years=1)
+ # # end_date1 = current_date + relativedelta(months=1)- relativedelta(years=1)
+ # start_date1,end_date1 = first_day_of_next_month(datetime.now())
+ # # start_date1 = start_date1- relativedelta(years=1)
+ # # end_date1 = end_date1 - relativedelta(years=1)
+ # elif forecast_btn_op == 'Next Quarter':
+ # # current_date = datetime.now()
+ # # start_date1 = current_date- relativedelta(years=1)
+ # # end_date1 = current_date + relativedelta(months = 3)- relativedelta(years=1)
+ # start_date1,end_date1 = first_day_of_next_quarter(datetime.now())
+ # # start_date1 = start_date1- relativedelta(years=1)
+ # # end_date1 = end_date1 - relativedelta(years=1)
+ # elif forecast_btn_op == 'Next Year':
+ # # current_date = datetime.now()
+ # # start_date1 = current_date- relativedelta(years=1)
+ # # end_date1 = current_date + relativedelta(months = 12)- relativedelta(years=1)
+ # start_date1,end_date1 = first_day_of_next_year(datetime.now())
+ # # start_date1 = start_date1- relativedelta(years=1)
+ # # end_date1 = end_date1 - relativedelta(years=1)
+ # if st.button('Generate Forecasts'):
+ # st.write(f"Forecasted Spends Time Period : {start_date1.strftime('%m-%d-%Y')} to {end_date1.strftime('%m-%d-%Y')}")
+ # if end_date1 < start_date1 :
+ # st.error("End date cannot be less than start date")
+ # forecasted_table_df2 = pd.DataFrame()
+ # try:
+
+ # st.write("Forecasted Spends wrt. Channels ")
+ # output_df1, output_df2 = sf.scenario_spend_forecasting(summary_df_sorted,start_date1- relativedelta(years=1),end_date1- relativedelta(years=1))
+ # forecasted_table_df = output_df1.copy()
+ # # forecasted_table_df.iloc[:2] = forecasted_table_df.iloc[:2].applymap(lambda x: "{:,.0f}".format(x))
+ # # forecasted_table_df.iloc[-1] = forecasted_table_df.iloc[-1].apply(lambda x: "{:.1f}%".format(x))
+ # st.dataframe(forecasted_table_df)
+
+ # st.write("Monthly Breakdown Of Forecasted Spends wrt. Channels ")
+ # # forecasted_table_df2 = output_df2.applymap(lambda x: "{:,.0f}".format(x))
+ # st.dataframe(output_df2)
+
+ # st.subheader("Download Report")
+ # report_name = st.text_input(
+ # "Report name",
+ # key="report_input",
+ # placeholder="Report name",
+ # label_visibility="collapsed",
+ # )
+ # st.download_button(
+ # "Download Report",
+ # data = save_report_forecast(output_df1,output_df2),
+ # file_name = report_name+".xlsx",
+ # mime="application/vnd.ms-excel",
+ # # on_click=lambda: save_report_forecast(forecasted_table_df,report_name),
+ # disabled=len(st.session_state["report_input"]) == 0,#use_container_width=True
+ # )
+
+ # except:
+ # st.warning("Please make sure the base data is updated")
+
+ # # filename = st.text_input("Save Report: ",placeholder="Report name")
+ # # if st.button("Download Report",disabled= (filename != "Report name")):
+ # # excel_file_path = filename+ '.xlsx'
+ # # forecasted_table_df.to_excel(excel_file_path, index=False)
+ # # message_container = st.empty()
+
+ # # with message_container:
+ # # st.write(f'{"Report Saved!"}
', unsafe_allow_html=True)
+ # # time.sleep(0.5)
+ # # st.empty()
+
+ # # on_click=lambda: save_scenario(scenario_name),
+ # # disabled=len(st.session_state["scenario_input"]) == 0,#use_container_width=True
-
- # with message_container:
- # st.write(f'{"Report Saved!"}
', unsafe_allow_html=True)
- # time.sleep(0.5)
- # st.empty()
-
- # on_click=lambda: save_scenario(scenario_name),
- # disabled=len(st.session_state["scenario_input"]) == 0,#use_container_width=True
-
_columns = st.columns(2)
# with _columns[0]:
st.subheader("Save Scenario")
@@ -2295,8 +2605,8 @@ if auth_status == True:
st.button(
"Save",
on_click=lambda: save_scenario(scenario_name),
- disabled=len(st.session_state["scenario_input"]) == 0,#use_container_width=True
-
+ disabled=len(st.session_state["scenario_input"])
+ == 0, # use_container_width=True
)
# def prepare_download_func():
@@ -2305,8 +2615,8 @@ if auth_status == True:
# ppt_file = save_ppt_file(summary_df_sorted,fig1,fig2,fig3)
if st.button("Prepare Analysis Download"):
- fig1,fig2,fig3 = scenario_planner_plots2()
- ppt_file = save_ppt_file(summary_df_sorted,fig1,fig2,fig3)
+ fig1, fig2, fig3 = scenario_planner_plots2()
+ ppt_file = save_ppt_file(summary_df_sorted, fig1, fig2, fig3)
# Add a download button
try:
# ppt_file = prepare_download_func()
@@ -2326,30 +2636,24 @@ if auth_status == True:
# file_name="MMM_Model_Quality_Presentation.pptx",
# mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
# )
-
-
-
-
elif auth_status == False:
- st.error("Username/Password is incorrect")
+ st.error("Username/Password is incorrect")
if auth_status != True:
try:
username_forgot_pw, email_forgot_password, random_password = (
- authenticator.forgot_password("Forgot password")
- )
+ authenticator.forgot_password("Forgot password")
+ )
if username_forgot_pw:
- st.session_state["config"]["credentials"]["usernames"][username_forgot_pw][
- "password"
- ] = stauth.Hasher([random_password]).generate()[0]
- send_email(email_forgot_password, random_password)
- st.success("New password sent securely")
- # Random password to be transferred to user securely
+ st.session_state["config"]["credentials"]["usernames"][username_forgot_pw][
+ "password"
+ ] = stauth.Hasher([random_password]).generate()[0]
+ send_email(email_forgot_password, random_password)
+ st.success("New password sent securely")
+ # Random password to be transferred to user securely
elif username_forgot_pw == False:
- st.error("Username not found")
+ st.error("Username not found")
except Exception as e:
st.error(e)
-
-
\ No newline at end of file