mirror of
https://github.com/th30d4y/OpenLearnX.git
synced 2026-05-26 11:25:49 +00:00
qizz + panel
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import tensorflow as tf
|
||||
import pickle
|
||||
import json
|
||||
import numpy as np
|
||||
import random
|
||||
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
||||
|
||||
class AdaptiveQuizMasterAPI:
|
||||
def __init__(self, models_path="./models/"):
|
||||
"""
|
||||
Initialize the adaptive quiz master for web deployment
|
||||
"""
|
||||
self.models_path = models_path
|
||||
|
||||
# Load model components
|
||||
self.model = tf.keras.models.load_model(f'{models_path}improved_cnn_model.h5')
|
||||
|
||||
with open(f'{models_path}tokenizer.pickle', 'rb') as f:
|
||||
self.tokenizer = pickle.load(f)
|
||||
|
||||
with open(f'{models_path}label_encoder.pickle', 'rb') as f:
|
||||
self.label_encoder = pickle.load(f)
|
||||
|
||||
with open(f'{models_path}processed_commonsenseqa_data.json', 'r') as f:
|
||||
self.quiz_data = json.load(f)
|
||||
|
||||
# Separate questions by difficulty
|
||||
self.questions_by_difficulty = {
|
||||
'easy': [q for q in self.quiz_data if q['difficulty'] == 'easy'],
|
||||
'medium': [q for q in self.quiz_data if q['difficulty'] == 'medium'],
|
||||
'hard': [q for q in self.quiz_data if q['difficulty'] == 'hard']
|
||||
}
|
||||
|
||||
print(f"✅ Quiz Master API initialized!")
|
||||
print(f"📊 Questions: Easy({len(self.questions_by_difficulty['easy'])}), Medium({len(self.questions_by_difficulty['medium'])}), Hard({len(self.questions_by_difficulty['hard'])})")
|
||||
|
||||
def get_question(self, difficulty='easy'):
|
||||
"""
|
||||
Get a random question of specified difficulty
|
||||
"""
|
||||
available_questions = self.questions_by_difficulty.get(difficulty, self.quiz_data)
|
||||
|
||||
if not available_questions:
|
||||
available_questions = self.quiz_data
|
||||
|
||||
question_data = random.choice(available_questions)
|
||||
|
||||
# Create formatted question with shuffled choices
|
||||
choices = question_data['incorrect_answers'] + [question_data['correct_answer']]
|
||||
random.shuffle(choices)
|
||||
|
||||
# Find correct answer position
|
||||
correct_position = choices.index(question_data['correct_answer'])
|
||||
correct_letter = chr(65 + correct_position)
|
||||
|
||||
return {
|
||||
'question': question_data['question'],
|
||||
'choices': {
|
||||
'A': choices[0],
|
||||
'B': choices[1],
|
||||
'C': choices[2],
|
||||
'D': choices[3]
|
||||
},
|
||||
'correct_answer': correct_letter,
|
||||
'difficulty': difficulty,
|
||||
'original_question': question_data['question']
|
||||
}
|
||||
|
||||
def predict_answer(self, question_text, choices):
|
||||
"""
|
||||
Use AI model to predict the answer
|
||||
"""
|
||||
# Format question for model prediction
|
||||
formatted_question = f"Difficulty: medium\nQuestion: {question_text}\n"
|
||||
formatted_question += f"A) {choices['A']}\n"
|
||||
formatted_question += f"B) {choices['B']}\n"
|
||||
formatted_question += f"C) {choices['C']}\n"
|
||||
formatted_question += f"D) {choices['D']}\n"
|
||||
|
||||
# Tokenize and predict
|
||||
sequence = self.tokenizer.texts_to_sequences([formatted_question])
|
||||
padded = pad_sequences(sequence, maxlen=400, padding='post')
|
||||
|
||||
prediction = self.model.predict(padded, verbose=0)
|
||||
predicted_class = np.argmax(prediction[0])
|
||||
predicted_letter = self.label_encoder.inverse_transform([predicted_class])[0]
|
||||
confidence = float(prediction[0][predicted_class])
|
||||
|
||||
return {
|
||||
'prediction': predicted_letter,
|
||||
'confidence': confidence,
|
||||
'all_probabilities': {
|
||||
'A': float(prediction[0][0]),
|
||||
'B': float(prediction[0][1]),
|
||||
'C': float(prediction[0][2]),
|
||||
'D': float(prediction[0][3])
|
||||
}
|
||||
}
|
||||
|
||||
def adjust_difficulty(self, current_difficulty, consecutive_correct, is_correct):
|
||||
"""
|
||||
Adjust difficulty based on performance
|
||||
"""
|
||||
if is_correct:
|
||||
consecutive_correct += 1
|
||||
|
||||
# Move up after 3 consecutive correct
|
||||
if consecutive_correct >= 3:
|
||||
if current_difficulty == 'easy':
|
||||
return 'medium', 0
|
||||
elif current_difficulty == 'medium':
|
||||
return 'hard', 0
|
||||
|
||||
else:
|
||||
consecutive_correct = 0
|
||||
|
||||
# Move down after 1 wrong answer
|
||||
if current_difficulty == 'hard':
|
||||
return 'medium', 0
|
||||
elif current_difficulty == 'medium':
|
||||
return 'easy', 0
|
||||
|
||||
return current_difficulty, consecutive_correct
|
||||
Reference in New Issue
Block a user