Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| Oklahoma Damage Assessment System with Comprehensive Sentiment Analysis | |
| Optimized for Hugging Face Spaces deployment | |
| """ | |
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| from datetime import datetime, timedelta | |
| import random | |
| import json | |
| from typing import Dict, List, Tuple, Optional | |
| import time | |
| import os | |
| # Hugging Face optimization | |
| os.environ['STREAMLIT_BROWSER_GATHER_USAGE_STATS'] = 'false' | |
| # Page configuration - MUST be first Streamlit command | |
| st.set_page_config( | |
| page_title="πͺοΈ Oklahoma Damage Assessment", | |
| page_icon="β οΈ", | |
| layout="wide", | |
| initial_sidebar_state="expanded", | |
| menu_items={ | |
| 'Get Help': 'https://github.com/your-repo/oklahoma-damage-assessment', | |
| 'Report a bug': 'https://github.com/your-repo/oklahoma-damage-assessment/issues', | |
| 'About': "# Oklahoma Damage Assessment System\nComprehensive disaster impact analysis with sentiment analysis!" | |
| } | |
| ) | |
| # Enhanced CSS for better Hugging Face compatibility | |
| def load_css(): | |
| st.markdown(""" | |
| <style> | |
| .main-header { | |
| background: linear-gradient(135deg, #ff7b7b 0%, #d4526e 100%); | |
| color: white; | |
| padding: 2rem; | |
| border-radius: 15px; | |
| text-align: center; | |
| margin-bottom: 2rem; | |
| box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37); | |
| } | |
| .sentiment-card { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| padding: 1.5rem; | |
| border-radius: 15px; | |
| margin: 1rem 0; | |
| box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37); | |
| } | |
| .metric-box { | |
| background: rgba(255, 255, 255, 0.9); | |
| border: 1px solid #dee2e6; | |
| padding: 1rem; | |
| border-radius: 10px; | |
| text-align: center; | |
| margin: 0.5rem 0; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| .damage-alert { | |
| background: linear-gradient(135deg, #ff9a56 0%, #ff6b35 100%); | |
| border-left: 4px solid #ff4500; | |
| padding: 1.5rem; | |
| margin: 1rem 0; | |
| border-radius: 10px; | |
| color: white; | |
| box-shadow: 0 4px 15px rgba(255, 107, 53, 0.4); | |
| } | |
| .psychological-panel { | |
| background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); | |
| padding: 2rem; | |
| border-radius: 15px; | |
| margin: 1rem 0; | |
| border: 1px solid rgba(255, 255, 255, 0.3); | |
| } | |
| .stMetric { | |
| background: white; | |
| padding: 1rem; | |
| border-radius: 10px; | |
| border: 1px solid #e0e0e0; | |
| } | |
| /* Fix for Hugging Face iframe */ | |
| .main .block-container { | |
| padding-top: 1rem; | |
| padding-bottom: 1rem; | |
| } | |
| /* Responsive design */ | |
| @media (max-width: 768px) { | |
| .main-header h1 { font-size: 1.5rem; } | |
| .sentiment-card { padding: 1rem; } | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Data Management with Closures (Simplified for HF) | |
| def get_location_data(): | |
| """Get Oklahoma location data with closure pattern""" | |
| counties = [ | |
| 'Oklahoma', 'Tulsa', 'Cleveland', 'Canadian', 'Comanche', 'Garfield', | |
| 'Rogers', 'Washington', 'Pottawatomie', 'Creek', 'Kay', 'Carter', | |
| 'Payne', 'McClain', 'Grady', 'Stephens', 'Pontotoc', 'Lincoln' | |
| ] | |
| cities = [ | |
| 'Oklahoma City', 'Tulsa', 'Norman', 'Lawton', 'Edmond', 'Moore', | |
| 'Midwest City', 'Enid', 'Stillwater', 'Muskogee', 'Bartlesville', | |
| 'Owasso', 'Shawnee', 'Yukon', 'Ardmore', 'Ponca City' | |
| ] | |
| return { | |
| 'counties': counties, | |
| 'cities': cities | |
| } | |
| def get_sentiment_lexicon(): | |
| """Get emotional lexicon for sentiment analysis""" | |
| return { | |
| 'devastating': {'sentiment': -0.95, 'emotion': 'despair', 'intensity': 'extreme'}, | |
| 'catastrophic': {'sentiment': -0.90, 'emotion': 'terror', 'intensity': 'extreme'}, | |
| 'destroyed': {'sentiment': -0.85, 'emotion': 'grief', 'intensity': 'high'}, | |
| 'damaged': {'sentiment': -0.65, 'emotion': 'distress', 'intensity': 'moderate'}, | |
| 'threatened': {'sentiment': -0.60, 'emotion': 'anxiety', 'intensity': 'moderate'}, | |
| 'displaced': {'sentiment': -0.75, 'emotion': 'fear', 'intensity': 'high'}, | |
| 'injured': {'sentiment': -0.80, 'emotion': 'pain', 'intensity': 'high'}, | |
| 'affected': {'sentiment': -0.45, 'emotion': 'concern', 'intensity': 'moderate'}, | |
| 'recovering': {'sentiment': 0.50, 'emotion': 'hope', 'intensity': 'moderate'}, | |
| 'resilient': {'sentiment': 0.70, 'emotion': 'strength', 'intensity': 'high'}, | |
| 'helping': {'sentiment': 0.60, 'emotion': 'compassion', 'intensity': 'moderate'}, | |
| 'support': {'sentiment': 0.55, 'emotion': 'comfort', 'intensity': 'moderate'} | |
| } | |
| def analyze_sentiment(text): | |
| """Simplified sentiment analysis""" | |
| lexicon = get_sentiment_lexicon() | |
| words = text.lower().split() | |
| sentiments = [] | |
| emotions = {} | |
| for word in words: | |
| clean_word = ''.join(c for c in word if c.isalnum()) | |
| if clean_word in lexicon: | |
| data = lexicon[clean_word] | |
| sentiments.append(data['sentiment']) | |
| emotions[data['emotion']] = emotions.get(data['emotion'], 0) + 1 | |
| avg_sentiment = np.mean(sentiments) if sentiments else 0.0 | |
| dominant_emotion = max(emotions.items(), key=lambda x: x[1])[0] if emotions else 'neutral' | |
| # Classification | |
| if avg_sentiment <= -0.6: | |
| classification = 'highly_negative' | |
| elif avg_sentiment <= -0.3: | |
| classification = 'negative' | |
| elif avg_sentiment <= 0.3: | |
| classification = 'neutral' | |
| else: | |
| classification = 'positive' | |
| return { | |
| 'sentiment_score': avg_sentiment, | |
| 'classification': classification, | |
| 'dominant_emotion': dominant_emotion, | |
| 'emotion_distribution': emotions | |
| } | |
| def generate_damage_data(location): | |
| """Generate comprehensive damage data""" | |
| damage_types = [ | |
| {'id': 'drought', 'name': 'Drought', 'color': '#ff8c00', 'icon': 'π΅'}, | |
| {'id': 'flood', 'name': 'Flood', 'color': '#1e90ff', 'icon': 'π'}, | |
| {'id': 'tornado', 'name': 'Tornado', 'color': '#dc143c', 'icon': 'πͺοΈ'}, | |
| {'id': 'wildfire', 'name': 'Wildfire', 'color': '#ff4500', 'icon': 'π₯'}, | |
| {'id': 'hail', 'name': 'Hail Storm', 'color': '#87ceeb', 'icon': 'π§οΈ'}, | |
| {'id': 'wind', 'name': 'High Winds', 'color': '#a9a9a9', 'icon': 'π¨'} | |
| ] | |
| severity_levels = [ | |
| {'id': 1, 'name': 'Minimal', 'color': '#fff3cd'}, | |
| {'id': 2, 'name': 'Minor', 'color': '#ffeeba'}, | |
| {'id': 3, 'name': 'Moderate', 'color': '#ffdf7e'}, | |
| {'id': 4, 'name': 'Severe', 'color': '#ffcc00'}, | |
| {'id': 5, 'name': 'Extreme', 'color': '#ff8c00'} | |
| ] | |
| damage_type = random.choice(damage_types) | |
| severity = random.choice(severity_levels) | |
| impact_templates = { | |
| 'drought': "Agricultural operations in {location} are experiencing {severity_adj} stress, causing {emotion} in farming communities", | |
| 'flood': "Flash flooding in {location} has {severity_adj} damaged infrastructure, creating {emotion} among residents", | |
| 'tornado': "Tornado touchdown in {location} has {severity_adj} damaged structures, leaving survivors with {emotion}", | |
| 'wildfire': "Wildfire near {location} has {severity_adj} threatened areas, forcing evacuations and causing {emotion}", | |
| 'hail': "Severe hail storm in {location} has {severity_adj} damaged property, creating {emotion} among homeowners", | |
| 'wind': "High winds in {location} have {severity_adj} damaged infrastructure, causing {emotion} in the community" | |
| } | |
| severity_adjectives = { | |
| 1: 'slightly', 2: 'moderately', 3: 'significantly', 4: 'severely', 5: 'catastrophically' | |
| } | |
| emotions = { | |
| 1: 'mild concern', 2: 'growing anxiety', 3: 'widespread distress', | |
| 4: 'severe trauma', 5: 'overwhelming devastation' | |
| } | |
| impact_text = impact_templates[damage_type['id']].format( | |
| location=location, | |
| severity_adj=severity_adjectives[severity['id']], | |
| emotion=emotions[severity['id']] | |
| ) | |
| base_multiplier = severity['id'] | |
| population_factor = 1.5 if 'City' in location else 1.0 | |
| assessments = { | |
| 'people': { | |
| 'injured': int(random.randint(0, 20) * base_multiplier), | |
| 'displaced': int(random.randint(0, 100) * base_multiplier), | |
| 'affected': int(random.randint(100, 1000) * base_multiplier * population_factor), | |
| 'psychologicalCasualties': int(random.randint(50, 300) * base_multiplier), | |
| 'communityMorale': max(20, 100 - (base_multiplier * random.randint(15, 25))) | |
| }, | |
| 'property': { | |
| 'homes_damaged': int(random.randint(0, 100) * base_multiplier), | |
| 'businesses_affected': int(random.randint(0, 25) * base_multiplier), | |
| 'estimated_cost': int(random.randint(100000, 5000000) * base_multiplier) | |
| }, | |
| 'infrastructure': { | |
| 'roads_damaged_miles': round(random.uniform(1, 30) * base_multiplier, 1), | |
| 'power_outages': int(random.randint(500, 10000) * base_multiplier), | |
| 'water_systems_affected': int(random.randint(0, 10) * base_multiplier) | |
| }, | |
| 'agriculture': { | |
| 'crop_loss_acres': int(random.randint(500, 10000) * base_multiplier), | |
| 'livestock_loss': int(random.randint(0, 200) * base_multiplier), | |
| 'estimated_cost': int(random.randint(100000, 2000000) * base_multiplier) | |
| } | |
| } | |
| return { | |
| 'location': location, | |
| 'damageType': damage_type, | |
| 'severity': severity, | |
| 'impact': impact_text, | |
| 'assessments': assessments, | |
| 'timestamp': datetime.now().isoformat() | |
| } | |
| def calculate_psychological_impact(assessments): | |
| """Calculate psychological impact score""" | |
| people_impact = min(1.0, ( | |
| assessments['people']['injured'] * 0.1 + | |
| assessments['people']['displaced'] * 0.05 + | |
| assessments['people']['affected'] * 0.0005 | |
| )) | |
| property_impact = min(1.0, assessments['property']['homes_damaged'] * 0.01) | |
| economic_impact = min(1.0, assessments['property']['estimated_cost'] / 10000000) | |
| total_impact = (people_impact * 0.5 + property_impact * 0.3 + economic_impact * 0.2) | |
| if total_impact < 0.25: | |
| level = 'minimal' | |
| elif total_impact < 0.5: | |
| level = 'moderate' | |
| elif total_impact < 0.75: | |
| level = 'severe' | |
| else: | |
| level = 'critical' | |
| return { | |
| 'total_score': total_impact, | |
| 'level': level, | |
| 'components': { | |
| 'people_impact': people_impact, | |
| 'property_impact': property_impact, | |
| 'economic_impact': economic_impact | |
| } | |
| } | |
| def assess_trauma_risk(assessments): | |
| """Assess trauma risk indicators""" | |
| indicators = { | |
| 'direct_victimization': assessments['people']['injured'] > 0, | |
| 'home_destruction': assessments['property']['homes_damaged'] > 0, | |
| 'economic_devastation': assessments['property']['estimated_cost'] > 1000000, | |
| 'social_disruption': assessments['people']['displaced'] > 50, | |
| 'infrastructure_collapse': assessments['infrastructure']['power_outages'] > 5000, | |
| 'community_breakdown': assessments['people']['communityMorale'] < 50 | |
| } | |
| active_indicators = sum(indicators.values()) | |
| risk_score = active_indicators / len(indicators) | |
| if risk_score < 0.3: | |
| risk_level = 'low' | |
| elif risk_score < 0.6: | |
| risk_level = 'moderate' | |
| else: | |
| risk_level = 'high' | |
| return { | |
| 'indicators': indicators, | |
| 'active_count': active_indicators, | |
| 'risk_score': risk_score, | |
| 'risk_level': risk_level | |
| } | |
| def calculate_overall_mental_health(sentiment_data, psych_impact, trauma_risk, community_morale): | |
| """Calculate overall mental health score""" | |
| sentiment_score = (sentiment_data['sentiment_score'] + 1) / 2 # Normalize to 0-1 | |
| psychological_score = 1 - psych_impact['total_score'] | |
| trauma_score = 1 - trauma_risk['risk_score'] | |
| morale_score = community_morale / 100 | |
| overall_score = ( | |
| sentiment_score * 0.25 + | |
| psychological_score * 0.35 + | |
| trauma_score * 0.25 + | |
| morale_score * 0.15 | |
| ) | |
| if overall_score > 0.75: | |
| level = 'excellent' | |
| elif overall_score > 0.6: | |
| level = 'good' | |
| elif overall_score > 0.4: | |
| level = 'concerning' | |
| else: | |
| level = 'critical' | |
| return { | |
| 'overall_score': overall_score, | |
| 'level': level, | |
| 'components': { | |
| 'sentiment': sentiment_score, | |
| 'psychological': psychological_score, | |
| 'trauma': trauma_score, | |
| 'morale': morale_score | |
| } | |
| } | |
| def main(): | |
| """Main application function""" | |
| # Load CSS | |
| load_css() | |
| # Header | |
| st.markdown(""" | |
| <div class="main-header"> | |
| <h1>β οΈ Oklahoma Damage Assessment System</h1> | |
| <h2>π§ Comprehensive Sentiment & Psychological Analysis</h2> | |
| <p>Advanced disaster impact analysis with emotional and mental health assessment</p> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Sidebar controls | |
| st.sidebar.title("ποΈ Assessment Controls") | |
| st.sidebar.markdown("---") | |
| location_data = get_location_data() | |
| # Location selection | |
| location_type = st.sidebar.radio("π Location Type", ["County", "City"]) | |
| if location_type == "County": | |
| selected_location = st.sidebar.selectbox("ποΈ Select County", location_data['counties']) | |
| else: | |
| selected_location = st.sidebar.selectbox("ποΈ Select City", location_data['cities']) | |
| # Analysis options | |
| st.sidebar.markdown("---") | |
| st.sidebar.subheader("π§ Analysis Options") | |
| show_detailed = st.sidebar.checkbox("Show Detailed Analysis", value=True) | |
| show_trauma = st.sidebar.checkbox("Show Trauma Assessment", value=True) | |
| show_timeline = st.sidebar.checkbox("Show Recovery Timeline", value=True) | |
| # Generate new assessment button | |
| if st.sidebar.button("π Generate New Assessment", type="primary"): | |
| st.rerun() | |
| # Generate data | |
| if 'damage_data' not in st.session_state or st.sidebar.button("π Refresh Data"): | |
| st.session_state.damage_data = generate_damage_data(selected_location) | |
| damage_data = st.session_state.damage_data | |
| # Update location if changed | |
| if damage_data['location'] != selected_location: | |
| damage_data = generate_damage_data(selected_location) | |
| st.session_state.damage_data = damage_data | |
| # Perform analysis | |
| sentiment_data = analyze_sentiment(damage_data['impact']) | |
| psych_impact = calculate_psychological_impact(damage_data['assessments']) | |
| trauma_risk = assess_trauma_risk(damage_data['assessments']) | |
| overall_mental_health = calculate_overall_mental_health( | |
| sentiment_data, psych_impact, trauma_risk, | |
| damage_data['assessments']['people']['communityMorale'] | |
| ) | |
| # Main damage alert | |
| damage_type = damage_data['damageType'] | |
| severity = damage_data['severity'] | |
| st.markdown(f""" | |
| <div class="damage-alert"> | |
| <h3>{damage_type['icon']} {damage_data['location']} Impact Assessment</h3> | |
| <h4>{damage_type['name']} - {severity['name']} Severity</h4> | |
| <p><strong>Impact:</strong> {damage_data['impact']}</p> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Mental health overview | |
| overall_score = overall_mental_health['overall_score'] | |
| level = overall_mental_health['level'] | |
| color_map = { | |
| 'excellent': '#28a745', | |
| 'good': '#17a2b8', | |
| 'concerning': '#ffc107', | |
| 'critical': '#dc3545' | |
| } | |
| color = color_map.get(level, '#6c757d') | |
| st.markdown(f""" | |
| <div class="sentiment-card"> | |
| <h4>π― Overall Community Mental Health Assessment</h4> | |
| <div style="display: flex; align-items: center; justify-content: space-between;"> | |
| <div> | |
| <h2 style="color: white; margin: 0;">{overall_score:.1%}</h2> | |
| <p style="margin: 0; font-size: 1.2em;">Mental Health Score</p> | |
| </div> | |
| <div style="text-align: right;"> | |
| <h3 style="color: white; margin: 0;">{level.upper()}</h3> | |
| <p style="margin: 0;">Status Level</p> | |
| </div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Key metrics | |
| st.subheader("π Key Impact Metrics") | |
| col1, col2, col3, col4 = st.columns(4) | |
| assessments = damage_data['assessments'] | |
| with col1: | |
| st.metric("π Injured", assessments['people']['injured']) | |
| st.metric("π§ Psychological", assessments['people']['psychologicalCasualties']) | |
| with col2: | |
| st.metric("π Homes Damaged", assessments['property']['homes_damaged']) | |
| st.metric("π Property Cost", f"${assessments['property']['estimated_cost']:,}") | |
| with col3: | |
| st.metric("π₯ Affected", assessments['people']['affected']) | |
| st.metric("π Displaced", assessments['people']['displaced']) | |
| with col4: | |
| st.metric("πͺ Community Morale", f"{assessments['people']['communityMorale']}%") | |
| st.metric("β‘ Power Outages", f"{assessments['infrastructure']['power_outages']:,}") | |
| # Detailed analysis sections | |
| if show_detailed: | |
| st.subheader("π Detailed Sentiment Analysis") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.markdown("**Text Sentiment Analysis:**") | |
| classification = sentiment_data['classification'] | |
| class_colors = { | |
| 'highly_negative': '#dc3545', | |
| 'negative': '#fd7e14', | |
| 'neutral': '#6c757d', | |
| 'positive': '#28a745' | |
| } | |
| st.markdown(f""" | |
| <div style="background: {class_colors.get(classification, '#6c757d')}20; | |
| border-left: 4px solid {class_colors.get(classification, '#6c757d')}; | |
| padding: 1rem; border-radius: 5px;"> | |
| <strong>Classification:</strong> {classification.replace('_', ' ').title()}<br> | |
| <strong>Sentiment Score:</strong> {sentiment_data['sentiment_score']:.3f}<br> | |
| <strong>Dominant Emotion:</strong> {sentiment_data['dominant_emotion'].title()} | |
| </div> | |
| """, unsafe_allow_html=True) | |
| with col2: | |
| st.markdown("**Psychological Impact Analysis:**") | |
| level_colors = { | |
| 'minimal': '#28a745', | |
| 'moderate': '#ffc107', | |
| 'severe': '#fd7e14', | |
| 'critical': '#dc3545' | |
| } | |
| level_color = level_colors.get(psych_impact['level'], '#6c757d') | |
| st.markdown(f""" | |
| <div style="background: {level_color}20; | |
| border-left: 4px solid {level_color}; | |
| padding: 1rem; border-radius: 5px;"> | |
| <strong>Impact Level:</strong> {psych_impact['level'].title()}<br> | |
| <strong>Total Score:</strong> {psych_impact['total_score']:.3f}<br> | |
| <strong>Primary Factors:</strong> People Impact, Property Loss, Economic Stress | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Trauma assessment | |
| if show_trauma: | |
| st.subheader("β οΈ Trauma Risk Assessment") | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| st.metric("β οΈ Risk Level", trauma_risk['risk_level'].upper()) | |
| with col2: | |
| st.metric("π¨ Active Indicators", f"{trauma_risk['active_count']}/6") | |
| with col3: | |
| st.metric("π Risk Score", f"{trauma_risk['risk_score']:.1%}") | |
| # Trauma indicators | |
| st.markdown("**Trauma Risk Indicators:**") | |
| indicators_data = [] | |
| for indicator, active in trauma_risk['indicators'].items(): | |
| indicators_data.append({ | |
| 'Indicator': indicator.replace('_', ' ').title(), | |
| 'Status': 'Active' if active else 'Inactive', | |
| 'Risk_Level': 1 if active else 0 | |
| }) | |
| indicators_df = pd.DataFrame(indicators_data) | |
| if not indicators_df.empty: | |
| fig = px.bar( | |
| indicators_df, | |
| x='Indicator', | |
| y='Risk_Level', | |
| color='Status', | |
| title="Trauma Risk Indicators", | |
| color_discrete_map={'Active': '#dc3545', 'Inactive': '#28a745'} | |
| ) | |
| fig.update_layout(height=400, xaxis_tickangle=-45) | |
| st.plotly_chart(fig, use_container_width=True) | |
| # Recovery timeline | |
| if show_timeline: | |
| st.subheader("π Recovery Timeline") | |
| timeline_phases = [ | |
| ("Immediate Response", "0-72 hours", "Acute stress management"), | |
| ("Short-term Recovery", "3 days - 4 weeks", "PTSD prevention"), | |
| ("Medium-term Adjustment", "1-6 months", "Adaptation support"), | |
| ("Long-term Recovery", "6+ months", "Post-traumatic growth") | |
| ] | |
| for i, (phase, duration, description) in enumerate(timeline_phases, 1): | |
| with st.expander(f"Phase {i}: {phase} ({duration})"): | |
| st.write(f"**Focus:** {description}") | |
| if i == 1: | |
| st.write(f"β’ Expected acute stress in {trauma_risk['risk_score']:.1%} of population") | |
| st.write("β’ Deploy crisis counselors immediately") | |
| elif i == 2: | |
| st.write(f"β’ PTSD screening for {trauma_risk['active_count'] * 100} individuals") | |
| st.write("β’ Establish support groups") | |
| elif i == 3: | |
| st.write("β’ Economic counseling for affected households") | |
| st.write("β’ Long-term housing solutions") | |
| else: | |
| st.write(f"β’ Post-traumatic growth potential: {overall_score:.1%}") | |
| st.write("β’ Community resilience building") | |
| # Mental health resources | |
| st.subheader("π₯ Mental Health Resource Recommendations") | |
| total_affected = assessments['people']['affected'] | |
| psychological_casualties = assessments['people']['psychologicalCasualties'] | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| st.markdown("**π¨ Immediate Response**") | |
| counselors_needed = max(5, psychological_casualties // 50) | |
| st.write(f"β’ Deploy {counselors_needed} crisis counselors") | |
| st.write("β’ Activate 24/7 mental health hotline") | |
| st.write("β’ Set up mobile crisis units") | |
| with col2: | |
| st.markdown("**β° Short-term Support**") | |
| support_groups = max(3, total_affected // 200) | |
| st.write(f"β’ Establish {support_groups} support groups") | |
| st.write("β’ Trauma screening programs") | |
| st.write("β’ Children's mental health services") | |
| with col3: | |
| st.markdown("**π± Long-term Recovery**") | |
| st.write("β’ Community resilience workshops") | |
| st.write("β’ PTSD treatment programs") | |
| st.write("β’ Economic counseling services") | |
| # Data export | |
| st.sidebar.markdown("---") | |
| st.sidebar.subheader("π Export Data") | |
| if st.sidebar.button("π₯ Export Assessment"): | |
| export_data = { | |
| 'damage_assessment': damage_data, | |
| 'sentiment_analysis': sentiment_data, | |
| 'psychological_impact': psych_impact, | |
| 'trauma_assessment': trauma_risk, | |
| 'mental_health_score': overall_mental_health, | |
| 'generated_at': datetime.now().isoformat() | |
| } | |
| st.sidebar.download_button( | |
| label="Download JSON Report", | |
| data=json.dumps(export_data, indent=2, default=str), | |
| file_name=f"oklahoma_assessment_{selected_location.replace(' ', '_')}.json", | |
| mime="application/json" | |
| ) | |
| # Footer | |
| st.markdown("---") | |
| st.markdown(""" | |
| <div style="text-align: center; padding: 2rem; background: #f8f9fa; border-radius: 10px;"> | |
| <h4>β οΈ Oklahoma Damage Assessment System</h4> | |
| <p>π§ Comprehensive Sentiment & Psychological Analysis Platform</p> | |
| <p><small>Last Updated: {}</small></p> | |
| </div> | |
| """.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')), unsafe_allow_html=True) | |
| if __name__ == "__main__": | |
| main() |