
    +\j%              
          S r SSKrSSKrSSKrSSKJr  SSKrSSKr	SSK
r
SSKrSSKrSrSrSrSrSrSrS	S	S	S
.rS rS\S\	R.                  4S jrS\S\4S jrS\	R.                  S\S\	R4                  S-  4S jrS\S-  S\4S jrS\	R.                  S\S\\ \ \!\   4   4S jr"S"S\S\S-  S\RF                  4S jjr$S\RF                  S\S\S\S\4
S jr%S\&4S  jr'\(S!:X  a  \RR                  " \'" 5       5        gg)#up  
Layer deterministico dell'agente formazioni: converte FATTI (assenze, dubbi,
turnover) in aggiustamenti dei gol attesi e produce le probabilità 1X2
aggiustate. Nessun LLM qui dentro: solo dati giocatore e modello DC.

Logica (docs/agent-01-formazioni-design.md):
  - attaccanti/centrocampisti assenti: quota del contributo offensivo squadra
    (xG+xA stagionali) -> riduzione dell'attacco: delta = -K_ATT * quota
  - difensori/portieri assenti: quota minuti del reparto difensivo
    -> indebolimento della difesa: delta = -K_DEF * quota
  - dubbio ("doubtful"): pesato per prob_out (default 0.5)
  - turnover: attacco ridotto di TURNOVER_COEF * rischio
  - cap di sicurezza: |delta| <= 0.25 per squadra e componente

Demo CLI (scenario simulato):
    python scripts/impact.py --league I1 --home Inter --away Torino         --absent-home "Lautaro Martinez" --turnover-home 0.5
    N)dateg?g      ?g?gŏ1w-!_?gffffff?      ?)confirmed_out	suspendedrestedc                     [         R                  " U R                  U R                  U R                  U R
                  SS9$ )N	tigertips)hostportuserpassworddatabase)pymysqlconnectr
   r   r   r   )argss    9/var/www/tigertips.talkandprofit.net/ai/scripts/impact.pyr   r   *   s0    ??						$(MMKI I    teamreturnc                 z    Sn[         R                  " X X4S9nS H  nX4   R                  [        5      X4'   M     U$ )uK   Rosa della squadra dalla stagione più recente disponibile in player_stats.z
        SELECT player, position, minutes, goals, assists, xg, xa
        FROM player_stats
        WHERE team = %s
          AND season = (SELECT MAX(season) FROM player_stats WHERE team = %s)
    params)xgxa)pdread_sqlastypefloat)connr   qdfcs        r   
load_squadr#   /   s>    	A 
Qd\	2BU# Ir   sc                 x    SR                  S [        R                  " SU R                  5       5       5       5      $ )z<minuscole + rimozione accenti, per un matching nomi robusto. c              3   ^   #    U  H#  n[         R                  " U5      S :w  d  M  Uv   M%     g7f)MnN)unicodedatacategory).0r"   s     r   	<genexpr>_normalize.<locals>.<genexpr>?   s,      7H!**1-5 1Hs   -	-NFD)joinr)   	normalizecasefold)r$   s    r   
_normalizer2   =   s2    77 7k33E1::<H 7 7 7r   squadnamec           	         X S   R                  [        5      R                  R                  [        U5      SS9   nUR                  (       a  [        SU S35        g [        U5      S:  aF  UR                  SSS9n[        S	U S
SR                  US   5       SUR                  S   S    35        UR                  S   $ )NplayerF)regexz  [ATTENZIONE] 'z"' non trovato nella rosa, ignorato   minutes)	ascendingz
  [nota] 'z' ambiguo (z, z
): scelto r   )
mapr2   strcontainsemptyprintlensort_valuesr/   iloc)r3   r4   hitss      r   find_playerrD   C   s    x$$Z044==j>NV[=\]Dzz &HIJ
4y1}	U;
4&DIId8n,E+F G		!X./1 	299Q<r   positionc                     U =(       d    SR                  5       nUR                  S5      =(       d    UR                  S5      $ )Nr&   DGK)upper
startswith)rE   poss     r   is_defensiverL   O   s1    >r
 
 
"C>>#6#.."66r   factsc                 *   [        U S   U S   -   R                  5       5      nX S   R                  [        5         n[        US   R                  5       5      nSS/ pvnUR	                  S/ 5       Vs/ s H*  nU[
        R	                  UR	                  S5      S5      4PM,     snUR	                  S	/ 5       Vs/ s H   nU[        UR	                  S
S5      5      4PM"     sn-   n	U	 H  u  p[        X
S   5      nUc  M  [        US   5      (       aF  U(       a  US   U-  OSn[        * U-  U-  nXn-  nUR                  US    SUS SUS SUS 35        Mq  U(       a  [        US   US   -   5      U-  OSn[        * U-  U-  nX^-  nUR                  US    SUS SUS SUS 35        M     UR	                  S/ 5       H&  nUR                  UR	                  S5       S35        M(     [        UR	                  SS5      5      nUS:  a'  [        * U-  nX^-  nUR                  SUS SUS 35        [        [        R                  " U[        * [        5      5      n[        [        R                  " U[        * [        5      5      nXVU4$ s  snf s  snf )z
Converte i fatti di una squadra in (delta_att, delta_dfn) in log-spazio
dei gol attesi. Ritorna anche il dettaglio leggibile per il log.
r   r   rE   r9           absentstatusr   doubtfulprob_outg      ?r6   z (dif, quota minuti reparto z.0%z, certezza z): dfn z+.3fz (att, quota xG+xA z): att 	returningz' (rientro): registrato, non usato in v1turnover_riskr   zturnover (rischio )r   sumr;   rL   getSTATUS_CERTAINTYrD   K_DEFappendK_ATTTURNOVER_COEFnpclip	DELTA_CAP)r3   rM   	off_total	defendersdef_minutes_total	delta_att	delta_dfndetailseentriesentry	certaintypsharedturnovers                   r   side_deltasrn   T   s   
 uT{U4[05578IJ'++L9:Ii	26689$'b'I 8R020A $((x#>?02 !99Z464a eAEE*c234466G
 $X/9*&&8IAiL#44sE*ANINNak]*FuSk R''0oWQtHF G =FE!D'AdG+,y83E*ANINNak]*=eC[ I''0oWQtHF G $" YY{B'!%%/**QRS ( UYY45H!|NX%	+HS>4IJbggi)Y?@Ibggi)Y?@I((C26s   21J9'Jleaguecutoffc                 z   Sn[         R                  " X0XU4S9n/ SQUl        S H  nXE   R                  [        5      XE'   M     [
        R                  " US   R                  5       S[        -
  US   -  [        US   -  -   US   5      US'   [
        R                  " US	   R                  5       S[        -
  US
   -  [        US	   -  -   US
   5      US'   [        [        US   5      [        US   5      -  5      n[        U5       VVs0 s H  u  pxX_M	     n	nnU(       a  [         R                  " U5      O([         R                  " [        R                  " 5       5      n
U
[         R                  " US   5      -
  R                   R"                  n[$        R&                  " US   R)                  U	5      R+                  5       US   R)                  U	5      R+                  5       US   R+                  5       US   R+                  5       [
        R,                  " [.        * UR+                  5       -  5      US9$ s  snnf )zw
Modello DC per la lega, addestrato sulle partite fino a `cutoff`
(default: oggi). Pseudo-gol con xG dove disponibile.
a  
        SELECT m.match_date, h.name, a.name, m.home_goals, m.away_goals,
               m.home_xg, m.away_xg
        FROM matches m
        JOIN leagues l ON l.id = m.league_id
        JOIN teams h ON h.id = m.home_team_id
        JOIN teams a ON a.id = m.away_team_id
        WHERE l.code = %s AND m.result IS NOT NULL
          AND m.match_date < COALESCE(%s, DATE_ADD(CURDATE(), INTERVAL 1 DAY))
          AND m.match_date >= DATE_SUB(COALESCE(%s, CURDATE()), INTERVAL 5 YEAR)
        ORDER BY m.match_date
    r   )r   homeawayhgagxg_hxg_a)rv   rw   rv   r8   rt   hg_trw   ru   ag_trr   rs   r   )home_idxaway_idx
home_goals
away_goalsweightsteams)r   r   columnsr   r   r]   wherenotnaALPHA_XGsortedset	enumerate	Timestampr   todayto_datetimedtdaysdcfitr;   to_numpyexpXI)r   ro   rp   r    r!   r"   r   itteam_idxref_datedays_agos               r   fit_currentr      s   
	A 
Qff%=	>BEBJU# "V***,x<2d83hF6KKRPTXWBvJ"V***,x<2d83hF6KKRPTXWBvJ 3r&z?SF_45E!*5!12!1!1H2'-r||F#2<<

3MH2>>"V*5599>>H66F)224F)224f:&&(f:&&(sX..001  3s   H7modelrr   rs   payloadc                 P   [         R                  " X5      u  pE[         R                  " X5      u  pg[         R                  " XXVU5      nUR                  SSS/ 45      u  pnUR                  SSS/ 45      u  pn[         R                  " XU	-   XZ-   Xl-   X}-   5      nXX4X4S.XS.S.$ )uJ   Probabilità baseline e aggiustate per una partita, dato il payload fatti._deltas_homer   _deltas_awayrr   rs   )baselineadjusteddeltasre   )r   team_paramspredictrW   )r   rr   rs   r   att_hdfn_hatt_adfn_ar   da_hdd_hdet_hda_add_adet_ar   s                   r   adjusted_predictionr      s     >>%.LE>>%.LEzz%e<HNQ2J?DNQ2J?Dzz%u|,6H  $|d\B %57 7r   c                  f   [         R                  " SS9n U R                  SSS9  U R                  SSS9  U R                  SSS9  U R                  SS	/ S
9  U R                  SS	/ S
9  U R                  SS	/ S
9  U R                  SS	/ S
9  U R                  S[        SS9  U R                  S[        SS9  [        R
                  " U 5        U R                  5       n[        U5      n[        SUR                   S35        [        X!R                  5      n0 nSUR                  4SUR                  44 H  u  pV[        X&5      nUR                  (       a  [        SU 35        [        USU 35       Vs/ s H  nUSS.PM
     sn[        USU 35       Vs/ s H  nSU0PM	     sn[        USU 35      S.n	[!        Xy5      USU 3'   M     [#        X1R                  UR                  U5      n
UR%                  5         [        SUR                   S UR                   35        S! H#  nU
S"   U    H  n[        S#U S$U 35        M     M%     U
S%   U
S&   p[        SS'S( S)S* S+S* S,S* 35        [        S%S( US-   S. US/   S. US0   S. 35        [        S1S( US-   S. US/   S. US0   S. 35        g-s  snf s  snf )2Nu1   Demo layer deterministico assenze -> probabilità)descriptionz--leagueT)requiredz--homez--awayz--absent-home*)nargsdefaultz--absent-awayz--doubtful-homez--doubtful-awayz--turnover-homerO   )typer   z--turnover-awayzAddestro il modello z aggiornato a oggi...rr   rs   z$  [ATTENZIONE] nessun dato rosa per absent_r   )r6   rQ   	doubtful_r6   	turnover_)rP   rR   rU   _deltas_
z - r   re   z  [z] r   r   r&   z<121z>8X2r   z>8.1%r8      
aggiustata)argparseArgumentParseradd_argumentr   configadd_db_args
parse_argsr   r?   ro   r   rr   rs   r#   r>   getattrrn   r   close)parserr   r   r   r   sider   r3   nrM   outlinebas                 r   mainr      s   $$1deF

T2
40
40
sB?
sB?
)bA
)bA
)sC
)sC
vD4=D	 -B
CDkk*EG		*VTYY,?@
4&;;8?@ !(v.> ?A ?1 #$? ?A07	$>P0QR0Q1(A0QR$TYtf+=>	
 &1%>(4&!" A eYY		7
CCJJL	BtyykTYYK
() 	N4(DCvRv&' ) ! z?C
Oq	Br#hs2hs2hs2h
/0	ZQqT%L1eQqT%L
AB	\#qtEl1Q4,qtEl
CD%ARs   0J)J.__main__)N)*__doc__r   sysr)   datetimer   numpyr]   pandasr   r   r   dixon_colesr   r[   rY   r\   r_   r   r   rX   r   r<   	DataFramer#   r2   SeriesrD   boolrL   dicttupler   listrn   DixonColesFitr   r   intr   __name__exit r   r   <module>r      sn  &  
       	%(scJ I
3 2<< 7# 7# 7	r|| 	3 	299t3C 	73: 7$ 7
,)r|| ,)D ,)U5%c;R5S ,)^%c %3: %AQAQ %P7r// 7s 7# 7!%7*.7 *c *Z zHHTV r   