@khanacademy/perseus-score 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/index.js +63 -54
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +72 -53
- package/dist/index.js.map +1 -1
- package/dist/validation.types.d.ts +134 -32
- package/dist/validation.typetest.d.ts +1 -0
- package/dist/widgets/categorizer/score-categorizer.d.ts +2 -2
- package/dist/widgets/cs-program/score-cs-program.d.ts +1 -1
- package/dist/widgets/expression/score-expression.d.ts +1 -1
- package/dist/widgets/grapher/score-grapher.d.ts +1 -1
- package/dist/widgets/interactive-graph/score-interactive-graph.d.ts +1 -1
- package/dist/widgets/label-image/score-label-image.d.ts +2 -3
- package/dist/widgets/label-image/validate-label-image.d.ts +3 -0
- package/dist/widgets/matcher/score-matcher.d.ts +1 -1
- package/dist/widgets/matrix/score-matrix.d.ts +1 -1
- package/dist/widgets/matrix/validate-matrix.d.ts +2 -2
- package/dist/widgets/number-line/score-number-line.d.ts +2 -2
- package/dist/widgets/plotter/score-plotter.d.ts +2 -2
- package/dist/widgets/sorter/score-sorter.d.ts +1 -1
- package/dist/widgets/table/score-table.d.ts +1 -1
- package/package.json +4 -4
package/dist/es/index.js
CHANGED
|
@@ -12545,13 +12545,13 @@ function validateCategorizer(userInput, validationData) {
|
|
|
12545
12545
|
return null;
|
|
12546
12546
|
}
|
|
12547
12547
|
|
|
12548
|
-
function scoreCategorizer(userInput,
|
|
12549
|
-
const validationError = validateCategorizer(userInput,
|
|
12548
|
+
function scoreCategorizer(userInput, rubric) {
|
|
12549
|
+
const validationError = validateCategorizer(userInput, rubric);
|
|
12550
12550
|
if (validationError) {
|
|
12551
12551
|
return validationError;
|
|
12552
12552
|
}
|
|
12553
12553
|
let allCorrect = true;
|
|
12554
|
-
|
|
12554
|
+
rubric.values.forEach((value, i) => {
|
|
12555
12555
|
if (userInput.values[i] !== value) {
|
|
12556
12556
|
allCorrect = false;
|
|
12557
12557
|
}
|
|
@@ -12564,24 +12564,23 @@ function scoreCategorizer(userInput, scoringData) {
|
|
|
12564
12564
|
};
|
|
12565
12565
|
}
|
|
12566
12566
|
|
|
12567
|
-
|
|
12568
|
-
function scoreCSProgram(state) {
|
|
12567
|
+
function scoreCSProgram(userInput) {
|
|
12569
12568
|
// The CS program can tell us whether it's correct or incorrect,
|
|
12570
12569
|
// and pass an optional message
|
|
12571
|
-
if (
|
|
12570
|
+
if (userInput.status === "correct") {
|
|
12572
12571
|
return {
|
|
12573
12572
|
type: "points",
|
|
12574
12573
|
earned: 1,
|
|
12575
12574
|
total: 1,
|
|
12576
|
-
message:
|
|
12575
|
+
message: userInput.message || null
|
|
12577
12576
|
};
|
|
12578
12577
|
}
|
|
12579
|
-
if (
|
|
12578
|
+
if (userInput.status === "incorrect") {
|
|
12580
12579
|
return {
|
|
12581
12580
|
type: "points",
|
|
12582
12581
|
earned: 0,
|
|
12583
12582
|
total: 1,
|
|
12584
|
-
message:
|
|
12583
|
+
message: userInput.message || null
|
|
12585
12584
|
};
|
|
12586
12585
|
}
|
|
12587
12586
|
return {
|
|
@@ -12654,9 +12653,7 @@ function validateExpression(userInput) {
|
|
|
12654
12653
|
* show the user an error. TODO(joel) - what error?
|
|
12655
12654
|
* - Otherwise, pass through the resulting points and message.
|
|
12656
12655
|
*/
|
|
12657
|
-
function scoreExpression(userInput, rubric,
|
|
12658
|
-
// TODO: remove strings as a param for scorers
|
|
12659
|
-
strings, locale) {
|
|
12656
|
+
function scoreExpression(userInput, rubric, locale) {
|
|
12660
12657
|
const validationError = validateExpression(userInput);
|
|
12661
12658
|
if (validationError) {
|
|
12662
12659
|
return validationError;
|
|
@@ -12676,7 +12673,11 @@ strings, locale) {
|
|
|
12676
12673
|
// in the function variables list for the expression.
|
|
12677
12674
|
if (!expression.parsed) {
|
|
12678
12675
|
/* c8 ignore next */
|
|
12679
|
-
throw new PerseusError("Unable to parse solution answer for expression", Errors.InvalidInput
|
|
12676
|
+
throw new PerseusError("Unable to parse solution answer for expression", Errors.InvalidInput, {
|
|
12677
|
+
metadata: {
|
|
12678
|
+
rubric: JSON.stringify(rubric)
|
|
12679
|
+
}
|
|
12680
|
+
});
|
|
12680
12681
|
}
|
|
12681
12682
|
return KhanAnswerTypes.expression.createValidatorFunctional(expression.expr, _({}).extend(options, {
|
|
12682
12683
|
simplify: answer.simplify,
|
|
@@ -13070,49 +13071,57 @@ function scoreInteractiveGraph(userInput, rubric) {
|
|
|
13070
13071
|
};
|
|
13071
13072
|
}
|
|
13072
13073
|
|
|
13074
|
+
function validateLabelImage(userInput) {
|
|
13075
|
+
let numAnswered = 0;
|
|
13076
|
+
for (let i = 0; i < userInput.markers.length; i++) {
|
|
13077
|
+
const userSelection = userInput.markers[i].selected;
|
|
13078
|
+
if (userSelection && userSelection.length > 0) {
|
|
13079
|
+
numAnswered++;
|
|
13080
|
+
}
|
|
13081
|
+
}
|
|
13082
|
+
// We expect all question markers to be answered before grading.
|
|
13083
|
+
if (numAnswered !== userInput.markers.length) {
|
|
13084
|
+
return {
|
|
13085
|
+
type: "invalid",
|
|
13086
|
+
message: null
|
|
13087
|
+
};
|
|
13088
|
+
}
|
|
13089
|
+
return null;
|
|
13090
|
+
}
|
|
13091
|
+
|
|
13073
13092
|
// Question state for marker as result of user selected answers.
|
|
13074
13093
|
|
|
13075
|
-
function scoreLabelImageMarker(
|
|
13094
|
+
function scoreLabelImageMarker(userInput, rubric) {
|
|
13076
13095
|
const score = {
|
|
13077
13096
|
hasAnswers: false,
|
|
13078
13097
|
isCorrect: false
|
|
13079
13098
|
};
|
|
13080
|
-
if (
|
|
13099
|
+
if (userInput && userInput.length > 0) {
|
|
13081
13100
|
score.hasAnswers = true;
|
|
13082
13101
|
}
|
|
13083
|
-
if (
|
|
13084
|
-
if (
|
|
13102
|
+
if (rubric.length > 0) {
|
|
13103
|
+
if (userInput && userInput.length === rubric.length) {
|
|
13085
13104
|
// All correct answers are selected by the user.
|
|
13086
|
-
score.isCorrect =
|
|
13105
|
+
score.isCorrect = userInput.every(choice => rubric.includes(choice));
|
|
13087
13106
|
}
|
|
13088
|
-
} else if (!
|
|
13107
|
+
} else if (!userInput || userInput.length === 0) {
|
|
13089
13108
|
// Correct as no answers should be selected by the user.
|
|
13090
13109
|
score.isCorrect = true;
|
|
13091
13110
|
}
|
|
13092
13111
|
return score;
|
|
13093
13112
|
}
|
|
13094
|
-
|
|
13095
|
-
// TODO(LEMS-2440): May need to pull answers out of PerseusLabelImageWidgetOptions[markers] for the rubric
|
|
13096
13113
|
function scoreLabelImage(userInput, rubric) {
|
|
13097
|
-
|
|
13114
|
+
const validationError = validateLabelImage(userInput);
|
|
13115
|
+
if (validationError) {
|
|
13116
|
+
return validationError;
|
|
13117
|
+
}
|
|
13098
13118
|
let numCorrect = 0;
|
|
13099
|
-
for (
|
|
13100
|
-
const score = scoreLabelImageMarker(
|
|
13101
|
-
if (score.hasAnswers) {
|
|
13102
|
-
numAnswered++;
|
|
13103
|
-
}
|
|
13119
|
+
for (let i = 0; i < userInput.markers.length; i++) {
|
|
13120
|
+
const score = scoreLabelImageMarker(userInput.markers[i].selected, rubric.markers[i].answers);
|
|
13104
13121
|
if (score.isCorrect) {
|
|
13105
13122
|
numCorrect++;
|
|
13106
13123
|
}
|
|
13107
13124
|
}
|
|
13108
|
-
|
|
13109
|
-
// We expect all question markers to be answered before grading.
|
|
13110
|
-
if (numAnswered !== userInput.markers.length) {
|
|
13111
|
-
return {
|
|
13112
|
-
type: "invalid",
|
|
13113
|
-
message: null
|
|
13114
|
-
};
|
|
13115
|
-
}
|
|
13116
13125
|
return {
|
|
13117
13126
|
type: "points",
|
|
13118
13127
|
// Markers with no expected answers are graded as correct if user
|
|
@@ -13123,8 +13132,8 @@ function scoreLabelImage(userInput, rubric) {
|
|
|
13123
13132
|
};
|
|
13124
13133
|
}
|
|
13125
13134
|
|
|
13126
|
-
function scoreMatcher(
|
|
13127
|
-
const correct = _.isEqual(
|
|
13135
|
+
function scoreMatcher(userInput, rubric) {
|
|
13136
|
+
const correct = _.isEqual(userInput.left, rubric.left) && _.isEqual(userInput.right, rubric.right);
|
|
13128
13137
|
return {
|
|
13129
13138
|
type: "points",
|
|
13130
13139
|
earned: correct ? 1 : 0,
|
|
@@ -13141,7 +13150,7 @@ function scoreMatcher(state, rubric) {
|
|
|
13141
13150
|
*
|
|
13142
13151
|
* @see `scoreMatrix()` for more details.
|
|
13143
13152
|
*/
|
|
13144
|
-
function validateMatrix(userInput
|
|
13153
|
+
function validateMatrix(userInput) {
|
|
13145
13154
|
const supplied = userInput.answers;
|
|
13146
13155
|
const suppliedSize = getMatrixSize(supplied);
|
|
13147
13156
|
for (let row = 0; row < suppliedSize[0]; row++) {
|
|
@@ -13158,9 +13167,9 @@ function validateMatrix(userInput, validationData) {
|
|
|
13158
13167
|
}
|
|
13159
13168
|
|
|
13160
13169
|
function scoreMatrix(userInput, rubric) {
|
|
13161
|
-
const
|
|
13162
|
-
if (
|
|
13163
|
-
return
|
|
13170
|
+
const validationError = validateMatrix(userInput);
|
|
13171
|
+
if (validationError != null) {
|
|
13172
|
+
return validationError;
|
|
13164
13173
|
}
|
|
13165
13174
|
const solution = rubric.answers;
|
|
13166
13175
|
const supplied = userInput.answers;
|
|
@@ -13225,16 +13234,16 @@ function validateNumberLine(userInput) {
|
|
|
13225
13234
|
return null;
|
|
13226
13235
|
}
|
|
13227
13236
|
|
|
13228
|
-
function scoreNumberLine(userInput,
|
|
13237
|
+
function scoreNumberLine(userInput, rubric) {
|
|
13229
13238
|
const validationError = validateNumberLine(userInput);
|
|
13230
13239
|
if (validationError) {
|
|
13231
13240
|
return validationError;
|
|
13232
13241
|
}
|
|
13233
|
-
const range =
|
|
13234
|
-
const start =
|
|
13235
|
-
const startRel =
|
|
13236
|
-
const correctRel =
|
|
13237
|
-
const correctPos = number.equal(userInput.numLinePosition,
|
|
13242
|
+
const range = rubric.range;
|
|
13243
|
+
const start = rubric.initialX != null ? rubric.initialX : range[0];
|
|
13244
|
+
const startRel = rubric.isInequality ? "ge" : "eq";
|
|
13245
|
+
const correctRel = rubric.correctRel || "eq";
|
|
13246
|
+
const correctPos = number.equal(userInput.numLinePosition, rubric.correctX || 0);
|
|
13238
13247
|
if (correctPos && correctRel === userInput.rel) {
|
|
13239
13248
|
return {
|
|
13240
13249
|
type: "points",
|
|
@@ -13548,9 +13557,9 @@ function validateOrderer(userInput) {
|
|
|
13548
13557
|
}
|
|
13549
13558
|
|
|
13550
13559
|
function scoreOrderer(userInput, rubric) {
|
|
13551
|
-
const
|
|
13552
|
-
if (
|
|
13553
|
-
return
|
|
13560
|
+
const validationError = validateOrderer(userInput);
|
|
13561
|
+
if (validationError) {
|
|
13562
|
+
return validationError;
|
|
13554
13563
|
}
|
|
13555
13564
|
const correct = _.isEqual(userInput.current, rubric.correctOptions.map(option => option.content));
|
|
13556
13565
|
return {
|
|
@@ -13577,14 +13586,14 @@ function validatePlotter(userInput, validationData) {
|
|
|
13577
13586
|
return null;
|
|
13578
13587
|
}
|
|
13579
13588
|
|
|
13580
|
-
function scorePlotter(userInput,
|
|
13581
|
-
const validationError = validatePlotter(userInput,
|
|
13589
|
+
function scorePlotter(userInput, rubric) {
|
|
13590
|
+
const validationError = validatePlotter(userInput, rubric);
|
|
13582
13591
|
if (validationError) {
|
|
13583
13592
|
return validationError;
|
|
13584
13593
|
}
|
|
13585
13594
|
return {
|
|
13586
13595
|
type: "points",
|
|
13587
|
-
earned: approximateDeepEqual(userInput,
|
|
13596
|
+
earned: approximateDeepEqual(userInput, rubric.correct) ? 1 : 0,
|
|
13588
13597
|
total: 1,
|
|
13589
13598
|
message: null
|
|
13590
13599
|
};
|
|
@@ -13836,5 +13845,5 @@ function scoreInputNumber(userInput, rubric) {
|
|
|
13836
13845
|
};
|
|
13837
13846
|
}
|
|
13838
13847
|
|
|
13839
|
-
export { ErrorCodes, KhanAnswerTypes, inputNumberAnswerTypes, scoreCSProgram, scoreCategorizer, scoreDropdown, scoreExpression, scoreGrapher, scoreIframe, scoreInputNumber, scoreInteractiveGraph, scoreLabelImage, scoreLabelImageMarker, scoreMatcher, scoreMatrix, scoreNumberLine, scoreNumericInput, scoreOrderer, scorePlotter, scoreRadio, scoreSorter, scoreTable };
|
|
13848
|
+
export { ErrorCodes, KhanAnswerTypes, inputNumberAnswerTypes, scoreCSProgram, scoreCategorizer, scoreDropdown, scoreExpression, scoreGrapher, scoreIframe, scoreInputNumber, scoreInteractiveGraph, scoreLabelImage, scoreLabelImageMarker, scoreMatcher, scoreMatrix, scoreNumberLine, scoreNumericInput, scoreOrderer, scorePlotter, scoreRadio, scoreSorter, scoreTable, validateCategorizer, validateDropdown, validateExpression, validateMatrix, validateNumberLine, validateOrderer, validatePlotter, validateRadio, validateSorter, validateTable };
|
|
13840
13849
|
//# sourceMappingURL=index.js.map
|