feat: AI grading bug (#420)
* worked on the AI grading task * worked on the AI grading task * improved the ai grading function * improved the ai grading function * update types --------- Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
parent
7e0443fc37
commit
594eb97caa
+70
-28
@@ -93,6 +93,29 @@
|
||||
}
|
||||
}
|
||||
|
||||
const getMultipleAnswersGrade = (options, answer, points) => {
|
||||
const correctOptions = options
|
||||
.filter((option) => option.is_correct)
|
||||
.map((option) => option.value);
|
||||
|
||||
const correctSelections = answer.answers.filter((answer) =>
|
||||
correctOptions.includes(answer)
|
||||
).length;
|
||||
|
||||
const incorrectSelections = answer.answers.length - correctSelections;
|
||||
|
||||
const pointsEarned = (correctSelections / correctOptions.length) * points;
|
||||
const deduction = (incorrectSelections * points) / correctOptions.length;
|
||||
const finalPoints = Math.max(pointsEarned - deduction, 0);
|
||||
|
||||
return {
|
||||
finalPoints,
|
||||
correctOptions,
|
||||
correctSelections,
|
||||
incorrectSelections
|
||||
};
|
||||
};
|
||||
|
||||
async function handleDeleteSubmission() {
|
||||
isDeleting = true;
|
||||
await deleteSubmission(data.id, status.id);
|
||||
@@ -118,18 +141,37 @@
|
||||
}
|
||||
|
||||
data?.questions.forEach((question) => {
|
||||
const { id, points, question_type_id } = question;
|
||||
|
||||
if (question_type_id !== QUESTION_TYPE.TEXTAREA) {
|
||||
const { id, points, question_type_id, options } = question;
|
||||
if (question_type_id == QUESTION_TYPE.RADIO) {
|
||||
const answer = data.questionAnswers.find((q) => q.question_id === id);
|
||||
|
||||
const answerPoints = answer?.answers?.length ?? 0;
|
||||
|
||||
reasons = {
|
||||
...reasons,
|
||||
[id]: `${$t(
|
||||
'course.navItem.submissions.grading_modal.questions_tried'
|
||||
[id]: `${$t('course.navItem.submissions.grading_modal.allocated')} ${$t(
|
||||
'course.navItem.submissions.grading_modal.total_try'
|
||||
)} ${answerPoints} `
|
||||
};
|
||||
data.questionAnswerByPoint[id] = `${Math.ceil(points / answerPoints)}`;
|
||||
} else if (question_type_id == QUESTION_TYPE.CHECKBOX) {
|
||||
const answer = data.questionAnswers.find((q) => q.question_id === id);
|
||||
|
||||
const { finalPoints, correctOptions, correctSelections, incorrectSelections } =
|
||||
getMultipleAnswersGrade(options, answer, points);
|
||||
|
||||
reasons = {
|
||||
...reasons,
|
||||
[id]: `${$t(
|
||||
'course.navItem.submissions.grading_modal.allocated'
|
||||
)} ${correctSelections} ${$t('course.navItem.submissions.grading_modal.out_of')} ${
|
||||
correctOptions.length
|
||||
} ${$t('course.navItem.submissions.grading_modal.options_correct')} ${$t(
|
||||
'course.navItem.submissions.grading_modal.options_wrong'
|
||||
)} ${incorrectSelections} `
|
||||
};
|
||||
|
||||
data.questionAnswerByPoint[id] = `${finalPoints}`;
|
||||
} else if (aiResponses.length) {
|
||||
const graded = aiResponses.find((res) => res.id === id);
|
||||
|
||||
@@ -182,10 +224,10 @@
|
||||
headerClass="py-2"
|
||||
labelClass="text-base font-semibold"
|
||||
>
|
||||
<div class="w-full h-full mt-2">
|
||||
<div class="mt-2 h-full w-full">
|
||||
{#if openDeletePrompt}
|
||||
<div class="w-96 mx-auto p-3 border border-gray-300 rounded-md">
|
||||
<h1 class="dark:text-white text-lg">
|
||||
<div class="mx-auto w-96 rounded-md border border-gray-300 p-3">
|
||||
<h1 class="text-lg dark:text-white">
|
||||
{$t('delete_modal.content')}
|
||||
</h1>
|
||||
|
||||
@@ -223,19 +265,19 @@
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="ml-4 mt-2 w-2/5 sticky top-0">
|
||||
<div class="border border-gray-300 rounded-md">
|
||||
<div class="sticky top-0 ml-4 mt-2 w-2/5">
|
||||
<div class="rounded-md border border-gray-300">
|
||||
<div
|
||||
class="flex gap-1 justify-between items-center border-b border-t-0 border-l-0 border-r-0 border-gray-300 p-3"
|
||||
class="flex items-center justify-between gap-1 border-b border-l-0 border-r-0 border-t-0 border-gray-300 p-3"
|
||||
>
|
||||
<p class="dark:text-white font-bold text-base">
|
||||
<p class="text-base font-bold dark:text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.details')}
|
||||
{#if data.isEarly}
|
||||
<span class="ml-2 text-sm badge rounded-sm px-2 bg-green-500 text-white">
|
||||
<span class="badge ml-2 rounded-sm bg-green-500 px-2 text-sm text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.early')}</span
|
||||
>
|
||||
{:else}
|
||||
<span class="ml-2 badge text-sm rounded-sm px-2 bg-red-500 text-white">
|
||||
<span class="badge ml-2 rounded-sm bg-red-500 px-2 text-sm text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.late')}
|
||||
</span>
|
||||
{/if}
|
||||
@@ -253,13 +295,13 @@
|
||||
</OverflowMenu>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4 text-sm px-3 py-2">
|
||||
<p class="dark:text-white text-sm text-gray-500 font-semibold">
|
||||
<div class="flex items-center space-x-4 px-3 py-2 text-sm">
|
||||
<p class="text-sm font-semibold text-gray-500 dark:text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.total_grade')}:
|
||||
</p>
|
||||
|
||||
<Tag
|
||||
class="dark:text-white font-semibold text-black bg-gray-100 dark:bg-neutral-700 rounded-md w-fit"
|
||||
class="w-fit rounded-md bg-gray-100 font-semibold text-black dark:bg-neutral-700 dark:text-white"
|
||||
>
|
||||
{total}/{maxPoints}
|
||||
</Tag>
|
||||
@@ -271,20 +313,20 @@
|
||||
<p class="dark:text-white">Grading</p>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="flex items-center space-x-4 text-sm px-3 py-2">
|
||||
<p class="dark:text-white text-sm text-gray-500 font-semibold">
|
||||
<div class="flex items-center space-x-4 px-3 py-2 text-sm">
|
||||
<p class="text-sm font-semibold text-gray-500 dark:text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.student')}:
|
||||
</p>
|
||||
{#if data.student}
|
||||
<div
|
||||
class="flex flex-row justify-center items-center bg-gray-100 dark:bg-neutral-700 rounded-md p-[6px]"
|
||||
class="flex flex-row items-center justify-center rounded-md bg-gray-100 p-[6px] dark:bg-neutral-700"
|
||||
>
|
||||
<img
|
||||
alt="Student avatar"
|
||||
class="flex rounded-full h-5 w-5"
|
||||
class="flex h-5 w-5 rounded-full"
|
||||
src={data.student.avatar_url}
|
||||
/>
|
||||
<p class="dark:text-white font-semibold ml-2 text-sm line-clamp-1">
|
||||
<p class="ml-2 line-clamp-1 text-sm font-semibold dark:text-white">
|
||||
{data.student.fullname}
|
||||
</p>
|
||||
</div>
|
||||
@@ -298,8 +340,8 @@
|
||||
>
|
||||
</div> -->
|
||||
|
||||
<div class="flex flex-col items-start text-sm px-3 py-2">
|
||||
<p class="dark:text-white text-gray-500 font-semibold">
|
||||
<div class="flex flex-col items-start px-3 py-2 text-sm">
|
||||
<p class="font-semibold text-gray-500 dark:text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.status')}:
|
||||
</p>
|
||||
<Dropdown
|
||||
@@ -310,8 +352,8 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-start text-sm px-3 py-2">
|
||||
<p class="dark:text-white text-gray-500 font-semibold">
|
||||
<div class="flex flex-col items-start px-3 py-2 text-sm">
|
||||
<p class="font-semibold text-gray-500 dark:text-white">
|
||||
{$t('course.navItem.submissions.grading_modal.add_comment')}:
|
||||
</p>
|
||||
<TextArea
|
||||
@@ -322,14 +364,14 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col w-full space-y-3 px-3 py-2">
|
||||
<div class="flex w-full flex-col space-y-3 px-3 py-2">
|
||||
<PrimaryButton
|
||||
onClick={gradeWithAI}
|
||||
variant={VARIANTS.OUTLINED}
|
||||
className="space-x-3 py-3 px-8 w-full "
|
||||
>
|
||||
<img src="/ai.svg" alt="ai" />
|
||||
<p class="font-semibold text-sm">
|
||||
<p class="text-sm font-semibold">
|
||||
{$t('course.navItem.submissions.grading_modal.grade_with_ai')}
|
||||
</p>
|
||||
</PrimaryButton>
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "Akzeptieren",
|
||||
"reject_grade": "Ablehnen",
|
||||
"add_comment_placeholder": "Hinterlasse einen Kommentar",
|
||||
"allocated": "Diese Punktzahl wurde vergeben, weil",
|
||||
"total_try": "der Gesamtversuche:",
|
||||
"options_correct": "Es wurden die richtigen Optionen ausgewählt",
|
||||
"out_of": "aus",
|
||||
"options_wrong": "und die Anzahl der falschen Auswahlen war",
|
||||
"questions_tried": "Diese Punktzahl wurde aufgrund der Gesamtzahl der Versuche vergeben:",
|
||||
"delete_prompt": "Löschen",
|
||||
"delete_error": "Die Übermittlung konnte nicht gelöscht werden",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "Sie haben nicht gerettete Änderungen. Bist du sicher, dass du gehen willst?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -912,6 +912,11 @@
|
||||
"submit_grades": "Submit Grades",
|
||||
"accept_grade": "Accept",
|
||||
"reject_grade": "Reject",
|
||||
"allocated": "Allocated this score because",
|
||||
"total_try": "of total tries:",
|
||||
"options_correct": "correct options were selected",
|
||||
"out_of": "out of",
|
||||
"options_wrong": "and the number of wrong selections were",
|
||||
"questions_tried": "Allocated this score because of total tries:",
|
||||
"delete_prompt": "Delete",
|
||||
"delete_error": "Failed to delete submission",
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "Aceptar",
|
||||
"reject_grade": "Rechazar",
|
||||
"add_comment_placeholder": "Deja un comentario",
|
||||
"allocated": "Asignó esta puntuación porque",
|
||||
"total_try": "de intentos totales:",
|
||||
"options_correct": "se seleccionaron las opciones correctas",
|
||||
"out_of": "fuera de",
|
||||
"options_wrong": "y el número de selecciones incorrectas fue",
|
||||
"questions_tried": "Se asignó esta puntuación debido al total de intentos:",
|
||||
"delete_prompt": "Borrar",
|
||||
"delete_error": "No se pudo eliminar el envío",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "Tienes cambios no salvos. ¿Estás seguro de que quieres irte?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "Accepter",
|
||||
"reject_grade": "Rejeter",
|
||||
"add_comment_placeholder": "laissez un commentaire",
|
||||
"allocated": "J'ai attribué ce score parce que",
|
||||
"total_try": "du total d'essais :",
|
||||
"options_correct": "les bonnes options ont été sélectionnées",
|
||||
"out_of": "hors de",
|
||||
"options_wrong": "et le nombre de mauvaises sélections était",
|
||||
"questions_tried": "Attribué ce score en raison du nombre total d'essais :",
|
||||
"delete_prompt": "Supprimer",
|
||||
"delete_error": "Échec de la suppression de la soumission",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "Vous avez des changements non sauvés. Êtes-vous sûr de vouloir partir?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "स्वीकार करना",
|
||||
"reject_grade": "अस्वीकार करना",
|
||||
"add_comment_placeholder": "एक टिप्पणी छोड़ें",
|
||||
"allocated": "यह अंक इसलिए आवंटित किया गया क्योंकि",
|
||||
"total_try": "कुल प्रयासों में से:",
|
||||
"options_correct": "सही विकल्प का चयन किया गया",
|
||||
"out_of": "से बाहर",
|
||||
"options_wrong": "और गलत चयनों की संख्या थी",
|
||||
"questions_tried": "कुल प्रयासों के कारण यह स्कोर आवंटित किया गया:",
|
||||
"delete_prompt": "मिटाना",
|
||||
"delete_error": "सबमिशन हटाने में विफल",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "आपके पास अनसुना परिवर्तन हैं। क्या आपकी वाकई छोड़ने की इच्छा है?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "Aceitar",
|
||||
"reject_grade": "Rejeitar",
|
||||
"add_comment_placeholder": "Deixe um comentário",
|
||||
"allocated": "Alocou esta pontuação porque",
|
||||
"total_try": "do total de tentativas:",
|
||||
"options_correct": "opções corretas foram selecionadas",
|
||||
"out_of": "fora de",
|
||||
"options_wrong": "e o número de seleções erradas foi",
|
||||
"questions_tried": "Alocada esta pontuação por causa do total de tentativas:",
|
||||
"delete_prompt": "Excluir",
|
||||
"delete_error": "Falha ao excluir o envio",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "Você tem mudanças não salvas. Tem certeza de que deseja sair?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "Принимать",
|
||||
"reject_grade": "Отклонять",
|
||||
"add_comment_placeholder": "Оставить комментарий",
|
||||
"allocated": "Присвоен этот балл, потому что",
|
||||
"total_try": "общего числа попыток:",
|
||||
"options_correct": "выбраны правильные варианты",
|
||||
"out_of": "снаружи",
|
||||
"options_wrong": "и количество неправильных выборов было",
|
||||
"questions_tried": "Присвоен этот балл из-за общего количества попыток:",
|
||||
"delete_prompt": "Удалить",
|
||||
"delete_error": "Не удалось удалить отправку",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "У вас есть неспасенные изменения. Вы уверены, что хотите уйти?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,6 +515,11 @@
|
||||
"accept_grade": "Chấp nhận",
|
||||
"reject_grade": "Từ chối",
|
||||
"add_comment_placeholder": "Để lại một bình luận",
|
||||
"allocated": "Phân bổ số điểm này bởi vì",
|
||||
"total_try": "trong tổng số lần thử:",
|
||||
"options_correct": "các phương án đúng đã được chọn",
|
||||
"out_of": "ra khỏi",
|
||||
"options_wrong": "và số lựa chọn sai là",
|
||||
"questions_tried": "Phân bổ số điểm này dựa trên tổng số lần thử:",
|
||||
"delete_prompt": "Xóa bỏ",
|
||||
"delete_error": "Không thể xóa bài nộp",
|
||||
@@ -1581,4 +1586,4 @@
|
||||
"message": "Bạn có những thay đổi chưa được lưu. Bạn có chắc bạn muốn rời đi?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Profile } from '.';
|
||||
import { Option, Profile } from '.';
|
||||
|
||||
export interface SubmissionItem {
|
||||
id: string;
|
||||
@@ -37,6 +37,7 @@ export interface SubmissionIdData {
|
||||
order: number;
|
||||
points: number;
|
||||
question_type_id: number;
|
||||
options: Option[];
|
||||
}[];
|
||||
questionAnswers: {
|
||||
open_answer: string;
|
||||
|
||||
Reference in New Issue
Block a user