Got the gradebook working again with the new fast grading method.

This commit is contained in:
Bridger Maxwell
2012-08-03 17:55:25 -04:00
parent 694520ebb2
commit 6d650d1825
7 changed files with 40 additions and 45 deletions

View File

@@ -52,6 +52,7 @@ def certificate_request(request):
return return_error(survey_response['error'])
grade = None
# TODO: (bridger) Update this to use the faster grade instead of grade_sheet
student_gradesheet = grades.grade_sheet(request.user)
grade = student_gradesheet['grade']
@@ -65,6 +66,7 @@ def certificate_request(request):
else:
#This is not a POST, we should render the page with the form
# TODO: (bridger) Update this to use the faster grade instead of grade_sheet
grade_sheet = grades.grade_sheet(request.user)
certificate_state = certificate_state_for_student(request.user, grade_sheet['grade'])

View File

@@ -30,6 +30,7 @@ def get_graded_sections(course_descriptor):
xmoduledescriptors = []
for module in yield_descriptor_descendents(s):
# TODO: Only include modules that have a score here
xmoduledescriptors.append(module)
section_description = { 'section_descriptor' : s, 'xmoduledescriptors' : xmoduledescriptors}
@@ -73,19 +74,20 @@ def fast_grade(student, request, course_graded_sections, grader, student_module_
scores = []
section_module = get_module(student, request, section_descriptor.location, student_module_cache)
for module in yield_descriptor_descendents(section_module):
# TODO: We may be able to speed this up by only getting a list of children IDs from section_module
# Then, we may not need to instatiate any problems if they are already in the database
for module in yield_module_descendents(section_module):
(correct, total) = get_score(student, module, student_module_cache)
graded = module.metadata.get("graded", False)
if correct is None and total is None:
continue
if settings.GENERATE_PROFILE_SCORES:
if total > 1:
correct = random.randrange(max(total - 2, 1), total + 1)
else:
correct = total
graded = module.metadata.get("graded", False)
if not total > 0:
#We simply cannot grade a problem that is 12/0, because we might need it as a percentage
graded = False
@@ -110,20 +112,18 @@ def fast_grade(student, request, course_graded_sections, grader, student_module_
def grade_sheet(student, course, grader, student_module_cache):
"""
This pulls a summary of all problems in the course. It returns a dictionary with two datastructures:
This pulls a summary of all problems in the course.
Returns
- courseware_summary is a summary of all sections with problems in the course. It is organized as an array of chapters,
each containing an array of sections, each containing an array of scores. This contains information for graded and ungraded
problems, and is good for displaying a course summary with due dates, etc.
- grade_summary is the output from the course grader. More information on the format is in the docstring for CourseGrader.
Arguments:
student: A User object for the student to grade
course: An XModule containing the course to grade
student_module_cache: A StudentModuleCache initialized with all instance_modules for the student
"""
totaled_scores = {}
chapters = []
for c in course.get_children():
sections = []
@@ -132,30 +132,13 @@ def grade_sheet(student, course, grader, student_module_cache):
scores = []
for module in yield_module_descendents(s):
(correct, total) = get_score(student, module, student_module_cache)
if correct is None and total is None:
continue
if settings.GENERATE_PROFILE_SCORES:
if total > 1:
correct = random.randrange(max(total - 2, 1), total + 1)
else:
correct = total
if not total > 0:
#We simply cannot grade a problem that is 12/0, because we might need it as a percentage
graded = False
scores.append(Score(correct, total, graded, module.metadata.get('display_name')))
section_total, graded_total = graders.aggregate_scores(scores, s.metadata.get('display_name'))
#Add the graded total to totaled_scores
format = s.metadata.get('format', "")
if format and graded_total.possible > 0:
format_scores = totaled_scores.get(format, [])
format_scores.append(graded_total)
totaled_scores[format] = format_scores
sections.append({
'section': s.metadata.get('display_name'),
'scores': scores,
@@ -169,10 +152,7 @@ def grade_sheet(student, course, grader, student_module_cache):
'chapter': c.metadata.get('display_name'),
'sections': sections})
grade_summary = grader.grade(totaled_scores)
return {'courseware_summary': chapters,
'grade_summary': grade_summary}
return chapters
def get_score(user, problem, student_module_cache):

View File

@@ -86,18 +86,20 @@ def gradebook(request, course_id):
if 'course_admin' not in user_groups(request.user):
raise Http404
course = check_course(course_id)
sections, all_descriptors = grades.get_graded_sections(course)
student_objects = User.objects.all()[:100]
student_info = []
for student in student_objects:
student_module_cache = StudentModuleCache(student, course)
course = get_module(request.user, request, course.location, student_module_cache)
student_module_cache = StudentModuleCache(student, descriptors=all_descriptors)
student_info.append({
'username': student.username,
'id': student.id,
'email': student.email,
'grade_info': grades.grade_sheet(student, course, student_module_cache),
'grade_summary': grades.fast_grade(student, request, sections, course.grader, student_module_cache),
'realname': UserProfile.objects.get(user=student).name
})
@@ -123,16 +125,21 @@ def profile(request, course_id, student_id=None):
student_module_cache = StudentModuleCache(request.user, course)
course_module = get_module(request.user, request, course.location, student_module_cache)
courseware_summary = grades.grade_sheet(student, course_module, course.grader, student_module_cache)
sections, _ = grades.get_graded_sections(course)
grade_summary = grades.fast_grade(request.user, request, sections, course.grader, student_module_cache)
context = {'name': user_info.name,
'username': student.username,
'location': user_info.location,
'language': user_info.language,
'email': student.email,
'course': course,
'format_url_params': format_url_params,
'csrf': csrf(request)['csrf_token']
'csrf': csrf(request)['csrf_token'],
'courseware_summary' : courseware_summary,
'grade_summary' : grade_summary
}
context.update(grades.grade_sheet(student, course_module, course.grader, student_module_cache))
context.update()
return render_to_response('profile.html', context)
@@ -157,6 +164,7 @@ def render_accordion(request, course, chapter, section):
('toc', toc),
('course_name', course.title),
('course_id', course.id),
#TODO: Do we need format_url_params anymore? What is a better way to create the reversed links?
('format_url_params', format_url_params),
('csrf', csrf(request)['csrf_token'])] + template_imports.items())
return render_to_string('accordion.html', context)

View File

@@ -41,7 +41,7 @@ PERFSTATS = False
MITX_FEATURES = {
'SAMPLE' : False,
'USE_DJANGO_PIPELINE' : True,
'DISPLAY_HISTOGRAMS_TO_STAFF' : True,
'DISPLAY_HISTOGRAMS_TO_STAFF' : False,
'REROUTE_ACTIVATION_EMAIL' : False, # nonempty string = address for all activation emails
'DEBUG_LEVEL' : 0, # 0 = lowest level, least verbose, 255 = max level, most verbose

View File

@@ -65,5 +65,7 @@ DEBUG_TOOLBAR_PANELS = (
# Django=1.3.1/1.4 where requests to views get duplicated (your method gets
# hit twice). So you can uncomment when you need to diagnose performance
# problems, but you shouldn't leave it on.
# 'debug_toolbar.panels.profiling.ProfilingDebugPanel',
'debug_toolbar.panels.profiling.ProfilingDebugPanel',
)
#PIPELINE = True

View File

@@ -28,7 +28,7 @@
%if len(students) > 0:
<table>
<%
templateSummary = students[0]['grade_info']['grade_summary']
templateSummary = students[0]['grade_summary']
%>
@@ -58,10 +58,10 @@
%for student in students:
<tr>
<td><a href="/profile/${student['id']}/">${student['username']}</a></td>
%for section in student['grade_info']['grade_summary']['section_breakdown']:
%for section in student['grade_summary']['section_breakdown']:
${percent_data( section['percent'] )}
%endfor
<th>${percent_data( student['grade_info']['grade_summary']['percent'])}</th>
<th>${percent_data( student['grade_summary']['percent'])}</th>
</tr>
%endfor
</table>

View File

@@ -105,7 +105,6 @@ if settings.COURSEWARE_ENABLED:
# TODO: These views need to be updated before they work
# url(r'^calculate$', 'util.views.calculate'),
# url(r'^gradebook$', 'courseware.views.gradebook'),
# TODO: We should probably remove the circuit package. I believe it was only used in the old way of saving wiki circuits for the wiki
# url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
# url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
@@ -139,6 +138,10 @@ if settings.COURSEWARE_ENABLED:
'courseware.views.profile', name="profile"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile/(?P<student_id>[^/]*)/$',
'courseware.views.profile'),
# For the instructor
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/gradebook$',
'courseware.views.gradebook'),
)
# Multicourse wiki