File size: 2,579 Bytes
c6abe34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import re
from typing import Tuple, Dict, List, Any
from app.models.stats import PlayerStatRow, TeamTotalsRow, TeamStatistics

def parse_made_attempted(value: str) -> Tuple[int, int]:
    """Parse a field like '5-10' or '5/10' into (made, attempted). Returns (0, 0) if invalid."""
    if not value or not isinstance(value, str):
        return 0, 0
    match = re.search(r'(\d+)\s*[\-/\|]\s*(\d+)', value)
    if match:
        return int(match.group(1)), int(match.group(2))
    return 0, 0

def validate_and_compute_totals(players: List[PlayerStatRow]) -> TeamTotalsRow:
    """Computes all FIBA-style totals from player rows."""
    totals = TeamTotalsRow()
    
    for p in players:
        # Re-parse ratios if integer components are 0 but ratio strings exist
        if p.fg and p.fg_m == 0 and p.fg_a == 0:
            p.fg_m, p.fg_a = parse_made_attempted(p.fg)
        if p.tp and p.tp_m == 0 and p.tp_a == 0:
            p.tp_m, p.tp_a = parse_made_attempted(p.tp)
        if p.thp and p.thp_m == 0 and p.thp_a == 0:
            p.thp_m, p.thp_a = parse_made_attempted(p.thp)
        if p.ft and p.ft_m == 0 and p.ft_a == 0:
            p.ft_m, p.ft_a = parse_made_attempted(p.ft)
            
        # Update percentages
        p.fg_pct = round((p.fg_m / p.fg_a * 100), 1) if p.fg_a > 0 else 0.0
        p.tp_pct = round((p.tp_m / p.tp_a * 100), 1) if p.tp_a > 0 else 0.0
        p.thp_pct = round((p.thp_m / p.thp_a * 100), 1) if p.thp_a > 0 else 0.0
        p.ft_pct = round((p.ft_m / p.ft_a * 100), 1) if p.ft_a > 0 else 0.0
        
        # Aggregate
        totals.pts += p.pts
        totals.fg_m += p.fg_m
        totals.fg_a += p.fg_a
        totals.tp_m += p.tp_m
        totals.tp_a += p.tp_a
        totals.thp_m += p.thp_m
        totals.thp_a += p.thp_a
        totals.ft_m += p.ft_m
        totals.ft_a += p.ft_a
        totals.off += p.off
        totals.def_reb += p.def_reb
        totals.reb += p.reb
        totals.ast += p.ast
        totals.to_cnt += p.to_cnt
        totals.stl += p.stl
        totals.blk += p.blk
        totals.pf += p.pf
        totals.fls_on += p.fls_on
        totals.index += (p.index or 0)

    # Compute team percentages
    totals.fg_pct = round((totals.fg_m / totals.fg_a * 100), 1) if totals.fg_a > 0 else 0.0
    totals.tp_pct = round((totals.tp_m / totals.tp_a * 100), 1) if totals.tp_a > 0 else 0.0
    totals.thp_pct = round((totals.thp_m / totals.thp_a * 100), 1) if totals.thp_a > 0 else 0.0
    totals.ft_pct = round((totals.ft_m / totals.ft_a * 100), 1) if totals.ft_a > 0 else 0.0
    
    return totals