Commit 71c46ff3 by Arjun Singh

Merge branch 'master' into hotfix/arjun/fix_integer_disc_ids

parents 3bff1893 2063b2db
...@@ -746,7 +746,7 @@ class NumericalResponse(LoncapaResponse): ...@@ -746,7 +746,7 @@ class NumericalResponse(LoncapaResponse):
id=xml.get('id'))[0] id=xml.get('id'))[0]
self.tolerance = contextualize_text(self.tolerance_xml, context) self.tolerance = contextualize_text(self.tolerance_xml, context)
except Exception: except Exception:
self.tolerance = 0 self.tolerance = '0'
try: try:
self.answer_id = xml.xpath('//*[@id=$id]//textline/@id', self.answer_id = xml.xpath('//*[@id=$id]//textline/@id',
id=xml.get('id'))[0] id=xml.get('id'))[0]
......
...@@ -11,7 +11,7 @@ def compare_with_tolerance(v1, v2, tol): ...@@ -11,7 +11,7 @@ def compare_with_tolerance(v1, v2, tol):
- v1 : student result (number) - v1 : student result (number)
- v2 : instructor result (number) - v2 : instructor result (number)
- tol : tolerance (string or number) - tol : tolerance (string representing a number)
''' '''
relative = tol.endswith('%') relative = tol.endswith('%')
......
...@@ -572,7 +572,7 @@ section.problem { ...@@ -572,7 +572,7 @@ section.problem {
} }
} }
section { > section {
padding: 9px; padding: 9px;
} }
} }
......
...@@ -11,7 +11,7 @@ class @Collapsible ...@@ -11,7 +11,7 @@ class @Collapsible
### ###
el.find('.longform').hide() el.find('.longform').hide()
el.find('.shortform').append('<a href="#" class="full">See full output</a>') el.find('.shortform').append('<a href="#" class="full">See full output</a>')
el.find('.collapsible section').hide() el.find('.collapsible header + section').hide()
el.find('.full').click @toggleFull el.find('.full').click @toggleFull
el.find('.collapsible header a').click @toggleHint el.find('.collapsible header a').click @toggleHint
......
...@@ -329,9 +329,15 @@ def progress_summary(student, request, course, student_module_cache): ...@@ -329,9 +329,15 @@ def progress_summary(student, request, course, student_module_cache):
def get_score(course_id, user, problem_descriptor, module_creator, student_module_cache): def get_score(course_id, user, problem_descriptor, module_creator, student_module_cache):
""" """
Return the score for a user on a problem, as a tuple (correct, total). Return the score for a user on a problem, as a tuple (correct, total).
e.g. (5,7) if you got 5 out of 7 points.
If this problem doesn't have a score, or we couldn't load it, returns (None,
None).
user: a Student object user: a Student object
problem: an XModule problem_descriptor: an XModuleDescriptor
module_creator: a function that takes a descriptor, and returns the corresponding XModule for this user.
Can return None if user doesn't have access, or if something else went wrong.
cache: A StudentModuleCache cache: A StudentModuleCache
""" """
if not (problem_descriptor.stores_state and problem_descriptor.has_score): if not (problem_descriptor.stores_state and problem_descriptor.has_score):
...@@ -339,14 +345,16 @@ def get_score(course_id, user, problem_descriptor, module_creator, student_modul ...@@ -339,14 +345,16 @@ def get_score(course_id, user, problem_descriptor, module_creator, student_modul
return (None, None) return (None, None)
correct = 0.0 correct = 0.0
instance_module = student_module_cache.lookup( instance_module = student_module_cache.lookup(
course_id, problem_descriptor.category, problem_descriptor.location.url()) course_id, problem_descriptor.category, problem_descriptor.location.url())
if not instance_module: if not instance_module:
# If the problem was not in the cache, we need to instantiate the problem. # If the problem was not in the cache, we need to instantiate the problem.
# Otherwise, the max score (cached in instance_module) won't be available # Otherwise, the max score (cached in instance_module) won't be available
problem = module_creator(problem_descriptor) problem = module_creator(problem_descriptor)
if problem is None:
return (None, None)
instance_module = get_instance_module(course_id, user, problem, student_module_cache) instance_module = get_instance_module(course_id, user, problem, student_module_cache)
# If this problem is ungraded/ungradable, bail # If this problem is ungraded/ungradable, bail
...@@ -361,7 +369,7 @@ def get_score(course_id, user, problem_descriptor, module_creator, student_modul ...@@ -361,7 +369,7 @@ def get_score(course_id, user, problem_descriptor, module_creator, student_modul
weight = getattr(problem_descriptor, 'weight', None) weight = getattr(problem_descriptor, 'weight', None)
if weight is not None: if weight is not None:
if total == 0: if total == 0:
log.exception("Cannot reweight a problem with zero weight. Problem: " + str(instance_module)) log.exception("Cannot reweight a problem with zero total points. Problem: " + str(instance_module))
return (correct, total) return (correct, total)
correct = correct * weight / total correct = correct * weight / total
total = weight total = weight
......
#!/usr/bin/python
#
# django management command: dump grades to csv files
# for use by batch processes
import os, sys, string
import datetime
import json
from instructor.views import *
from courseware.courses import get_course_by_id
from xmodule.modulestore.django import modulestore
from django.conf import settings
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "dump grades to CSV file. Usage: dump_grades course_id_or_dir filename dump_type\n"
help += " course_id_or_dir: either course_id or course_dir\n"
help += " filename: where the output CSV is to be stored\n"
# help += " start_date: end date as M/D/Y H:M (defaults to end of available data)"
help += " dump_type: 'all' or 'raw' (see instructor dashboard)"
def handle(self, *args, **options):
# current grading logic and data schema doesn't handle dates
# datetime.strptime("21/11/06 16:30", "%m/%d/%y %H:%M")
print "args = ", args
course_id = 'MITx/8.01rq_MW/Classical_Mechanics_Reading_Questions_Fall_2012_MW_Section'
fn = "grades.csv"
get_raw_scores = False
if len(args)>0:
course_id = args[0]
if len(args)>1:
fn = args[1]
if len(args)>2:
get_raw_scores = args[2].lower()=='raw'
request = self.DummyRequest()
try:
course = get_course_by_id(course_id)
except Exception as err:
if course_id in modulestore().courses:
course = modulestore().courses[course_id]
else:
print "-----------------------------------------------------------------------------"
print "Sorry, cannot find course %s" % course_id
print "Please provide a course ID or course data directory name, eg content-mit-801rq"
return
print "-----------------------------------------------------------------------------"
print "Dumping grades from %s to file %s (get_raw_scores=%s)" % (course.id, fn, get_raw_scores)
datatable = get_student_grade_summary_data(request, course, course.id, get_raw_scores=get_raw_scores)
fp = open(fn,'w')
writer = csv.writer(fp, dialect='excel', quotechar='"', quoting=csv.QUOTE_ALL)
writer.writerow(datatable['header'])
for datarow in datatable['data']:
encoded_row = [unicode(s).encode('utf-8') for s in datarow]
writer.writerow(encoded_row)
fp.close()
print "Done: %d records dumped" % len(datatable['data'])
class DummyRequest(object):
META = {}
def __init__(self):
return
def get_host(self):
return 'edx.mit.edu'
def is_secure(self):
return False
...@@ -65,16 +65,19 @@ ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph") ...@@ -65,16 +65,19 @@ ${progress_graph.body(grade_summary, course.grade_cutoffs, "grade-detail-graph")
%endif %endif
</p> </p>
%if len(section['scores']) > 0: <section class="scores">
<section class="scores"> %if len(section['scores']) > 0:
<h3> ${ "Problem Scores: " if section['graded'] else "Practice Scores: "} </h3> <h3> ${ "Problem Scores: " if section['graded'] else "Practice Scores: "} </h3>
<ol> <ol>
%for score in section['scores']: %for score in section['scores']:
<li>${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</li> <li>${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</li>
%endfor %endfor
</ol> </ol>
</section> %else:
%endif <h3 class="no-scores"> No problem scores in this section </h3>
%endif
</section>
</li> <!--End section--> </li> <!--End section-->
%endfor %endfor
......
...@@ -244,7 +244,7 @@ if settings.MITX_FEATURES.get('AUTH_USE_OPENID'): ...@@ -244,7 +244,7 @@ if settings.MITX_FEATURES.get('AUTH_USE_OPENID'):
if settings.MITX_FEATURES.get('AUTH_USE_OPENID_PROVIDER'): if settings.MITX_FEATURES.get('AUTH_USE_OPENID_PROVIDER'):
urlpatterns += ( urlpatterns += (
url(r'^openid/provider/login/$', 'external_auth.views.provider_login', name='openid-provider-login'), url(r'^openid/provider/login/$', 'external_auth.views.provider_login', name='openid-provider-login'),
url(r'^openid/provider/login/(?:[\w%\. ]+)$', 'external_auth.views.provider_identity', name='openid-provider-login-identity'), url(r'^openid/provider/login/(?:.+)$', 'external_auth.views.provider_identity', name='openid-provider-login-identity'),
url(r'^openid/provider/identity/$', 'external_auth.views.provider_identity', name='openid-provider-identity'), url(r'^openid/provider/identity/$', 'external_auth.views.provider_identity', name='openid-provider-identity'),
url(r'^openid/provider/xrds/$', 'external_auth.views.provider_xrds', name='openid-provider-xrds') url(r'^openid/provider/xrds/$', 'external_auth.views.provider_xrds', name='openid-provider-xrds')
) )
......
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