Commit 5a1c72ac by solashirai

code improvement

parent 7b088a39
...@@ -102,7 +102,7 @@ class CrowdsourceHinter(XBlock): ...@@ -102,7 +102,7 @@ class CrowdsourceHinter(XBlock):
frag.add_javascript_url('//cdnjs.cloudflare.com/ajax/libs/mustache.js/0.8.1/mustache.min.js') frag.add_javascript_url('//cdnjs.cloudflare.com/ajax/libs/mustache.js/0.8.1/mustache.min.js')
frag.add_css(self.resource_string("static/css/crowdsourcehinter.css")) frag.add_css(self.resource_string("static/css/crowdsourcehinter.css"))
frag.add_javascript(self.resource_string("static/js/src/crowdsourcehinter.js")) frag.add_javascript(self.resource_string("static/js/src/crowdsourcehinter.js"))
frag.initialize_js('CrowdsourceHinter', {'hinting_element': self.Element, 'isStaff': self.Element}) frag.initialize_js('CrowdsourceHinter', {'hinting_element': self.Element, 'isStaff': self.xmodule_runtime.user_is_staff})
return frag return frag
@XBlock.json_handler @XBlock.json_handler
...@@ -115,7 +115,7 @@ class CrowdsourceHinter(XBlock): ...@@ -115,7 +115,7 @@ class CrowdsourceHinter(XBlock):
data['submittedanswer']: The string of text that the student submits for a problem. data['submittedanswer']: The string of text that the student submits for a problem.
returns: returns:
'HintsToUse': the highest rated hint for an incorrect answer 'Hints': the highest rated hint for an incorrect answer
or another random hint for an incorrect answer or another random hint for an incorrect answer
or 'Sorry, there are no more hints for this answer.' if no more hints exist or 'Sorry, there are no more hints for this answer.' if no more hints exist
""" """
...@@ -146,12 +146,12 @@ class CrowdsourceHinter(XBlock): ...@@ -146,12 +146,12 @@ class CrowdsourceHinter(XBlock):
# currently set by default to True # currently set by default to True
if best_hint not in self.Reported.keys(): if best_hint not in self.Reported.keys():
self.Used.append(best_hint) self.Used.append(best_hint)
return {'HintsToUse': best_hint, "StudentAnswer": answer} return {'Hints': best_hint, "StudentAnswer": answer}
if best_hint not in self.Used: if best_hint not in self.Used:
# choose highest rated hint for the incorrect answer # choose highest rated hint for the incorrect answer
if best_hint not in self.Reported.keys(): if best_hint not in self.Reported.keys():
self.Used.append(best_hint) self.Used.append(best_hint)
return {'HintsToUse': best_hint, "StudentAnswer": answer} return {'Hints': best_hint, "StudentAnswer": answer}
# choose another random hint for the answer. # choose another random hint for the answer.
temporary_hints_list = [] temporary_hints_list = []
for hint_keys in self.hint_database[str(answer)]: for hint_keys in self.hint_database[str(answer)]:
...@@ -160,16 +160,16 @@ class CrowdsourceHinter(XBlock): ...@@ -160,16 +160,16 @@ class CrowdsourceHinter(XBlock):
temporary_hints_list.append(str(hint_keys)) temporary_hints_list.append(str(hint_keys))
not_used = random.choice(temporary_hints_list) not_used = random.choice(temporary_hints_list)
self.Used.append(not_used) self.Used.append(not_used)
return {'HintsToUse': not_used, "StudentAnswer": answer} return {'Hints': not_used, "StudentAnswer": answer}
# find generic hints for the student if no specific hints exist # find generic hints for the student if no specific hints exist
if len(self.generic_hints) != 0: if len(self.generic_hints) != 0:
not_used = random.choice(self.generic_hints) not_used = random.choice(self.generic_hints)
self.Used.append(not_used) self.Used.append(not_used)
return {'HintsToUse': not_used, "StudentAnswer": answer} return {'Hints': not_used, "StudentAnswer": answer}
else: else:
# if there are no more hints left in either the database or defaults # if there are no more hints left in either the database or defaults
self.Used.append(str("There are no hints for" + " " + answer)) self.Used.append(str("There are no hints for" + " " + answer))
return {'HintsToUse': "Sorry, there are no hints for this answer.", "StudentAnswer": answer} return {'Hints': "Sorry, there are no hints for this answer.", "StudentAnswer": answer}
def find_hints(self, answer): def find_hints(self, answer):
""" """
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
<div class="crowdsourcehinter_block"> <div class="crowdsourcehinter_block">
<div class='csh_hint_reveal'> <div class='csh_hint_reveal'>
<div class='csh_HintsToUse' student_answer = '' hint_received=''> <div class='csh_Hints' student_answer = '' hint_received=''>
</div> </div>
<div class='csh_HintQuickFeedback'> <div class='csh_HintQuickFeedback'>
<div role="button" class="csh_rate_hint" data-rate="upvote" title="This hint was helpful!"> <div role="button" class="csh_rate_hint" data-rate="upvote" title="This hint was helpful!">
......
...@@ -4,10 +4,13 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -4,10 +4,13 @@ function CrowdsourceHinter(runtime, element, data){
var executeHinter = true; var executeHinter = true;
$(".crowdsourcehinter_block", element).hide(); $(".crowdsourcehinter_block", element).hide();
if(executeHinter){ if(!executeHinter){
return;
}
var isShowingHintFeedback = false; var isShowingHintFeedback = false;
var voted = false; var voted = false;
$(".csh_HintsToUse", element).text(""); var correctSubmission = false;
function stopScript(){ function stopScript(){
//This function is used to prevent a particular instance of the hinter from acting after //This function is used to prevent a particular instance of the hinter from acting after
...@@ -18,44 +21,52 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -18,44 +21,52 @@ function CrowdsourceHinter(runtime, element, data){
Logger.listen('seq_prev', null, stopScript); Logger.listen('seq_prev', null, stopScript);
Logger.listen('seq_goto', null, stopScript); Logger.listen('seq_goto', null, stopScript);
//data about the problem obtained from Logger.listen('problem_graded') is passed on to the onStudentSubmission. //send student answer data and receive a hint from ajax call.
//directly passing data to onStudentSubmission does not appear to work //pass data to showHint to actually show hint to student
function get_event_data(event_type, data, element){ function get_hint(data){
onStudentSubmission(data); $(".crowdsourcehinter_block", element).show();
$.ajax({
type: "POST",
url: runtime.handlerUrl(element, 'get_hint'),
data: JSON.stringify({"submittedanswer": unescape(data[0])}),
success: showHint
});
} }
Logger.listen('problem_graded', data.hinting_element, get_event_data);
function onStudentSubmission(problem_graded_event_data){ //first step to starting student feedback for hints
//This function will determine whether or not the student correctly answered the question. //this function will be called after student correctly answers question
//If it was correctly answered it will begin the process for giving feedback on hints. function start_feedback(){
if (problem_graded_event_data[1].search(/class="correct/) === -1){ $('.csh_correct', element).show();
$(".crowdsourcehinter_block", element).show(); $(".csh_hint_reveal", element).hide();
$.ajax({ //send empty data for ajax call because not having a data field causes error
type: "POST", $.ajax({
url: runtime.handlerUrl(element, 'get_hint'), type: "POST",
data: JSON.stringify({"submittedanswer": unescape(problem_graded_event_data[0])}), url: runtime.handlerUrl(element, 'get_feedback'),
success: seehint data: JSON.stringify({}),
}); success: showStudentContribution
}else{ });
$('.csh_correct', element).show();
$(".csh_hint_reveal", element).hide();
//send empty data for ajax call because not having a data field causes error
$.ajax({
type: "POST",
url: runtime.handlerUrl(element, 'get_feedback'),
data: JSON.stringify({}),
success: getFeedback
});
}
} }
function seehint(result){ //This function will determine whether or not the student correctly answered the question.
//Show a hint to the student after an incorrect answer is submitted. //if incorrect, call function to get hint to show to student
$('.csh_HintsToUse', element).attr('student_answer', result.StudentAnswer); //if correct, call function to start student feedback on hints
$('.csh_HintsToUse', element).attr('hint_received', result.HintsToUse); function onStudentSubmission(){ return function(event_type, data, element){
$('.csh_HintsToUse', element).text("Hint: " + result.HintsToUse); //search method of correctness of problem is brittle due to checking for a class within
Logger.log('crowd_hinter.seehint', {"student_answer": result.StudentAnswer, "hint_received": result.HintsToUse}); //the problem block.
if (data[1].search(/class="correct/) === -1){
get_hint(data);
} else { //if the correct answer is submitted
start_feedback();
}
}}
Logger.listen('problem_graded', data.hinting_element, onStudentSubmission());
function showHint(result){
//Show a hint to the student after an incorrect answer is submitted.
$('.csh_Hints', element).attr('student_answer', result.StudentAnswer);
$('.csh_Hints', element).attr('hint_received', result.Hints);
$('.csh_Hints', element).text("Hint: " + result.Hints);
Logger.log('crowd_hinter.showHint', {"student_answer": result.StudentAnswer, "hint_received": result.Hints});
} }
function showHintFeedback(hint, student_answer){ function showHintFeedback(hint, student_answer){
...@@ -93,7 +104,7 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -93,7 +104,7 @@ function CrowdsourceHinter(runtime, element, data){
$(".csh_reported_hints", element).append(html); $(".csh_reported_hints", element).append(html);
} }
function setStudentAnswers(student_answers){ function showStudentSubmissionHistory(student_answers){
//Append new divisions into html for each answer the student submitted before correctly //Append new divisions into html for each answer the student submitted before correctly
//answering the question. showHintFeedback appends new hints into these divs. //answering the question. showHintFeedback appends new hints into these divs.
//When the hinter is set to show best, only one div will be created //When the hinter is set to show best, only one div will be created
...@@ -106,7 +117,7 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -106,7 +117,7 @@ function CrowdsourceHinter(runtime, element, data){
$(".csh_feedback", element).append(html); $(".csh_feedback", element).append(html);
} }
function getFeedback(result){ function showStudentContribution(result){
//Set up the student feedback stage. Each student answer and all answer-specific hints for that answer are shown //Set up the student feedback stage. Each student answer and all answer-specific hints for that answer are shown
//to the student, as well as an option to create a new hint for an answer. //to the student, as well as an option to create a new hint for an answer.
if(data.isStaff){ if(data.isStaff){
...@@ -121,7 +132,7 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -121,7 +132,7 @@ function CrowdsourceHinter(runtime, element, data){
if(!isShowingHintFeedback){ if(!isShowingHintFeedback){
$.each(result, function(index, value) { $.each(result, function(index, value) {
if(value != "Reported"){ if(value != "Reported"){
setStudentAnswers(value); showStudentSubmissionHistory(value);
student_answer = value; student_answer = value;
hint = index; hint = index;
//hints return null if no answer-specific hints exist //hints return null if no answer-specific hints exist
...@@ -151,17 +162,17 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -151,17 +162,17 @@ function CrowdsourceHinter(runtime, element, data){
} }
} }
$(element).on('click', '.csh_student_hint_creation', function(){ function create_text_input(){ return function(clicked){
//create text input area for contributing a new hint //create text input area for contributing a new hint
$('.csh_student_hint_creation', element).each(function(){ $('.csh_student_hint_creation', element).each(function(){
$(this).show(); $(clicked.currentTarget).show();
}); });
$('.csh_student_text_input', element).remove(); $('.csh_student_text_input', element).remove();
$('.csh_submit_new', element).remove(); $('.csh_submit_new', element).remove();
$(this).hide(); $(clicked.currentTarget).hide();
student_answer = $(this).parent().parent().find('.csh_answer_text').attr('answer'); student_answer = $(clicked.currentTarget).parent().parent().find('.csh_answer_text').attr('answer');
$(".csh_student_answer", element).each(function(){ $(".csh_student_answer", element).each(function(){
if ($(this).find('.csh_answer_text').attr('answer') == student_answer){ if ($('.csh_answer_text', element).attr('answer') == student_answer){
var html = ""; var html = "";
$(function(){ $(function(){
var template = $('#student_hint_creation').html(); var template = $('#student_hint_creation').html();
...@@ -171,12 +182,13 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -171,12 +182,13 @@ function CrowdsourceHinter(runtime, element, data){
$(this).append(html); $(this).append(html);
} }
}); });
}) }}
$(element).on('click', '.csh_student_hint_creation', create_text_input($(this)));
$(element).on('click', '.csh_submit_new', function(){ function submit_new_hint(){ return function(clicked){
//add the newly created hint to the hinter's pool of hints //add the newly created hint to the hinter's pool of hints
if($(this).parent().parent().find('.csh_student_text_input').val().length > 0){ if($('.csh_student_text_input', element).val().length > 0){
var answerdata = unescape($(this).attr('answer')); var answerdata = unescape(clicked.currentTarget.attributes['answer'].value);
var newhint = unescape($('.csh_student_text_input').val()); var newhint = unescape($('.csh_student_text_input').val());
$('.csh_submitbutton', element).show(); $('.csh_submitbutton', element).show();
$.ajax({ $.ajax({
...@@ -185,28 +197,31 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -185,28 +197,31 @@ function CrowdsourceHinter(runtime, element, data){
data: JSON.stringify({"submission": newhint, "answer": answerdata}), data: JSON.stringify({"submission": newhint, "answer": answerdata}),
success: Logger.log('crowd_hinter.submit_new.click.event', {"student_answer": answerdata, "new_hint_submission": newhint}) success: Logger.log('crowd_hinter.submit_new.click.event', {"student_answer": answerdata, "new_hint_submission": newhint})
}); });
$(this).parent().parent().find('.csh_student_text_input').remove(); $('.csh_student_text_input', element).remove();
$(this).remove(); $(clicked.currentTarget).remove();
} }
}) }}
$(element).on('click', '.csh_submit_new', submit_new_hint($(this)));
$(element).on('click', '.csh_rate_hint', function(){ function rate_hint(){ return function(clicked){
//send info to hinter indicating whether the hint was upvoted, downvoted, or reported //send info to hinter indicating whether the hint was upvoted, downvoted, or reported
if(!voted || $(this).attr('data-rate')=="report"){ rating = clicked.currentTarget.attributes['data-rate'].value;
if ($(this).attr('data-rate') == "report"){ if(!voted || rating=="report"){
alert("This hint has been reported for review."); if (rating == "report"){
} alert("This hint has been reported for review.");
hint = $('.csh_HintsToUse', element).attr('hint_received'); }
student_answer = $('.csh_HintsToUse', element).attr('student_answer'); hint = $('.csh_Hints', element).attr('hint_received');
$.ajax({ student_answer = $('.csh_Hints', element).attr('student_answer');
type: "POST", $.ajax({
url: runtime.handlerUrl(element, 'rate_hint'), type: "POST",
data: JSON.stringify({"student_rating": $(this).attr('data-rate'), "hint": hint, "student_answer": student_answer}), url: runtime.handlerUrl(element, 'rate_hint'),
success: Logger.log('crowd_hinter.rate_hint.click.event', {"hint": hint, "student_answer": student_answer, "rating": $(this).attr('data-rate')}) data: JSON.stringify({"student_rating": rating, "hint": hint, "student_answer": student_answer}),
}); success: Logger.log('crowd_hinter.rate_hint.click.event', {"hint": hint, "student_answer": student_answer, "rating": rating})
voted = true; });
} voted = true;
}); }
}}
$(element).on('click', '.csh_rate_hint', rate_hint($(this)));
function removeFeedback(){ function removeFeedback(){
//remove a hint from the staff feedback area after a staff member has //remove a hint from the staff feedback area after a staff member has
...@@ -218,17 +233,19 @@ function CrowdsourceHinter(runtime, element, data){ ...@@ -218,17 +233,19 @@ function CrowdsourceHinter(runtime, element, data){
}); });
} }
$(element).on('click', '.csh_staff_rate', function(){ function staff_rate_hint(){ return function(clicked){
//Staff "rating" removes or returns a reported hint from/to the hinter's pool of hints //Staff "rating" removes or returns a reported hint from/to the hinter's pool of hints
hint = $(this).parent().find(".csh_hint").text(); hint = $(clicked.currentTarget).parent().find(".csh_hint").text();
rating = clicked.currentTarget.attributes['data-rate'].value
student_answer = "Reported"; student_answer = "Reported";
Logger.log('crowd_hinter.staff_rate_hint.click.event', {"hint": hint, "student_answer": student_answer, "rating": $(this).attr('data-rate')}); Logger.log('crowd_hinter.staff_rate_hint.click.event', {"hint": hint, "student_answer": student_answer, "rating": rating});
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: runtime.handlerUrl(element, 'rate_hint'), url: runtime.handlerUrl(element, 'rate_hint'),
data: JSON.stringify({"student_rating": $(this).attr('data-rate'), "hint": hint, "student_answer": student_answer}), data: JSON.stringify({"student_rating": rating, "hint": hint, "student_answer": student_answer}),
success: removeFeedback() success: removeFeedback()
}); });
}) }}
$(element).on('click', '.csh_staff_rate', staff_rate_hint($(this)));
}} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment