Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| from scipy.stats import binom | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| from plotly.subplots import make_subplots | |
| # Configuração da página | |
| st.set_page_config( | |
| page_title="Aérea Confiável - Simulador", | |
| page_icon="✈️", | |
| layout="wide" | |
| ) | |
| # Título principal | |
| st.title("✈️ Aérea Confiável - Simulador de Overbooking e ROI") | |
| st.markdown("---") | |
| # Sidebar com controles | |
| st.sidebar.header("Configurações") | |
| # Abas para organização | |
| tab1, tab2, tab3 = st.tabs(["Análise de Overbooking", "Simulação de ROI", "Relatório Executivo"]) | |
| with tab1: | |
| st.header("Análise de Overbooking") | |
| # Controles interativos | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| capacidade = st.slider("Capacidade da Aeronave", 100, 200, 120) | |
| with col2: | |
| passagens_vendidas = st.slider("Passagens Vendidas", capacidade, capacidade+30, 130) | |
| with col3: | |
| taxa_comparecimento = st.slider("Taxa de Comparecimento (%)", 70, 100, 88) / 100 | |
| # Cálculos | |
| prob_overbooking = 1 - binom.cdf(capacidade, passagens_vendidas, taxa_comparecimento) | |
| # Métricas | |
| col1, col2, col3 = st.columns(3) | |
| col1.metric("Probabilidade de Overbooking", f"{prob_overbooking*100:.2f}%") | |
| col2.metric("Passageiros Esperados", f"{passagens_vendidas * taxa_comparecimento:.1f}") | |
| col3.metric("Assentos Excedentes Esperados", | |
| f"{(passagens_vendidas * taxa_comparecimento) - capacidade:.1f}") | |
| # Gráficos | |
| fig = make_subplots( | |
| rows=1, cols=2, | |
| subplot_titles=( | |
| f"Probabilidade de Overbooking vs Passagens Vendidas", | |
| f"Distribuição de Comparecimento para {passagens_vendidas} Passagens" | |
| ) | |
| ) | |
| # Gráfico 1 | |
| passagens_range = np.arange(capacidade, capacidade+30) | |
| probabilidades = [1 - binom.cdf(capacidade, n, taxa_comparecimento) for n in passagens_range] | |
| fig.add_trace( | |
| go.Scatter(x=passagens_range, y=probabilidades, mode='lines+markers', name='Probabilidade'), | |
| row=1, col=1 | |
| ) | |
| # Linha de limite de risco | |
| fig.add_hline(y=0.07, line_dash="dash", line_color="red", | |
| annotation_text="Limite de Risco 7%", row=1, col=1) | |
| # Gráfico 2 | |
| x = np.arange(max(0, capacidade-20), min(passagens_vendidas+1, capacidade+30)) | |
| prob_dist = binom.pmf(x, passagens_vendidas, taxa_comparecimento) | |
| fig.add_trace( | |
| go.Bar(x=x, y=prob_dist, name='Distribuição', marker_color='orange'), | |
| row=1, col=2 | |
| ) | |
| # Linha de capacidade | |
| fig.add_vline(x=capacidade, line_dash="dash", line_color="red", | |
| annotation_text=f"Capacidade: {capacidade}", row=1, col=2) | |
| fig.update_layout(height=500, showlegend=False) | |
| st.plotly_chart(fig, use_container_width=True) | |
| # Análise de viabilidade | |
| st.subheader("Análise de Viabilidade Financeira") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| lucro_passagem = st.number_input("Lucro por Passagem (R$)", value=400) | |
| with col2: | |
| custo_indenizacao = st.number_input("Custo por Indenização (R$)", value=800) | |
| # Cálculo do lucro esperado | |
| lucro_esperado = 0 | |
| for comparecem in range(0, passagens_vendidas + 1): | |
| prob = binom.pmf(comparecem, passagens_vendidas, taxa_comparecimento) | |
| if comparecem <= capacidade: | |
| lucro = comparecem * lucro_passagem | |
| else: | |
| excedentes = comparecem - capacidade | |
| lucro = capacidade * lucro_passagem - excedentes * custo_indenizacao | |
| lucro_esperado += lucro * prob | |
| lucro_120 = 120 * lucro_passagem * taxa_comparecimento | |
| col1, col2 = st.columns(2) | |
| col1.metric("Lucro Esperado (120 passagens)", f"R$ {lucro_120:,.2f}") | |
| col2.metric("Lucro Esperado ( estratégia atual)", f"R$ {lucro_esperado:,.2f}") | |
| if lucro_esperado > lucro_120: | |
| st.success("✅ ESTRATÉGIA VIÁVEL: A venda adicional traz lucro esperado positivo") | |
| else: | |
| st.error("❌ ESTRATÉGIA NÃO VIÁVEL: O risco supera o lucro esperado") | |
| with tab2: | |
| st.header("Simulação de ROI do Sistema de Informação") | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| investimento = st.number_input("Investimento Inicial (R$)", value=50000) | |
| with col2: | |
| receita_esperada = st.number_input("Receita Adicional Esperada (R$)", value=80000) | |
| with col3: | |
| custo_operacional = st.number_input("Custo Operacional Anual (R$)", value=10000) | |
| # Simulação | |
| n_simulacoes = st.slider("Número de Simulações", 1000, 10000, 5000) | |
| variabilidade = st.slider("Variabilidade do Sistema (%)", 10, 50, 30) / 100 | |
| if st.button("Executar Simulação de ROI"): | |
| with st.spinner("Simulando..."): | |
| # Simulação de Monte Carlo | |
| receitas_simuladas = np.random.normal( | |
| receita_esperada, | |
| receita_esperada * variabilidade, | |
| n_simulacoes | |
| ) | |
| rois_simulados = [] | |
| for receita in receitas_simuladas: | |
| lucro = receita - custo_operacional | |
| roi = (lucro / investimento) * 100 | |
| rois_simulados.append(roi) | |
| rois_simulados = np.array(rois_simulados) | |
| # Métricas | |
| roi_medio = np.mean(rois_simulados) | |
| prob_negativo = np.mean(rois_simulados < 0) | |
| prob_alto = np.mean(rois_simulados > 50) | |
| col1, col2, col3 = st.columns(3) | |
| col1.metric("ROI Médio Esperado", f"{roi_medio:.2f}%") | |
| col2.metric("Probabilidade de ROI Negativo", f"{prob_negativo*100:.2f}%") | |
| col3.metric("Probabilidade de ROI > 50%", f"{prob_alto*100:.2f}%") | |
| # Gráficos | |
| fig = make_subplots(rows=1, cols=2, subplot_titles=("Distribuição do ROI", "Probabilidade Acumulada")) | |
| fig.add_trace(go.Histogram(x=rois_simulados, nbinsx=50, name="ROI"), row=1, col=1) | |
| fig.add_vline(x=0, line_dash="dash", line_color="red", row=1, col=1) | |
| sorted_rois = np.sort(rois_simulados) | |
| cdf = np.arange(1, len(sorted_rois) + 1) / len(sorted_rois) | |
| fig.add_trace(go.Scatter(x=sorted_rois, y=cdf, mode='lines', name="CDF"), row=1, col=2) | |
| fig.add_hline(y=0.5, line_dash="dash", line_color="green", row=1, col=2) | |
| fig.update_layout(height=400, showlegend=False) | |
| st.plotly_chart(fig, use_container_width=True) | |
| # Recomendação | |
| if prob_negativo < 0.1 and roi_medio > 30: | |
| st.success("✅ RECOMENDA-SE O INVESTIMENTO: Bom retorno com risco controlado") | |
| elif prob_negativo < 0.25 and roi_medio > 20: | |
| st.warning("⚠️ INVESTIMENTO MODERADAMENTE RECOMENDADO: Retorno aceitável com risco moderado") | |
| else: | |
| st.error("❌ NÃO RECOMENDA-SE O INVESTIMENTO: Risco muito alto ou retorno insuficiente") | |
| with tab3: | |
| st.header("Relatório Executivo") | |
| st.subheader("Principais Conclusões") | |
| st.info(""" | |
| **Sobre a Estratégia de Overbooking:** | |
| - A venda de 130 passagens para um voo de 120 assentos apresenta risco calculado | |
| - É essencial equilibrar o lucro adicional com o risco de indenizações | |
| - Recomenda-se implementar protocolos para gestão de situações de overbooking | |
| """) | |
| st.info(""" | |
| **Sobre o Sistema de Informação:** | |
| - O investimento em sistema de gestão mostra ROI potencialmente positivo | |
| - A automatização pode reduzir significativamente os riscos de overbooking | |
| - Recomenda-se implementação faseada com monitoramento contínuo | |
| """) | |
| st.subheader("Próximos Passos Recomendados") | |
| st.write(""" | |
| 1. Implementar política de overbooking com limite máximo de 125 passagens | |
| 2. Adquirir sistema de informação com módulo de previsão de demanda | |
| 3. Desenvolver programa de compensação para passageiros afetados | |
| 4. Estabelecer métricas de acompanhamento contínuo | |
| 5. Realizar revisão trimestral da estratégia | |
| """) | |
| # Rodapé | |
| st.markdown("---") | |
| st.caption("Simulador desenvolvido para Aérea Confiável - Análise de Dados e Tomada de Decisão") |