Commit e6330716 by Chris Rodriguez

AC-551 updating Custom JS tool

parent 20fc5bae
...@@ -38,34 +38,144 @@ data: | ...@@ -38,34 +38,144 @@ data: |
<script type="loncapa/python"> <script type="loncapa/python">
<![CDATA[ <![CDATA[
import json import json
def vglcfn(e, ans): # These are REQUIRED for all problems.
''' problem_type = 'interval' # Set to 'interval' or a 'number'
par is a dictionary that contains two keys, "answer" and "state". show_open_close = False # Do we ask for open/closed interval?
The value of "answer" is the JSON string that "getGrade" returns. feedback = True # Do we tell people how close they were?
The value of "state" is the JSON string that "getState" returns. is_time_question = True # Should we convert these numbers to times (min:sec)?
Clicking either "Check" or "Save" registers the current state. # If this is set True, course authors still use seconds.
''' # Only for number-guessing:
par = json.loads(ans) correct_number = 10 # The right answer
# You can use the value of the answer key to grade: tolerance = [2, 4, 6] # How close do they have to be? [correct, near, far]
answer = json.loads(par["answer"]) brackets = [1, 0.5, 0.25, 0] # Scores for various range brackets
return answer["cylinder"] and not answer["cube"]
''' # Only for interval-guessing:
# Or you can use the value of the state key to grade: correct_interval = [416,660] # Please put the lower value on the left.
state = json.loads(par["state"]) interval_type = ['closed', 'closed'] # Are endpoints 'open' or 'closed'?
selectedObjects = state["selectedObjects"] interval_tolerance = 'linear' # Options: 'linear', 'strict', or 'generous'
return selectedObjects["cylinder"] and not selectedObjects["cube"] type_penalty = 0.1 # Points off if open/closed incorrect
'''
# Only for estimation
max_time = 1000 # Large number of people beyond actual high
# Set the outer bounds for the slider
lowerlimit = 0
upperlimit = 1000
def answercheck(e, ans):
# Get the student's answer.
parsed = json.loads(ans)
answer = json.loads(parsed['answer'])
guess_upper = answer['upperguess']
guess_lower = answer['lowerguess']
guess_upper_closed = answer['upperclosed']
guess_lower_closed = answer['lowerclosed']
# Now begins the grading.
message = ''
final_grade = 0
if problem_type == 'interval':
if guess_upper &lt; correct_interval[0]:
# No points if there's no overlap.
message = 'Answer not in selected range.'
elif guess_lower &gt; correct_interval[1]:
# Same here.
message = 'Answer not in selected range.'
else:
# Points based on percentage overlap.
endpoints = []
endpoints.append(correct_interval[0])
endpoints.append(correct_interval[1])
endpoints.append(guess_upper)
endpoints.append(guess_lower)
endpoints.sort()
overlap = endpoints[2] - endpoints[1]
bigrange = max(correct_interval[1] - correct_interval[0], guess_upper - guess_lower)
final_grade = float(overlap) / float(bigrange)
message = str(int(round(final_grade, 2) * 100)) + '% overlap with correct answer.'
if interval_tolerance == 'strict':
final_grade = final_grade * final_grade
elif interval_tolerance == 'generous':
final_grade = math.sqrt(final_grade)
# Round up to the nearest tenth.
final_grade = math.ceil(final_grade*10.0) / 10.0
if show_open_close:
if(guess_lower_closed != True and interval_type[0] == 'closed'):
final_grade = final_grade - type_penalty
message += ' Lower endpoint is wrong.'
if(guess_lower_closed == True and interval_type[0] != 'closed'):
final_grade = final_grade - type_penalty
message += ' Lower endpoint is wrong.'
if(guess_upper_closed != True and interval_type[1] == 'closed'):
final_grade = final_grade - type_penalty
message += ' Upper endpoint is wrong.'
if(guess_upper_closed == True and interval_type[1] != 'closed'):
final_grade = final_grade - type_penalty
message += ' Upper endpoint is wrong.'
else:
farthest = max(abs(correct_number - guess_upper), abs(correct_number - guess_lower))
if farthest &lt; tolerance[0]:
final_grade = brackets[0]
message = 'Close enough! Actual answer: ' + str(correct_number)
elif farthest &lt; tolerance[1]:
final_grade = brackets[1]
message = 'Close. You are off by ' + str(farthest)
elif farthest &lt; tolerance[2]:
final_grade = brackets[2]
message = 'Not very close. You are off by ' + str(farthest)
else:
final_grade = brackets[3]
message = 'Your range is too large to get points.'
if guess_upper &gt; correct_number and guess_lower &lt; correct_number:
message += ' The answer is within your range.'
else:
message += ' The answer is outside your range.'
if not feedback:
message = ''
if final_grade &gt; 0.95:
isOK = True
elif final_grade &gt; 0.05:
isOK = "Partial"
else:
isOK = False
return {
'input_list': [
{ 'ok': isOK, 'msg': message, 'grade_decimal': final_grade},
]
}
]]> ]]>
</script> </script>
<p>In the following image, click the objects until the cone is yellow and the cube is blue.</p> <p>What is the range of passengers that can fit on a 747 aircraft? Set the low and high bounds. (416 and 660 persons)</p>
<jsinput gradefn="WebGLDemo.getGrade" <p class="sr" aria-hidden="true">
get_statefn="WebGLDemo.getState" <span id="lowerlimit">$lowerlimit</span>
set_statefn="WebGLDemo.setState" <span id="upperlimit">$upperlimit</span>
initial_state='{"selectedObjects":{"cube":true,"cylinder":false}}' <span id="openclose">$show_open_close</span>
width="400" <span id="istimequestion">$is_time_question</span>
height="400" <span id="maxtime">$max_time</span>
html_file="https://studio.edx.org/c4x/edX/DemoX/asset/webGLDemo.html" </p>
sop="false"/> <customresponse cfn="answercheck">
</customresponse> <jsinput gradefn="guesser.getGrade" get_statefn="guesser.getState" set_statefn="guesser.setState" width="800" height="120" html_file="https://files.edx.org/custom-js/guesser.html" sop="false"/>
</problem> </customresponse>
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>Answer: The 747-400 passenger version can accommodate between 416 and 660 passengers depending on the layout and configuration.</p>
</div>
</solution>
</problem>
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