def _calculate_totals(sid=None, student_rownum=None, assignment_name=None, assignment_id=None): if assignment_id: assignment = (db( (db.assignments.id == assignment_id) & (db.assignments.course == auth.user.course_id)).select().first()) else: assignment = (db( (db.assignments.name == assignment_name) & (db.assignments.course == auth.user.course_id)).select().first()) if assignment: return do_calculate_totals( assignment, auth.user.course_id, auth.user.course_name, sid, student_rownum, db, settings, ) else: return { "success": False, "message": "Select an assignment before trying to calculate totals.", }
def calculate_totals(): assignment_name = request.vars.assignment sid = request.vars.get('sid', None) assignment = db( (db.assignments.name == assignment_name) & (db.assignments.course == auth.user.course_id)).select().first() if assignment: return json.dumps( do_calculate_totals(assignment, auth.user.course_id, auth.user.course_name, sid, db, settings)) else: return json.dumps({'success': False, 'message': "Select an assignment before trying to calculate totals."})
from rs_grading import do_autograde, do_calculate_totals import json, datetime, sys userinfo = json.loads(os.environ['RSM_USERINFO']) # print(userinfo['course'], userinfo['pset']) # # print(db.keys()) # print(settings) assignmentid = userinfo['pset'] assignment = db(db.assignments.id == assignmentid).select().first() course = db(db.courses.course_name == userinfo['course']).select().first() do_autograde( assignment, course.id, course.course_name, sid=None, question_name=None, enforce_deadline=userinfo['enforce_deadline'], # I don't know what this is for, but if you want to set this to Michigan timezone offset, it should be 4 # not 5. timezoneoffset=240, db=db, settings=settings) do_calculate_totals(assignment, course.id, course.course_name, sid=None, db=db, settings=settings)
def record_grade(): """ Called from the grading interface when the instructor manually records a grade. """ # Validate parameters. if "acid" not in request.vars or not (("sid" in request.vars) or ("sid[]" in request.vars)): return json.dumps({ "success": False, "message": "Need problem and user." }) if ("sid" in request.vars) and ("sid[]" in request.vars): return json.dumps({ "success": False, "message": "Cannot specify both sid and sid[]." }) if ("comment" not in request.vars) and ("grade" not in request.vars): return json.dumps({ "success": False, "message": "Must provide either grade or comment." }) if "assignmentid" not in request.vars: return json.dumps({ "success": False, "message": "Must provide assignment id." }) # Create a dict of updates for this grade. updates = dict(course_name=auth.user.course_name) # Parse the grade into a score. if "grade" in request.vars: score_str = request.vars.grade.strip() # An empty score means delete it. if not score_str: updates["score"] = None else: try: updates["score"] = float(score_str) except ValueError as e: logger.error("Bad Score: {} - Details: {}".format( score_str, e)) return json.dumps({"response": "not replaced"}) # Update the comment if supplied. comment = request.vars.comment if comment is not None: updates["comment"] = comment # Gather the remaining parameters. div_id = request.vars.acid # Accept input of a single sid from the request variable ``sid`` or a list from ``sid[]``, following the way `jQuery serielizes this <https://api.jquery.com/jQuery.param/>`_ (with the ``traditional`` flag set to its default value of ``false``). Note that ``$.param({sid: ["one"]})`` produces ``"sid%5B%5D=one"``, meaning that this "list" will still be a single-element value. Therefore, use ``getlist`` for **both** "sid" (which should always be only one element) and "sid[]" (which could be a single element or a list). sids = request.vars.getlist("sid") or request.vars.getlist("sid[]") # Gather assignment id for future use by do_calculate_totals function assignment_id = request.vars.assignmentid if assignment_id.isnumeric(): assignment = (db( (db.assignments.id == assignment_id) & (db.assignments.course == auth.user.course_id)).select().first()) else: assignment = (db( (db.assignments.name == assignment_id) & (db.assignments.course == auth.user.course_id)).select().first()) student_rownum = None # Update the score(s). try: # sid can be a list of sids to change. Walk through each element in the list. for sid in sids: db.question_grades.update_or_insert( ((db.question_grades.sid == sid) & (db.question_grades.div_id == div_id) & (db.question_grades.course_name == auth.user.course_name)), sid=sid, div_id=div_id, **updates, ) if assignment: try: do_calculate_totals( assignment, auth.user.course_id, auth.user.course_name, sid, student_rownum, db, settings, ) except Exception as e: logger.error( f"Calculate totals failed for reason {e} - {auth.user.course_name} {sid} {student_rownum} {assignment}" ) except IntegrityError: logger.error("IntegrityError {} {} {}".format(sid, div_id, auth.user.course_name)) # TODO: Maybe we should just do an update when we get an Integrity error? return json.dumps({"response": "not replaced"}) return json.dumps({"response": "replaced"})