
    ѱoiU,                        d Z ddlZddlZddlZddlmZmZ ddlmZ i dddgdddgd	d	d
gdddgdddgdddgddgddgddgddgddgdddgdd d!gd"g d#g d$g d%dd	gddgd	dgg d&ddgd'd(d)gd*d+gd,d-gd.d/gd0d1gd2d3gd4d5gd6d7gd8d9gd:d;gd<
dd=gd>d?gdd@gg dAdBdCgdDdEgdFdGZdH Z	dI Z
dJ ZdK ZedLk(  r e        yy)Mz
Link Player Props to Actual Game Outcomes
Matches props to player game stats to calculate hit rates.

Run: python3 scripts/link_props_to_outcomes.py
    N)datetimetimezone)defaultdictpointsespn_ptsassistsespn_astreboundsespn_rebstealsespn_stlblocksespn_blkthreepointersmadethreesnba_fg3mthreepointersattemptednba_fg3afieldgoalsmadenba_fgmfieldgoalsattemptednba_fgafreethrowsmadenba_ftmfreethrowsattemptednba_fta	turnoversespn_tonba_tovminutesnba_minespn_minfantasyscoretwopointersmadetwopointersattemptedzpoints+rebounds)r   r
   r   )zpoints+assistszrebounds+assistszpoints+rebounds+assistszblocks+stealspassing_yardspass_ydsrushing_yardsrush_ydsreceiving_yardsrec_ydspassing_touchdownspass_tdrushing_touchdownsrush_tdreceiving_touchdownsrec_td
touchdownstotal_td
receptionsreccompletionspass_cmpinterceptionspass_int)
r&   r(   r*   r,   r.   r0   r2   r4   r6   r8   nhl_ptsgoals	nhl_goalsnhl_assists)shotsshots_on_goalsogsavesgoalie_savespower_play_pointspp_pts)r   r;   r   r?   rA   rC   )nbanflnhlc                     | syd| v rE| j                  d      }t        |      dkD  r&|d   j                         r|d   j                         S | j                         S )a  Extract base prop type from complex prop type strings.

    Examples:
    - 'points' -> 'points'
    - 'points-LEBRON_JAMES_1_NBA-game-ou-over' -> 'points'
    - 'fieldGoalsMade-PLAYER_NAME-1q-ou-under' -> 'fieldGoalsMade'
    - 'blocks+steals' -> 'blocks+steals'
    N-   r   )splitlenisupperlower)	prop_typepartss     ;/var/www/html/eventheodds/scripts/link_props_to_outcomes.pyextract_base_prop_typerR   A   sX     
i$u:>eAh..08>>##??    c                 f   | syt        j                  dd| t         j                        } t        j                  dd| t         j                        } | j                  dd      j                  dd      j                  d	d      } dj	                  | j                               j                         } | S )
zNormalize player name for matching.

    Handles variations like:
    - De'Aaron Fox vs DeAaron Fox vs deaaron fox
    - Nickeil Alexander-Walker vs Nickeil Alexanderwalker
    - Kevin Porter Jr. vs Kevin Porter
    Nz\s+(Jr\.?|Sr\.?|III|II|IV|V)$ )flagsz\s+Jr\.?\s+ 'rI   .)resub
IGNORECASEreplacejoinrK   rN   )names    rQ   normalize_player_namer`   U   s     662BBMMRD66.#t2==AD<<R ((b199#rBD88DJJL!'')DKrS   c                     d} 	 t        | d      5 }|D ]b  }|j                  d      s|j                  dd      d   j                         j                  d      j                  d      d   c cd d d        S  	 d d d        t
        j                  j                  d	d
      j                  d      d   S # 1 sw Y   ;xY w# t        $ r Y Iw xY w)Nz/var/www/html/eventheodds/.envrzSPORTS_DATABASE_URL==rJ   "?r   SPORTS_DATABASE_URLrU   )open
startswithrK   stripFileNotFoundErrorosenvironget)env_pathflines      rQ   load_db_urlrq   j   s    /H(C  	RA R??#9:::c1-a0668>>sCII#NqQQ	R 	RR	R ::>>/4::3?BB	R 	R  s:   B? B3AB3-	B? 7B39B? 3B<8B? ?	C
Cc                     t        d       t        d       t        dt        j                  t        j                        j                                 t        d       t               } t        j                  |       }|j                         }t        d       dD ]  \  }}	 |j                  d| d| d         |j                          t        d	       t        d
       |j                  d       |j                         }t        dt        |       d       |s2t        d       |j                          |j                          dddddS t        d       t!               }t!               }|D ]3  }	|j#                  |	d          |j#                  t%        |	d                5 dj'                  t)        |            }
dj'                  t)        |            }|j                  d| d|
 d       t+        t,              }|j                         D ],  }	|	\  }}}}}}t/        |      }||t%        |      f}|||   |<   . t        dt        |       d       t        d       g }dddddd}|D ]  }|\
  }}}}}}}}}}t/        |      }||t%        |      f}|j1                  |i       }|s|dxx   dz  cc<   Lt3        |      } t4        j1                  |i       j1                  | g       }!|!s| r| gng }!|!s|dxx   dz  cc<   d }"d| v st        |!      dkD  rqg }#|!D ]\  }$|$|v r|#j7                  ||$          |D ]<  }%|$|%j9                         v s|%j9                         |$v s(|#j7                  ||%           \ ^ |#rTt;        |#      }"nH|!D ]C  }$|$|v r||$   }" n8|D ]-  }%|$|%j9                         v s|%j9                         |$v s(||%   }" n |"C n |"|dxx   dz  cc<   t|"|kD  rd}&|dxx   dz  cc<   n$|"|k  rd}&|dxx   dz  cc<   nd }&|d xx   dz  cc<   |d!xx   dz  cc<   |j7                  |"|&|f        |rRt        d"t        |       d#       |j=                  d$|       |j                          t        d%t        |       d&       t        d'       t        d(       t        d)|d!           t        d*|d    d+d,|d   z  t?        |d!   d      z  d-d.       t        d/|d    d+d,|d   z  t?        |d!   d      z  d-d.       t        d0|d            t        d1|d           t        d       |j                  d2       t        d3       |j                         D ]%  }	|	\  }'}}(})}&t        d4|' d5| d6|( d7|) d+|& d8       ' |j                          |j                          |S # t        $ r}Y d }~*d }~ww xY w)9Nz<============================================================zLINK PROPS TO OUTCOMESzTime: z&
[1] Ensuring outcome columns exist...))actualValuezDOUBLE PRECISION)resultzVARCHAR(10))linkedAt	TIMESTAMPzH
                ALTER TABLE "PlayerPropLine" ADD COLUMN IF NOT EXISTS "z" z
            z  Columns readyz
[2] Finding props to link...aU  
        SELECT
            ppl.id, ppl.league, ppl."gameId", ppl."playerExternalId",
            ppl."propType", ppl."lineValue",
            p.name as player_name,
            sg."homeTeam", sg."awayTeam", sg."gameDate"::date as game_date
        FROM "PlayerPropLine" ppl
        JOIN "Player" p ON ppl."playerExternalId" = p."externalPlayerId" AND ppl.league = p.league
        JOIN "SportsGame" sg ON ppl."gameId" = sg.id
        WHERE ppl.result IS NULL
          AND sg."homeScore" IS NOT NULL
          AND ppl.league IN ('nba', 'nfl', 'nhl')
        ORDER BY ppl.league, ppl."gameId"
    z  Found z props to linkz  No props need linkingr   )linkedoverunderpushz$
[3] Building player stats lookup...rJ   	   z', 'z
        SELECT
            league,
            "playerName",
            "gameDate"::date as game_date,
            team,
            "statKey",
            value
        FROM "PlayerGameMetric"
        WHERE league IN ('z'')
          AND "gameDate"::date IN ('z')
    z  Loaded stats for z player-gamesz!
[4] Linking props to outcomes...)rw   rx   ry   rz   no_matchr|   +rx   ry   rz   rw   z
[5] Updating z	 props...z
            UPDATE "PlayerPropLine"
            SET "actualValue" = %s, result = %s, "linkedAt" = NOW()
            WHERE id = %s
        z
  Updated z propsz=
============================================================zRESULTS:z  Props linked: z  Over hits: z (d   z.1fz%)z  Under hits: z
  Pushes: z  No stat match: ah  
        SELECT
            p.name, ppl."propType", ppl."lineValue", ppl."actualValue", ppl.result
        FROM "PlayerPropLine" ppl
        JOIN "Player" p ON ppl."playerExternalId" = p."externalPlayerId" AND ppl.league = p.league
        WHERE ppl.result IS NOT NULL
          AND ppl.league = 'nba'
        ORDER BY ppl."linkedAt" DESC
        LIMIT 10
    z
Sample linked props (NBA):z  z: rW   u    → )) printr   nowr   utc	isoformatrq   psycopg2connectcursorexecute	ExceptioncommitfetchallrL   closesetaddstrr^   sortedr   dictr`   rm   rR   PROP_TO_STATappendrN   sumexecutemanymax)*db_urlconncurcolcol_typeeprops_to_linkdatesleaguesrow	date_listleague_liststats_lookupleagueplayer_name	game_dateteamstat_keyvalue	norm_namekeyupdatesstatsprop_rowprop_idgame_idplayer_ext_idrO   
line_valuehomeawayplayer_statsbase_prop_type	stat_keysactual_valuevaluessk	actual_skrt   r_   rp   actuals*                                             rQ   run_linkager   v   sl   	(O	
"#	F8<<-779:
;<	(O]FF#D
++-C 

34 
X
	KK HHKuBxj Y 
 	KKM	
 

*+KK  	 LLNM	HS'(
78'(		

QA>> 

12 EEeG CF		#c!f+ F5M*I++fWo.KKK 	 '- (%%.K 0 	 t$L||~ ,@C=Yh)+6	y#i.1&+S(#	, 
L 12-
@A 

./G!aJE! G8muj-JUY[_aj)+6	y#i.1#''R0*" 0	: !$$VR044^RH	,:(I *" . C	NQ$6F "%MM,r"23 &2 "	!22ioo6G26M"MM,y*AB!"" "6{   
%#/#3L!- IY__..)//2Cr2I'3I'>  +
 *" *$F&MQMJ&F'NaNF&MQMh1fg67OG8T G~Y78  		
 	
3w<./0 
/	*	U8_-
./	M%-3uV}+<SxQR=S+STW*XXZ
[\	N5>*"Sw-?E(OTU@V-VWZ,[[]
^_	JuV}o
&'	eJ/0
12	(O KK 	 		 

()||~ G03-ivv4&9+QtfE&F81EFG IIKJJLLq  		s   "V66	W
W
__main__)__doc__r   rk   rZ   r   r   collectionsr   r   rR   r`   rq   r   __name__ rS   rQ   <module>r      s    	 	 ' #
8Z(Iz* 	Z, 	8Z(	
 	8Z( 	h
3 	!:, 	9+ 		{ 	9+ 		{ 	i+ 	Iz* 	  	2!" 	#& 	Hj1'( $Y/'3#D"H-/4 *:6):6-y93Y?3Y?!7 B#Z0#U+%z2):6 Y';'}-:>*18<M.b(*	CM` zM rS   