def submit_autograding(self, docker): # create the autograded assignment file path self.autograded_assignment_path = os.path.join(self.grader_repo_path, self.grader_local_autograded_folder) self.autograde_fail_flag_path = os.path.join(self.grader_repo_path, 'autograde_failed_'+self.asgn.name+'-'+self.stu.canvas_id) print('Autograding submission ' + self.asgn.name+':'+self.stu.canvas_id) if os.path.exists(self.autograde_fail_flag_path): print('Autograde failed previously. Returning') return SubmissionStatus.AUTOGRADE_FAILED_PREVIOUSLY if os.path.exists(self.autograded_assignment_path): print('Assignment previously autograded & validated.') return SubmissionStatus.AUTOGRADED else: print('Removing old autograding result from DB if it exists') try: gb = Gradebook('sqlite:///'+self.grader_repo_path +'/gradebook.db') gb.remove_submission(self.asgn.name, self.student_prefix+self.stu.canvas_id) except MissingEntry as e: pass finally: gb.close() print('Submitting job to docker pool for autograding') self.autograde_docker_job_id = docker.submit('nbgrader autograde --force --assignment=' + self.asgn.name + ' --student='+self.student_prefix+self.stu.canvas_id, self.grader_repo_path) return SubmissionStatus.NEEDS_AUTOGRADE
async def add_user_to_nbgrader_gradebook( self, course_id: str, username: str, lms_user_id: str) -> Awaitable['HTTPResponse']: """ Adds a user to the nbgrader gradebook database for the course. Args: course_id: The normalized string which represents the course label. username: The user's username Raises: InvalidEntry: when there was an error adding the user to the database """ if not course_id: raise ValueError('course_id missing') if not username: raise ValueError('username missing') if not lms_user_id: raise ValueError('lms_user_id missing') grader_name = f'grader-{course_id}' db_url = Path('/home', grader_name, course_id, 'gradebook.db') db_url.parent.mkdir(exist_ok=True, parents=True) self.log.debug('Database url path is %s' % db_url) if not db_url.exists(): self.log.debug('Gradebook database file does not exist') return gradebook = Gradebook(f'sqlite:///{db_url}', course_id=course_id) try: gradebook.update_or_create_student(username, lms_user_id=lms_user_id) self.log.debug('Added user %s with lms_user_id %s to gradebook' % (username, lms_user_id)) except InvalidEntry as e: self.log.debug('Error during adding student to gradebook: %s' % e) gradebook.close()
def needs_manual_grading(self): try: gb = Gradebook('sqlite:///'+self.grader_repo_path +'/gradebook.db') subm = gb.find_submission(self.asgn.name, self.student_prefix+self.stu.canvas_id) flag = subm.needs_manual_grade finally: gb.close() return flag
def del_nbgrader_user(user, course): print(f"del {user} from course {course}") home = get_home_dir(f"grader-{course}") course_dir = f"{home}/{course}" gradebook = Gradebook(f"sqlite:///{course_dir}/gradebook.db", course_id=course) gradebook.remove_student(user) gradebook.close() for subdir in ("autograded", "feedback", "submitted"): os.system(f"rm -rf {course_dir}/{subdir}/{user}")
def add_nbgrader_user(user, first_name, last_name, course): print(f"add {user} ({last_name}, {first_name}) to course {course}") home = get_home_dir(f"grader-{course}") course_dir = f"{home}/{course}" gradebook = Gradebook(f"sqlite:///{course_dir}/gradebook.db", course_id=course) gradebook.update_or_create_student(user, first_name=first_name, last_name=last_name) gradebook.close()
def check_needs_manual_grading(course, anm, stu, grader): gradebook_file = os.path.join(course['course_storage_path'], grader, course['instructor_repo_path'], course['gradebook_filename']) gb = Gradebook('sqlite:///' + gradebook_file) try: subm = gb.find_submission(anm, course['student_name_prefix'] + stu) flag = subm.needs_manual_grade except MissingEntry as e: print(e) finally: gb.close() return flag
def upload_grade(self, canvas, failed = False): if self.grade_uploaded: print('Grade already uploaded. Returning') return SubmissionStatus.GRADE_UPLOADED print('Uploading grade for submission ' + self.asgn.name+':'+self.stu.canvas_id) if failed: score = 0 else: try: gb = Gradebook('sqlite:///'+self.grader_repo_path +'/gradebook.db') subm = gb.find_submission(self.asgn.name, self.student_prefix+self.stu.canvas_id) score = subm.score except Exception as e: print('Error when accessing grade from gradebook db') print(e) self.error = e return SubmissionStatus.ERROR finally: gb.close() try: max_score = self.compute_max_score() except Exception as e: print('Error when trying to compute max score from release notebook') print(e) self.error = e return SubmissionStatus.ERROR self.score = score self.max_score = max_score pct = "{:.2f}".format(100*score/max_score) print('Student ' + self.stu.canvas_id + ' assignment ' + self.asgn.name + ' score: ' + str(score) + (' [HARDFAIL]' if failed else '')) print('Assignment ' + self.asgn.name + ' max score: ' + str(max_score)) print('Pct Score: ' + pct) print('Posting to canvas...') try: canvas.put_grade(self.asgn.canvas_id, self.stu.canvas_id, pct) except GradeNotUploadedError as e: print('Error when uploading grade') print(e.message) self.error = e return SubmissionStatus.ERROR self.grade_uploaded = True return SubmissionStatus.GRADE_UPLOADED
def upload_grade(course, anm, stu, grader): print('Getting grade for student ' + stu + ' assignment ' + anm) course_dir_path = os.path.join(course['course_storage_path'], grader, course['instructor_repo_path']) gradebook_file = os.path.join(course['course_storage_path'], grader, course['instructor_repo_path'], course['gradebook_filename']) gb = Gradebook('sqlite:///' + gradebook_file) try: subm = gb.find_submission(anm, course['student_name_prefix'] + stu) score = subm.score except MissingEntry as e: print(e) finally: gb.close() max_score = compute_max_score(course, anm, grader) print('Student ' + stu + ' assignment ' + anm + ' score: ' + str(score)) print('Assignment ' + anm + ' max score: ' + str(max_score)) print('Pct Score: ' + str(100 * score / max_score)) print('Posting to canvas...') canvas.post_grade(course, anm, stu, str(100 * score / max_score))
# Create a dictionary that will store information about this student's # submitted assignment score = {} score['max_score'] = assignment.max_score score['student'] = student.id score['assignment'] = assignment.name # Try to find the submission in the database. If it doesn't exist, the # `MissingEntry` exception will be raised, which means the student # didn't submit anything, so we assign them a score of zero. try: submission = gb.find_submission(assignment.name, student.id) except MissingEntry: score['score'] = 0.0 else: score['score'] = submission.score grades.append(score) # Create a pandas dataframe with our grade information, and save it to disk grades = pd.DataFrame(grades).set_index(['student', 'assignment']).sortlevel() grades.to_csv('grades.csv') # Print out what the grades look like with open('grades.csv', 'r') as fh: print(fh.read()) # Close the connection to the database gb.close()