Spaces:
Sleeping
Sleeping
Download dashboard/statement_view.py from Viney/readthrough: direct link, hf CLI and curl.
- Browser
- Download file 7.03 kB
-
https://huggingface.co/spaces/Viney/readthrough/resolve/main/dashboard/statement_view.py
- Command line
-
hf download hf://spaces/Viney/readthrough/dashboard/statement_view.py
-
curl -L -o statement_view.py https://huggingface.co/spaces/Viney/readthrough/resolve/main/dashboard/statement_view.py
7.03 kB
| """Three figures, then whatever is out of line — and nothing else. | |
| One block, bounded height. The alternative shape, two blocks of ratios, was | |
| rejected on purpose: this page already runs long, and a reader who has to | |
| decide which of forty numbers is the finding has been handed the analyst's | |
| job back. | |
| So the strip is fixed at three cards, and the list under it is usually | |
| empty. When it is not, each line names the figure, the base it is out of | |
| line with, and nothing else. The base is always the company's own record -- | |
| its median, its own days, its own prior year -- which is what turns a ratio | |
| into a finding. | |
| """ | |
| from __future__ import annotations | |
| from html import escape | |
| import streamlit as st | |
| from dashboard.components import evidence_link, section_header | |
| from dashboard.i18n import t | |
| from dashboard.theme import ( | |
| BEAR, | |
| BEAR_BG, | |
| BORDER, | |
| BULL, | |
| FS_EYEBROW, | |
| FS_META, | |
| TEXT, | |
| TEXT_FAINT, | |
| TEXT_MUTED, | |
| WARN, | |
| ) | |
| # A flow-through above this is genuine operating leverage rather than a | |
| # normal year; below zero the added revenue lost money. Only the colouring | |
| # depends on these -- the figure itself is always shown. | |
| _STRONG_INCREMENTAL_PCT = 40.0 | |
| # Cash conversion below this means the reported profit did not arrive in the | |
| # period it was reported for. | |
| _WEAK_CONVERSION_PCT = 80.0 | |
| def has_signals(ticker: str) -> bool: | |
| """True when either half has something to show. No Streamlit.""" | |
| from analytics.statement_signals import signals | |
| return bool(signals(ticker)) | |
| def _pct(value: float | None, digits: int = 0, signed: bool = False) -> str: | |
| if value is None: | |
| return "—" | |
| return f"{value:+.{digits}f}%" if signed else f"{value:.{digits}f}%" | |
| def cards(view: dict) -> list[dict]: | |
| """The context strip, in display order. Pure, so the wording is testable. | |
| A figure that could not be computed is dropped rather than shown as a | |
| dash: three cards where one is empty reads as a broken panel, and the | |
| other two say everything the third would have qualified. | |
| """ | |
| out: list[dict] = [] | |
| incremental = view.get("incremental_margin_pct") | |
| if incremental is not None: | |
| out.append({ | |
| "key": "incremental_margin", | |
| "label": t("stmt_incremental_label"), | |
| "value": _pct(incremental), | |
| "note": t("stmt_incremental_note"), | |
| "tone": ( | |
| "good" if incremental >= _STRONG_INCREMENTAL_PCT | |
| else "bad" if incremental < 0 else "flat" | |
| ), | |
| }) | |
| stack = view.get("two_year_stack") | |
| if stack: | |
| out.append({ | |
| "key": "two_year_stack", | |
| "label": t("stmt_stack_label"), | |
| "value": _pct(stack["stack_pct"], signed=True), | |
| "note": t("stmt_stack_note").format( | |
| latest=_pct(stack["latest_pct"], signed=True), | |
| earlier=_pct(stack["earlier_pct"], signed=True), | |
| period=stack["earlier_period"], | |
| ), | |
| "tone": "flat", | |
| }) | |
| conversion = view.get("cash_conversion_pct") | |
| if conversion is not None: | |
| prior = view.get("cash_conversion_prior_pct") | |
| out.append({ | |
| "key": "cash_conversion", | |
| "label": t("stmt_conversion_label"), | |
| "value": _pct(conversion), | |
| "note": ( | |
| t("stmt_conversion_note").format(prior=_pct(prior), period=view.get("prior_period") or "") | |
| if prior is not None else t("stmt_conversion_note_alone") | |
| ), | |
| "tone": "bad" if conversion < _WEAK_CONVERSION_PCT else "good", | |
| }) | |
| return out | |
| def flag_lines(view: dict) -> list[str]: | |
| """One sentence per flag, in the order the analytics ranked them.""" | |
| out: list[str] = [] | |
| for flag in view.get("flags") or []: | |
| key = flag.get("key") | |
| if key == "accruals": | |
| out.append(t("stmt_flag_accruals").format( | |
| value=f'{flag["value"]:.1f}', base=f'{flag["base"]:.1f}', | |
| multiple=f'{flag["multiple"]:.1f}', | |
| )) | |
| elif key in ("receivables", "inventory"): | |
| out.append(t(f"stmt_flag_{key}").format( | |
| days=f'{flag["value"]:.0f}', base=f'{flag["base"]:.0f}', | |
| change=f'{flag["change_days"]:+.0f}', | |
| )) | |
| elif key == "payout": | |
| out.append(t("stmt_flag_payout").format(pct=f'{flag["value"]:.0f}')) | |
| elif key == "sbc_offset": | |
| out.append(t("stmt_flag_sbc").format( | |
| pct=f'{flag["value"]:.0f}', | |
| gross=f'{flag["gross"] / 1e9:.1f}', | |
| net=f'{flag["net"] / 1e9:.1f}', | |
| )) | |
| return out | |
| _TONE_COLOR = {"good": BULL, "bad": BEAR, "flat": TEXT} | |
| def _card_html(card: dict) -> str: | |
| return ( | |
| f'<div style="flex:1 1 0;min-width:0;padding:12px 14px;border:1px solid {BORDER};' | |
| f'border-radius:10px;">' | |
| f'<div style="font-size:{FS_EYEBROW};font-weight:700;letter-spacing:0.08em;' | |
| f'text-transform:uppercase;color:{TEXT_FAINT};">{escape(card["label"])}</div>' | |
| f'<div style="font-size:1.35rem;font-weight:700;margin:4px 0 2px;' | |
| f'color:{_TONE_COLOR.get(card["tone"], TEXT)};">{escape(card["value"])}</div>' | |
| f'<div style="font-size:{FS_META};color:{TEXT_MUTED};line-height:1.45;">' | |
| f'{escape(card["note"])}</div>' | |
| f'</div>' | |
| ) | |
| def _flags_html(lines: list[str]) -> str: | |
| if not lines: | |
| return "" | |
| items = "".join( | |
| f'<div style="font-size:0.85rem;line-height:1.55;color:{TEXT};' | |
| f'padding:8px 12px;border-left:2px solid {WARN};background:{BEAR_BG};' | |
| f'border-radius:0 6px 6px 0;margin-top:6px;">{escape(line)}</div>' | |
| for line in lines | |
| ) | |
| return ( | |
| f'<div style="margin-top:14px;">' | |
| f'<div style="font-size:{FS_EYEBROW};font-weight:700;letter-spacing:0.1em;' | |
| f'text-transform:uppercase;color:{TEXT_MUTED};">{t("stmt_flags_title")}</div>' | |
| f'{items}</div>' | |
| ) | |
| def render(ticker: str) -> None: | |
| """Render the statement read for *ticker*, or nothing.""" | |
| from analytics.statement_signals import signals | |
| view = signals(ticker) | |
| if not view: | |
| return | |
| strip = cards(view) | |
| lines = flag_lines(view) | |
| if not strip and not lines: | |
| return | |
| caption = t("stmt_caption").format( | |
| period=view.get("period") or "", prior=view.get("prior_period") or "", | |
| ) | |
| link = evidence_link({"source_url": view.get("source_url")}, t("stmt_source_link")) | |
| st.markdown( | |
| section_header(t("stmt_title")) | |
| + f'<div style="font-size:{FS_META};color:{TEXT_FAINT};margin:-4px 0 10px;">' | |
| f'{escape(caption)}{" · " + link if link else ""}</div>' | |
| + f'<div style="display:flex;gap:10px;flex-wrap:wrap;">' | |
| + "".join(_card_html(card) for card in strip) | |
| + "</div>" | |
| + _flags_html(lines), | |
| unsafe_allow_html=True, | |
| ) | |
| st.markdown("<div style='height:12px'></div>", unsafe_allow_html=True) | |