diff --git a/app.py b/app.py index 3e7c15b..e9345e3 100644 --- a/app.py +++ b/app.py @@ -142,6 +142,13 @@ TRANSLATIONS = { 'es': 'Estos dos equipos no se enfrentaron en las simulaciones.', 'ru': 'Эти две команды не встретились в симуляциях.', }, + 'did_not_reach_stage': { + 'de': '{team} hat das {stage} in den Simulationen nicht erreicht.', + 'en': '{team} did not reach the {stage} in the simulations.', + 'fr': '{team} n’a pas atteint le {stage} dans les simulations.', + 'es': '{team} no alcanzó {stage} en las simulaciones.', + 'ru': '{team} не вышла в {stage} в симуляциях.', + }, 'total_encounters': { 'de': '- Insgesamt {count} Begegnungen mit Deutschland ({prob} der Simulationen)', 'en': '- Total {count} meetings with Germany ({prob} of simulations)', @@ -240,6 +247,27 @@ TRANSLATIONS = { 'es': '{team} llega a {stage} en **{value}** de las simulaciones.', 'ru': '{team} выходит в {stage} в **{value}** симуляциях.', }, + 'select_team': { + 'de': 'Team auswählen', + 'en': 'Select team', + 'fr': 'Choisir une équipe', + 'es': 'Selecciona un equipo', + 'ru': 'Выберите команду', + }, + 'column_opponent': { + 'de': 'Gegner', + 'en': 'Opponent', + 'fr': 'Adversaire', + 'es': 'Rival', + 'ru': 'Соперник', + }, + 'Probability': { + 'de': 'Wahrscheinlichkeit', + 'en': 'Probability', + 'fr': 'Probabilité', + 'es': 'Probabilidad', + 'ru': 'Вероятность', + }, 'possible_opponents': { 'de': 'Mögliche Gegner von {team}', 'en': 'Possible opponents for {team}', @@ -285,11 +313,11 @@ TRANSLATIONS = { } ROUND_NAMES = { - 'de': {'R32': 'Runde der letzten 32', 'R16': 'Achtelfinale', 'QF': 'Viertelfinale', 'SF': 'Halbfinale', 'Final': 'Finale'}, - 'en': {'R32': 'Round of 32', 'R16': 'Round of 16', 'QF': 'Quarterfinal', 'SF': 'Semifinal', 'Final': 'Final'}, - 'fr': {'R32': '8es', 'R16': '8es', 'QF': 'Quarts', 'SF': 'Démis', 'Final': 'Finale'}, - 'es': {'R32': 'Octavos', 'R16': 'Octavos', 'QF': 'Cuartos', 'SF': 'Semifinales', 'Final': 'Final'}, - 'ru': {'R32': '1/8', 'R16': '1/8', 'QF': '1/4', 'SF': '1/2', 'Final': 'Финал'}, + 'de': {'R32': 'Runde der letzten 32', 'R16': 'Achtelfinale', 'QF': 'Viertelfinale', 'SF': 'Halbfinale', 'Final': 'Finale', 'Winner': 'Sieg'}, + 'en': {'R32': 'Round of 32', 'R16': 'Round of 16', 'QF': 'Quarterfinal', 'SF': 'Semifinal', 'Final': 'Final', 'Winner': 'Winner'}, + 'fr': {'R32': '8es', 'R16': '8es', 'QF': 'Quarts', 'SF': 'Démis', 'Final': 'Finale', 'Winner': 'Victoire'}, + 'es': {'R32': 'Octavos', 'R16': 'Octavos', 'QF': 'Cuartos', 'SF': 'Semifinales', 'Final': 'Final', 'Winner': 'Victoria'}, + 'ru': {'R32': '1/8', 'R16': '1/8', 'QF': '1/4', 'SF': '1/2', 'Final': 'Финал', 'Winner': 'Победа'}, } COLUMN_LABELS = { @@ -1129,13 +1157,113 @@ def main(): with tab2: st.subheader(translate('germany_comparison_header', lang)) - st.markdown( - translate( - 'germany_reaches', - lang, - team=display_team_name('Germany', lang), - stage=stage_label('R16', lang), - value=f'{germany[ + for r in ['R16', 'QF', 'SF', 'Final', 'Winner']: + st.markdown( + translate( + 'germany_reaches', + lang, + team=display_team_name('Germany', lang), + stage=stage_label(r, lang), + value=f"{germany[r] / n:.1%}", + ) + ) + + st.subheader(translate('possible_opponents', lang, team=display_team_name('Germany', lang))) + for r in ['R32', 'R16', 'QF', 'SF', 'Final']: + cnt = counters[r] + total = sum(cnt.values()) + st.markdown(f"**{stage_label(r, lang)}**") + if total == 0: + st.write( + translate( + 'did_not_reach_stage', + lang, + team=display_team_name('Germany', lang), + stage=stage_label(r, lang), + ) + ) + continue + df = pd.DataFrame([ + {'Opponent': k, 'Count': v, 'Probability': v / total} + for k, v in cnt.most_common() + ]) + df = df.rename(columns={ + 'Opponent': translate('column_opponent', lang), + 'Count': label('Count', lang), + 'Probability': translate('Probability', lang), + }) + st.dataframe(df) + + st.subheader(translate('team_summary_header', lang)) + team_rows = [] + for team, stats in team_stats.items(): + team_rows.append({ + label('team', lang): display_team_name(team, lang), + label('avg_group_wins', lang): stats['group_wins'] / n, + label('avg_group_draws', lang): stats['group_draws'] / n, + label('avg_group_losses', lang): stats['group_losses'] / n, + label('place_1', lang): stats['group_positions'][1] / n, + label('place_2', lang): stats['group_positions'][2] / n, + label('place_3', lang): stats['group_positions'][3] / n, + label('place_4', lang): stats['group_positions'][4] / n, + label('R16', lang): stats['R16'] / n, + label('QF', lang): stats['QF'] / n, + label('SF', lang): stats['SF'] / n, + label('Final', lang): stats['Final'] / n, + label('Winner', lang): stats['Winner'] / n, + }) + summary_df = pd.DataFrame(team_rows).sort_values(label('R16', lang), ascending=False) + st.dataframe(summary_df) + + team_options = ['Germany'] + [t for t in sorted(teams) if t != 'Germany'] + selected_team = st.selectbox( + translate('select_team', lang), + team_options, + format_func=lambda t: display_team_name(t, lang), + ) + if selected_team: + selected = team_stats[selected_team] + st.subheader( + translate('detailed_overview', lang, team=display_team_name(selected_team, lang)) + ) + st.markdown( + translate( + 'group_place_line', + lang, + p1=f"{selected['group_positions'][1] / n:.1%}", + p2=f"{selected['group_positions'][2] / n:.1%}", + p3=f"{selected['group_positions'][3] / n:.1%}", + p4=f"{selected['group_positions'][4] / n:.1%}", + ) + ) + st.markdown( + translate( + 'average_group_results', + lang, + wins=f"{selected['group_wins'] / n:.2f}", + draws=f"{selected['group_draws'] / n:.2f}", + losses=f"{selected['group_losses'] / n:.2f}", + ) + ) + st.markdown( + translate( + 'stage_stats_line', + lang, + r16=f"{selected['R16'] / n:.1%}", + qf=f"{selected['QF'] / n:.1%}", + sf=f"{selected['SF'] / n:.1%}", + final=f"{selected['Final'] / n:.1%}", + winner=f"{selected['Winner'] / n:.1%}", + ) + ) + else: + st.warning(translate('please_start', lang)) + + st.markdown(translate('final_note', lang)) + + +if __name__ == '__main__': + main() if __name__ == '__main__': main()