Salut à tous!
Je suis débutant et j'aurai besoin d'un coup de pouce!
Je pense que ce problème peux être réglé en 2 min par quelqu'un qui a de l'experience! Pour ma part je ne suis qu'en Licence1 d'info, donc je galère...
Bien sûr j'aurai pu attendre de maîtriser le code pour m'y attaquer mais c'est urgent!...
Je réalise un petit site de e-learning avec des QCM (ou plutôt "Multi Selection") sous HotPotatoes.
Je voudrais changer le système de notation au niveau de:
function CalculateMultiSelQuestionScore(QNum){
Le but est d'avoir une notation pour des exercices spécifiques:
Pour une question il serra toujours édité 5 réponses possibles,
pour la notation on aura:
cocher une réponse juste= correct
ne pas cocher une réponse fausse= correct
cocher une réponse fausse= erreur
ne pas cocher une réponse juste= erreur
Ainsi pour Une question on aura 0/5; 1/5; 2/5; 3/5; 4/5 ou 5/5 "cochages" corrects...
J'aimerai pouvoir attribuer des notes constantes à ces résultats:
5/5 =>1/1
4/5 =>0,5/1
3/5 =>0,25/1
2/5; 1/5 ou 0/5 => 0/1
Voilà!
Le code à modifier se situ aux environs de function CalculateMultiSelQuestionScore(QNum){ dans le fichier jquiz6.js de HotPotatoes V6.2Release4
Voici le code:
[inclScorm1.2] //JQUIZ-SPECIFIC SCORM-RELATED JAVASCRIPT CODE function SetScormScore(){ //Reports the current score and any other information back to the LMS if (API != null){ API.LMSSetValue('cmi.core.score.raw', Score); //Now send detailed reports about each item for (var i=0; i<State.length; i++){ if (State[i] != null){ var ItemLabel = 'Item_' + (i+1).toString(); var ThisItemScore = ''; var ThisItemStatus = ''; API.LMSSetValue('cmi.objectives.' + i + '.id', 'obj'+ItemLabel); API.LMSSetValue('cmi.interactions.' + i + '.id', 'int'+ItemLabel); API.LMSSetValue('cmi.objectives.' + i + '.score.min', '0'); API.LMSSetValue('cmi.objectives.' + i + '.score.max', '100'); if (State[i][2] > 0){ ThisItemScore = Math.floor(State[i][0] * 100) + ''; ThisItemStatus = 'completed'; } else{ ThisItemScore = '0'; ThisItemStatus = 'incomplete'; } API.LMSSetValue('cmi.objectives.' + i + '.score.raw', ThisItemScore); API.LMSSetValue('cmi.objectives.' + i + '.status', ThisItemStatus); API.LMSSetValue('cmi.interactions.' + i + '.weighting', I[i][0]); //We can only use the performance type, because we're storing multiple responses of various types. API.LMSSetValue('cmi.interactions.' + i + '.type', 'performance'); API.LMSSetValue('cmi.interactions.' + i + '.student_response', State[i][5]); } } API.LMSCommit(''); } } [/inclScorm1.2] //JQUIZ CORE JAVASCRIPT CODE var CurrQNum = 0; var CorrectIndicator = '[strCorrectIndicator]'; var IncorrectIndicator = '[strIncorrectIndicator]'; var YourScoreIs = '[strYourScoreIs]'; //New for 6.2.2.0 var CompletedSoFar = '[strCompletedSoFar]'; var ExerciseCompleted = '[strExerciseCompleted]'; var ShowCompletedSoFar = true; var ContinuousScoring = [boolContinuousScoring]; var CorrectFirstTime = '[strCorrectFirstTime]'; var ShowCorrectFirstTime = [boolShowCorrectFirstTime]; var ShuffleQs = [boolShuffleQs]; var ShuffleAs = [boolShuffleAs]; var DefaultRight = '[strDefaultRight]'; var DefaultWrong = '[strDefaultWrong]'; var QsToShow = [QsToShow]; var Score = 0; var Finished = false; var Qs = null; var QArray = new Array(); var ShowingAllQuestions = false; var ShowAllQuestionsCaption = '[strShowAllQuestionsCaptionJS]'; var ShowOneByOneCaption = '[strShowOneByOneCaptionJS]'; var State = new Array(); var Feedback = ''; var TimeOver = false; var strInstructions = ''; var Locked = false; //The following variable can be used to add a message explaining that //the question is finished, so no further marking will take place. var strQuestionFinished = ''; function CompleteEmptyFeedback(){ var QNum, ANum; for (QNum=0; QNum<I.length; QNum++){ //Only do this if not multi-select if (I[QNum][2] != '3'){ for (ANum = 0; ANum<I[QNum][3].length; ANum++){ if (I[QNum][3][ANum][1].length < 1){ if (I[QNum][3][ANum][2] > 0){ I[QNum][3][ANum][1] = DefaultRight; } else{ I[QNum][3][ANum][1] = DefaultWrong; } } } } } } function SetUpQuestions(){ var AList = new Array(); var QList = new Array(); var i, j; Qs = document.getElementById('Questions'); while (Qs.getElementsByTagName('li').length > 0){ QList.push(Qs.removeChild(Qs.getElementsByTagName('li')[0])); } var DumpItem = 0; if (QsToShow > QList.length){ QsToShow = QList.length; } while (QsToShow < QList.length){ DumpItem = Math.floor(QList.length*Math.random()); for (j=DumpItem; j<(QList.length-1); j++){ QList[j] = QList[j+1]; } QList.length = QList.length-1; } if (ShuffleQs == true){ QList = Shuffle(QList); } if (ShuffleAs == true){ var As; for (var i=0; i<QList.length; i++){ As = QList[i].getElementsByTagName('ol')[0]; if (As != null){ AList.length = 0; while (As.getElementsByTagName('li').length > 0){ AList.push(As.removeChild(As.getElementsByTagName('li')[0])); } AList = Shuffle(AList); for (j=0; j<AList.length; j++){ As.appendChild(AList[j]); } } } } for (i=0; i<QList.length; i++){ Qs.appendChild(QList[i]); QArray[QArray.length] = QList[i]; } //Show the first item QArray[0].style.display = ''; //Now hide all except the first item for (i=1; i<QArray.length; i++){ QArray[i].style.display = 'none'; } SetQNumReadout(); SetFocusToTextbox(); } function SetFocusToTextbox(){ //if there's a textbox, set the focus in it if (QArray[CurrQNum].getElementsByTagName('input')[0] != null){ QArray[CurrQNum].getElementsByTagName('input')[0].focus(); //and show a keypad if there is one if (document.getElementById('CharacterKeypad') != null){ document.getElementById('CharacterKeypad').style.display = 'block'; } } else{ if (QArray[CurrQNum].getElementsByTagName('textarea')[0] != null){ QArray[CurrQNum].getElementsByTagName('textarea')[0].focus(); //and show a keypad if there is one if (document.getElementById('CharacterKeypad') != null){ document.getElementById('CharacterKeypad').style.display = 'block'; } } //This added for 6.0.4.11: hide accented character buttons if no textbox else{ if (document.getElementById('CharacterKeypad') != null){ document.getElementById('CharacterKeypad').style.display = 'none'; } } } } function ChangeQ(ChangeBy){ //The following line prevents moving to another question until the current //question is answered correctly. Uncomment it to enable this behaviour. // if (State[CurrQNum][0] == -1){return;} if (((CurrQNum + ChangeBy) < 0)||((CurrQNum + ChangeBy) >= QArray.length)){return;} QArray[CurrQNum].style.display = 'none'; CurrQNum += ChangeBy; QArray[CurrQNum].style.display = ''; //Undocumented function added 10/12/2004 ShowSpecialReadingForQuestion(); SetQNumReadout(); SetFocusToTextbox(); } var HiddenReadingShown = false; function ShowSpecialReadingForQuestion(){ //Undocumented function for showing specific reading text elements which change with each question //Added on 10/12/2004 if (document.getElementById('ReadingDiv') != null){ if (HiddenReadingShown == true){ document.getElementById('ReadingDiv').innerHTML = ''; } if (QArray[CurrQNum] != null){ //Fix for 6.0.4.25 var Children = QArray[CurrQNum].getElementsByTagName('div'); for (var i=0; i<Children.length; i++){ if (Children[i].className=="HiddenReading"){ document.getElementById('ReadingDiv').innerHTML = Children[i].innerHTML; HiddenReadingShown = true; //Hide the ShowAllQuestions button to avoid confusion if (document.getElementById('ShowMethodButton') != null){ document.getElementById('ShowMethodButton').style.display = 'none'; } } } } } } function SetQNumReadout(){ document.getElementById('QNumReadout').innerHTML = (CurrQNum+1) + ' / ' + QArray.length; if ((CurrQNum+1) >= QArray.length){ if (document.getElementById('NextQButton') != null){ document.getElementById('NextQButton').style.visibility = 'hidden'; } } else{ if (document.getElementById('NextQButton') != null){ document.getElementById('NextQButton').style.visibility = 'visible'; } } if (CurrQNum <= 0){ if (document.getElementById('PrevQButton') != null){ document.getElementById('PrevQButton').style.visibility = 'hidden'; } } else{ if (document.getElementById('PrevQButton') != null){ document.getElementById('PrevQButton').style.visibility = 'visible'; } } } [strItemArray] function StartUp(){ RemoveBottomNavBarForIE(); //If there's only one question, no need for question navigation controls if (QsToShow < 2){ document.getElementById('QNav').style.display = 'none'; } //Stash the instructions so they can be redisplayed strInstructions = document.getElementById('InstructionsDiv').innerHTML; [inclScorm1.2] ScormStartUp(); [/inclScorm1.2] [inclSendResults] GetUserName(); [/inclSendResults] [inclPreloadImages] PreloadImages([PreloadImageList]); [/inclPreloadImages] CompleteEmptyFeedback(); SetUpQuestions(); ClearTextBoxes(); CreateStatusArray(); [inclTimer] setTimeout('StartTimer()', 50); [/inclTimer] //Check search string for q parameter if (document.location.search.length > 0){ if (ShuffleQs == false){ var JumpTo = parseInt(document.location.search.substring(1,document.location.search.length))-1; if (JumpTo <= QsToShow){ ChangeQ(JumpTo); } } } //Undocumented function added 10/12/2004 ShowSpecialReadingForQuestion(); } function ShowHideQuestions(){ FuncBtnOut(document.getElementById('ShowMethodButton')); document.getElementById('ShowMethodButton').style.display = 'none'; if (ShowingAllQuestions == false){ for (var i=0; i<QArray.length; i++){ QArray[i].style.display = ''; } document.getElementById('Questions').style.listStyleType = 'decimal'; document.getElementById('OneByOneReadout').style.display = 'none'; document.getElementById('ShowMethodButton').innerHTML = ShowOneByOneCaption; ShowingAllQuestions = true; } else{ for (var i=0; i<QArray.length; i++){ if (i != CurrQNum){ QArray[i].style.display = 'none'; } } document.getElementById('Questions').style.listStyleType = 'none'; document.getElementById('OneByOneReadout').style.display = ''; document.getElementById('ShowMethodButton').innerHTML = ShowAllQuestionsCaption; ShowingAllQuestions = false; } document.getElementById('ShowMethodButton').style.display = 'inline'; } function CreateStatusArray(){ var QNum, ANum; //For each item in the item array for (QNum=0; QNum<I.length; QNum++){ //Check if the question still exists (hasn't been nuked by showing a random selection) if (document.getElementById('Q_' + QNum) != null){ State[QNum] = new Array(); State[QNum][0] = -1; //Score for this q; -1 shows question not done yet State[QNum][1] = new Array(); //answers for (ANum = 0; ANum<I[QNum][3].length; ANum++){ State[QNum][1][ANum] = 0; //answer not chosen yet; when chosen, will store its position in the series of choices } State[QNum][2] = 0; //tries at this q so far State[QNum][3] = 0; //incrementing percent-correct values of selected answers State[QNum][4] = 0; //penalties incurred for hints State[QNum][5] = ''; //Sequence of answers chosen by number } else{ State[QNum] = null; } } } [inclMultiChoice] function CheckMCAnswer(QNum, ANum, Btn){ //if question doesn't exist, bail if (State[QNum].length < 1){return;} //Get the feedback Feedback = I[QNum][3][ANum][1]; //Now show feedback and bail if question already complete if (State[QNum][0] > -1){ //Add an extra message explaining that the question // is finished if defined by the user if (strQuestionFinished.length > 0){Feedback += '<br />' + strQuestionFinished;} //Show the feedback ShowMessage(Feedback); //New for 6.2.2.1: If you want to mark an answer as correct even when it's the final choice, uncomment this line. // if (I[QNum][3][ANum][2] >= 1){Btn.innerHTML = CorrectIndicator;}else{Btn.innerHTML = IncorrectIndicator;} return; } //Hide the button while processing Btn.style.display = 'none'; //Increment the number of tries State[QNum][2]++; //Add the percent-correct value of this answer State[QNum][3] += I[QNum][3][ANum][3]; //Store the try number in the answer part of the State array, for tracking purposes State[QNum][1][ANum] = State[QNum][2]; if (State[QNum][5].length > 0){State[QNum][5] += ' | ';} State[QNum][5] += String.fromCharCode(65+ANum); //Should this answer be accepted as correct? if (I[QNum][3][ANum][2] < 1){ //It's wrong //Mark the answer Btn.innerHTML = IncorrectIndicator; //Remove any previous score unless exercise is finished (6.0.3.8+) if (Finished == false){ WriteToInstructions(strInstructions); } //Check whether this leaves just one MC answer unselected, in which case the Q is terminated var RemainingAnswer = FinalAnswer(QNum); if (RemainingAnswer > -1){ //Behave as if the last answer had been selected, but give no credit for it //Increment the number of tries State[QNum][2]++; //Calculate the score for this question CalculateMCQuestionScore(QNum); //Get the overall score and add it to the feedback CalculateOverallScore(); //New for 6.2.2.1 var QsDone = CheckQuestionsCompleted(); if ((ContinuousScoring == true)||(Finished == true)){ Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.' + '<br />' + QsDone; WriteToInstructions(YourScoreIs + ' ' + Score + '%.' + '<br />' + QsDone); } else{ WriteToInstructions(QsDone); } } } else{ //It's right //Mark the answer Btn.innerHTML = CorrectIndicator; //Calculate the score for this question CalculateMCQuestionScore(QNum); //New for 6.2.2.0 var QsDone = CheckQuestionsCompleted(); //Get the overall score and add it to the feedback if (ContinuousScoring == true){ CalculateOverallScore(); if ((ContinuousScoring == true)||(Finished == true)){ Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.' + '<br />' + QsDone; WriteToInstructions(YourScoreIs + ' ' + Score + '%.' + '<br />' + QsDone); } } else{ WriteToInstructions(QsDone); } } //Show the button again Btn.style.display = 'inline'; //Finally, show the feedback ShowMessage(Feedback); //Check whether all questions are now done CheckFinished(); } function CalculateMCQuestionScore(QNum){ var Tries = State[QNum][2] + State[QNum][4]; //include tries and hint penalties var PercentCorrect = State[QNum][3]; var TotAns = GetTotalMCAnswers(QNum); var HintPenalties = State[QNum][4]; //Make sure it's not already complete if (State[QNum][0] < 0){ //Allow for Hybrids if (HintPenalties >= 1){ State[QNum][0] = 0; } else{ //This line calculates the score for this question if (TotAns == 1){ State[QNum][0] = 1; } else{ State[QNum][0] = ((TotAns-((Tries*100)/State[QNum][3]))/(TotAns-1)); } } //Fix for Safari bug added for version 6.0.3.42 (negative infinity problem) if ((State[QNum][0] < 0)||(State[QNum][0] == Number.NEGATIVE_INFINITY)){ State[QNum][0] = 0; } } } function GetTotalMCAnswers(QNum){ var Result = 0; for (var ANum=0; ANum<I[QNum][3].length; ANum++){ if (I[QNum][3][ANum][4] == 1){ //This is an MC answer Result++; } } return Result; } function FinalAnswer(QNum){ var UnchosenAnswers = 0; var FinalAnswer = -1; for (var ANum=0; ANum<I[QNum][3].length; ANum++){ if (I[QNum][3][ANum][4] == 1){ //This is an MC answer if (State[QNum][1][ANum] < 1){ //This answer hasn't been chosen yet UnchosenAnswers++; FinalAnswer = ANum; } } } if (UnchosenAnswers == 1){ return FinalAnswer; } else{ return -1; } } [/inclMultiChoice] [inclMultiSelect] function CheckMultiSelAnswer(QNum){ //bail if question doesn't exist or exercise finished if ((State[QNum].length < 1)||(Finished == true)){return;} //Increment the tries for this question State[QNum][2]++; var ShouldBeChecked; var Matches = 0; if (State[QNum][5].length > 0){State[QNum][5] += ' | ';} //Check if there are any mismatches Feedback = ''; var CheckBox = null; for (var ANum=0; ANum<I[QNum][3].length; ANum++){ CheckBox = document.getElementById('Q_' + QNum + '_' + ANum + '_Chk'); if (CheckBox.checked == true){ State[QNum][5] += 'Y'; } else{ State[QNum][5] += 'N'; } ShouldBeChecked = (I[QNum][3][ANum][2] == 1); if (ShouldBeChecked == CheckBox.checked){ Matches++; } else{ Feedback = I[QNum][3][ANum][1]; } } //Add the hit readout Feedback = Matches + ' / ' + I[QNum][3].length + '<br />' + Feedback; if (Matches == I[QNum][3].length){ //It's right CalculateMultiSelQuestionScore(QNum); //New for 6.2.2.0 var QsDone = CheckQuestionsCompleted(); if (ContinuousScoring == true){ CalculateOverallScore(); if ((ContinuousScoring == true)||(Finished == true)){ Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.' + '<br />' + QsDone; WriteToInstructions(YourScoreIs + ' ' + Score + '%.' + '<br />' + QsDone); } else{ WriteToInstructions(QsDone); } } } else{ //It's wrong -- Remove any previous score unless exercise is finished (6.0.3.8+) if (Finished == false){ WriteToInstructions(strInstructions); } } //Show the feedback ShowMessage(Feedback); //Check whether all questions are now done CheckFinished(); } function CalculateMultiSelQuestionScore(QNum){ var Tries = State[QNum][2]; var TotAns = State[QNum][1].length; //Make sure it's not already complete if (State[QNum][0] < 0){ State[QNum][0] = (TotAns - (Tries-1)) / TotAns; if (State[QNum][0] < 0){ State[QNum][0] = 0; } } } [/inclMultiSelect] function CalculateOverallScore(){ var TotalWeighting = 0; var TotalScore = 0; for (var QNum=0; QNum<State.length; QNum++){ if (State[QNum] != null){ if (State[QNum][0] > -1){ TotalWeighting += I[QNum][0]; TotalScore += (I[QNum][0] * State[QNum][0]); } } } if (TotalWeighting > 0){ Score = Math.floor((TotalScore/TotalWeighting)*100); } else{ //if TotalWeighting is 0, no questions so far have any value, so //no penalty should be shown. Score = 100; } } //New for 6.2.2.0 function CheckQuestionsCompleted(){ if (ShowCompletedSoFar == false){return '';} var QsCompleted = 0; for (var QNum=0; QNum<State.length; QNum++){ if (State[QNum] != null){ if (State[QNum][0] >= 0){ QsCompleted++; } } } //Fixes for 6.2.2.2 if (QsCompleted >= QArray.length){ return ExerciseCompleted; } else{ return CompletedSoFar + ' ' + QsCompleted + '/' + QArray.length + '.'; } } function CheckFinished(){ var FB = ''; var AllDone = true; for (var QNum=0; QNum<State.length; QNum++){ if (State[QNum] != null){ if (State[QNum][0] < 0){ AllDone = false; } } } if (AllDone == true){ //Report final score and submit if necessary CalculateOverallScore(); FB = YourScoreIs + ' ' + Score + '%.'; if (ShowCorrectFirstTime == true){ var CFT = 0; for (QNum=0; QNum<State.length; QNum++){ if (State[QNum] != null){ if (State[QNum][0] >= 1){ CFT++; } } } FB += '<br />' + CorrectFirstTime + ' ' + CFT + '/' + QsToShow; } //New for 6.2.2.0 FB += '<br />' + ExerciseCompleted; WriteToInstructions(FB); Finished == true; [inclTimer] window.clearInterval(Interval); [/inclTimer] [inclScorm1.2] if (TimeOver == true){ SetScormTimedOut(); } else{ SetScormComplete(); } [/inclScorm1.2] TimeOver = true; Locked = true; [inclSendResults] setTimeout('SendResults(' + Score + ')', 50); [/inclSendResults] Finished = true; Detail = '<?xml version="1.0"?><hpnetresult><fields>'; for (QNum=0; QNum<State.length; QNum++){ if (State[QNum] != null){ if (State[QNum][5].length > 0){ Detail += '<field><fieldname>Question #' + (QNum+1) + '</fieldname><fieldtype>question-tracking</fieldtype><fieldlabel>Q ' + (QNum+1) + '</fieldlabel><fieldlabelid>QuestionTrackingField</fieldlabelid><fielddata>' + State[QNum][5] + '</fielddata></field>'; } } } Detail += '</fields></hpnetresult>'; setTimeout('Finish()', SubmissionTimeout); } [inclScorm1.2] else{ SetScormIncomplete(); } [/inclScorm1.2] } [inclTimer] function TimesUp(){ document.getElementById('Timer').innerHTML = '[strTimesUp]'; [inclPreloadImages] RefreshImages(); [/inclPreloadImages] TimeOver = true; Finished = true; ShowMessage('[strTimesUp]'); //Set all remaining scores to 0 for (var QNum=0; QNum<State.length; QNum++){ if (State[QNum] != null){ if (State[QNum][0] < 0){ State[QNum][0] = 0; } } } CheckFinished(); } [/inclTimer]
Quelqu'un pourrait-il me donner un coup de pouce!? MERCI!!!