bparrino's picture
Update app.py
f661694 verified
import streamlit as st
import json
import time
import random
# Set page config
st.set_page_config(
page_title="Training Content Format Discovery",
page_icon="🎓",
layout="wide",
initial_sidebar_state="collapsed"
)
# Custom CSS
st.markdown("""
<style>
.main .block-container {
padding-top: 2rem;
padding-bottom: 2rem;
max-width: 1000px;
margin: 0 auto;
}
.stApp {
background-color: #f8f9fa;
}
.title-area {
text-align: center;
margin-bottom: 2rem;
}
.custom-subheader {
background-color: #f0f2f6;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
font-weight: 600;
}
.results-container {
border: 1px solid #ddd;
border-radius: 5px;
padding: 20px;
background-color: white;
margin-bottom: 20px;
min-height: 300px;
}
.format-card {
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
background-color: #fafafa;
}
.format-title {
font-size: 1.2rem;
font-weight: 600;
color: #2c3e50;
margin-bottom: 8px;
}
.format-description {
color: #5a6c7d;
margin-bottom: 10px;
}
.format-details {
font-size: 0.9rem;
color: #7f8c8d;
}
.match-score {
background-color: #e8f5e8;
color: #2d6a2d;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.8rem;
font-weight: 600;
float: right;
}
.stButton button {
width: 100%;
}
.footnote {
font-size: 0.8rem;
color: #6c757d;
margin-top: 2rem;
}
.settings-section {
background-color: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.examples-section {
background-color: #e9f7fe;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.placeholder-area {
border: 2px dashed #ddd;
border-radius: 10px;
padding: 40px;
text-align: center;
background-color: #f8f9fa;
color: #666;
}
.consultation-cta {
background-color: #4CAF50;
border: none;
border-radius: 8px;
padding: 15px;
margin: 20px 0;
text-align: center;
color: white;
cursor: pointer;
transition: background-color 0.3s ease;
}
.consultation-cta:hover {
background-color: #45a049;
}
.consultation-cta h4 {
color: white;
margin-bottom: 10px;
}
.section-spacer {
margin: 30px 0;
}
.action-buttons-container {
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #e0e0e0;
}
.roi-metrics {
background-color: #e8f5e8;
padding: 8px;
border-radius: 4px;
margin: 8px 0;
font-size: 0.9rem;
}
.additional-option {
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
background-color: #f9f9f9;
}
.sample-link {
color: #1f77b4;
text-decoration: none;
font-size: 0.9rem;
}
.sample-link:hover {
text-decoration: underline;
}
</style>
""", unsafe_allow_html=True)
# Title and description
st.markdown("""
<div class="title-area">
<h1>Training Content Format Discovery</h1>
<p>Find the perfect training content format for your audience, budget, and goals. Get personalized recommendations in minutes!</p>
</div>
""", unsafe_allow_html=True)
# Initialize session state
if "recommendations" not in st.session_state:
st.session_state["recommendations"] = None
if "analysis_history" not in st.session_state:
st.session_state["analysis_history"] = []
# Training content formats database
TRAINING_FORMATS = {
"video_tutorials": {
"name": "Video Tutorials",
"description": "Engaging visual content with step-by-step demonstrations",
"best_for": ["Visual learners", "Technical skills", "Software training"],
"budget": "Medium",
"production_time": "High",
"engagement": "High",
"scalability": "High",
"interaction": "Low",
"sample_link": "https://youtu.be/HPUWGE9B_UQ?si=a4vr6BL43eMCR9Th",
"roi_metrics": "85% knowledge retention, 60% faster skill acquisition"
},
"powerpoint_presentations": {
"name": "PowerPoint Presentations",
"description": "Slide-based presentations for structured information delivery",
"best_for": ["Information sharing", "Concepts explanation", "Quick updates"],
"budget": "Very Low",
"production_time": "Low",
"engagement": "Low",
"scalability": "High",
"interaction": "Low",
"sample_link": "https://motivace.sharepoint.com/sites/FileStorage/Shared%20Documents/CreativeSP/Other-Clients/NewClient_Samples/PPT_Samples/202312PD-CoreUltra.pdf",
"roi_metrics": "Quick deployment, 70% cost savings vs. live training"
},
"microlearning_modules": {
"name": "Microlearning Modules",
"description": "Bite-sized content focused on specific skills or concepts",
"best_for": ["Busy professionals", "Just-in-time learning", "Skill reinforcement"],
"budget": "Low",
"production_time": "Low",
"engagement": "Medium",
"scalability": "Very High",
"interaction": "Medium",
"sample_link": "http://www.motechhq.com/contentdemos",
"roi_metrics": "40% higher completion rates, 50% less time investment"
},
"elearning_courses": {
"name": "E-Learning Courses",
"description": "Comprehensive online courses with structured learning paths",
"best_for": ["Certification programs", "Comprehensive training", "Self-paced learning"],
"budget": "Medium",
"production_time": "High",
"engagement": "Medium",
"scalability": "Very High",
"interaction": "Medium",
"sample_link": "http://www.motechhq.com/contentdemos",
"roi_metrics": "90% completion rates, 25% faster time-to-competency"
},
"simulation_training": {
"name": "Simulation Training",
"description": "Virtual environments for safe practice of real-world scenarios",
"best_for": ["High-risk training", "Technical skills", "Safety training"],
"budget": "Very High",
"production_time": "Very High",
"engagement": "Very High",
"scalability": "Medium",
"interaction": "Very High",
"roi_metrics": "95% skill transfer, 80% reduction in safety incidents"
},
"gamified_learning": {
"name": "Gamified Learning",
"description": "Game elements integrated into training content for motivation",
"best_for": ["Engagement challenges", "Younger audiences", "Skill practice"],
"budget": "High",
"production_time": "High",
"engagement": "Very High",
"scalability": "High",
"interaction": "High",
"roi_metrics": "3x higher engagement, 65% better knowledge retention"
},
"mobile_learning": {
"name": "Mobile Learning",
"description": "Training content optimized for smartphones and tablets",
"best_for": ["Remote workforce", "Field training", "Accessibility"],
"budget": "Medium",
"production_time": "Medium",
"engagement": "Medium",
"scalability": "Very High",
"interaction": "Medium",
"sample_link": "http://www.motechhq.com/contentdemos",
"roi_metrics": "Mobile access increases completion by 45%"
},
"blended_learning": {
"name": "Blended Learning",
"description": "Combination of online and in-person training methods",
"best_for": ["Comprehensive programs", "Varied learning styles", "Flexibility"],
"budget": "High",
"production_time": "High",
"engagement": "High",
"scalability": "Medium",
"interaction": "High",
"roi_metrics": "Best of both worlds: 80% satisfaction + flexibility"
},
"webinar_series": {
"name": "Webinar Series",
"description": "Live or recorded online presentations with Q&A sessions",
"best_for": ["Expert knowledge sharing", "Large audiences", "Thought leadership"],
"budget": "Low",
"production_time": "Low",
"engagement": "Medium",
"scalability": "Very High",
"interaction": "Medium",
"roi_metrics": "Reach thousands simultaneously, 60% cost reduction"
},
"pdf_guides": {
"name": "PDF Guides & Manuals",
"description": "Downloadable documents with detailed instructions and references",
"best_for": ["Reference materials", "Policy training", "Quick deployment"],
"budget": "Very Low",
"production_time": "Low",
"engagement": "Low",
"scalability": "Very High",
"interaction": "Very Low",
"sample_link": "https://www.motechhq.com/contentdemos/BunzleBrochure_SinglePg_Digital_Abbreviated.pdf",
"roi_metrics": "Instant deployment, 90% cost savings, evergreen content"
}
}
# Scoring algorithm
def calculate_format_scores(audience_type, budget, objectives, goals, timeline, interaction_level, team_size):
scores = {}
for format_id, format_data in TRAINING_FORMATS.items():
score = 0
# Budget matching
budget_map = {"Very Low": 1, "Low": 2, "Medium": 3, "High": 4, "Very High": 5}
user_budget = budget_map.get(budget, 3)
format_budget = budget_map.get(format_data["budget"], 3)
if format_budget <= user_budget:
score += 20
else:
score -= (format_budget - user_budget) * 5
# Timeline matching
timeline_map = {"ASAP (1-2 weeks)": 1, "1 month": 2, "2-3 months": 3, "3+ months": 4}
user_timeline = timeline_map.get(timeline, 3)
production_map = {"Low": 1, "Medium": 2, "High": 3, "Very High": 4}
format_production = production_map.get(format_data["production_time"], 2)
if format_production <= user_timeline:
score += 15
else:
score -= (format_production - user_timeline) * 5
# Team size matching - boost scalable solutions for larger teams
size_map = {"Small team (10-50)": 1, "Medium team (51-200)": 2, "Large team (201-1000)": 3, "Enterprise (1000+)": 4}
user_size = size_map.get(team_size, 2)
scalability_map = {"Low": 1, "Medium": 2, "High": 3, "Very High": 4}
format_scalability = scalability_map.get(format_data["scalability"], 2)
if user_size >= 3 and format_scalability >= 3: # Large teams need scalable solutions
score += 15
elif user_size <= 2 and format_scalability <= 2: # Small teams can use less scalable solutions
score += 10
# Audience type matching
audience_matches = {
"Corporate employees": ["elearning_courses", "webinar_series", "blended_learning", "mobile_learning", "powerpoint_presentations"],
"Technical professionals": ["video_tutorials", "simulation_training", "elearning_courses"],
"Sales teams": ["gamified_learning", "mobile_learning", "powerpoint_presentations", "microlearning_modules"],
"Remote workers": ["mobile_learning", "elearning_courses", "webinar_series", "microlearning_modules"],
"New hires": ["blended_learning", "elearning_courses", "powerpoint_presentations", "video_tutorials"],
"Managers/Leaders": ["webinar_series", "blended_learning", "powerpoint_presentations", "elearning_courses"],
"External customers": ["video_tutorials", "webinar_series", "pdf_guides", "elearning_courses"],
"Field workers": ["mobile_learning", "microlearning_modules", "video_tutorials", "pdf_guides"]
}
if format_id in audience_matches.get(audience_type, []):
score += 25
# Objectives matching
objective_matches = {
"Technical Skills": ["simulation_training", "video_tutorials", "gamified_learning", "elearning_courses"],
"Leadership & Management": ["blended_learning", "webinar_series", "elearning_courses", "simulation_training"],
"Compliance Training": ["elearning_courses", "pdf_guides", "webinar_series", "blended_learning", "powerpoint_presentations"],
"Product Knowledge": ["video_tutorials", "elearning_courses", "webinar_series", "mobile_learning", "powerpoint_presentations"],
"New Employee Onboarding": ["blended_learning", "elearning_courses", "video_tutorials", "powerpoint_presentations"],
"Safety Training": ["simulation_training", "video_tutorials", "elearning_courses", "gamified_learning"],
"Sales Training": ["gamified_learning", "video_tutorials", "mobile_learning", "simulation_training"],
"Professional Certification": ["elearning_courses", "blended_learning", "webinar_series", "pdf_guides"],
"Process Standardization": ["video_tutorials", "elearning_courses", "pdf_guides", "microlearning_modules"],
"Soft Skills Development": ["blended_learning", "webinar_series", "gamified_learning", "elearning_courses"]
}
for objective in objectives:
if format_id in objective_matches.get(objective, []):
score += 15
# Interaction level matching
interaction_map = {"Low": 1, "Medium": 2, "High": 3, "Very High": 4}
user_interaction = interaction_map.get(interaction_level, 2)
format_interaction = interaction_map.get(format_data["interaction"], 2)
if abs(format_interaction - user_interaction) <= 1:
score += 10
# Goals matching
goal_matches = {
"Cost Effectiveness": ["microlearning_modules", "pdf_guides", "webinar_series", "elearning_courses", "powerpoint_presentations"],
"High Engagement": ["gamified_learning", "simulation_training", "video_tutorials", "mobile_learning"],
"Scalability": ["elearning_courses", "mobile_learning", "webinar_series", "microlearning_modules"],
"Quick Deployment": ["microlearning_modules", "pdf_guides", "webinar_series", "mobile_learning", "powerpoint_presentations"],
"Knowledge Retention": ["gamified_learning", "simulation_training", "microlearning_modules", "video_tutorials"],
"Measurable Results": ["elearning_courses", "gamified_learning", "simulation_training", "blended_learning"]
}
for goal in goals:
if format_id in goal_matches.get(goal, []):
score += 10
scores[format_id] = max(0, min(100, score))
return scores
# Main content
col1, col2 = st.columns([1, 1])
with col1:
st.markdown('<div class="custom-subheader">Tell Us About Your Training Needs</div>', unsafe_allow_html=True)
# Audience Type
audience_type = st.selectbox(
"Who is your target audience?",
[
"Corporate employees",
"Technical professionals",
"Sales teams",
"Remote workers",
"New hires",
"Managers/Leaders",
"External customers",
"Field workers"
],
help="Consider their learning preferences and work environment"
)
# Budget
budget = st.select_slider(
"What's your budget range?",
options=["Very Low", "Low", "Medium", "High", "Very High"],
value="Medium",
help="Consider development, production, and deployment costs"
)
# Team Size
team_size = st.selectbox(
"How many learners will this reach?",
[
"Small team (10-50)",
"Medium team (51-200)",
"Large team (201-1000)",
"Enterprise (1000+)"
],
index=1,
help="This helps us recommend formats that scale appropriately"
)
# Timeline
timeline = st.selectbox(
"When do you need this deployed?",
[
"ASAP (1-2 weeks)",
"1 month",
"2-3 months",
"3+ months"
],
index=1,
help="How quickly do you need the training content ready?"
)
st.markdown('<div class="section-spacer"></div>', unsafe_allow_html=True)
# Simplified Objectives
objectives = st.multiselect(
"What type of training do you need? (Select all that apply)",
[
"Technical Skills",
"Leadership & Management",
"Compliance Training",
"Product Knowledge",
"New Employee Onboarding",
"Safety Training",
"Sales Training",
"Professional Certification",
"Process Standardization",
"Soft Skills Development"
],
help="What specific areas do you need to train on?"
)
# Simplified Goals
goals = st.multiselect(
"What's most important to you? (Select your top priorities)",
[
"Cost Effectiveness",
"High Engagement",
"Scalability",
"Quick Deployment",
"Knowledge Retention",
"Measurable Results"
],
help="What matters most for your training success?"
)
# Interaction Level
interaction_level = st.select_slider(
"How much interaction do you want?",
options=["Low", "Medium", "High", "Very High"],
value="Medium",
help="Level of learner interaction and engagement"
)
# Additional Context
additional_context = st.text_area(
"Any additional requirements?",
placeholder="e.g., Must work on mobile devices, need multilingual support, integration with LMS required...",
height=60,
help="Tell us about any special requirements"
)
st.markdown('<div class="section-spacer"></div>', unsafe_allow_html=True)
# Generate recommendations button
generate_button = st.button(
"Get My Recommendations",
disabled=not objectives or not goals,
use_container_width=True,
type="primary"
)
if not objectives:
st.info("Please select at least one training type")
elif not goals:
st.info("Please select at least one priority")
# Display recommendations
with col2:
st.markdown('<div class="custom-subheader">Your Personalized Recommendations</div>', unsafe_allow_html=True)
# Always show the results container
st.markdown('<div class="results-container">', unsafe_allow_html=True)
if generate_button and objectives and goals:
with st.spinner("Analyzing your requirements..."):
# Simulate processing time
time.sleep(1.5)
# Calculate scores
scores = calculate_format_scores(
audience_type, budget, objectives, goals, timeline, interaction_level, team_size
)
# Sort by score
sorted_formats = sorted(scores.items(), key=lambda x: x[1], reverse=True)
# Store recommendations
st.session_state["recommendations"] = {
"formats": sorted_formats,
"params": {
"audience": audience_type,
"budget": budget,
"timeline": timeline,
"objectives": objectives,
"goals": goals,
"interaction": interaction_level,
"team_size": team_size,
"context": additional_context
}
}
st.success("Analysis complete! Here are your recommendations:")
# Check if we have recommendations to display
if st.session_state["recommendations"] is not None:
recommendations = st.session_state["recommendations"]
# Personalized headline
st.markdown(f'<h3 style="color: #2c3e50; margin-bottom: 20px;">Recommended for {recommendations["params"]["audience"].lower()}:</h3>', unsafe_allow_html=True)
# Show top 3 recommendations
for i, (format_id, score) in enumerate(recommendations["formats"][:3]):
format_data = TRAINING_FORMATS[format_id]
st.markdown('<div class="format-card">', unsafe_allow_html=True)
st.markdown(f'<div class="format-title">{format_data["name"]} <span class="match-score">{score}% Match</span></div>', unsafe_allow_html=True)
st.markdown(f'<div class="format-description">{format_data["description"]}</div>', unsafe_allow_html=True)
# Add sample link if available
if "sample_link" in format_data:
st.markdown(f'<a href="{format_data["sample_link"]}" target="_blank" class="sample-link">🔗 View Sample</a>', unsafe_allow_html=True)
st.markdown("<br>", unsafe_allow_html=True)
# Show ROI metrics
if "roi_metrics" in format_data:
st.markdown(f'<div class="roi-metrics"><strong>Expected Results:</strong> {format_data["roi_metrics"]}</div>', unsafe_allow_html=True)
# Show key details
st.markdown(f"""
<div class="format-details">
<strong>Best for:</strong> {', '.join(format_data['best_for'])}<br>
<strong>Budget:</strong> {format_data['budget']} |
<strong>Production Time:</strong> {format_data['production_time']} |
<strong>Engagement:</strong> {format_data['engagement']}
</div>
""", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
# Expandable "View More Options" section
with st.expander("View More Options", expanded=False):
if len(recommendations["formats"]) > 3:
st.markdown("**Additional Recommendations:**")
for i, (format_id, score) in enumerate(recommendations["formats"][3:5], 4):
format_data = TRAINING_FORMATS[format_id]
st.markdown('<div class="additional-option">', unsafe_allow_html=True)
st.markdown(f'**{format_data["name"]}** ({score}% Match)')
st.markdown(f'{format_data["description"]}')
if "sample_link" in format_data:
st.markdown(f'<a href="{format_data["sample_link"]}" target="_blank" class="sample-link">🔗 View Sample</a>', unsafe_allow_html=True)
if "roi_metrics" in format_data:
st.markdown(f'<div style="font-size: 0.85rem; color: #666; margin-top: 5px;"><strong>Expected Results:</strong> {format_data["roi_metrics"]}</div>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
else:
st.markdown("*All relevant options are shown above.*")
# Grouped Action Buttons
st.markdown('<div class="action-buttons-container">', unsafe_allow_html=True)
st.markdown("**Take Action:**", unsafe_allow_html=True)
col_b1, col_b2 = st.columns(2)
with col_b1:
# Get proposal button for top recommendation
top_format = TRAINING_FORMATS[recommendations["formats"][0][0]]
if st.button(f"Get Custom Proposal for {top_format['name']}", use_container_width=True, type="primary"):
st.balloons()
st.success("Excellent choice! Our learning design experts will be in touch within 24 hours.")
with col_b2:
# Fixed consultation button using st.link_button
st.link_button(
"Schedule Free Consultation",
"https://www.motechhq.com/connect/",
use_container_width=True
)
# New analysis button (full width, secondary action)
st.markdown('<div style="margin-top: 10px;">', unsafe_allow_html=True)
if st.button("Start New Analysis", use_container_width=True):
st.session_state["recommendations"] = None
st.rerun()
st.markdown('</div>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
else:
# Show placeholder INSIDE the results container
st.markdown('''
<div class="placeholder-area">
<h3>🎯 Your Recommendations Will Appear Here</h3>
<p>Complete the form and click "Get My Recommendations" to see your personalized training format suggestions.</p>
</div>
''', unsafe_allow_html=True)
# Close the results container
st.markdown('</div>', unsafe_allow_html=True)
# Consultation CTA outside the results container - only show when no recommendations
if st.session_state["recommendations"] is None:
st.markdown('<div class="section-spacer"></div>', unsafe_allow_html=True)
st.link_button(
"Want Expert Guidance? Schedule a Free Consultation",
"https://www.motechhq.com/connect/",
use_container_width=True,
type="secondary"
)
# Footer
st.markdown('<div class="footnote">', unsafe_allow_html=True)
st.markdown('*This tool uses advanced algorithms to match your requirements with optimal training formats based on industry best practices.*')
st.markdown('</div>', unsafe_allow_html=True)