log when not loading a file

This commit is contained in:
2025-10-23 12:47:34 -06:00
parent b53948db72
commit e35a5ffab6
7 changed files with 125 additions and 29 deletions

View File

@@ -21,3 +21,5 @@ courses:
name: 1400-spring
- path: ./1420/2024-fall/Modules/
name: 1420_old
- path: ./3820_BackEnd/2025-fall/Modules/
name: jonathan-backend

View File

@@ -30,6 +30,11 @@ Content-Type: application/json
GET https://snow.instructure.com/api/v1/courses/958185/assignments
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
###
GET https://snow.instructure.com/api/v1/courses/1155293/quizzes/4366122/questions
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
###
POST https://snow.instructure.com/api/v1/courses/958185/quizzes/3358912/questions
Authorization: Bearer {{$dotenv CANVAS_TOKEN}}

View File

@@ -33,10 +33,33 @@ export const getAnswersForCanvas = (
});
if (question.questionType === QuestionType.NUMERICAL) {
return question.answers.map((answer) => ({
numerical_answer_type: answer.numericalAnswerType,
exact: answer.numericAnswer,
}));
// if (question.answers[0].numericalAnswerType === "range_answer") {
// console.log(
// "answer range",
// question.answers.map((answer) => ({
// numerical_answer_type: answer.numericalAnswerType,
// start: answer.numericAnswerRangeMin,
// end: answer.numericAnswerRangeMax,
// }))
// );
// return question.answers.map((answer) => ({
// numerical_answer_type: answer.numericalAnswerType,
// start: answer.numericAnswerRangeMin + "",
// end: answer.numericAnswerRangeMax + "",
// }));
// }
return question.answers.map((answer) => {
if (answer.numericalAnswerType === "range_answer")
return {
numerical_answer_type: answer.numericalAnswerType,
answer_range_start: answer.numericAnswerRangeMin,
answer_range_end: answer.numericAnswerRangeMax,
};
return {
numerical_answer_type: answer.numericalAnswerType,
exact: answer.numericAnswer,
};
});
}
return question.answers.map((answer) => ({

View File

@@ -92,7 +92,8 @@ export const courseItemFileStorageService = {
try {
const item = await getItem({ courseName, moduleName, name, type });
return item;
} catch {
} catch (e) {
console.log(`Error loading ${type} ${name} in module ${moduleName}:`, e);
return null;
}
})

View File

@@ -25,26 +25,28 @@ What is 2+3?
expect(question.questionType).toBe(QuestionType.NUMERICAL);
expect(question.answers[0].numericAnswer).toBe(5);
});
// it("can parse question with range answers", () => {
// const name = "Test Quiz";
// const rawMarkdownQuiz = `
// ShuffleAnswers: true
// OneQuestionAtATime: false
// DueAt: 08/21/2023 23:59:00
// LockAt: 08/21/2023 23:59:00
// AssignmentGroup: Assignments
// AllowedAttempts: -1
// Description: quiz description
// ---
// What is 2+3?
// = 5
// `;
it("can parse question with range answers", () => {
const name = "Test Quiz";
const rawMarkdownQuiz = `
ShuffleAnswers: true
OneQuestionAtATime: false
DueAt: 08/21/2023 23:59:00
LockAt: 08/21/2023 23:59:00
AssignmentGroup: Assignments
AllowedAttempts: -1
Description: quiz description
---
What is the cube root of 2?
= [1.2598, 1.2600]
`;
// const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
// const question = quiz.questions[0];
const quiz = quizMarkdownUtils.parseMarkdown(rawMarkdownQuiz, name);
const question = quiz.questions[0];
// expect(question.text).toBe("What is 2+3?");
// expect(question.questionType).toBe(QuestionType.NUMERICAL);
// expect(question.answers[0].numericAnswer).toBe(5);
// });
expect(question.text).toBe("What is the cube root of 2?");
expect(question.questionType).toBe(QuestionType.NUMERICAL);
expect(question.answers[0].numericalAnswerType).toBe("range_answer");
expect(question.answers[0].numericAnswerRangeMin).toBe(1.2598);
expect(question.answers[0].numericAnswerRangeMax).toBe(1.26);
});
});

View File

@@ -195,7 +195,6 @@ describe("QuizDeterministicChecks", () => {
],
allowedAttempts: -1,
showCorrectAnswers: true,
};
const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz);
@@ -221,13 +220,54 @@ describe("QuizDeterministicChecks", () => {
points: 1,
matchDistractors: [],
answers: [
{ text: "= 42", correct: true, numericalAnswerType: "exact_answer", numericAnswer: 42 },
{
text: "= 42",
correct: true,
numericalAnswerType: "exact_answer",
numericAnswer: 42,
},
],
},
],
allowedAttempts: -1,
showCorrectAnswers: true,
};
const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz);
const parsedQuiz = quizMarkdownUtils.parseMarkdown(quizMarkdown, name);
expect(parsedQuiz).toEqual(quiz);
});
it("SerializationIsDeterministic Numeric with range answer", () => {
const name = "Test Quiz";
const quiz: LocalQuiz = {
name,
description: "quiz description",
lockAt: "08/21/2023 23:59:00",
dueAt: "08/21/2023 23:59:00",
shuffleAnswers: true,
oneQuestionAtATime: true,
password: undefined,
localAssignmentGroupName: "Assignments",
questions: [
{
text: "test numeric",
questionType: QuestionType.NUMERICAL,
points: 1,
matchDistractors: [],
answers: [
{
text: "= [2, 5]",
correct: true,
numericalAnswerType: "range_answer",
numericAnswerRangeMin: 2,
numericAnswerRangeMax: 5,
},
],
},
],
allowedAttempts: -1,
showCorrectAnswers: true,
};
const quizMarkdown = quizMarkdownUtils.toMarkdown(quiz);

View File

@@ -15,7 +15,27 @@ const _multipleChoicePrefix = ["a)", "*a)", "*)", ")"];
const _multipleAnswerPrefix = ["[ ]", "[*]", "[]"];
const parseNumericalAnswer = (input: string): LocalQuizQuestionAnswer => {
const numericValue = parseFloat(input.replace(/^=\s*/, "").trim());
const trimmedInput = input.replace(/^=\s*/, "").trim();
// Check if it's a range answer: = [min, max]
const minMaxPattern = /^\[([^,]+),\s*([^\]]+)\]$/;
const rangeNumbericAnswerMatch = trimmedInput.match(minMaxPattern);
if (rangeNumbericAnswerMatch) {
const minValue = parseFloat(rangeNumbericAnswerMatch[1].trim());
const maxValue = parseFloat(rangeNumbericAnswerMatch[2].trim());
const answer: LocalQuizQuestionAnswer = {
correct: true,
text: input.trim(),
numericalAnswerType: "range_answer",
numericAnswerRangeMin: minValue,
numericAnswerRangeMax: maxValue,
};
return answer;
}
// Otherwise, it's an exact answer
const numericValue = parseFloat(trimmedInput);
const answer: LocalQuizQuestionAnswer = {
correct: true,
text: input.trim(),
@@ -200,6 +220,9 @@ export const quizQuestionAnswerMarkdownUtils = {
} else if (question.questionType === "matching") {
return `^ ${answer.text} - ${answer.matchedText}`;
} else if (question.questionType === "numerical") {
if (answer.numericalAnswerType === "range_answer") {
return `= [${answer.numericAnswerRangeMin}, ${answer.numericAnswerRangeMax}]`;
}
return `= ${answer.numericAnswer}`;
} else {
const questionLetter = String.fromCharCode(97 + index);