
    %i =                         S r SSKrSSKJs  Jr  SSKJr  SSK	J
r
Jr  SSKrSSKJr  SSKJrJrJrJr  SSKJrJr   " S S	5      r " S
 S5      rg)z/Tests for barrier/handicap adjustment learning.    N)date)Mockpatch)RatingEngine)
EntityTypeMeetingRaceStarter)BarrierAdjustmentRepositoryHandicapAdjustmentRepositoryc                       \ rS rSrSr\R                  S 5       r\R                  S 5       rS r	S r
S rS rS	 rS
 rS rSrg)TestAdjustmentLearning   z,Tests for adjustment learning functionality.c                     [        5       $ )zCreate mock database session.)r   )selfs    C/root/tipsharks/tipsharks-elo-api/tests/test_adjustment_learning.pymock_dbTestAdjustmentLearning.mock_db   s     v    c                    UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS	5        S
SKJn  U" 5         [        R                  " [
        S/ S9   [        R                  " [        S/ S9   [        US9sSSS5        sSSS5        $ ! , (       d  f       O= f SSS5        g! , (       d  f       g= f)z.Create rating engine with adjustments enabled.HRNZ_USERNAMEtestHRNZ_PASSWORDDATABASE_URLpostgresql://testENABLE_ADJUSTMENTStrueADJ_LEARNING_RATE0.5r   reload_settingsget_allreturn_value
db_sessionN)setenvpackages.core.common.settingsr!   r   objectr   r   r   )r   r   monkeypatchr!   s       r   engineTestAdjustmentLearning.engine   s     	?F3?F3>+>?/8.6A \\5yrR:ITVW#w7 XW SRWWW SRRs$   C	B9&	C9
C	C
C"c           	         UR                  SS5        SSKJn  U" 5         [        5       nSUl        SUl        SUl        SUl        S	Ul        [        R                  " [        S
U/S9   [        R                  " [        S
/ S9   [        US9nSnUR                  ovU;   o(       d  [        R                   " SU4SXg45      S["        R$                  " 5       ;   d  [        R&                  " U5      (       a  [        R(                  " U5      OSS["        R$                  " 5       ;   d  [        R&                  " U5      (       a  [        R(                  " U5      OS[        R(                  " U5      S.-  n	SSU	0-  n
[+        [        R,                  " U
5      5      eS=pUR                  U   nS	o{U:H  o(       do  [        R                   " SU4SX45      [        R(                  " U5      [        R(                  " U5      S.-  n	SSU	0-  n
[+        [        R,                  " U
5      5      eS=n=pSSS5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f)z/Test loading barrier adjustments from database.r   r   r   r    	Cambridgemobile	1700-2000         @r"   r#   r%   )r.   r/   r0   r1   in)z;%(py0)s in %(py4)s
{%(py4)s = %(py2)s.barrier_adjustments
}keyr+   py0py2py4assert %(py6)spy6N==)z%(py1)s == %(py4)spy1r9   )r'   r(   r!   r   venue
start_typedistance_bucketbarrier
adjustmentr   r)   r   r   r   barrier_adjustments
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation)r   r   r*   r!   mock_adjr+   r5   @py_assert3@py_assert1@py_format5@py_format7@py_assert0@py_assert2s                r   test_barrier_adjustment_loading6TestAdjustmentLearning.test_barrier_adjustment_loading*   s   /8A6$&#. !\\'(
 :ITVW%9 >$888888888s888888s8888s888888f8888f8888888888811#6=#=#=====6===6===#======= X
 
 XW
 
s%   (I	F$H8'I	8
I	I		
Ic           	         UR                  SS5        SSKJn  U" 5         [        5       nSUl        SUl        SUl        SUl        SUl        [        R                  " [        S	/ S
9   [        R                  " [        S	U/S
9   [        US9nSnUR                  ovU;   o(       d  [        R                   " SU4SXg45      S["        R$                  " 5       ;   d  [        R&                  " U5      (       a  [        R(                  " U5      OSS["        R$                  " 5       ;   d  [        R&                  " U5      (       a  [        R(                  " U5      OS[        R(                  " U5      S.-  n	SSU	0-  n
[+        [        R,                  " U
5      5      eS=pUR                  U   nSow* oU:H  o(       do  [        R                   " SU4SX45      [        R(                  " U5      [        R(                  " U5      S.-  nSSU0-  n[+        [        R,                  " U5      5      eS=n=n=p|SSS5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f)z0Test loading handicap adjustments from database.r   r   r   r    Nr0   
   g       r"   r#   r%   )NNr0   rX   r3   )z<%(py0)s in %(py4)s
{%(py4)s = %(py2)s.handicap_adjustments
}r5   r+   r6   r:   r;   g       @r<   )z%(py1)s == -%(py4)sr>   assert %(py7)spy7)r'   r(   r!   r   r@   rA   rB   
handicap_mrD   r   r)   r   r   r   handicap_adjustmentsrF   rG   rH   rI   rJ   rK   rL   rM   )r   r   r*   r!   rN   r+   r5   rO   rP   rQ   rR   rS   @py_assert5rT   @py_format6@py_format8s                   r    test_handicap_adjustment_loading7TestAdjustmentLearning.test_handicap_adjustment_loadingC   s   /8A6"#.  "\\5yrR,ixj &9 4$999999999s999999s9999s999999f9999f999999999992237?C?4?4?????7???7???C??????? SR  SRs%   'IF(H<+I<
I
	I
Ic                 r   [        [        S9nSUl        [        SSS5      Ul        [        [
        S9nSUl        SUl        SUl        X4l	        [        [        S9nSUl        SUl        S	Ul        S	Ul        SUl        S	Ul        SUl        S
Ul        [        [        S9nSUl        SUl        S	Ul        S	Ul        SUl        S	Ul        SUl        S
Ul        XV/nUR%                  [&        R(                  S5        UR%                  [&        R(                  S5        [*        R,                  " [.        S5       nUR1                  XGSS9  UR2                  n	SoU
:H  o(       d  [4        R6                  " SU4SX45      S[8        R:                  " 5       ;   d  [4        R<                  " U5      (       a  [4        R>                  " U5      OS[4        R>                  " U	5      [4        R>                  " U
5      S.-  nSSU0-  n[A        [4        RB                  " U5      5      eS	=n	=pS	S	S	5        g	! , (       d  f       g	= f)z,Test learning adjustments from race results.specr.     r1        r/   d   NF         increment_sampleT)use_global_onlyr<   z2%(py2)s
{%(py2)s = %(py0)s.call_count
} == %(py5)smock_incrementr7   r8   py5rY   rZ   )"r   r   r@   r   meeting_dater	   id
distance_mrA   meetingr
   horse_id	driver_id
trainer_idrC   r[   placingdid_not_finishget_or_init_ratingr   HORSEr   r)   r   learn_adjustments_from_race
call_countrF   rG   rH   rI   rJ   rK   rL   rM   )r   r+   r   mock_meeting	mock_racestarter1starter2startersro   rP   @py_assert4rO   r^   r_   s                 r    test_learn_adjustments_from_race7TestAdjustmentLearning.test_learn_adjustments_from_race\   s    )($(q"$5!dO		#	'	( W%!"""'W%!"""'' 	!!*"2"2C8!!*"2"2C8 \\');
..T / 
 ",,1111111,111111>1111>111,1111111111
 
 
s   7C(H((
H6c                 &	   [        5       n[        5       n[        5       UR                  R                  R                  l        X!R                  l        Sn[        [        U5      oD(       d  SS[        R                  " 5       ;   d  [        R                  " [
        5      (       a  [        R                  " [
        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS=p4Sn[        [        U5      oD(       d  SS[        R                  " 5       ;   d  [        R                  " [
        5      (       a  [        R                  " [
        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS=p4Sn[        [        U5      oD(       d  SS[        R                  " 5       ;   d  [        R                  " [
        5      (       a  [        R                  " [
        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS=p4Sn[        [        U5      oD(       d  SS[        R                  " 5       ;   d  [        R                  " [
        5      (       a  [        R                  " [
        5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      S.-  n[        [        R                  " U5      5      eS=p4g)	z*Test barrier adjustment repository upsert.upsertz5assert %(py5)s
{%(py5)s = %(py0)s(%(py1)s, %(py3)s)
}hasattrr   )r7   r?   py3rq   Nr   rl   )r   filterr$   onequeryr   r   rH   rI   rF   rJ   rK   rL   rM   r   )r   mock_session
mock_queryrT   r   r^   s         r   !test_adjustment_repository_upsert8TestAdjustmentLearning.test_adjustment_repository_upsert   sT   v V
:>&
&&**7*4' 5==w2H=========w====w======2====2===H==========5=>w3X>>>>>>>>>w>>>>w>>>>>>3>>>>3>>>X>>>>>>>>>>4FGw24FGGGGGGGGGwGGGGwGGGGGG2GGGG2GGG4FGGGGGGGGGG5GHw35GHHHHHHHHHwHHHHwHHHHHH3HHHH3HHH5GHHHHHHHHHHr   c                    UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS5        UR                  S	S
5        SSKJn  U" 5         [        R                  " [
        S/ S9   [        R                  " [        S/ S9   [        US9nSSS5        SSS5        SnSWR                  U'   SUR                  U'   UR                  nSnSnSn	So" XxX5      nSoU:H  o(       Gd#  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                   " U5      OS[        R                   " U5      [        R                   " U5      [        R                   " U5      [        R                   " U	5      [        R                   " U
5      [        R                   " U5      [        R                   " U5      S.-  nSSU0-  n[#        [        R$                  " U5      5      eS=n=n=n=n	=n
=n=pSUR                  U'   UR                  nSnSnSn	So" XxX5      nSoU:H  o(       Gd#  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                   " U5      OS[        R                   " U5      [        R                   " U5      [        R                   " U5      [        R                   " U	5      [        R                   " U
5      [        R                   " U5      [        R                   " U5      S.-  nSSU0-  n[#        [        R$                  " U5      5      eS=n=n=n=n	=n
=n=pg! , (       d  f       GN= f! , (       d  f       GN= f) z-Test adjustment minimum samples and clamping.r   r   r   r   ADJ_MIN_SAMPLES2ADJ_CLAMP_MINz-5.0ADJ_CLAMP_MAXz5.0r   r    r"   r#   r%   N)Testr/   r0   r1   g      (@r1   r   r/   rg           r<   z|%(py12)s
{%(py12)s = %(py2)s
{%(py2)s = %(py0)s._get_barrier_adjustment
}(%(py4)s, %(py6)s, %(py8)s, %(py10)s)
} == %(py15)sr+   r7   r8   r9   r;   py8py10py12py15assert %(py17)spy17ri   r2   )r'   r(   r!   r   r)   r   r   r   rE   barrier_adjustment_samples_get_barrier_adjustmentrF   rG   rH   rI   rJ   rK   rL   rM   )r   r*   r   r!   r+   r5   rP   rO   r]   @py_assert7@py_assert9@py_assert11@py_assert14@py_assert13@py_format16@py_format18s                   r   %test_adjustment_min_samples_and_clamp<TestAdjustmentLearning.test_adjustment_min_samples_and_clamp   s   >+>?/8,c2?F3?E2A\\5yrR:ITVW%9 X S 1*.""3'12))#.--OfOhOOaO-fHOCOCOOOOOHOOOOOOvOOOOvOOO-OOOfOOOhOOOOOOaOOOHOOOCOOOOOOOO12))#.--OfOhOOaO-fHOCOCOOOOOHOOOOOOvOOOOvOOO-OOOfOOOhOOOOOOaOOOHOOOCOOOOOOOO XW SRs$   N/
N'N/
N,	'N//
N>c           
      	   UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS5        SS	KJn  U" 5         [        R                  " [
        S
/ S9   [        R                  " [        S
/ S9   [        US9nSSS5        SSS5        [        [        S9nSUl
        [        SSS5      Ul        [        [        S9nSUl        SUl        SUl        XVl        [        [$        S9nSUl        SUl        SUl        SUl        SUl        SUl        SUl        SUl        [        [$        S9nSUl        SUl        SUl        SUl        SUl        SUl        SUl        SUl        [        R                  " [
        S5       n	[        R                  " [        S5       n
WR5                  XgU/5        U	R6                  nSoU:H  o(       d  [8        R:                  " SU4SX45      S[<        R>                  " 5       ;   d  [8        R@                  " U	5      (       a  [8        RB                  " U	5      OS[8        RB                  " U5      [8        RB                  " U5      S.-  nSS U0-  n[E        [8        RF                  " U5      5      eS=n=pU
R6                  nSoU:H  o(       d  [8        R:                  " SU4SX45      S![<        R>                  " 5       ;   d  [8        R@                  " U
5      (       a  [8        RB                  " U
5      OS![8        RB                  " U5      [8        RB                  " U5      S.-  nSS U0-  n[E        [8        RF                  " U5      5      eS=n=pU	RH                   GH  u  nnUS"   nSnUUL nU(       dp  [8        R:                  " S#U4S$UU45      [8        RB                  " U5      [8        RB                  " U5      S%.-  nS&S'U0-  n[E        [8        RF                  " U5      5      eS=n=nnUS(   nSnUUL nU(       dp  [8        R:                  " S#U4S$UU45      [8        RB                  " U5      [8        RB                  " U5      S%.-  nS&S'U0-  n[E        [8        RF                  " U5      5      eS=n=nnGM     SSS5        SSS5        g! , (       d  f       GN!= f! , (       d  f       GN+= f! , (       d  f       N;= f! , (       d  f       g= f))z+Test global-only updates and delta scaling.r   r   r   r   ADJ_GLOBAL_ONLYADJ_UPDATE_SCALEz2.0r   r    r"   r#   r%   Nrc   r.   re   r1   rf   ri   rg   r/   rh   rX   Frj   rl   r<   rn   mock_barrierrp   rY   rZ   mock_handicapr@   )is)z%(py1)s is %(py4)sr>   r:   r;   rA   )%r'   r(   r!   r   r)   r   r   r   r   r   r@   r   rr   r	   rs   rt   rA   ru   r
   rv   rw   rx   rC   r[   ry   rz   r}   r~   rF   rG   rH   rI   rJ   rK   rL   rM   call_args_list)r   r*   r   r!   r+   r   r   r   r   r   r   rP   r   rO   r^   r_   _kwargsrS   rT   rQ   rR   s                         r   ,test_adjustment_global_only_and_update_scaleCTestAdjustmentLearning.test_adjustment_global_only_and_update_scale   s}   >+>?/8,f5-u5A\\5yrR:ITVW%9 X S )($(q"$5!dO		#	'	(W%!" "'W%!""'\\');
,.@229>RS#..3!3!33333.333333|3333|333.333!3333333$//414144444/444444}4444}444/44414444444!-!<!<IAv!'?2d2?d22222?d222?222d2222222!,/747/477777/4777/77747777777 "=
 
C XW SRJ 
 
sI   0S
R/SS$4K*SS$/
R>	9S
S
S!	S$$
S2c                    UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS5        SS	KJn  U" 5         [        R                  " [
        S
/ S9   [        R                  " [        S
/ S9   [        US9nSSS5        SSS5        SWR                  S'   SUR                  S'   SUR                  S'   SUR                  S'   UR                  nSnSnSnSo" XgX5      n
SoU:H  o(       Gd#  [        R                  " SU4SX45      S[        R                   " 5       ;   d  [        R"                  " U5      (       a  [        R$                  " U5      OS[        R$                  " U5      [        R$                  " U5      [        R$                  " U5      [        R$                  " U5      [        R$                  " U	5      [        R$                  " U
5      [        R$                  " U5      S.-  nSSU0-  n['        [        R(                  " U5      5      eS=n=n=n=n=n	=n
=pUR*                  nSnSnSnSo" XgX5      n
So* oU:H  o(       Gd#  [        R                  " SU4S X45      S[        R                   " 5       ;   d  [        R"                  " U5      (       a  [        R$                  " U5      OS[        R$                  " U5      [        R$                  " U5      [        R$                  " U5      [        R$                  " U5      [        R$                  " U	5      [        R$                  " U
5      [        R$                  " U5      S.-  nS!S"U0-  n['        [        R(                  " U5      5      eS=n=n=n=n=n	=n
=n=pg! , (       d  f       GN= f! , (       d  f       GN= f)#z#Test barrier/handicap toggle flags.r   r   r   r   ADJ_BARRIER_ENABLEDfalseADJ_HANDICAP_ENABLEDr   r    r"   r#   r%   N      $@)Vr/   r0   r1      g      )r   r/   r0   rX   r   r/   rg   r1   r   r<   r   r+   r   r   r   rX   r2   )z~%(py12)s
{%(py12)s = %(py2)s
{%(py2)s = %(py0)s._get_handicap_adjustment
}(%(py4)s, %(py6)s, %(py8)s, %(py10)s)
} == -%(py15)szassert %(py18)spy18)r'   r(   r!   r   r)   r   r   r   rE   r   r\   handicap_adjustment_samplesr   rF   rG   rH   rI   rJ   rK   rL   rM   _get_handicap_adjustment)r   r*   r   r!   r+   rP   rO   r]   r   r   r   r   r   r   r   @py_assert16@py_format17@py_format19s                     r   test_adjustment_feature_toggles6TestAdjustmentLearning.test_adjustment_feature_toggles   s   >+>?/80':16:A\\5yrR:ITVW%9 X S GK""#BCMN))*IJHL##$DEOP**+KL--LcL8LTL1L-cTELLLLLLLELLLLLLvLLLLvLLL-LLLcLLL8LLLTLLL1LLLELLLLLLLLLLL..OsOHOdOBO.sdGOCO4O4OOOOOGOOOOOOvOOOOvOOO.OOOsOOOHOOOdOOOBOOOGOOOCOOOOOOOOO XW SRs$   0N.
NN.
N+	&N..
N= N)__name__
__module____qualname____firstlineno____doc__pytestfixturer   r+   rU   r`   r   r   r   r   r   __static_attributes__r   r   r   r   r      s\    6^^  ^^8 8">2@212fI P088tPr   r   c                   `    \ rS rSrSr\R                  S 5       rS rS r	S r
S rS rS	 rS
rg)TestRatingDeviationi	  z.Tests for Rating Deviation (RD) functionality.c                 t   UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS5        UR                  SS	5        UR                  S
S5        UR                  SS	5        UR                  SS5        UR                  SS5        SSKJn  U" 5         [        5       $ )z%Create rating engine with RD enabled.r   r   r   r   r   	ENABLE_RDr   
INITIAL_RDz350.0RD_MINz50.0RD_MAXRD_DECAY_PER_RACEz15.0RD_INFLATION_PER_DAYr   r   r    )r'   r(   r!   r   )r   r*   r!   s      r   engine_with_rd"TestRatingDeviation.engine_with_rd  s     	?F3?F3>+>?;/<18V,8W-.7159A~r   c                    UR                  [        R                  S5      nUR                  nSoCU:H  oU(       d  [        R
                  " SU4SX445      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS	=n=pTg	)
z!Test initial RD is set correctly.r1        u@r<   )z*%(py2)s
{%(py2)s = %(py0)s.rd
} == %(py5)sstaterp   rY   rZ   N)r{   r   r|   rdrF   rG   rH   rI   rJ   rK   rL   rM   )r   r   r   rP   r   rO   r^   r_   s           r   test_initial_rd#TestRatingDeviation.test_initial_rd  s    11*2B2BAFxx 5 5     x      u    u   x   5       r   c                 :   UR                  [        R                  S5      nUR                  n/ nUR	                  [        R                  SSS[        SSS5      US9  UR                  oUU:  of(       d  [        R                  " SU4SXS45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	S
.-  nSSU0-  n[        [        R                  " U5      5      eS=pVUR                  nSoU	-
  n
Sn[        X5      oU:H  of(       Gd  [        R                  " SU4SX\45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OSS	[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS	[        R                  " U	5      [        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=n=n	=n
=pg)z0Test RD decreases after participating in a race.r1   r   re   rf   deltarace_id	race_dateupdates<)z)%(py2)s
{%(py2)s = %(py0)s.rd
} < %(py4)sr   
initial_rdr6   r:   r;   Ng      .@      I@r<   )z`%(py2)s
{%(py2)s = %(py0)s.rd
} == %(py12)s
{%(py12)s = %(py4)s((%(py5)s - %(py7)s), %(py10)s)
}max)r7   r8   r9   rq   rZ   r   r   zassert %(py14)spy14)r{   r   r|   r   _apply_updater   rF   rG   rH   rI   rJ   rK   rL   rM   r   )r   r   r   r   r   rP   rO   rQ   rR   @py_assert6@py_assert8r   r   @py_format13@py_format15s                  r   test_rd_decay_after_race,TestRatingDeviation.test_rd_decay_after_race$  s   11*2B2BAFXX
$$4B' 	% 	
 xx$*$$$$$x$$$$$$u$$$$u$$$x$$$$$$*$$$$*$$$$$$$xx7D7D07$73077777777x777777u7777u777x777777377773777777z7777z777D777$777777777777r   c                    UR                  [        R                  S5      n/ nUR                  [        R                  SSS[	        SSS5      US9  UR                  [        R                  SSS[	        SSS5      US9  UR
                  nSoTULof(       d  [        R                  " S	U4S
XE45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS=n=peg)z"Test RD increases with inactivity.r1   r   re   r   r2   ri      N)is not)z.%(py2)s
{%(py2)s = %(py0)s.rd
} is not %(py5)sr   rp   rY   rZ   )r{   r   r|   r   r   r   rF   rG   rH   rI   rJ   rK   rL   rM   )	r   r   r   r   rP   r   rO   r^   r_   s	            r    test_rd_inflation_for_inactivity4TestRatingDeviation.test_rd_inflation_for_inactivity7  s    11*2B2BAF $$4A& 	% 	
 	$$4B' 	% 	
 xx#t#t#####x######u####u###x###t#######r   c                    UR                  [        R                  S5      n/ n[        S5       H0  nUR	                  [        R                  SSU[        SSS5      US9  M2     UR                  nSoeU:  ow(       d  [        R                  " SU4S	XV45      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n	[        [        R                  " U	5      5      eS=n=pvUR                  [        R                  S5      n
[        SSS5      U
l        UR	                  [        R                  SSS[        SSS5      US9  U
R                  nSoeU:*  ow(       d  [        R                  " SU4SXV45      S[        R                  " 5       ;   d  [        R                  " U
5      (       a  [        R                  " U
5      OS[        R                  " U5      [        R                  " U5      S.-  nSSU0-  n	[        [        R                  " U	5      5      eS=n=pvg)z$Test RD respects min and max bounds.r1   2         ?re   rf   r   r   )>=)z*%(py2)s
{%(py2)s = %(py0)s.rd
} >= %(py5)sr   rp   rY   rZ   Nri   i  rh      r   r   )<=)z*%(py2)s
{%(py2)s = %(py0)s.rd
} <= %(py5)sstate2)r{   r   r|   ranger   r   r   rF   rG   rH   rI   rJ   rK   rL   rM   last_race_date)r   r   r   r   irP   r   rO   r^   r_   r   s              r   test_rd_min_max_bounds*TestRatingDeviation.test_rd_min_max_boundsV  s   11*2B2BAF rA((  tQ+ )   xx44xuux4  22:3C3CQG $T1a 0$$4R( 	% 	
 yy!E!E!!!!!y!!!!!!v!!!!v!!!y!!!E!!!!!!!r   c                 >
   UR                  [        R                  S5      nUR                  [        R                  S5      n[        R
                  nSoT" U5      ocU:H  ow(       Gd"  [        R                  " SU4SX645      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n	[        [        R                  " U	5      5      eS
=n=n=pV/ n
[        S5       H0  nUR                  [        R                  SSU[!        SSS5      U
S9  M2     UR                  [        R                  S5      nX:  ow(       d  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS
nSoU:  ow(       d  [        R                  " SU4SX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  nSSU0-  n[        [        R                  " U5      5      eS
=pSUR"                  S-  -  n[        R
                  oD" U5      nUU:H  ow(       GdY  [        R                  " SU4SUU45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS[        R                  " U5      S.-  nSS U0-  n[        [        R                  " U5      5      eS
=n=nng
)!z%Test K-factor adjustment based on RD.r1         8@r<   zL%(py0)s == %(py8)s
{%(py8)s = %(py4)s
{%(py4)s = %(py2)s.approx
}(%(py6)s)
}k_newr   r7   r8   r9   r;   r   assert %(py10)sr   N   r   re   rf   r   r   )z%(py0)s < %(py2)sk_established)r7   r8   zassert %(py4)sr9   r   )z%(py0)s < %(py3)s)r7   r   zassert %(py5)srq   r   )zL%(py0)s == %(py7)s
{%(py7)s = %(py4)s
{%(py4)s = %(py2)s.approx
}(%(py5)s)
}
expected_k)r7   r8   r9   rq   rZ   zassert %(py9)spy9)r{   r   r|   get_effective_k_factorr   approxrF   rG   rH   rI   rJ   rK   rL   rM   r   r   r   r   )r   r   	state_newr  rO   r]   r   rP   @py_format9@py_format11r   r  r  @py_format3rQ   rT   @py_format4r^   r  r   r_   @py_format10s                         r   test_effective_k_factor_with_rd3TestRatingDeviation.test_effective_k_factor_with_rdy  s    #55j6F6FJ	55j6F6FJ +d+d++++++++u++++++u++++u++++++++++++++++d+++++++++++ rA((  tQ+ )   '==j>N>NPQR$$$$$}$$$$$$}$$$$}$$$$$$u$$$$u$$$$$$$##t#####}######}####}###t####### Y\\E12
 &9j 99} 999999} 9999999}9999}9999999999999999999j9999j999 99999999r   c                 
   UR                  SS5        SSKJn  U" 5         [        5       nUR	                  [
        R                  S5      nUR	                  [
        R                  S5      n[        R                  nSov" U5      oU:H  o(       Gd"  [        R                  " SU	4S	XH45      S
[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OS
S[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n
SSU
0-  n[        [        R                   " U5      5      eS=n	=n=px[        R                  nSov" U5      oU:H  o(       Gd"  [        R                  " SU	4S	XX45      S[        R                  " 5       ;   d  [        R                  " U5      (       a  [        R                  " U5      OSS[        R                  " 5       ;   d  [        R                  " [        5      (       a  [        R                  " [        5      OS[        R                  " U5      [        R                  " U5      [        R                  " U5      S.-  n
SSU
0-  n[        [        R                   " U5      5      eS=n	=n=pxg)z3Test K-factor remains constant when RD is disabled.r   r   r   r    r1   ri   r  r<   r  k1r   r  r	  r   Nk2)r'   r(   r!   r   r  r   r|   r   r  rF   rG   rH   rI   rJ   rK   rL   rM   )r   r*   r!   engine_no_rdr  r  rO   r]   r   rP   r  r  s               r   "test_effective_k_factor_without_rd6TestRatingDeviation.test_effective_k_factor_without_rd  s   ;0A#~ 001A1A1E001A1A1E]](4(]4((((((((r((((((r((((r((((((V((((V(((](((4(((((((((((]](4(]4((((((((r((((((r((((r((((((V((((V(((](((4(((((((((((r   r   N)r   r   r   r   r   r   r   r   r   r   r   r  r  r  r   r   r   r   r   r   	  s:    8^^ $!
8&$>!"F:>)r   r   )r   builtinsrH   _pytest.assertion.rewrite	assertionrewriterF   datetimer   unittest.mockr   r   r   packages.core.ratings.enginer   packages.core.storage.modelsr   r   r	   r
   "packages.core.storage.repositoriesr   r   r   r   r   r   r   <module>r'     s?    5     %  5 K KvP vPr]) ])r   