
    kj                         S r SSKrSSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKJr  SSKJr  S r " S	 S
5      r " S S5      rS r\S:X  a  S r\R*                  " \" 5       5        gg)z
generate_mcq_ppt.py
===================
MCQ generation module for PPT/PPTX presentation formats.
Generates MCQs from FAISS embeddings created during PPT/PPTX training.
    N)tqdm)OllamaEmbeddings)FAISS)PromptTemplate)
ChatOllamac                    [        SS9nSU  SU S3n[        R                  R                  U5      (       az  [        R                  " U5       Vs/ s H  oDR                  S5      (       d  M  UPM     nnU(       a%  [        R                  " X2SS9n[        S	U 35        U$ [        S
U S35         g[        SU  SU S35        gs  snf )z:Load FAISS embeddings for a specific client and reference.znomic-embed-text)modelzmy_embeddings//z/merged_faiss)z.faissz.pklT)allow_dangerous_deserializationz[PPT] Embeddings loaded from z"[PPT] No embedding files found in .z([PPT] No embeddings found for client_id=z, reference_id=N)	r   ospathisdirlistdirendswithr   
load_localprint)	client_idreference_id
embeddingsreference_dirfembedding_filesvectorss          H/var/www/eduai.edurigo.com/question_generate/testing/generate_mcq_ppt.pyload_all_embeddingsr      s    !(:;J$YKqmLM	ww}}]##&(jj&?b&?::N`Ca1&?b&&}bfgG1-ABN6}oQGH  	8?S_R``abc cs   C,Cc                   <    \ rS rSrSrS rS rS rS rS r	S r
S	rg
)QuestionHistory&   z<Tracks previously generated questions to prevent duplicates.c                 J    SU SU S3U l         U R                  5       U l        g )Nzquestion_history/r
   z.json)	file_pathload	questions)selfr   r   s      r   __init__QuestionHistory.__init__(   s%    ,YKqeL    c                    [         R                  R                  U R                  5      (       ao   [	        U R                  S5       nUR                  5       R                  5       nU(       a  [        [        R                  " U5      5      O	[        5       sS S S 5        $ [        5       $ ! , (       d  f       [        5       $ = f! [        R                   a    [        5       s $ f = f)Nr)r   r   existsr!   openreadstripsetjsonloadsJSONDecodeError)r$   r   contents      r   r"   QuestionHistory.load,   s    77>>$..))$..#.!ffhnn.G7>3tzz'23CE /.
 u /.
 u '' us0   C AB(	C (
B?2C ?C C#"C#c                 0   [         R                  " [         R                  R                  U R                  5      SS9  [        U R                  S5       n[        R                  " [        U R                  5      U5        S S S 5        g ! , (       d  f       g = f)NT)exist_okw)
r   makedirsr   dirnamer!   r+   r/   dumplistr#   )r$   r   s     r   saveQuestionHistory.save6   sT    
BGGOODNN3dC$..#&!IId4>>*A. '&&s   +B
Bc                 :    U R                   R                  U5        g N)r#   addr$   questions     r   r?   QuestionHistory.add;   s    8$r'   c                     XR                   ;   $ r>   )r#   r@   s     r   __contains__QuestionHistory.__contains__>   s    >>))r'   c                 ,    [        U R                  5      $ r>   )lenr#   )r$   s    r   __len__QuestionHistory.__len__A   s    4>>""r'   )r!   r#   N)__name__
__module____qualname____firstlineno____doc__r%   r"   r;   r?   rD   rH   __static_attributes__ r'   r   r   r   &   s#    F%/
%*#r'   r   c                   $    \ rS rSrSrS rS rSrg)RateLimiterE   z%Async rate limiter for LLM API calls.c                 *    Xl         X l        / U l        g r>   max_requestsperiodrequests)r$   rV   rW   s      r   r%   RateLimiter.__init__G   s    (r'   c                   #    [         R                   " 5       nU R                   Vs/ s H  o!U-
  U R                  :  d  M  UPM     snU l        [        U R                  5      U R                  :  aB  U R                  XR                  S   -
  -
  nUS:  a  [
        R                  " U5      I S h  vN   U R                  R                  [         R                   " 5       5        g s  snf  N87f)Nr   )timerX   rW   rG   rV   asynciosleepappend)r$   nowreq
sleep_times       r   waitRateLimiter.waitL   s     iik(,QsT[[9PQt}}!2!22mmA.>(>?JA~mmJ///TYY[) R 0s#   $C)C" C"A(C).C'/9C)rU   N)rJ   rK   rL   rM   rN   r%   rb   rO   rP   r'   r   rR   rR   E   s    /
*r'   rR   c                   ^^^^^#    [        X5      nU(       d  / S4$ [        X5      mUR                  5       n[        SSS9m[	        SS/SS9m[
        R                  " S	[
        R                  5      m/ nS
n[        SSS9mUUUUU4S jn[        USS9 n	[        R                  " 5       S-   n
[        U5      U:  Ga3  [        R                  " 5       U
:  Ga  U[        U5      -
  n[        US5      nS[        R                  " S
S5       3nUR                  U5      nU H  n[        U5      U:  a    OUR                   n U" UX|5      I Sh  vN nU HZ  n[        U5      U:  d  M  US   T;  d  M  UR#                  U5        TR%                  US   5        US
-  nU	R'                  S
5        M\     [        U5      U:  d  M    O   [        U5      U:  a  [        R                  " 5       U
:  a  GM  [        U5      U:  a  [+        S[        U5       SU S35        SSS5        TR-                  5         U[        T5      4$  N! [(         a  n[+        SU 35         SnAGMB  SnAff = f! , (       d  f       NT= f7f)z4Generate MCQs from PPT/PPTX presentation embeddings.r   zhttp://127.0.0.1:11434z
gemma3:12b)base_urlr	   contextnum_questionsaO  
        {context}

        Generate {num_questions} multiple-choice questions based on the provided presentation content. Each question should include one correct answer and three plausible but incorrect options. Follow the format below:
        Q: <question>
        A) <option_a>
        B) <option_b>
        C) <option_c>
        D) <option_d>
        Correct: <correct_letter>

        Guidelines:
    Ensure questions are clear, relevant, and focused on key details from the presentation slides.
    Phrase questions concisely to avoid ambiguity.
    Avoid questions like "in this presentation" or "in this slide" or "in given slides" unless accompanied by specific, relevant information.
    Make incorrect options (distractors) credible and similar in structure or content to the correct answer, encouraging thoughtful selection.
        )input_variablestemplatezFQ: (.+?)\nA\) (.+?)\nB\) (.+?)\nC\) (.+?)\nD\) (.+?)\nCorrect: ([A-D])      <   )rV   rW   c           
        >#    TR                  5       I S h  vN   TR                  XS9nTR                  U5      I S h  vN n/ nTR                  UR                  5       H  nUR                  5       u  pxppUR                  5       nUT;  d  M/  UR                  U[        U5      -   UUR                  5       U	R                  5       U
R                  5       UR                  5       S.US.5        M     U$  N N7f)N)rf   rg   )ABCD)numberrA   optionscorrect_answer)	rb   formatainvokefinditerr2   groupsr-   r^   rG   )rf   start_number
batch_sizepromptresponser#   matchrA   option_aoption_boption_coption_dcorrect_letterllm	mcq_regexmcq_templatequestion_historyrate_limiters                r   process_context)generate_mcq_ppt.<locals>.process_context~   s     !!!$$W$OV,,	''(8(89EOT||~LHH~~'H//  *S^; (%-^^%5HNN<LS[SaSaScjrjxjxjz{&4	" 	 :  	",s(   C9C5'C9C7 AC9A&C97C9zGenerating MCQs (PPT))totaldesci,     zRandom query for retrieval i  NrA   z [PPT] Error processing context: z[PPT] Warning: Only generated z unique questions out of z requested.)r   r   as_retrieverr   r   recompileDOTALLrR   r   r[   rG   minrandomrandintinvokepage_contentr^   r?   update	Exceptionr   r;   )r   rg   r   GPUr   	retrievermcqsquestion_numberr   pbartimeoutremaining_questionsrz   queryresultsresultrf   new_mcqsmcqer   r   r   r   r   s                       @@@@@r   generate_mcq_pptr   V   sT    !):G1u&y?$$&I
)C
 ""O4L* 

dfhfofopIDOBr:L " 
M(?	@D))+#$i-'DIIK',A"/#d)";0!4J1&..D2I1JKE&&u-G!t9- --
%4Wo%ZZH't9}4ZP`9` KK,,00ZA+q0O KKN  ( t9-! " $i-'DIIK',A0 t9}$23t9+=VWdVeepqr7 
A: %&&&#  [ ! <QC@A) 
A	@ss   BI;B*I*III(I3?I2I*,I*2*I*%I;I
I'I"I*"I''I**
I84I;__main__c                     #    [        SSSS5      I S h  vN u  pU (       a/  [        SU 35        U  H  n[        SUS    SUS	    35        M     g g  N=7f)
N   
   d   rj   zTotal questions in history: Qrr   z: rA   )r   r   )r   history_countr   s      r   mainr      sa     $4QC$CC0@A#h-3z?*;<=   Ds   AA>A)rN   r   r   r/   r\   r   r[   r   langchain_ollamar    langchain_community.vectorstoresr   langchain_core.promptsr   r   r   r   rR   r   rJ   r   runrP   r'   r   <module>r      sq    
    	   - 2 1 '"# #>* *"W't z> KK r'   