|
def render_decision_simulator(startup_data): |
|
""" |
|
Render the AI-powered decision simulator page. |
|
|
|
This feature helps startup founders test the financial impact of business |
|
decisions before implementing them, using AI to analyze risks and benefits. |
|
""" |
|
st.markdown("<h1 class='main-header'>Decision Simulator</h1>", unsafe_allow_html=True) |
|
st.markdown("<p class='sub-header'>AI-powered analysis of business decisions</p>", unsafe_allow_html=True) |
|
|
|
|
|
with st.expander("ℹ️ How AI enhances your decision-making"): |
|
st.markdown(""" |
|
### How AI Powers Your Decision Simulator |
|
|
|
The decision simulator uses AI to help you make better strategic decisions: |
|
|
|
- **Scenario Analysis**: Our AI model simulates multiple financial scenarios based on your input variables |
|
- **Risk Assessment**: The system automatically evaluates risk levels based on your cash runway and growth metrics |
|
- **Return Prediction**: AI algorithms predict potential returns on investments like hiring or marketing |
|
- **Opportunity Cost Analysis**: The model compares different allocations of capital to maximize growth |
|
- **Personalized Recommendations**: Based on your specific situation, the AI provides tailored alternatives |
|
|
|
This helps founders make data-driven decisions with less guesswork, avoid costly mistakes, and optimize resource allocation. |
|
""") |
|
|
|
st.write("Test the financial impact of key business decisions before implementing them. Our AI advisor will analyze the risks and benefits.") |
|
|
|
|
|
st.subheader("Common Scenarios") |
|
|
|
decision_templates = { |
|
"Hiring Engineering Team": { |
|
"description": "Evaluate the impact of growing your engineering team", |
|
"new_hires": 3, |
|
"new_marketing": 0, |
|
"other_expenses": 2000, |
|
"growth_impact": 0.02, |
|
"question": "We're considering hiring 3 more engineers to accelerate product development. How will this affect our runway and what growth impact should we expect to justify this investment?" |
|
}, |
|
"Marketing Expansion": { |
|
"description": "Test increasing your marketing budget", |
|
"new_hires": 0, |
|
"new_marketing": 15000, |
|
"other_expenses": 0, |
|
"growth_impact": 0.04, |
|
"question": "We want to increase our marketing spend by $15K/month to drive growth. What growth rate would we need to achieve to make this financially viable?" |
|
}, |
|
"Office Expansion": { |
|
"description": "Analyze the cost of moving to a larger office", |
|
"new_hires": 0, |
|
"new_marketing": 0, |
|
"other_expenses": 8000, |
|
"growth_impact": 0.01, |
|
"question": "We're considering moving to a larger office space that would add $8K/month to our expenses. Is this justified at our current stage?" |
|
}, |
|
"Custom Scenario": { |
|
"description": "Create your own custom scenario", |
|
"new_hires": 0, |
|
"new_marketing": 0, |
|
"other_expenses": 0, |
|
"growth_impact": 0.0, |
|
"question": "" |
|
} |
|
} |
|
|
|
|
|
template_cols = st.columns(4) |
|
selected_template = None |
|
|
|
for i, (template_name, template) in enumerate(decision_templates.items()): |
|
with template_cols[i]: |
|
if st.button(f"{template_name}\n{template['description']}", key=f"template_{i}"): |
|
selected_template = template_name |
|
|
|
|
|
if selected_template and selected_template != "Custom Scenario": |
|
new_hires = decision_templates[selected_template]["new_hires"] |
|
new_marketing = decision_templates[selected_template]["new_marketing"] |
|
other_expenses = decision_templates[selected_template]["other_expenses"] |
|
growth_impact = decision_templates[selected_template]["growth_impact"] |
|
question = decision_templates[selected_template]["question"] |
|
else: |
|
new_hires = 0 |
|
new_marketing = 0 |
|
other_expenses = 0 |
|
growth_impact = 0.0 |
|
question = "" |
|
|
|
|
|
with st.form("decision_form"): |
|
st.subheader("Scenario Parameters") |
|
|
|
col1, col2 = st.columns(2) |
|
|
|
with col1: |
|
new_hires = st.number_input("New Engineering Hires", min_value=0, max_value=10, value=new_hires, |
|
help=f"Each engineer costs ${ENGINEER_SALARY:,} per month") |
|
st.caption(f"Monthly Cost: ${new_hires * ENGINEER_SALARY:,}") |
|
|
|
new_marketing = st.number_input("Additional Monthly Marketing Budget", |
|
min_value=0, max_value=50000, value=new_marketing, step=1000, |
|
help="Additional marketing spend per month") |
|
|
|
with col2: |
|
other_expenses = st.number_input("Other Additional Monthly Expenses", |
|
min_value=0, max_value=50000, value=other_expenses, step=1000, |
|
help="Any other additional monthly expenses") |
|
|
|
growth_impact = st.slider("Estimated Impact on Monthly Growth Rate", |
|
min_value=0.0, max_value=0.10, value=growth_impact, step=0.01, |
|
format="%.2f", |
|
help="Estimated increase in monthly growth rate due to these investments") |
|
st.caption(f"New Growth Rate: {(startup_data['growth_rate'] + growth_impact) * 100:.1f}% (current: {startup_data['growth_rate'] * 100:.1f}%)") |
|
|
|
question = st.text_area("Describe your decision scenario", |
|
value=question, |
|
height=100, |
|
placeholder="E.g., We're considering hiring two more engineers and increasing our marketing budget...") |
|
|
|
decision_summary = f""" |
|
- {new_hires} new engineers: ${new_hires * ENGINEER_SALARY:,}/month |
|
- Marketing increase: ${new_marketing:,}/month |
|
- Other expenses: ${other_expenses:,}/month |
|
- Total additional burn: ${new_hires * ENGINEER_SALARY + new_marketing + other_expenses:,}/month |
|
- Growth impact: +{growth_impact * 100:.1f}% monthly growth |
|
""" |
|
|
|
st.markdown(f"**Decision Summary:**\n{decision_summary}") |
|
|
|
submitted = st.form_submit_button("Simulate Decision") |
|
|
|
if submitted: |
|
|
|
current_runway, new_runway, current_df, new_df = simulate_decision( |
|
startup_data['cash'], |
|
startup_data['burn_rate'], |
|
startup_data['revenue'], |
|
startup_data['growth_rate'], |
|
other_expenses, |
|
new_hires, |
|
new_marketing, |
|
growth_impact |
|
) |
|
|
|
|
|
st.markdown("<h3>Decision Impact Analysis</h3>", unsafe_allow_html=True) |
|
|
|
|
|
col1, col2, col3 = st.columns(3) |
|
|
|
with col1: |
|
st.metric("Current Runway", f"{current_runway} months") |
|
with col2: |
|
runway_change = new_runway - current_runway |
|
st.metric("New Runway", f"{new_runway} months", |
|
delta=f"{runway_change} months", |
|
delta_color="off" if runway_change == 0 else ("normal" if runway_change > 0 else "inverse")) |
|
with col3: |
|
new_burn = startup_data['burn_rate'] + other_expenses + (new_hires * ENGINEER_SALARY) + new_marketing |
|
burn_change = new_burn - startup_data['burn_rate'] |
|
burn_percentage = burn_change / startup_data['burn_rate'] * 100 |
|
st.metric("New Monthly Burn", f"${new_burn:,}", |
|
delta=f"${burn_change:,} ({burn_percentage:.1f}%)", |
|
delta_color="inverse") |
|
|
|
|
|
st.subheader("Cash Projection Comparison") |
|
|
|
|
|
current_df['Scenario'] = 'Current' |
|
new_df['Scenario'] = 'After Decision' |
|
|
|
combined_df = pd.concat([current_df, new_df]) |
|
combined_df = combined_df.reset_index() |
|
combined_df = combined_df.rename(columns={'index': 'Date'}) |
|
|
|
|
|
fig = px.line(combined_df, x='Date', y='Cumulative_Cash', color='Scenario', |
|
title="Cash Runway Comparison", |
|
labels={'Cumulative_Cash': 'Remaining Cash'}, |
|
color_discrete_sequence=['#4c78a8', '#f58518']) |
|
|
|
fig.add_hline(y=0, line_dash="dash", line_color="red", annotation_text="Out of Cash") |
|
|
|
fig.update_layout( |
|
height=400, |
|
plot_bgcolor='rgba(240,247,255,0.8)', |
|
xaxis_title="Date", |
|
yaxis_title="Cash Balance ($)", |
|
font=dict(family="Arial, sans-serif", size=12), |
|
margin=dict(l=20, r=20, t=40, b=20), |
|
) |
|
|
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
|
|
if question: |
|
decision_params = { |
|
"new_hires": new_hires, |
|
"new_marketing": new_marketing, |
|
"other_expenses": other_expenses, |
|
"growth_impact": growth_impact |
|
} |
|
|
|
analysis = get_decision_analysis(question, startup_data, decision_params) |
|
|
|
st.markdown("<div class='advisor-card'>", unsafe_allow_html=True) |
|
st.markdown("<span class='ai-badge'>AI Decision Analysis</span>", unsafe_allow_html=True) |
|
st.markdown(f"<p class='advice-text'>{analysis}</p>", unsafe_allow_html=True) |
|
st.markdown("</div>", unsafe_allow_html=True) |
|
|
|
|
|
st.subheader("Component Impact Analysis") |
|
|
|
|
|
_, hiring_runway, _, _ = simulate_decision( |
|
startup_data['cash'], |
|
startup_data['burn_rate'], |
|
startup_data['revenue'], |
|
startup_data['growth_rate'], |
|
0, |
|
new_hires, |
|
0, |
|
0 |
|
) |
|
|
|
_, marketing_runway, _, _ = simulate_decision( |
|
startup_data['cash'], |
|
startup_data['burn_rate'], |
|
startup_data['revenue'], |
|
startup_data['growth_rate'], |
|
0, |
|
0, |
|
new_marketing, |
|
growth_impact |
|
) |
|
|
|
_, expenses_runway, _, _ = simulate_decision( |
|
startup_data['cash'], |
|
startup_data['burn_rate'], |
|
startup_data['revenue'], |
|
startup_data['growth_rate'], |
|
other_expenses, |
|
0, |
|
0, |
|
0 |
|
) |
|
|
|
component_data = { |
|
"Component": ["Engineering Hires", "Marketing Increase", "Other Expenses", "Combined Impact"], |
|
"Runway Impact (months)": [ |
|
hiring_runway - current_runway, |
|
marketing_runway - current_runway, |
|
expenses_runway - current_runway, |
|
new_runway - current_runway |
|
] |
|
} |
|
|
|
component_df = pd.DataFrame(component_data) |
|
|
|
fig = px.bar(component_df, x='Component', y='Runway Impact (months)', |
|
title="Impact of Each Component on Runway", |
|
color='Runway Impact (months)', |
|
color_continuous_scale=['#dc3545', '#ffc107', '#28a745'], |
|
text='Runway Impact (months)') |
|
|
|
fig.update_layout( |
|
height=400, |
|
plot_bgcolor='rgba(240,247,255,0.8)', |
|
font=dict(family="Arial, sans-serif", size=12), |
|
margin=dict(l=20, r=20, t=40, b=20), |
|
) |
|
|
|
fig.update_traces(texttemplate='%{text:.1f}', textposition='outside') |
|
st.plotly_chart(fig, use_container_width=True) |
|
|
|
|
|
risk_level = "High" if new_runway < 3 else ("Medium" if new_runway < 6 else "Low") |
|
risk_color = "danger-metric" if risk_level == "High" else ("warning-metric" if risk_level == "Medium" else "good-metric") |
|
|
|
st.markdown(f""" |
|
<div class='metric-card'> |
|
<p class='metric-label'>Risk Assessment</p> |
|
<p class='metric-value {risk_color}'>{risk_level} Risk Decision</p> |
|
<p>This decision would give you {new_runway} months of runway.</p> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.info("💡 **Want personalized guidance on this decision?** [Book a session](#book-a-session) with our AI financial advisor for detailed analysis.") |
|
|
|
def get_decision_analysis(question, financial_data, decision_params): |
|
"""Get AI analysis for a specific business decision.""" |
|
prompt = f""" |
|
You are a financial advisor for startups. A founder asks: |
|
"{question}" |
|
|
|
Here's their current financial situation: |
|
- Current cash: ${financial_data['cash']} |
|
- Monthly burn rate: ${financial_data['burn_rate']} |
|
- Monthly revenue: ${financial_data['revenue']} |
|
- Monthly growth rate: {financial_data['growth_rate'] * 100}% |
|
|
|
They're considering these changes: |
|
- Adding {decision_params['new_hires']} new engineers (${ENGINEER_SALARY}/month each) |
|
- Increasing marketing budget by ${decision_params['new_marketing']}/month |
|
- Adding ${decision_params['other_expenses']}/month in other expenses |
|
- Expecting {decision_params['growth_impact'] * 100}% additional monthly growth |
|
|
|
Analyze this decision thoroughly: |
|
1. Quantify the impact on runway (exact calculation) |
|
2. Assess the risk level (low, medium, high) |
|
3. Compare the ROI potential |
|
4. Provide 3 specific recommendations or alternatives |
|
5. Suggest timeline and milestones for implementation if approved |
|
|
|
Be direct and specific with numbers and timeframes. |
|
""" |
|
|
|
return generate_ai_response(prompt) |