Skip to content

Commit

Permalink
feat(Match): Implement component export for choice reuse (#1254)
Browse files Browse the repository at this point in the history
  • Loading branch information
geoffreykwan authored May 17, 2023
1 parent 69c0351 commit 89c5029
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { LabelComponentDataExportStrategy } from '../strategies/LabelComponentDa
import { Component as WISEComponent } from '../../../common/Component';
import { removeHTMLTags } from '../../../common/string/string';
import { millisecondsToDateTime } from '../../../common/datetime/datetime';
import { Choice } from '../../../components/match/choice';
import { Bucket } from '../../../components/match/bucket';

@Component({
selector: 'data-export',
Expand Down Expand Up @@ -1171,11 +1173,7 @@ export class DataExportComponent implements OnInit {
componentRevisionCounter: any,
matchComponentState: any
): string[] {
/*
* Populate the cells in the row that contain the information about the
* student, project, run, step, and component.
*/
let row = this.createStudentWorkExportRow(
const row = this.createStudentWorkExportRow(
columnNames,
columnNameToNumber,
rowCounter,
Expand All @@ -1190,18 +1188,132 @@ export class DataExportComponent implements OnInit {
componentRevisionCounter,
matchComponentState
);
for (const bucket of matchComponentState.studentData.buckets) {
for (const item of bucket.items) {
if (component.choiceReuseEnabled) {
this.insertMatchChoiceReuseValues(row, columnNameToNumber, component, matchComponentState);
} else {
this.insertMatchDefaultValues(row, columnNameToNumber, component, matchComponentState);
}
return row;
}

private insertMatchDefaultValues(
row: string[],
columnNameToNumber: any,
component: any,
matchComponentState: any
): void {
matchComponentState.studentData.buckets.forEach((bucket: Bucket) => {
bucket.items.forEach((item: Choice) => {
row[columnNameToNumber[item.id]] = this.getBucketValueById(component, bucket.id);
if (
this.includeCorrectnessColumns &&
this.matchService.componentHasCorrectAnswer(component)
) {
this.setCorrectnessValue(row, columnNameToNumber, item);
}
});
});
}

private insertMatchChoiceReuseValues(
row: string[],
columnNameToNumber: any,
component: any,
matchComponentState: any
): void {
matchComponentState.studentData.buckets
.filter((bucket: Bucket) => bucket.id !== '0')
.forEach((bucket: Bucket) => {
bucket.items.forEach((item: Choice) => {
this.setBucketValue(row, columnNameToNumber, component, bucket, item);
if (
this.includeCorrectnessColumns &&
this.matchService.componentHasCorrectAnswer(component)
) {
this.setCorrectnessValueForChoiceReuse(row, columnNameToNumber, item);
}
});
});
}

private setBucketValue(
row: string[],
columnNameToNumber: any,
component: any,
bucket: Bucket,
item: Choice
): void {
const previousValue = row[columnNameToNumber[item.id]];
const bucketValue = this.getBucketValueById(component, bucket.id);
row[columnNameToNumber[item.id]] =
previousValue === '' ? bucketValue : `${previousValue}, ${bucketValue}`;
}

private setCorrectnessValueForChoiceReuse(
row: any[],
columnNameToNumber: any,
item: Choice
): void {
const columnName = item.id + '-boolean';
if (item.isCorrect == null) {
// The item does not have an isCorrect field so we will not show anything in the cell.
} else if (item.isCorrect) {
this.mergeCorrectnessValue(row, columnNameToNumber, columnName, 1);
} else {
if (item.isIncorrectPosition) {
this.mergeCorrectnessValue(row, columnNameToNumber, columnName, 2);
} else {
this.mergeCorrectnessValue(row, columnNameToNumber, columnName, 0);
}
}
return row;
}

/**
* Matrix to determine the merged correctness value.
* Legend
* e = empty
* 0 = incorrect
* 1 = correct
* 2 = correct bucket but incorrect position
* previous
* e 0 1 2
* --------
* n 0 | 0 0 0 0
* e 1 | 1 0 1 2
* w 2 | 2 0 2 2
* @param row: any[]
* @param columnNameToNumber: any
* @param columnName: string
* @param newValue: number
*/
private mergeCorrectnessValue(
row: any,
columnNameToNumber: any,
columnName: string,
newValue: number
): void {
const previousValue = row[columnNameToNumber[columnName]];
if (previousValue === '') {
row[columnNameToNumber[columnName]] = newValue;
} else if (this.bothValuesAreCorrect(previousValue, newValue)) {
row[columnNameToNumber[columnName]] = 1;
} else if (this.eitherValuesAreIncorrect(previousValue, newValue)) {
row[columnNameToNumber[columnName]] = 0;
} else if (this.eitherValuesAreIncorrectPosition(previousValue, newValue)) {
row[columnNameToNumber[columnName]] = 2;
}
}

private bothValuesAreCorrect(value1: number, value2: number): boolean {
return value1 === 1 && value2 === 1;
}

private eitherValuesAreIncorrect(value1: number, value2: number): boolean {
return value1 === 0 || value2 === 0;
}

private eitherValuesAreIncorrectPosition(value1: number, value2: number): boolean {
return value1 === 2 || value2 === 2;
}

getBucketValueById(component: any, id: string): string {
Expand Down
12 changes: 12 additions & 0 deletions src/assets/wise5/components/match/bucket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Choice } from './choice';

export class Bucket {
id: string;
items?: Choice[];
value: string;

constructor(id: string, value: string) {
this.id = id;
this.value = value;
}
}

0 comments on commit 89c5029

Please sign in to comment.