
    kjI                         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	r	S SK
r
S SKrS SKJr  S SKrS r " S S	5      r " S
 S5      rS rS r\S:X  a  \R(                  " \" 5       5        gg)    N)OllamaEmbeddings)FAISS)PromptTemplate)
ChatOllama)tqdmc                    [        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 )Nznomic-embed-text)modelzmy_embeddings//z/merged_faiss)z.faissz.pklT)allow_dangerous_deserializationzEmbeddings loaded from zNo embedding files found in .z"No embeddings found for client_id z and reference_id )	r   ospathisdirlistdirendswithr   
load_localprint)	client_idreference_id
embeddingsreference_dirfembedding_filesvectorss          D/var/www/eduai.edurigo.com/question_generate/testing/generate_mcq.pyload_all_embeddingsr      s    !(:;J$YKqmLM	ww}}]##&(jj&?b&?::N`Ca1&?b&&}bfgG+M?;<N0qAB  	29+=OP\~]^_` cs   C,Cc                   8    \ rS rSrS rS rS rS rS rS r	Sr
g	)
QuestionHistory   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        $ [        S5        [        5       $ ! , (       d  f       g = f! [        R                   a&    [        SU R                   S35        [        5       s $ f = f)NrzWarning: Invalid JSON in z!. Starting with an empty history.z6No history file found. Starting with an empty history.)r   r   existsr!   openreadstripsetjsonloadsJSONDecodeErrorr   )r$   r   contents      r   r"   QuestionHistory.load!   s    77>>$..))$..#.!ffhnn.G7>3tzz'23CE /. JL5L /. '' 1$..1AAbcdus0   C AB3	C 3
C=C C 7C>=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.save.   sT    
BGGOODNN3dC$..#&!IId4>>*A. '&&s   +B
Bc                 :    U R                   R                  U5        g N)r#   addr$   questions     r   r?   QuestionHistory.add3   s    8$r'   c                     XR                   ;   $ r>   )r#   r@   s     r   __contains__QuestionHistory.__contains__6   s    >>))r'   c                 ,    [        U R                  5      $ r>   )lenr#   )r$   s    r   __len__QuestionHistory.__len__9   s    4>>""r'   )r!   r#   N)__name__
__module____qualname____firstlineno__r%   r"   r;   r?   rD   rH   __static_attributes__ r'   r   r   r      s     %/
%*#r'   r   c                        \ rS rSrS rS rSrg)RateLimiter<   c                 *    Xl         X l        / U l        g r>   max_requestsperiodrequests)r$   rU   rV   s      r   r%   RateLimiter.__init__=   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   )timerW   rV   rG   rU   asynciosleepappend)r$   nowreq
sleep_times       r   waitRateLimiter.waitB   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)rT   N)rJ   rK   rL   rM   r%   ra   rN   rO   r'   r   rQ   rQ   <   s    
*r'   rQ   c                   ^^^^^#    [        X5      nU(       d  [        S5        / 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)Nz=No embeddings found for the given client ID and reference ID.r   zhttp://127.0.0.1:11434z
gemma3:12b)base_urlr	   contextnum_questionsa7  
        {context}

        Generate {num_questions} multiple-choice questions based on the provided context. 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 context.
    Phrase questions concisely to avoid ambiguity.
    Avoid questions like "in this document" or "in this code" or "  in given document" 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])      rR   )rU   rV   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UR                  n/ nTR	                  U5       H  nUR                  5       u  pppU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)re   rf   )ABCD)numberrA   optionscorrect_answer)	ra   formatainvoker2   finditergroupsr-   r]   rG   )re   start_number
batch_sizepromptresponseresponse_strr#   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.<locals>.process_contextu   s     !!!$$W$OV,,''	''5EOT||~LHH~~'H//  *S^; (%^^-%^^-%^^-%^^-	  '5
" 
	 6 ) 	",s(   C;C7'C;C9 AC;A&C;9C;zGenerating MCQs)totaldesci,     zRandom query for retrieval i  rA   zError processing context: zWarning: Only generated z unique questions out of z requested.)r   r   r   as_retrieverr   r   recompileDOTALLrQ   r   rZ   rG   minrandomrandintinvokepage_contentr]   r?   update	Exceptionr;   )r   rf   r   GPUr   	retrievermcqsquestion_numberr   pbartimeoutremaining_questionsrx   queryresultsresultre   new_mcqsmcqer   r   r   r   r   s                       @@@@@r   generate_mcqr   K   s[    !):GMN1u&y?$$&I
)C ""O4L. 

dfhfofopIDOBr:L . 
M(9	: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',A4 t9}$,SYK7PQ^P__jkl; 
;> %&&&%  [ ! 6qc:;+ 
;	:ss   BJ!B*I5III3I>?I=I5,I5=*I5'%JI
I2I-&I5-I22I55
J?Jc                  J  #    Sn SnSnSn[        XX#5      I S h  vN u  pEU(       d  [        S5        g [        SU 35        U HX  n[        SUS    S	US
    35        US   R                  5        H  u  px[        U SU 35        M     [        SUS    S35        MZ     g  N7f)Nrich      ri   z'No multiple-choice questions generated.zTotal questions in history: z	Question rp   z: rA   rq   z) zCorrect Answer: rr   
)r   r   items)	r   rf   r   r   r   history_countr   optiontexts	            r   mainr      s     IML	C ,Y| XXD78	(
89	#h-3z?*;<=	N002LFVHBtf%& 3 %5!6 7r:;	  Ys   B#B!BB#__main__)r   r   langchain_ollamar    langchain_community.vectorstoresr   langchain_core.promptsr   r   r   r/   r[   r   rZ   r   r   rQ   r   r   rJ   runrO   r'   r   <module>r      si    	  - 2 1 ' 	    # #@* *a'F<$ zKK r'   