|
import pandas as pd |
|
from typing import Sequence, Any |
|
|
|
import re |
|
|
|
_NEG_COLOR = "red" |
|
|
|
def format_large_number(n, decimals=2): |
|
if n >= 1e12: |
|
return f'{n / 1e12:.{decimals}f} T' |
|
elif n >= 1e9: |
|
return f'{n / 1e9:.{decimals}f} B' |
|
elif n >= 1e6: |
|
return f'{n / 1e6:.{decimals}f} M' |
|
else: |
|
return str(n) |
|
|
|
def format_results(df: pd.DataFrame, rename_columns: dict) -> pd.DataFrame: |
|
|
|
if "ind_sust" in df.columns: |
|
df["ind_sust"] = df["ind_sust"].apply(lambda x: "-" if pd.isna(x) else int(round(x * 100, 0))) |
|
|
|
for col in ["trailingPE", "beta"]: |
|
if col in df.columns: |
|
df[col] = df[col].apply(lambda x: "-" if pd.isna(x) else f"{x:.1f}") |
|
|
|
|
|
if "Search dist." in df.columns: |
|
df["Search dist."] = df["Search dist."].apply(lambda n: "-" if pd.isna(n) else f"{n:.2f}") |
|
|
|
|
|
if "marketCap" in df.columns: |
|
df["marketCap"] = df["marketCap"].apply(lambda n: "-" if pd.isna(n) else format_large_number(n, 1)) |
|
|
|
for col in ["ret_365", "revenueGrowth"]: |
|
if col in df.columns: |
|
df[col] = df[col].apply(lambda x: "-" if pd.isna(x) or x == 0 else f"{(x * 100):.1f}%") |
|
|
|
for col in ["dividendYield"]: |
|
if col in df.columns: |
|
df[col] = df[col].apply(lambda x: "-" if pd.isna(x) else f"{round(x, 1)}%") |
|
|
|
if "vol_365" in df.columns: |
|
df["vol_365"] = df["vol_365"].apply(lambda x: "-" if pd.isna(x) or x == 0 else f"{x:.4f}") |
|
|
|
|
|
return df.rename(columns=rename_columns) |
|
|
|
|
|
def random_ticker(df: pd.DataFrame) -> str: |
|
return df["ticker"].sample(n=1).values[0] |
|
|
|
def styler_negative_red(df: pd.DataFrame, cols: list[str] | None = None): |
|
""" |
|
Returns a Styler that paints negative numeric values in *cols*. |
|
Columns absent in *df* are ignored. |
|
""" |
|
cols = [c for c in (cols or df.columns) if c in df.columns] |
|
|
|
def _style(v): |
|
try: |
|
num = float(re.sub(r"[ %,TMB]", "", str(v))) |
|
if num < 0: |
|
return f"color:{_NEG_COLOR}" |
|
except ValueError: |
|
pass |
|
return "" |
|
|
|
return df.style.applymap(_style, subset=cols) |