tiantian-paris's picture
fix exmaple issue
55d1cfb
from typing import Any, Optional
from smolagents.tools import Tool
import json
import random
class QCMTool(Tool):
"""
A tool for running multiple-choice question (QCM) quizzes.
It picks a random question, checks the user's answer, and provides feedback.
"""
name = "qcm_tool"
description = "A tool for running multiple-choice question (QCM) quizzes. It picks a random question, checks the user's answer, and provides feedback."
inputs = {
'user_answer': {
'type': 'string',
'description': 'The user\'s selected answer (e.g., "A", "B", "C", "D").'
}
}
output_type = "string"
def __init__(self, json_file: str, *args, **kwargs):
"""
Initialize the QCM tool with a JSON file containing questions.
Args:
json_file (str): Path to the JSON file containing the questions.
"""
super().__init__(*args, **kwargs)
self.json_file = json_file
self.questions = self._load_questions()
self.is_initialized = True
def _load_questions(self):
"""
Load questions from the JSON file.
Returns:
list: A list of questions loaded from the JSON file.
Raises:
FileNotFoundError: If the JSON file is not found.
json.JSONDecodeError: If the JSON file is malformed.
"""
try:
with open(self.json_file, 'r') as file:
return json.load(file)
except FileNotFoundError:
raise FileNotFoundError(f"The file {self.json_file} was not found.")
except json.JSONDecodeError:
raise json.JSONDecodeError(f"The file {self.json_file} contains invalid JSON.")
def _pick_random_question(self):
"""
Pick a random question from the loaded questions.
Returns:
dict: A randomly selected question.
"""
return random.choice(self.questions)
def _check_answer(self, question: dict, user_answer: str) -> tuple[bool, str]:
"""
Check if the user's answer is correct and provide an explanation.
Args:
question (dict): The question dictionary containing the correct answer and explanation.
user_answer (str): The user's selected answer.
Returns:
tuple: A tuple containing a boolean (True if correct, False otherwise) and the explanation.
"""
is_correct = user_answer == question["correct_answer"]
return is_correct, question["explanation"]
def forward(self, user_answer: str) -> str:
"""
The main entry point for the QCM tool. It picks a random question, checks the user's answer,
and provides feedback.
Args:
user_answer: The user's selected answer (e.g., "A", "B", "C", "D").
Returns:
str: A formatted string indicating whether the answer was correct and providing an explanation.
Raises:
ValueError: If the user's answer is invalid.
"""
# Pick a random question
question = self._pick_random_question()
# Validate the user's answer
if user_answer.upper() not in ['A', 'B', 'C', 'D']:
raise ValueError("Invalid input. Please enter a valid option letter (A, B, C, D).")
# Map the user's answer to the corresponding option
option_index = ord(user_answer.upper()) - 65 # Convert 'A' to 0, 'B' to 1, etc.
selected_option = question["options"][option_index]
# Check the answer
is_correct, explanation = self._check_answer(question, selected_option)
# Return feedback
if is_correct:
return f"Correct! 🎉\nExplanation: {explanation}"
else:
return f"Incorrect! 😞\nExplanation: {explanation}"
if __name__ == "__main__":
# Initialize the QCM tool
qcm_tool = QCMTool(json_file="../info/questions.json")
question = qcm_tool._pick_random_question()
print(question)
# Simulate a user answering 'A'
try:
result = qcm_tool.forward(user_answer="A")
print(result)
except ValueError as e:
print(f"Error: {e}")