File size: 3,337 Bytes
07ff2cb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""
Utility functions for Agent Tools.

Provides shared helpers: ticker validation, currency formatting,
safe dictionary access, and percentage formatting.
"""


def validate_ticker(ticker: str) -> tuple[bool, str]:
    """Validate and normalize a ticker string.

    Strips whitespace from input. If empty or whitespace-only after strip,
    returns an error tuple. Otherwise returns the uppercase normalized ticker.

    Args:
        ticker: Raw ticker string from user/agent input.

    Returns:
        (True, normalized_ticker) if valid
        (False, error_message) if invalid
    """
    stripped = ticker.strip()
    if not stripped:
        return (False, "Error: Invalid ticker provided. Ticker must be a non-empty string.")
    return (True, stripped.upper())


def format_currency(value: float, precision: int = 2) -> str:
    """Format monetary values with appropriate units (B/M/K).

    Args:
        value: The monetary value to format. If None, returns "N/A".
        precision: Number of decimal places (default 2).

    Returns:
        Formatted string like "$1.50B", "$250.00M", "$45.00K", or "$123.45".

    Examples:
        >>> format_currency(1_500_000_000)
        '$1.50B'
        >>> format_currency(250_000_000)
        '$250.00M'
        >>> format_currency(45_000)
        '$45.00K'
        >>> format_currency(123.456)
        '$123.46'
        >>> format_currency(None)
        'N/A'
    """
    if value is None:
        return "N/A"

    abs_value = abs(value)
    sign = "-" if value < 0 else ""

    if abs_value >= 1_000_000_000:
        return f"{sign}${abs_value / 1_000_000_000:.{precision}f}B"
    elif abs_value >= 1_000_000:
        return f"{sign}${abs_value / 1_000_000:.{precision}f}M"
    elif abs_value >= 1_000:
        return f"{sign}${abs_value / 1_000:.{precision}f}K"
    else:
        return f"{sign}${abs_value:.{precision}f}"


def safe_get(info: dict, key: str, default: str = "N/A") -> str:
    """Safely extract a value from a dict, returning default if missing or None.

    Args:
        info: Dictionary to look up.
        key: Key to retrieve.
        default: Value to return if key is missing or value is None.

    Returns:
        String representation of the value, or default.
    """
    value = info.get(key)
    if value is None:
        return default
    return str(value)


def format_percent(value: float, precision: int = 2) -> str:
    """Format a decimal or percentage value as a string with % sign.

    If value is None, returns "N/A". If value appears to be a decimal
    (absolute value less than 1), it is multiplied by 100 first to
    convert to a percentage.

    Args:
        value: The value to format. Decimals (e.g., 0.082) are converted
               to percentages (8.20%). Values >= 1 are treated as already
               being percentages.
        precision: Number of decimal places (default 2).

    Returns:
        Formatted string like "8.20%" or "N/A".

    Examples:
        >>> format_percent(0.082)
        '8.20%'
        >>> format_percent(25.5)
        '25.50%'
        >>> format_percent(None)
        'N/A'
    """
    if value is None:
        return "N/A"

    # If value is a decimal (abs < 1), multiply by 100 to get percentage
    if abs(value) < 1:
        value = value * 100

    return f"{value:.{precision}f}%"