Skip to content

fix: Numeric input with variables conversion to StringResponse #1767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: open-release/sumac.master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js
Original file line number Diff line number Diff line change
@@ -44,6 +44,16 @@
this.problemState = problemState.problem;
}

/**
* Checks if an answer string contains variables (letters except 'e' which is used for scientific notation)
* @param {string} answer - The answer string to check
* @return {boolean} - True if variables are present, false otherwise
*/
containsVariables(answer) {
// Similar to checkIsNumeric in edit.js (legacy editor)
return /[a-df-z]/i.test(answer);
}

/** addHints()
* The editorObject saved to the class constuctor is parsed for the attribute hints. No hints returns an empty object.
* The hints are parsed and appended to the hintsArray as object representations of the hint. The hints array is saved
@@ -365,6 +375,21 @@
const answerObject = this.buildNumericalResponse();
const solution = this.addSolution();

// Verify if it is already stringresponse
if (this.convertedToStringResponse) {
answerObject[ProblemTypeKeys.TEXTINPUT].push(...solution);

Check warning on line 380 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L380

Added line #L380 was not covered by tests

const problemBody = this.richTextBuilder.build([answerObject]);
const questionString = this.richTextBuilder.build(question);
const hintString = this.richTextBuilder.build(demandhint);
const [problemTypeTag] = problemBody.match(/<stringresponse>|<stringresponse.[^>]+>/);
const updatedString = `${problemTypeTag}\n${questionString}`;
const problemBodyString = problemBody.replace(problemTypeTag, updatedString);
const fullProblemString = `<problem>${problemBodyString}${hintString}\n</problem>`;

Check warning on line 388 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L382-L388

Added lines #L382 - L388 were not covered by tests

return fullProblemString;

Check warning on line 390 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L390

Added line #L390 was not covered by tests
}

answerObject[ProblemTypeKeys.NUMERIC].push(...solution);

const problemBody = this.richTextBuilder.build([answerObject]);
@@ -394,6 +419,55 @@
const { answers, problemType } = this.problemState;
const { tolerance } = this.problemState.settings;
const { selectedFeedback } = this.editorObject;
// Verify if the answer has a correct answer
const correctAnswers = answers.filter(answer => answer.correct);
const mainAnswer = correctAnswers.length > 0 ? correctAnswers[0].title : '';

// If contain variables, generate as stringresponse instead of numericalresponse
if (mainAnswer && this.containsVariables(mainAnswer)) {
// Create a stringresponse type
const answerObject = {

Check warning on line 429 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L429

Added line #L429 was not covered by tests
':@': {
'@_answer': mainAnswer,
'@_type': 'ci',
},
[ProblemTypeKeys.TEXTINPUT]: [],
};
const firstCorrectAnswerParsed = true;

Check warning on line 436 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L436

Added line #L436 was not covered by tests

answers.forEach((answer) => {
const correcthint = this.getAnswerHints(selectedFeedback?.[answer.id]);

Check warning on line 439 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L438-L439

Added lines #L438 - L439 were not covered by tests

if (answer === correctAnswers[0]) {
if (correcthint.length > 0) {
answerObject[ProblemTypeKeys.TEXTINPUT].push(...correcthint);

Check warning on line 443 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L443

Added line #L443 was not covered by tests
}
} else if (answer.correct && firstCorrectAnswerParsed) {
answerObject[ProblemTypeKeys.TEXTINPUT].push({

Check warning on line 446 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L446

Added line #L446 was not covered by tests
':@': { '@_answer': answer.title },
additional_answer: [...correcthint],
});
// Wrong answers as stringequalhint (if exists)
} else if (!answer.correct) {
const wronghint = correcthint[0]?.correcthint;

Check warning on line 452 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L452

Added line #L452 was not covered by tests
if (wronghint) {
answerObject[ProblemTypeKeys.TEXTINPUT].push({

Check warning on line 454 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L454

Added line #L454 was not covered by tests
':@': { '@_answer': answer.title },
stringequalhint: wronghint ? [...wronghint] : [],

Check warning on line 456 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L456

Added line #L456 was not covered by tests
});
}
}
});
answerObject[ProblemTypeKeys.TEXTINPUT].push({

Check warning on line 461 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L461

Added line #L461 was not covered by tests
textline: { '#text': '' },
':@': { '@_size': 20 },
});
// Save the answer type so buildNumericInput will know what to do
this.convertedToStringResponse = true;
return answerObject;

Check warning on line 467 in src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js

Codecov / codecov/patch

src/editors/containers/ProblemEditor/data/ReactStateOLXParser.js#L466-L467

Added lines #L466 - L467 were not covered by tests
}
// If there is not variables, foollow the normal workflow
this.convertedToStringResponse = false;
let answerObject = { [problemType]: [] };
let firstCorrectAnswerParsed = false;
answers.forEach((answer) => {