File size: 4,180 Bytes
e672925
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cf1e649
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e672925
 
 
 
 
 
 
 
 
 
 
 
 
 
cf1e649
 
 
 
e672925
 
 
 
 
 
 
 
 
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
"""Genera el diccionario de variables (columna → nombre lindo + tipo) para la sección
"Equipos y variables", a partir de ``diccionario_variables.xlsx``.

El xlsx (3 columnas: Categoría · Nombre · Nombre Columna) NO está en el repo; vive
en el disco del autor. Este script lo lee, matchea contra las columnas reales del
agregado (case-insensitive) y escribe ``vendor/data/var_dict.json`` (chico,
bundleado) que la app usa para mostrar nombres legibles y agrupar por tipo.

El "tipo" top-level sale de la parte de la Categoría anterior al "–"
(p.ej. "Defensiva – Presión" y "Defensiva" → "Defensiva").

Uso: python scripts/build_var_dict.py [ruta_xlsx]
"""

from __future__ import annotations

import json
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))

import pandas as pd

from racing_reports import team_vars

XLSX = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.home() / "Documents/Racing/diccionario_variables.xlsx"
OUT = Path(__file__).resolve().parents[1] / "vendor" / "data" / "var_dict.json"


# Variables donde MENOS es mejor (rival / en contra / concedidas / errores propios).
# Para estas, el "mejor de la liga" es el de valor (z) MÁS BAJO. Revisado una por una;
# se EXCLUYEN las _rival neutrales/de estilo (altura offside, ancho, posición de pase,
# dispersión, sweeper, % pases largos, recuperaciones del rival) y las buenas para
# nosotros (tarjetas rojas del rival, faltas sufridas).
NEGATIVE_COLS = {
    # --- rival: amenaza / concedido / progresión permitida ---
    "acciones_defensivas_en_ofensiva_rival", "big_chances_generadas_rival",
    "counter_press_recovery_rival", "duelos_aereos_ganados_rival", "faltas_a_favor_rival",
    "goles_corner_rival", "goles_regular_play_rival", "goles_tempranos_rival",
    "goles_totales_rival", "goles_transicion_rival", "pases_<20m_no_cross_rival",
    "pases_peligrosos_exitosos_con_centros_rival", "pases_progresivos_exitosos_rival",
    "pases_progresivos_rival", "pct_centros_pases_totales_ultimo_tercio_rival",
    "pct_pases_exitosos_t1-2_rival", "pct_pases_exitosos_t3_rival", "pct_posesion_rival",
    "recepciones_area_rival", "ritmo_circulacion_pases_por_min_rival", "ritmo_progresion_rival",
    "shots_on_target_rival", "shots_rival", "situacion_fast_break_rival",
    "situacion_regular_play_rival", "throughballs_exitosos_rival", "throughballs_rival",
    "tiros_area_grande_rival", "tiros_area_pequeña_rival", "tiros_bloqueados_rival",
    "tiros_corner_rival", "tiros_fuera_de_area_rival", "touches_area_rival",
    "velocidad_progresion_m_por_s_rival", "xa_acumulado_rival", "xg_avg_tras_corner_rival",
    "xg_suma_tiros_rival", "xg_tiros_tras_corner_rival", "xgot_avg__tras_corner_rival",
    "xgot_suma_ontarget_rival", "xgot_tiros_tras_corner_rival", "xt_acumulado_rival",
    # --- propias: errores / pérdidas / tarjetas / presión propia (ppda bajo = mejor) ---
    "errores_quederivan_tiro/gol", "perdidas_no_forzadas", "tarjetas_totales",
    "tarjetas_rojas", "gpi_perdidas", "ppda",
}


def _top_type(cat: str) -> str:
    base = str(cat).split("–")[0].strip()  # separador es en-dash U+2013
    return "Estrategia" if base.upper() == "ESTRATEGIA" else base


def main() -> None:
    dic = pd.read_excel(XLSX, sheet_name=0)
    by_col = {}
    for _, r in dic.iterrows():
        col = str(r["Nombre Columna"]).strip().lower()
        by_col[col] = {"label": str(r["Nombre"]).strip(), "tipo": _top_type(r["Categoría"])}
    # mapear a las columnas reales del agregado (canónicas, en minúscula)
    out = {}
    for c in team_vars.variables():
        info = by_col.get(c.lower()) or {"label": c, "tipo": "Otras"}
        info = dict(info)
        info["negativa"] = c in NEGATIVE_COLS
        out[c] = info
    OUT.parent.mkdir(parents=True, exist_ok=True)
    OUT.write_text(json.dumps(out, ensure_ascii=False, indent=0), encoding="utf-8")
    n_lbl = sum(1 for v in out.values() if v["tipo"] != "Otras")
    tipos = sorted({v["tipo"] for v in out.values()})
    print(f"Guardado {OUT} | {len(out)} columnas ({n_lbl} con nombre del diccionario) | tipos: {tipos}")


if __name__ == "__main__":
    main()