答案检查 - 更 elegant/efficient 的解决方案?

Answer checking - a more elegant/efficient solution?

我正在为一些学生编写一个应用程序,它会自动生成问题(例如速度 = distance/time 问题),做一个小动画,并自动对学生给出的答案进行评分。它看起来像这样:

关于我的目标的详细信息 虽然总的来说代码不是问题并且一切正常,但我想让一部分更优雅并且想知道是否有 Javascript 解决方案可以做到这一点。基本上我想要的是采用一些功能,上面写着'是这个吗?是这个吗?是这个吗? ...' 变成'它是其中之一吗?如果是,它是哪一个?'。

没有预期或实际结果,因为它有效,我正在努力简化。同样没有错误。

这是堆栈闪电战:https://stackblitz.com/edit/angular-qrldtz?devtoolsheight=33&file=src/app/app.component.ts

HTML 示例,使用 Angular 语法:显示当前问题。这是上图的右侧。

<form [formGroup]="formAnswers" (ngSubmit)="answersSubmitted()">
  <div class="question-container" *ngFor="let question of questionBank[0].questions; let i = index">
      <div class="question-question">{{ question.question }}</div>
      <div class="question-input">
          <input type="text" formControlName="{{ question.id }}" class="answer-input" maxlength="8">
      </div>
  </div>
  <button type="submit" style="float: right;">Submit Answers</button>
</form>

我在下面有一个适用的 typescript 代码的精简示例。我要精简的地方在 'answersSubmitted()' 函数中。这是提交答案时从 HTML 调用的内容。它将根据代码中存储的值检查输入的值。

formAnswers: FormGroup;
velocity: number = 0;
valueInitialSpeed = {'x': 0, 'y': 0};

// this is the database of questions. Only one is provided here as an example
questionBank = [
    {
        'questionText': `A tennis ball is hit from an overhand serve towards a net.`, 
        'startVelocityRange': 25.2,
        'angleAppliedRange': 12,
        'xAccelerationRange': 0,
        'yAccelerationRange': 0,
        'gravity': 9.81,
        'startHeightRange': [0, 0],
        'dataGiven': { 'velocity': true, 'yInitSpeed': false, 'xInitSpeed': false},
        'questions': [
            {
                'question':'What is the initial vertical velocity of the ball',
                'answerValue': 'yInitSpeed', // this helps identify the answer and refers to the dataGiven object above.
                'id':'getYVelocity' // this is the identification which gets put onto the input. It relates the answer given to the variable above.
            }
        ]
    }
];

answersSubmitted() {

    this.questionBank[0].questions.forEach(question => {

        // gets the value entered by the student from the relevant input box.
        var value = parseFloat(this.formAnswers.value[question.id]);

        // xInitSpeed refers to questionBank[0].question[questionid].answerValue
        // it identifies which value to check the input against in the questionBank array
        if(question.answerValue === 'xInitSpeed') {
          // this function checks whether the input answer and the calculated answer are roughly equal.
          // valueInitialSpeed.x is calculated when the question is generated.
          // this.tolerance is just a percentage of how tolerant we are being with answer values
          if(this.percentageWithinBounds(value, this.valueInitialSpeed.x, this.tolerance)) {
            // correctanswer is just what functions we run when the answer given is correct
            this.correctAnswer(question);
          }
          // this repetition is what I am interested in streamlining
        } else if(question.answerValue === 'yInitSpeed') {
          if(this.percentageWithinBounds(value, this.valueInitialSpeed.y, this.tolerance)) {
            this.correctAnswer(question);
          }
        } else {}// if{} ... etc etc
        
    });
}

private percentageWithinBounds(x, y, z) {
    // not applicable for now.
}

private correctAnswer(x) {
    // not applicable for now.
}
                    

我觉得 questionBank 数组可能需要稍微更改以适应这一点,并且我愿意接受更改以简化此操作。虽然这段代码没有问题,但这是我要重用的东西,并且希望简化编码过程以及将来进行的任何更复杂的模拟。

好吧,看起来您通过 return 一个引用答案的变量而不是简单地 return 答案本身来使事情变得过于复杂。

https://stackblitz.com/edit/angular-ahlosh?file=src/app/app.component.ts

通过将答案移到问题的 属性 中,我已经大大简化了事情。

如果您需要更复杂的东西,您可以将 answer 变成一个计算适当值的函数,如下所示:

https://stackblitz.com/edit/angular-zckmwj?file=src%2Fapp%2Fapp.component.ts

您可以在答案函数中放入任何您想要的逻辑,您甚至可以传入给定的答案,并且 return 如果合适,只需要一个真或假。

我在那里留下了一些关于小问题的其他评论。我强烈建议在 tsconfig.json 中启用 noImplicitAny - 这将强制您输入所有内容。如果你不这样做,那么使用 Typescript 有什么意义呢?类型可以帮助您!