File size: 2,381 Bytes
8f074bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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:
    # Índice 100
    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)))
    # 1 decimal
    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}")

    # 2 decimales
    if "Search dist." in df.columns:
        df["Search dist."] = df["Search dist."].apply(lambda n: "-" if pd.isna(n) else f"{n:.2f}")

    # Cantidades monetarias grandes
    if "marketCap" in df.columns:
        df["marketCap"] = df["marketCap"].apply(lambda n: "-" if pd.isna(n) else format_large_number(n, 1))
    # Porcentajes 1 decimal
    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}%")
    # Porcentajes 1 decimal (porcentaje numérico en fuente)
    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)}%")
    # Volatilidad
    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}")

    # Devolvemos el dataframe con los nombres de columnas renombrados
    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)