Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import streamlit as st | |
| from config.config import CRRA_COLORS, CRRA_FONT, PLOTLY_TEMPLATE | |
| def render_resource_input(name_clean, r, tooltip=None): | |
| """Render a number_input widget for a single resource availability cap. | |
| Writes the entered value into st.session_state.resource_caps[r]. | |
| Args: | |
| name_clean (str): display label (resource name without unit suffix). | |
| r (str): canonical resource name used as the session state key. | |
| tooltip (str | None): optional help text shown on hover. | |
| Returns: | |
| None | |
| """ | |
| widget_key = f"cap_{r}" | |
| if widget_key not in st.session_state: | |
| existing = st.session_state.resource_caps.get(r, 0.0) | |
| st.session_state[widget_key] = existing if existing else None | |
| cap = st.number_input( | |
| label=name_clean, | |
| min_value=0.0, | |
| format="%.10g", | |
| value=None, | |
| placeholder="0.0", | |
| key=widget_key, | |
| help=tooltip, | |
| ) | |
| st.session_state.resource_caps[r] = cap if cap is not None else 0.0 | |
| def apply_chart_style(fig, height=None): | |
| """Apply the standard CRRA theme (font, colours, margins) to a Plotly figure. | |
| Args: | |
| fig: Plotly figure object. | |
| height (int | None): optional fixed height in pixels. | |
| Returns: | |
| fig: the same figure with updated layout. | |
| """ | |
| fig.update_layout( | |
| template=PLOTLY_TEMPLATE, | |
| font=dict(family=CRRA_FONT, size=12, color=CRRA_COLORS["black"]), | |
| margin=dict(t=40, b=40, l=40, r=20), | |
| legend=dict( | |
| orientation="v", | |
| yanchor="middle", y=0.5, | |
| xanchor="left", x=1.02, | |
| ), | |
| ) | |
| if height: | |
| fig.update_layout(height=height) | |
| return fig | |
| def register_chart_data(name: str, df: pd.DataFrame): | |
| """Store a chart's underlying DataFrame in the session-level registry for bulk export. | |
| Args: | |
| name (str): unique chart label used as the dict key and export sheet name. | |
| df (pd.DataFrame): data behind the chart. | |
| Returns: | |
| None | |
| """ | |
| st.session_state.setdefault("chart_data_registry", {}) | |
| st.session_state["chart_data_registry"][name] = df.copy() | |
| def show_bar(): | |
| """Render the CRRA four-colour decorative bar below page headings. | |
| Returns: | |
| None | |
| """ | |
| st.markdown( | |
| """ | |
| <div class="et_pb_module"> | |
| <div style="display:flex;width:100%;height:12px;margin:0 auto 0 0;"> | |
| <span style="flex:1;background:#FF5F4D;"></span> | |
| <span style="flex:1;background:#A0A0A0;"></span> | |
| <span style="flex:1;background:#D9E210;"></span> | |
| <span style="flex:1;background:#55C95B;"></span> | |
| </div> | |
| </div> | |
| """, | |
| unsafe_allow_html=True, | |
| ) | |
| def smart_display_format(val): | |
| """Format a numeric value showing all significant digits, no rounding. | |
| Uses repr() which gives the shortest decimal string that round-trips | |
| exactly to the same float — avoids floating-point noise like | |
| 462961.099999999976717 when the value is actually 462961.1. | |
| Falls back to fixed-decimal notation when repr() produces scientific | |
| notation (very small numbers such as 1e-11). | |
| Args: | |
| val (float): numeric value to format. | |
| Returns: | |
| str: formatted string, or "" for near-zero values. | |
| """ | |
| if abs(val) < 1e-14: | |
| return "" | |
| s = repr(val) | |
| if "e" not in s.lower(): | |
| return s | |
| # Scientific notation → convert to fixed decimal (e.g. 1e-11 → 0.00000000001) | |
| return f"{val:.15f}".rstrip("0").rstrip(".") | |
| def format_efficiency_summary(df: pd.DataFrame, df_default: pd.DataFrame): | |
| """Build a styled Pandas Styler for the resource-efficiency coefficient summary table. | |
| Cells whose value differs from the default median are highlighted in red. | |
| Args: | |
| df (pd.DataFrame): current coefficient values (methods × resources). | |
| df_default (pd.DataFrame): default median values for the same shape. | |
| Returns: | |
| pandas.io.formats.style.Styler: styled dataframe ready for st.dataframe(). | |
| """ | |
| df_numeric = df.copy() | |
| df_display = df_numeric.map(smart_display_format) | |
| def highlight_changes(data): | |
| styled = pd.DataFrame('', index=data.index, columns=data.columns) | |
| for m in data.index: | |
| for r in data.columns: | |
| try: | |
| current = df_numeric.at[m, r] | |
| default = df_default.at[m, r] | |
| if abs(current - default) > 1e-6: | |
| styled.at[m, r] = 'background-color: #ff5f4d' | |
| except: | |
| continue | |
| return styled | |
| return ( | |
| df_display | |
| .style | |
| .apply(highlight_changes, axis=None) | |
| ) |