Commit 6b87e0a6 by Tim Krones

Address review comments.

parent 6c1b897a
...@@ -213,10 +213,6 @@ class Grader(object): ...@@ -213,10 +213,6 @@ class Grader(object):
return {'ok': False, 'msg': result} return {'ok': False, 'msg': result}
return {'ok': True, 'msg': self.success_message} return {'ok': True, 'msg': self.success_message}
def cfn(self, e, ans):
answer = json.loads(json.loads(ans)['answer'])
return self.grade(answer)
def _get_vectors(self, answer): def _get_vectors(self, answer):
vectors = {} vectors = {}
for name, props in answer['vectors'].iteritems(): for name, props in answer['vectors'].iteritems():
......
...@@ -608,15 +608,11 @@ function VectorDrawXBlock(runtime, element, init_args) { ...@@ -608,15 +608,11 @@ function VectorDrawXBlock(runtime, element, init_args) {
} }
var state = getInput(vectordraw); var state = getInput(vectordraw);
checkXHR = $.post(checkHandlerUrl, JSON.stringify(state)) checkXHR = $.post(checkHandlerUrl, JSON.stringify(state))
.success(function(response) { .success(updateStatus);
updateStatus(response);
});
} }
// Initialization logic // Initialization logic
$(function ($) {
// Initialize exercise // Initialize exercise
var vectordraw = new VectorDraw('vectordraw', init_args.settings); var vectordraw = new VectorDraw('vectordraw', init_args.settings);
...@@ -629,5 +625,4 @@ function VectorDrawXBlock(runtime, element, init_args) { ...@@ -629,5 +625,4 @@ function VectorDrawXBlock(runtime, element, init_args) {
// Set up click handlers // Set up click handlers
$('.action .check', element).on('click', function(e) { checkAnswer(vectordraw); }); $('.action .check', element).on('click', function(e) { checkAnswer(vectordraw); });
});
} }
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
import json import json
import logging import logging
import pkg_resources
from xblock.core import XBlock from xblock.core import XBlock
from xblock.exceptions import JsonHandlerError
from xblock.fields import Scope, Boolean, Dict, Float, Integer, String from xblock.fields import Scope, Boolean, Dict, Float, Integer, String
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xblockutils.resources import ResourceLoader from xblockutils.resources import ResourceLoader
...@@ -48,14 +48,14 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock): ...@@ -48,14 +48,14 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
) )
height = Integer( height = Integer(
display_name="", display_name="Height",
help="The height of the board in pixels", help="The height of the board in pixels",
default=400, default=400,
scope=Scope.content scope=Scope.content
) )
bounding_box_size = Integer( bounding_box_size = Integer(
display_name="", display_name="Bounding box size",
help=( help=(
"Defines the bounding box height of the graph area. " "Defines the bounding box height of the graph area. "
"The bounding box width is calculated from the width/height ratio." "The bounding box width is calculated from the width/height ratio."
...@@ -183,7 +183,12 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock): ...@@ -183,7 +183,12 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
) )
# User state # User state
# Dictionary containing vectors and points present on the board when user last clicked "Check",
# as well as checks to perform in order to obtain grade
answer = Dict(scope=Scope.user_state) answer = Dict(scope=Scope.user_state)
# Dictionary that represents result returned by the grader for the most recent answer;
# contains info about correctness of answer and feedback message
result = Dict(scope=Scope.user_state) result = Dict(scope=Scope.user_state)
editable_fields = ( editable_fields = (
...@@ -254,11 +259,6 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock): ...@@ -254,11 +259,6 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
def expected_result_json(self): def expected_result_json(self):
return json.loads(self.expected_result) return json.loads(self.expected_result)
def resource_string(self, path):
"""Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path)
return data.decode("utf8")
def student_view(self, context=None): def student_view(self, context=None):
""" """
The primary view of the VectorDrawXBlock, shown to students The primary view of the VectorDrawXBlock, shown to students
...@@ -268,17 +268,53 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock): ...@@ -268,17 +268,53 @@ class VectorDrawXBlock(StudioEditableXBlockMixin, XBlock):
fragment = Fragment() fragment = Fragment()
fragment.add_content(loader.render_template('static/html/vectordraw.html', context)) fragment.add_content(loader.render_template('static/html/vectordraw.html', context))
fragment.add_css_url("//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css") fragment.add_css_url("//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css")
fragment.add_css(self.resource_string('static/css/vectordraw.css')) fragment.add_css(loader.load_unicode('static/css/vectordraw.css'))
fragment.add_javascript_url("//cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.98/jsxgraphcore.js") fragment.add_javascript_url("//cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.98/jsxgraphcore.js")
fragment.add_javascript(self.resource_string("static/js/src/vectordraw.js")) fragment.add_javascript(loader.load_unicode("static/js/src/vectordraw.js"))
fragment.initialize_js('VectorDrawXBlock', {"settings": self.settings, "user_state": self.user_state}) fragment.initialize_js('VectorDrawXBlock', {"settings": self.settings, "user_state": self.user_state})
return fragment return fragment
def is_valid(self, data):
"""
Validate answer data submitted by user.
"""
# Check vectors
vectors = data.get('vectors')
if vectors is None:
return False
for vector_data in vectors.values():
# Validate vector
vector_valid = 'tip' in vector_data and 'tail' in vector_data
if not vector_valid:
return False
# Validate tip and tail
tip = vector_data['tip']
tip_valid = type(tip) == list and len(tip) == 2
tail = vector_data['tail']
tail_valid = type(tail) == list and len(tail) == 2
if not (tip_valid and tail_valid):
return False
# Check points
points = data.get('points')
if points is None:
return False
for coords in points.values():
# Validate point
point_valid = type(coords) == list and len(coords) == 2
if not point_valid:
break
# If we get to this point, it means that vector and point data is valid;
# the only thing left to check is whether data contains a list of checks:
return 'checks' in data
@XBlock.json_handler @XBlock.json_handler
def check_answer(self, data, suffix=''): def check_answer(self, data, suffix=''):
""" """
Check and persist student's answer to this vector drawing problem. Check and persist student's answer to this vector drawing problem.
""" """
# Validate data
if not self.is_valid(data):
raise JsonHandlerError(400, "Invalid data")
# Save answer # Save answer
self.answer = dict( self.answer = dict(
vectors=data["vectors"], vectors=data["vectors"],
......
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