//CORE CODE FOR CHECKING SHORT ANSWER GUESSES AGAINST ANSWER ARRAYS var CaseSensitive = [boolCaseSensitive]; var ShowAlsoCorrect = [boolShowAlsoCorrect]; var PleaseEnter = '[strPleaseEnter]'; var HybridTries = [intHybridTries]; var PartlyIncorrect = '[strPartlyIncorrect]'; var CorrectList = '[strCorrectList]'; var NextCorrect = '[strNextCorrect]'; var CurrBox = null; function TrackFocus(BoxID){ InTextBox = true; CurrBox = document.getElementById(BoxID); } function LeaveGap(){ InTextBox = false; } function TypeChars(Chars){ if (CurrBox != null){ //Following check added for 6.0.4.4 to avoid error message in IE6 if (CurrBox.style.display != 'none'){ CurrBox.value += Chars; CurrBox.focus(); } } } function CheckGuess(Guess, Answer, CaseSensitive, PercentCorrect, Feedback){ this.Guess = Guess; this.Answer = Answer; this.PercentCorrect = PercentCorrect; this.Feedback = Feedback; if (CaseSensitive == false){ this.WorkingGuess = Guess.toLowerCase(); this.WorkingAnswer = Answer.toLowerCase(); } else{ this.WorkingGuess = Guess; this.WorkingAnswer = Answer; } this.Hint = ''; this.HintPenalty = 1/Answer.length; this.CorrectStart = ''; this.WrongMiddle = ''; this.CorrectEnd = ''; this.PercentMatch = 0; this.DoCheck(); } function CheckGuess_DoCheck(){ //Check if it's an exact match if (this.WorkingAnswer == this.WorkingGuess){ this.PercentMatch = 100; this.CorrectStart = this.Guess; return; } //Figure out how much of the beginning is correct var i = 0; var CorrectChars = 0; while (this.WorkingAnswer.charAt(i) == this.WorkingGuess.charAt(i)){ i++; CorrectChars++; } //Stash the hint this.Hint = this.Answer.charAt(i); this.CorrectStart = this.Guess.substring(0, i); //If there's more to the answer, look at the rest of it if (i=i)&&((this.WorkingAnswer.charAt(k) == this.WorkingGuess.charAt(j))&&(CorrectChars < this.Answer.length))){ CorrectChars++; j--; k--; } this.CorrectEnd = this.Guess.substring(j+1, this.Guess.length); this.WrongMiddle = this.Guess.substring(i, j+1); } if (TrimString(this.WrongMiddle).length < 1){this.WrongMiddle = '_';} //Calculate match score based on how much of the guess is correct if (CorrectChars < this.Answer.length){ this.PercentMatch = Math.floor(100*CorrectChars)/this.Answer.length; } else{ this.PercentMatch = Math.floor((100 * CorrectChars)/this.Guess.length); } } CheckGuess.prototype.DoCheck = CheckGuess_DoCheck; function CheckAnswerArray(CaseSensitive){ this.CaseSensitive = CaseSensitive; this.Answers = new Array(); this.Score = 0; this.Feedback = ''; this.Hint = ''; this.HintPenalty = 0; this.MatchedAnswerLength = 1; this.CompleteMatch = false; this.MatchNum = -1; } function CheckAnswerArray_AddAnswer(Guess, Answer, PercentCorrect, Feedback){ this.Answers.push(new CheckGuess(Guess, Answer, this.CaseSensitive, PercentCorrect, Feedback)); } CheckAnswerArray.prototype.AddAnswer = CheckAnswerArray_AddAnswer; function CheckAnswerArray_ClearAll(){ this.Answers.length = 0; } CheckAnswerArray.prototype.ClearAll = CheckAnswerArray_ClearAll; function CheckAnswerArray_GetBestMatch(){ //First check for a 100% match for (var i=0; i PercentMatch)&&(this.Answers[i].PercentCorrect == 100)){ BestMatch = i; PercentMatch = this.Answers[i].PercentMatch; } } if (BestMatch > -1){ this.Score = this.Answers[BestMatch].PercentMatch; this.Feedback = PartlyIncorrect + ' '; this.Feedback += '' + this.Answers[BestMatch].CorrectStart; this.Feedback += '' + this.Answers[BestMatch].WrongMiddle + ''; this.Feedback += this.Answers[BestMatch].CorrectEnd + ''; this.Hint = '' + this.Answers[BestMatch].CorrectStart; this.Hint += '' + this.Answers[BestMatch].Hint + ''; this.HintPenalty = this.Answers[BestMatch].HintPenalty; } else{ this.Score = 0; this.Feedback = ''; } } CheckAnswerArray.prototype.GetBestMatch = CheckAnswerArray_GetBestMatch; function CheckShortAnswer(QNum){ //bail if question doesn't exist or exercise finished if ((State[QNum].length < 1)||(Finished == true)){return;} //bail if question already complete if (State[QNum][0] > -1){return;} //Get the guess (TrimString added to fix bug for 6.0.4.3) var G = TrimString(document.getElementById('Q_' + QNum + '_Guess').value); //If no guess, bail with message; no penalty if (G.length < 1){ ShowMessage(PleaseEnter); return; } //Increment tries State[QNum][2]++; //Create a check object var CA = new CheckAnswerArray(CaseSensitive); CA.ClearAll(); for (var ANum=0; ANum 0){State[QNum][5] += ' | ';} if (CA.MatchNum > -1){ State[QNum][5] += String.fromCharCode(65+CA.MatchNum); } //Else store the student's answer else{ State[QNum][5] += G; } //Add the percent correct value for this answer to the Q State (works for all //situations, wrong or right) State[QNum][3] += CA.Score; //Now branch, based on the nature of the match //Is it a complete match? if (CA.CompleteMatch == true){ //Is it with a wrong answer, or a right answer? if (CA.Score == 100){ //It's right CalculateShortAnsQuestionScore(QNum); //Get correct answer list if required, assuming there are any other correct alternatives if (ShowAlsoCorrect == true){ var AlsoCorrectList = GetCorrectList(QNum, G, false); if (AlsoCorrectList.length > 0){ CA.Feedback += '
' + CorrectList + '
' + AlsoCorrectList; } } //Get the overall score and add it to the feedback if (ContinuousScoring == true){ CalculateOverallScore(); CA.Feedback += '
' + YourScoreIs + ' ' + Score + '%.'; WriteToInstructions(YourScoreIs + ' ' + Score + '%.'); } ShowMessage(CA.Feedback); //Put the answer in ReplaceGuessBox(QNum, G); CheckFinished(); return; } } //Otherwise, it's a match to a predicted wrong/partially correct, or a partial //match to a right answer if (CA.Feedback.length < 1){CA.Feedback = DefaultWrong;} //Remove any previous score unless exercise is finished (6.0.3.8+) if (Finished == false){ WriteToInstructions(strInstructions); } ShowMessage(CA.Feedback); //If necessary, switch a hybrid question to m/c if (State[QNum][2] >= HybridTries){ SwitchHybridDisplay(QNum); } } function CalculateShortAnsQuestionScore(QNum){ var Tries = State[QNum][2] + State[QNum][4]; //include tries and hint penalties; var PercentCorrect = State[QNum][3]; var HintPenalties = State[QNum][4]; //Make sure it's not already complete if (State[QNum][0] < 0){ if (HintPenalties >= 1){ State[QNum][0] = 0; } else{ State[QNum][0] = (PercentCorrect/(100*Tries)); } if (State[QNum][0] < 0){ State[QNum][0] = 0; } } } function SwitchHybridDisplay(QNum){ if (document.getElementById('Q_' + QNum + '_Hybrid_MC') != null){ document.getElementById('Q_' + QNum + '_Hybrid_MC').style.display = ''; if (document.getElementById('Q_' + QNum + '_SA') != null){ document.getElementById('Q_' + QNum + '_SA').style.display = 'none'; } } } function GetCorrectArray(QNum){ var Result = new Array(); for (var ANum=0; ANum'; } } return Result; } function GetFirstCorrectAnswer(QNum){ var As = GetCorrectArray(QNum); if (As.length > 0){ return As[0]; } else{ return ''; } } function ReplaceGuessBox(QNum, Ans){ if (document.getElementById('Q_' + QNum + '_SA') != null){ var El = document.getElementById('Q_' + QNum + '_SA'); while (El.childNodes.length > 0){ El.removeChild(El.childNodes[0]); } var A = document.createElement('span'); A.setAttribute('class', 'Answer'); var T = document.createTextNode(Ans); A.appendChild(T); El.appendChild(A); } } [inclShowAnswer] function ShowAnswers(QNum){ //bail if question doesn't exist or exercise finished if ((State[QNum].length < 1)||(Finished == true)){return;} //Get the answer list to display var Ans = GetCorrectList(QNum, '', false); Ans = CorrectList + '
' + Ans; //Display feedback ShowMessage(Ans); //Set the score for this question to 0 if no if (State[QNum][0] < 1){ State[QNum][0] = 0; } //Get the first correct answer var FirstAns = GetFirstCorrectAnswer(QNum); //Replace the textbox ReplaceGuessBox(QNum, FirstAns); //Remove any current score WriteToInstructions(strInstructions); //This may be the last, so check finished status CheckFinished(); } [/inclShowAnswer] [inclHint] function ShowHint(QNum){ //bail if question doesn't exist or exercise finished if ((State[QNum].length < 1)||(Finished == true)){return;} //bail if question already complete if (State[QNum][0] > -1){return;} //Get the guess var G = document.getElementById('Q_' + QNum + '_Guess').value; //If no guess, give the first correct bit if (G.length < 1){ var Ans = GetFirstCorrectAnswer(QNum); var Hint = Ans.charAt(0); ShowMessage(NextCorrect + '
' + Hint); //Penalty for hint State[QNum][4] += (1/Ans.length); return; } //Increment tries State[QNum][2]++; //Create a check object var CA = new CheckAnswerArray(CaseSensitive); CA.ClearAll(); for (var ANum=0; ANum 0){ ShowMessage(NextCorrect + '
' + CA.Hint); State[QNum][4] += CA.HintPenalty; } else{ ShowMessage(DefaultWrong + '
' + NextCorrect + '
' + GetFirstCorrectAnswer(QNum).charAt(0)); } } } [/inclHint]