mirror of
https://github.com/shawnkim1997/All-in-one-Financial-Analysis.git
synced 2026-07-28 02:57:44 +00:00
d337c63976
Architecture (3,909-line monolith → 28 focused modules, all < 300 lines):
- config/: constants.py (company lists, row maps, Damodaran baselines), theme.py (CSS/HTML)
- utils/: prefs, formatting, ticker, dcf, charts, ui_helpers
- data/: sec_parser, sec_fetcher, sec_downloader, financials, fundamentals,
valuation, ratios, scores, scores_ai, market
- ai/: gemini_core, gemini_sec, gemini_insights
- views/: sidebar, tab1_quant, tab1_ai, tab1_filings, tab2_dcf,
tab3_comps, tab4_news, tab5_markets, tab6_crypto, tab7_technical
- app.py: thin orchestrator (~118 lines)
- Strict unidirectional dependency graph (no circular imports)
- All @st.cache_data TTLs and st.session_state keys preserved identically
SEC filing viewer fix:
- Rebuilt EDGAR fetch chain: company_tickers.json → CIK → submissions API
→ filings.recent.primaryDocument[] (replaces deprecated directory.item)
- Filing type selectbox (10-K, 10-Q, 8-K, 20-F, 6-K) connected to backend
- Native HTML rendered via streamlit.components.v1.html() with CSS reset
- Errors surfaced explicitly with st.error()
- DART direct links restored for Korean-listed companies
.gitignore: data/ → data/*.json + data/*.html (preserve Python modules)
README: full rewrite for master's portfolio — 7-tab layout, architecture
diagram, modular structure tree, technical challenges, design rationale
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
37 lines
930 B
Python
37 lines
930 B
Python
"""
|
|
Small formatting/type-safety helpers used across multiple modules.
|
|
"""
|
|
from typing import Optional
|
|
|
|
import pandas as pd
|
|
|
|
|
|
def _safe_float(x) -> Optional[float]:
|
|
if x is None or (isinstance(x, float) and (x != x or pd.isna(x))):
|
|
return None
|
|
try:
|
|
return float(x)
|
|
except (TypeError, ValueError):
|
|
return None
|
|
|
|
|
|
def _format_shares_display(shares: float) -> str:
|
|
"""Format share count for UI, e.g. 15.42B Shares or 1.2B Shares."""
|
|
if shares is None or shares <= 0:
|
|
return "N/A"
|
|
s = float(shares)
|
|
if s >= 1e9:
|
|
return f"{s / 1e9:.2f}B Shares"
|
|
if s >= 1e6:
|
|
return f"{s / 1e6:.2f}M Shares"
|
|
if s >= 1e3:
|
|
return f"{s / 1e3:.2f}K Shares"
|
|
return f"{s:.0f} Shares"
|
|
|
|
|
|
def _na(x):
|
|
"""Return N/A for None/NaN, else value (for display)."""
|
|
if x is None or (isinstance(x, float) and (pd.isna(x) or x != x)):
|
|
return "N/A"
|
|
return x
|