
     hE.                         S SK Jr  S SKJrJr  S SKJrJrJr  SSKJ	r	J
r
Jr  SSKJr  S SKJr  S SKr\R"                  " \5      r " S	 S
5      rg)    )timezone)datetime	timedelta)ListDictOptional   )UserPatternMLModelAnomalyAlert)PushNotificationService)StampNc                   &   \ rS rSrSrS rS\S\4S jrS\4S jr	S\S	\
S\4S
 jrS\S\4S jrS\S\S\\   4S jrS\S\S\\   4S jrS\S\S\\   4S jrS\S\S\4S jrS\S\4S jrS\4S jrS\4S jrS\S\S\4S jrS\
S\4S jrSrg)	MLService   z6Main ML Service with exact time scheduling integrationc                 "    [        5       U l        g )N)r   push_service)selfs    $D:\TimeStamps\ml_service\services.py__init__MLService.__init__   s    35    user_idreturnc                 r    [         R                  R                  US9n[        U5      S:  a  SS0$ U R	                  U5      nU[
        R                  " 5       R                  5       [        U5      UR                  5        VVs0 s H  u  pEU[        U5      _M     snn0 S.nUR                  5        H.  u  px[        U5      S:  d  M  U R                  Xx5      n	XS   U'   M0     U R                  X5        U$ s  snnf ! [         a/  n
[        R                  SU
 35        S[        U
5      0s S	n
A
$ S	n
A
ff = f)
z1
Analyze user patterns using question_type field
user__id   errorz!Insufficient data for ML analysis)r   analysis_datetotal_stampscategorized_stampspatterns   r#   zError analyzing user patterns: N)r   objectsfilterlen"categorize_stamps_by_question_typer   now	isoformatitemsanalyze_pattern_typesave_patterns_to_database	Exceptionloggerr   str)r   r   stampsr"   kvresultsquestion_type
stamp_listpattern_analysises              r   analyze_user_patternsMLService.analyze_user_patterns   s+   	%]]))7);F6{Q!DEE "&!H!H!P #!)!9!9!; #F=O=U=U=W&X=WTQq#a&y=W&XG .@-E-E-G)z?a''+'@'@'[$9IJ'6 .H **7<N 'Y  	%LL:1#>?SV$$	%s;   /C= AC= C7)C= .C= 7C= =
D6$D1+D61D6c                 r    / / / / S.nU H)  nUR                   nXB;   d  M  X$   R                  U5        M+     U$ )z.
Categorize stamps using stamp_function field
)clock_in	lunch_outlunch_in	clock_out)stamp_functionappend)r   r1   r#   stampr5   s        r   r(   ,MLService.categorize_stamps_by_question_type6   sN    
 	
 E!00M ('..u5  r   r5   r1   c                    SSK nU Vs/ s H  oDR                  PM     nnU Vs/ s H  oDR                  PM     nnU Vs/ s H  opR                  U5      PM     nnUR	                  U5      n	UR                  U5      n
U R                  [        U5      U
5      nUU R                  [        U	5      5      [        U
S-  5      U[        U5      U R                  U5      S.$ s  snf s  snf s  snf )z
Analyze specific pattern type
r   N<   )r5   average_timevariance_minutesconfidence_scoresample_sizepattern_strength)numpytimedatetime_to_secondsmeanstdcalculate_confidencer'   seconds_to_timeintcalculate_pattern_strength)r   r5   r1   nprB   timesdatesttimes_secondsmean_secondsstd_seconds
confidences               r   r,   MLService.analyze_pattern_typeJ   s     	)/00)/00 ;@@%Q--a0%@ww}-ff]+ ..s5z;G
 + 00\1BC #K"$4 5 *u: $ ? ? F
 	
 10 As   CC"C'r4   c           
          SU;  a  gUS   R                  5        H5  u  p4[        R                  R                  UUUS   US   US   US   S.S9  M7     g)	z!Save learned patterns to databaser#   NrF   rG   rH   rI   )rF   rG   rH   rI   )r   r5   defaults)r+   r
   r%   update_or_create)r   r   r4   r5   pattern_datas        r   r-   #MLService.save_patterns_to_databased   so    W$+2:+>+D+D+F'M00+$0$@(45G(H(45G(H#/#>	 1 	 ,Gr   	new_stampc           	      >    U R                  X5      nU(       a;  [        R                  R                  UUR                  UR
                  SSUS   S9  U$ U R                  X5      nU(       a  U$ g! [         a"  n[        R                  SU 35         SnAgSnAff = f)z5
Detect anomalies for new stamp using stamp_function
g      ?sequence_detectionseverity)r   stamp_idr5   anomaly_scorealgorithm_usedrf   NzError detecting anomalies: )
detect_sequence_anomaliesr   r%   createidr@   detect_time_anomalyr.   r/   r   )r   r   rc   sequence_anomalytime_anomalyr8   s         r   detect_anomalies_for_new_stamp(MLService.detect_anomalies_for_new_stampu   s    	#==gQ$$++#&\\"+":":"%#7-j9 ,  ('  33GGL## 	LL6qc:;	s   AA0 A0 0
B:BBc                     [         R                  R                  US9R                  UR                  S9R                  SS5      R                  5       nU(       d  gUR                  nUR                  n/ SQnXT4nXv;   a  SSS	U S
U 3SU R                  XT5      S.$ g! [         a"  n[        R                  SU 35         SnAgSnAff = f)z1
Detect sequence violations using stamp_function
r   )rl   z-datez-timeN)r<   r<   )r=   r=   )r>   r>   )r?   r?   Tsequence_violationzInvalid sequence: u    → high)
is_anomalyanomaly_typemessagerf   
suggestionz$Error detecting sequence anomalies: )r   r%   r&   excluderl   order_byfirstr@   get_sequence_suggestionr.   r/   r   )	r   r   rc   
last_stampcurrent_question_typelast_question_typeinvalid_sequencessequencer8   s	            r   rj   #MLService.detect_sequence_anomalies   s    #	--  . gg&xx'A%%'  $-$<$<!!+!:!:! +BH,"&$8!34F3GuMbLcd &"&">">?Q"i   	LL?sCD	s   AB A B 
C
(CC
c           
          [         R                  R                  UUR                  S9nU R	                  UR
                  5      nU R	                  UR                  5      nUR                  S-  nUS:  al  [        XT-
  5      U-  nUS:  aV  SSSUR                   SUR                  R                  S	5       S
UR
                  R                  S	5       S3US:  a  SOSUS.$ g! [         R                   a     gf = f)zDetect if stamp time is unusual)r   r5   rE   r   g       @Ttime_deviationzUnusual time for z: %H:%Mz (typical: )g      @ru   medium)rv   rw   rx   rf   z_scoreN)r
   r%   getr@   rN   rF   rL   rG   absstrftimeDoesNotExist)r   r   rc   patterntypical_time_secondsnew_time_secondsvariance_secondsr   s           r   rm   MLService.detect_time_anomaly   sA   	!))--'66 . G $(#7#78L8L#M #33INNC&77"<!#.EFIYYS=&*(8%6y7O7O6PPRS\SaSaSjSjkrSsRtt  AH  AU  AU  A^  A^  _f  Ag  @h  hi  $j.5mF#*   '' 		s   CC" "C98C9	last_typecurrent_typec                 6    SSSSS.nUR                  X4S5      $ )z#Get suggestion for correct sequencez7You're already clocked in. Did you mean to go to lunch?z6You're already on lunch break. Did you mean to return?z:You're already back from lunch. Did you mean to clock out?zCYou're already clocked out. Did you mean to clock in for a new day?rs   zPlease check your sequence.)r   )r   r   r   suggestionss       r   r}   !MLService.get_sequence_suggestion   s/     '`(`&b(m	
 	8:WXXr   c                     [         R                  R                  US9nUUR                  5       / S.nU H  nUS   R	                  UR
                  UR                  5       UR                  R                  S5      UR                  UR                  UR                  UR                  R                  5       S.5        M     U$ ! [         a/  n[        R!                  SU 35        S[#        U5      0s SnA$ SnAff = f)	z&Get summary of user's learned patterns)r   )r   total_patternsr#   r#   r   )r5   question_type_displayrF   rG   rH   rI   last_updatedz%Error getting user patterns summary: r   N)r
   r%   r&   countrA   r5   get_question_type_displayrF   r   rG   rH   rI   r   r*   r.   r/   r   r0   )r   r   r#   summaryr   r8   s         r   get_user_patterns_summary#MLService.get_user_patterns_summary   s    	%"**11'1BH #"*.."2G $
#**%,%:%:-4-N-N-P$+$8$8$A$A'$J(/(@(@(/(@(@#*#6#6$+$8$8$B$B$D,  $ N 	%LL@DESV$$	%s   B>C 
C:$C5/C:5C:c                 Z    UR                   S-  UR                  S-  -   UR                  -   $ )z&Convert time to seconds since midnight  rE   )hourminutesecond)r   rX   s     r   rN   MLService.time_to_seconds  s&    vv}qxx"},qxx77r   secondsc                 D    SSK Jn  US-  nUS-  S-  nUS-  nU" X4U5      $ )z&Convert seconds since midnight to timer   )rL   r   rE   )r   rL   )r   r   rL   hoursminutessecss         r   rR   MLService.seconds_to_time  s2    !4T>b(|ED))r   rI   std_deviationc                 Z    SSK n[        SSUS-  -
  5      n[        SUS-  5      nXE-   S-  $ )zCalculate confidence scorer   Nr	   r         )rK   maxmin)r   rI   r   rU   consistencysample_scores         r   rQ   MLService.calculate_confidence  s:    !Q-$"6781kB./*a//r   rV   c                     SSK nU Vs/ s H  o0R                  U5      PM     nnUR                  U5      nUS:  a  gUS:  a  gUS:  a  gg	s  snf )
zCalculate pattern strengthr   Ni  very_strongi  strongr   moderateweak)rK   rN   rP   )r   rV   rU   rX   rY   r   s         r   rT   $MLService.calculate_pattern_strength  sZ    :?@%Q--a0%@}-3 T!T! As   A)r   N)__name__
__module____qualname____firstlineno____doc__r   r0   r   r9   r(   r   r,   r-   r   r   rp   rj   rm   r}   r   rS   rN   rR   floatrQ   rT   __static_attributes__ r   r   r   r      s,   @6#%S #%T #%JD (
# 
t 
 
4 t "c e PXY]P^ <' ' '8TX> 'R3 5 Xd^ <Y YC YC Y% % %:8C 8*s *0 0E 0e 0  r   r   )django.utilsr   r   r   typingr   r   r   modelsr
   r   r   r   r   stamps.modelsr   logging	getLoggerr   r/   r   r   r   r   <module>r      s<    ! ( ' ' 6 6 1  			8	$V Vr   