mq-quiz / src /quizzes /models.py
Teddy Xinyuan Chen
2024-10-08T17-12-41Z
07bbfbd
raw
history blame
2.77 kB
import typing
from django.contrib.postgres import fields
from django.db import models
class Quiz(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
prompt = models.CharField(max_length=200)
def __str__(self):
return self.prompt
def get_answer(self) -> typing.Union["Answer", None]:
return (
getattr(self, "multiplechoiceanswer", None)
or getattr(self, "freetextanswer", None)
or getattr(self, "llmgradedanswer", None)
)
class Answer(models.Model):
question = models.OneToOneField(Question, on_delete=models.CASCADE)
correct_answer = models.CharField(max_length=200, default="")
rubrics = models.TextField(
blank=True, null=True, verbose_name="Grading Rubrics - For LLM-graded questions only. You can leave this empty."
)
class Meta:
abstract = True
def __str__(self) -> str:
return self.correct_answer or self.rubrics or "No answer or rubrics provided"
def is_correct(self, user_answer) -> bool:
return user_answer == self.correct_answer
class FreeTextAnswer(Answer):
case_sensitive = models.BooleanField(default=False)
def is_correct(self, user_answer) -> bool:
if not self.case_sensitive:
return user_answer.lower() == self.correct_answer.lower()
return user_answer == self.correct_answer
class LLMGradedAnswer(Answer):
def grade(self, user_answer, rubrics) -> dict:
import requests
"""
Grades the user's answer by calling the grading API.
Args:
user_answer (str): The answer provided by the user.
rubrics (str): The grading rubrics.
Returns:
bool: True if the user's answer is correct, False otherwise.
"""
api_url = "http://localhost/api/grade"
payload = {"user_answer": user_answer, "rubrics": rubrics}
try:
response = requests.post(api_url, json=payload)
response.raise_for_status() # Raise an error for bad status codes
result = response.json()
# Assuming the API returns a JSON object with a 'correct' field
return result
except requests.RequestException as e:
# Handle any errors that occur during the request
print(f"An error occurred: {e}")
return {"result": "error", "message": str(e)}
class MultipleChoiceAnswer(Answer):
choices = fields.ArrayField(models.CharField(max_length=200, blank=True))
def __str__(self) -> str:
return f"{self.correct_answer} from {self.choices}"