o
    Ý3âiôi  ã                   @   s  d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	 ej
ejdd e d¡Ze d¡ dZd	Ze j d
e j e j e j e¡¡d¡¡Ze jedd G dd„ deeƒZdedefdd„Zdedefdd„Zdedefdd„Z dCdd„Z!dd„ Z"dd„ Z#dd „ Z$d!d"„ Z%d#d$„ Z&ded%ee defd&d'„Z'dedefd(d)„Z(ded*ee defd+d,„Z)dedefd-d.„Z*ded/ed0ed1ed2ed3ee fd4d5„Z+d6ed7efd8d9„Z,d:ede-fd;d<„Z.dCded=ee d>ee d?ee d3ee d@eeeee f  fdAdB„Z/dS )Dé    N)ÚEnum)ÚDictÚListÚOptionalÚAnyz4%(asctime)s | %(levelname)s | %(name)s | %(message)s)ÚlevelÚformatÚassessment_report_processorz>Initializing Agentic Analytics Processor with os module ready.ÚnoneÚ ÚTRAINED_DATA_DIRÚtrained_dataT©Úexist_okc                   @   s   e Zd ZdZdZdZdZdS )ÚTrainingStatusÚqueuedÚ
processingÚ	completedÚfailedN)Ú__name__Ú
__module__Ú__qualname__ÚQUEUEDÚ
PROCESSINGÚ	COMPLETEDÚFAILED© r   r   úk/var/www/eduai.edurigo.com/assessment_competency_evaluation/testing/assessment_report_analysis_processor.pyr      s
    r   Ú	client_idÚreturnc                 C   s   t j tt| ƒ¡S ©N)ÚosÚpathÚjoinÚ	DATA_ROOTÚstr©r   r   r   r   Ú_client_dir   s   r'   c                 C   s   t | ƒ}tj|dd |S )NTr   )r'   r!   Úmakedirs)r   r"   r   r   r   Ú_ensure_client_dir   s   r)   Úqc                 C   s|   t |  dd¡ƒ}t |  d¡pdƒ ¡ }| d¡d  d¡d  ¡ }|r)| ¡ dv r,d	}n| ¡ }| ¡ d
kr8d}|||dœS )NÚidr   ÚcategoryNamezGeneral Knowledgeú>r   ú-)z
input typeÚtestÚuncategorizedÚdefaultzGeneral AssessmentÚgk)Úquestion_idr,   Úskill)r%   ÚgetÚstripÚsplitÚlowerÚtitle)r*   ÚqidÚcatÚroot_domainr4   r   r   r   Ú_classify_question!   s   r=   c           	      C   sZ   t | ƒ}dtjji}ttj |d¡dƒ}t 	||¡ W d   ƒ |S 1 s&w   Y  |S )NÚstatusústatus.jsonÚw)
r)   r   r   ÚvalueÚopenr!   r"   r#   ÚjsonÚdump)	r   Úquestion_bankÚassessment_summaryÚcompleted_users_dataÚuser_attempt_detailsÚmanager_mappingr"   ÚmetaÚfr   r   r   Ústart_training_meta6   s   
ÿþrL   c                 C   óZ   t j t| ƒd¡}t j |¡sd S t|dƒ}t |¡W  d   ƒ S 1 s&w   Y  d S )Nr?   Úr©r!   r"   r#   r'   ÚexistsrB   rC   Úload©r   r"   rK   r   r   r   Úget_training_status=   ó
   $ÿrS   c                 C   rM   )Núresult.jsonrN   rO   rR   r   r   r   Úget_analysis_resultC   rT   rV   c                   C   s   g S r    r   r   r   r   r   Úlist_all_clientsI   ó    rW   c                 C   s   d S r    r   r&   r   r   r   Údelete_client_dataJ   rX   rY   c                   C   s   dS )NTr   r   r   r   r   Úcheck_ollama_healthK   rX   rZ   Ú	questionsc                 C   óÊ   t | ƒ}tj |d¡}g }tj |¡r-t|dƒ}t |¡}W d  ƒ n1 s(w   Y  | |¡ t|dƒ}t 	||¡ W d  ƒ n1 sHw   Y  t
|ƒ}t dt
|ƒ› d| › d|› ¡ d|iS )	z¦
    Accumulates a batch of question bank data for a client.
    Appends to an existing JSON file so multiple batches can be accumulated
    before finalization.
    úaccumulated_questions.jsonrN   Nr@   úAccumulated z questions for client ú	. Total: Útotal_questions©r)   r!   r"   r#   rP   rB   rC   rQ   ÚextendrD   ÚlenÚloggerÚinfo)r   r[   r"   Ú
store_fileÚexistingrK   Útotalr   r   r   Úaccumulate_question_bankR   s   ÿ
ÿ ri   c              	   C   sB  t | ƒ}tj |d¡}tj |¡st d| › ¡ ddiS t|dƒ}t 	|¡}W d  ƒ n1 s2w   Y  i }i }|D ] }t
|ƒ}|d }	|d }
|d	 }|
||< | |
d¡d
 ||
< q=||t|ƒdœ}ttj |d¡dƒ}t ||¡ W d  ƒ n1 sw   Y  t d| › dt|ƒ› dt|ƒ› ¡ t|ƒt|ƒdœS )z®
    Processes all accumulated question bank data for a client.
    Builds the skill classification map and stores it for later use
    by the user attempt finalization.
    r]   z*No accumulated questions found for client r`   r   rN   Nr,   r4   r3   é   )Úqid_to_skillÚ
cat_countsr`   úquestion_classification.jsonr@   z#Finalized question bank for client z. Total questions: z
, Skills: )r`   Úskills)r)   r!   r"   r#   rP   rd   ÚwarningrB   rC   rQ   r=   r5   rc   rD   re   )r   r"   rf   rK   rE   rl   rk   r*   Úclsr;   r4   r:   Úclassification_datar   r   r   Úfinalize_question_bankk   s<   ÿýÿÿÿrr   Úattemptsc                 C   r\   )	z”
    Accumulates a batch of user attempt detail data for a client.
    Appends to an existing JSON file so multiple batches can be accumulated.
    úaccumulated_attempts.jsonrN   Nr@   r^   z attempts for client r_   Útotal_attemptsra   )r   rs   r"   rf   rg   rK   rh   r   r   r   Úaccumulate_user_attempts˜   s   ÿ
ÿ rv   c                 C   sˆ  t | ƒ}tj |d¡}tj |¡s!t d| › d¡ i }i }d}n,t|dƒ}t 	|¡}W d  ƒ n1 s6w   Y  | 
di ¡}| 
di ¡}| 
d	d¡}tj |d
¡}tj |¡set d| › ¡ g }	nt|dƒ}t 	|¡}	W d  ƒ n1 szw   Y  zdtjji}
ttj |d¡dƒ}t |
|¡ W d  ƒ n1 s¡w   Y  t| |||||	ƒ dtjji}
ttj |d¡dƒ}t |
|¡ W d  ƒ n1 sÐw   Y  dD ]}tj ||¡}tj |¡rët |¡ q×t d| › dt|	ƒ› ¡ dt|	ƒdœW S  tyC } z6t d| › d|› ¡ tjjt|ƒdœ}
ttj |d¡dƒ}t |
|¡ W d  ƒ ‚ 1 s9w   Y  ‚ d}~ww )u.  
    Processes all accumulated user attempt data against the previously-processed
    question bank classification. Generates the full report (admin, manager, user)
    and stores the final result.

    This is the terminal step â€” after this, the report is available via GET /report/{client_id}.
    rm   z,No question classification found for client z. Running with empty map.r   rN   Nrk   rl   r`   rt   z)No accumulated attempts found for client r>   r?   r@   )r]   rt   rm   z#Finalized user attempts for client z. Attempts: r   )r>   ru   z*Error finalizing user attempts for client ú: ©r>   Úerror)r)   r!   r"   r#   rP   rd   ro   rB   rC   rQ   r5   r   r   rA   rD   Ú_run_analysis_from_accumulatedr   Úremovere   rc   Ú	Exceptionry   r   r%   )r   r"   Úcls_filerk   rl   Útotal_q_bankrK   Úcls_dataÚattempts_filerH   rJ   Útmp_fileÚtmp_pathÚer   r   r   Úfinalize_user_attempts°   sn   ÿÿÿþÿ
€ÿþ
ÿþ€ûr„   r"   rk   rl   r~   rH   c           3      C   s„  t  d| › ¡ t| ¡ ƒt| ¡ ƒdddœ}i }| ¡ D ]	}dddœ||< qi }	i }
i }i }i }d}d}tƒ }|D ]J}t| dd¡ƒ}t| d	¡pQ| d
¡pQ|ƒ}t| d¡p_| d¡p_dƒ}t| d|¡ƒ}|||< | |¡ ||	vrƒi |	|< tƒ ||< i |
|< ||  |¡ ||vr˜|i ddi dœ||< | dg ¡D ]æ}| dd¡s§qžt| d¡ƒ}| |d¡}t	|ƒ}|r¼dnd}|d7 }||7 }||vrÑdddœ||< || d  |7  < || d  d7  < ||	| vrôdddœ|	| |< |	| | d  |7  < |	| | d  d7  < ||
| vrtƒ |
| |< |
| |  |¡ ||| d vr7dddœ|| d |< || d | d  |7  < || d | d  d7  < || d  d7  < || d  |7  < ||| d vrytƒ || d |< || d |  |¡ qžq:t
|dƒ}|dkr™t|| d dƒnd}|t|ƒ|t|	 ¡ ƒd œ}g }|	 ¡ D ]k\}} td!d"„ |  ¡ D ƒƒ}!td#d"„ |  ¡ D ƒƒ}"|!dkrÖt|"|! d dƒnd}#d$d%„ |
 |i ¡ ¡ D ƒ}$t|$ ¡ ƒ}%t|$ ¡ ƒt|$ ¡ ƒdd&dœ}&| || ||¡|%t| |g ¡ƒ|#d'œ|&t
| d(ƒd)œd*œ¡ q®g }'| ¡ D ]^\}(})|)d+ }*|)d } |)d }+|)d },|+dkrBt|,|+ d dƒnd}-d,d%„ |) di ¡ ¡ D ƒ}.t|. ¡ ƒ}/t|. ¡ ƒt|. ¡ ƒdd-dœ}0|' |(|*|/|-d.œ|0t
| d/|*› d0ƒd)œd1œ¡ q |||d)œd2œ||'d3œ}1ttj |d4¡d5ƒ}2tj|1|2d6d7 W d8  ƒ n	1 s©w   Y  t  d9| › d:t|ƒ› d;t|ƒ› ¡ d8S )<zŽ
    Core analysis logic extracted from run_training_pipeline.
    Works with pre-classified question data and accumulated user attempts.
    zRunning analysis for client ÚdoughnutúQuestion Skill Mapping©ÚlabelsÚdataÚtyper9   r   ©Úquestions_correctÚquestions_attemptedÚuserNameÚUnknown_UserÚuserIdÚuser_idÚ	managerIdÚ
manager_idÚ
UnassignedÚmanagerName©Ú	user_namern   Ú	attemptedÚcorrectÚunique_qr‰   Úis_attemptedTr3   ÚUncategorizedrj   rŒ   r   rn   r˜   r™   rš   ú%Overall Skill Distribution & Accuracyéd   é   ç        ©Útotal_questions_in_bankÚtotal_usersÚaverage_accuracyÚtotal_managersc                 s   ó    | ]	}|  d d¡V  qdS ©r   r   N©r5   ©Ú.0Úsr   r   r   Ú	<genexpr>`  ó   € z1_run_analysis_from_accumulated.<locals>.<genexpr>c                 s   r¦   ©rŒ   r   Nr¨   r©   r   r   r   r¬   a  r­   c                 S   ó   i | ]	\}}|t |ƒ“qS r   ©rc   ©rª   ÚskÚqidsr   r   r   Ú
<dictcomp>d  ó    z2_run_analysis_from_accumulated.<locals>.<dictcomp>úTeam Question Skill Mapping©r`   r£   r¤   ú"Team Skill Distribution & Accuracy©Úquestion_skill_mapping_chartÚ!skill_distribution_accuracy_chart©r“   Úmanager_nameÚsummaryÚ
chart_datar—   c                 S   r¯   r   r°   r±   r   r   r   r´   „  rµ   úUser Question Skill Mapping©r`   r¤   ú$User Skill Distribution & Accuracy (ú)©r‘   r—   r¾   r¿   ©r¾   r¿   ©Úadmin_reportÚmanager_reportsÚuser_reportsrU   r@   é   ©ÚindentNzAnalysis complete for client z	. Users: z, Managers: )rd   re   ÚlistÚkeysÚvaluesÚsetr%   r5   ÚaddÚ_evaluate_correctnessÚbuild_skill_chartÚroundrc   ÚitemsÚsumÚappendrB   r!   r"   r#   rC   rD   )3r   r"   rk   rl   r~   rH   Úchart1_adminÚadmin_skill_statsr«   Úmanager_statsÚmanager_unique_qÚ
user_statsÚmanager_usersÚmanager_namesÚglobal_attemptedÚglobal_correctÚall_user_idsÚattemptr—   r‘   r“   r½   Úq_datar:   r4   Ú
is_correctÚcorr_valÚchart2_adminÚ
global_accÚadmin_summaryrÈ   ÚmidÚstatsÚmgr_attemptedÚmgr_correctÚmgr_accÚmgr_cat_countsÚmgr_total_questionsÚchart1_managerrÉ   ÚuidÚudataÚunameÚu_attemptedÚ	u_correctÚu_accÚusr_cat_countsÚusr_total_questionsÚchart1_userÚresultrK   r   r   r   rz   ø   s  

ü


Ý
% 
ü 

ü
ýþø 

üþþùþþ÷ÿÿÿrz   Úskill_statsr9   c           	      C   s€   t |  ¡ ƒ}g }|D ]*}| | }| dd¡}| dd¡}|dkr/|| d }| t|dƒ¡ q
| d¡ q
|d|dœgd	|d
œS )Nr   r   rŒ   rž   rŸ   r    z
Accuracy %)Úlabelr‰   Úbar)rˆ   ÚdatasetsrŠ   r9   )rÍ   rÎ   r5   r×   rÔ   )	rû   r9   rˆ   Údata_accuracyr²   Ús_datar˜   r™   Úaccr   r   r   rÓ   ®  s$   þÿ÷rÓ   rã   c                 C   sL  t |  dd¡ƒ}|dkrdS t|  d¡pdƒ ¡  ¡ }t|  d¡p"dƒ ¡  ¡ }|s,dS ||kr2dS d|v rXd|v rXtd	d
„ | d¡D ƒƒ}tdd
„ | d¡D ƒƒ}||krXdS |  dg ¡}|r¤t|tƒr¤d}d}d}	|D ](}
t	|
 dd¡ƒ}t	|
 dd¡ƒ}|r…|d7 }|r|r|d7 }|r•|s•|	d7 }	qm|dkr¤||kr¤|	dkr¤dS dS )NÚobtained_marksr   TÚcorrect_answerr   Úuser_answerFú,c                 S   ó   g | ]}|  ¡ ‘qS r   ©r6   ©rª   Úxr   r   r   Ú
<listcomp>Ù  ó    z)_evaluate_correctness.<locals>.<listcomp>c                 S   r  r   r  r  r   r   r   r
  Ú  r  Úquestion_optionÚcorrect_answer_optionrj   )
Úfloatr5   r%   r6   r8   Úsortedr7   Ú
isinstancerÍ   Úbool)rã   ÚobtainedÚexpectedÚactualÚexp_listÚact_listÚ	q_optionsÚtrue_correctsÚ	user_hitsÚuser_missesÚoptÚis_truth_corrÚis_user_selr   r   r   rÒ   É  s@   €rÒ   rE   rF   rG   rI   c           <      C   s8  z8t | ƒ}dtjji}ttj |d¡dƒ}t 	||¡ W d   ƒ n1 s'w   Y  t
 d| › ¡ i }	i }
|D ] }t|ƒ}|d }|d }|d }||
|< |	 |d¡d	 |	|< q:t|	 ¡ ƒt|	 ¡ ƒd
ddœ}i }|	 ¡ D ]	}dddœ||< qpi }i }i }i }i }d}d}t|ƒ}tƒ }|D ]M}t| dd¡ƒ}t| d¡p¨| d¡p¨|ƒ}t| d¡p¶| d¡p¶dƒ}t| d|¡ƒ} | ||< | |¡ ||vrÚi ||< tƒ ||< i ||< ||  |¡ ||vrï|i ddi dœ||< | dg ¡D ]é}!|! dd¡sþqõt|! d¡ƒ}|
 |d¡}t|!ƒ}"|"rd	nd}#|d	7 }||#7 }||vr*dddœ||< || d  |#7  < || d  d	7  < ||| vrNdddœ|| |< || | d  |#7  < || | d  d	7  < ||| vrttƒ || |< || |  |¡ ||| d vr‘dddœ|| d |< || d | d  |#7  < || d | d  d	7  < || d  d	7  < || d  |#7  < ||| d  vrÓtƒ || d  |< || d  |  |¡ qõq‘t|d!ƒ}$|dkrót|| d" d#ƒnd$}%|t|ƒ|%t| ¡ ƒd%œ}&g }'| ¡ D ]k\}(})td&d'„ |) ¡ D ƒƒ}*td(d'„ |) ¡ D ƒƒ}+|*dkr0t|+|* d" d#ƒnd$},d)d*„ | |(i ¡ ¡ D ƒ}-t|- ¡ ƒ}.t|- ¡ ƒt|- ¡ ƒd
d+dœ}/|' |(| |(|(¡|.t| |(g ¡ƒ|,d,œ|/t|)d-ƒd.œd/œ¡ qg }0| ¡ D ]^\}1}2|2d0 }3|2d })|2d }4|2d }5|4dkrœt|5|4 d" d#ƒnd$}6d1d*„ |2 d i ¡ ¡ D ƒ}7t|7 ¡ ƒ}8t|7 ¡ ƒt|7 ¡ ƒd
d2dœ}9|0 |1|3|8|6d3œ|9t|)d4|3› d5ƒd.œd6œ¡ qz|&||$d.œd7œ|'|0d8œ}:ttj |d9¡dƒ}tj	|:|d:d; W d   ƒ n	1 sw   Y  dtjji}ttj |d¡dƒ}t 	||¡ W d   ƒ n	1 s*w   Y  t
 d<| › ¡ W d S  ty› }; zUt
 d=| › d>|;› ¡ tjjt|;ƒd?œ}t| ƒ}tj  |¡r‰ttj |d¡dƒ}t 	||¡ W d   ƒ n1 s}w   Y  W Y d };~;d S W Y d };~;d S W Y d };~;d S d };~;ww )@Nr>   r?   r@   zProcessing client r,   r4   r3   r   rj   r…   r†   r‡   r‹   rŽ   r   r   r‘   r’   r“   r”   r•   r–   r‰   r›   Trœ   rŒ   r   rn   r˜   r™   rš   r   rž   rŸ   r    r¡   c                 s   r¦   r§   r¨   r©   r   r   r   r¬   j  r­   z(run_training_pipeline.<locals>.<genexpr>c                 s   r¦   r®   r¨   r©   r   r   r   r¬   k  r­   c                 S   r¯   r   r°   r±   r   r   r   r´   n  rµ   z)run_training_pipeline.<locals>.<dictcomp>r¶   r·   r¸   r¹   r¼   r—   c                 S   r¯   r   r°   r±   r   r   r   r´   Ž  rµ   rÀ   rÁ   rÂ   rÃ   rÄ   rÅ   rÆ   rU   rÊ   rË   zSuccessfully processed client zError processing client rw   rx   )!r)   r   r   rA   rB   r!   r"   r#   rC   rD   rd   re   r=   r5   rÍ   rÎ   rÏ   rc   rÐ   r%   rÑ   rÒ   rÓ   rÔ   rÕ   rÖ   r×   r   r|   ry   r   r'   rP   )<r   rE   rF   rG   rH   rI   r"   rJ   rK   rl   rk   r*   rp   r;   r4   r:   rØ   rÙ   r«   rÚ   rÛ   rÜ   rÝ   rÞ   rß   rà   r~   rá   râ   r—   r‘   r“   r½   rã   rä   rå   ræ   rç   rè   rÈ   ré   rê   rë   rì   rí   rî   rï   rð   rÉ   rñ   rò   ró   rô   rõ   rö   r÷   rø   rù   rú   rƒ   r   r   r   Úrun_training_pipelineõ  s>  ÿ

ü



Ù
) 
ü 

ü
ýþø 

üþþùþþ÷ÿÿ,ÿÿ€ûr  r    )0r!   rC   ÚloggingÚenumr   Útypingr   r   r   r   ÚbasicConfigÚINFOÚ	getLoggerrd   re   ÚOLLAMA_MODELÚOLLAMA_BASE_URLÚenvironr5   r"   r#   ÚdirnameÚabspathÚ__file__r$   r(   r%   r   Úintr'   r)   Údictr=   rL   rS   rV   rW   rY   rZ   ri   rr   rv   r„   rz   rÓ   r  rÒ   r  r   r   r   r   Ú<module>   sV    

(
-Hÿþýüû
ú 7H,