def test_grade_timestamp(self): """Is a timestamp correctly read in?""" with self._temp_cwd(["files/submitted-unchanged.ipynb", "files/submitted-changed.ipynb"]): dbpath = self._setup_db() os.makedirs('source/ps1') shutil.copy('submitted-unchanged.ipynb', 'source/ps1/p1.ipynb') self._run_command('nbgrader assign ps1 --db="{}" '.format(dbpath)) os.makedirs('submitted/foo/ps1') shutil.move('submitted-unchanged.ipynb', 'submitted/foo/ps1/p1.ipynb') with open('submitted/foo/ps1/timestamp.txt', 'w') as fh: fh.write("2015-02-02 15:58:23.948203 PST") os.makedirs('submitted/bar/ps1') shutil.move('submitted-changed.ipynb', 'submitted/bar/ps1/p1.ipynb') with open('submitted/bar/ps1/timestamp.txt', 'w') as fh: fh.write("2015-02-01 14:58:23.948203 PST") self._run_command('nbgrader autograde ps1 --db="{}"'.format(dbpath)) assert os.path.isfile("autograded/foo/ps1/p1.ipynb") assert os.path.isfile("autograded/foo/ps1/timestamp.txt") assert os.path.isfile("autograded/bar/ps1/p1.ipynb") assert os.path.isfile("autograded/bar/ps1/timestamp.txt") gb = Gradebook(dbpath) submission = gb.find_submission('ps1', 'foo') assert submission.total_seconds_late > 0 submission = gb.find_submission('ps1', 'bar') assert submission.total_seconds_late == 0 # make sure it still works to run it a second time self._run_command('nbgrader autograde ps1 --db="{}"'.format(dbpath))
def test_grade_timestamp(self, gradebook): """Is a timestamp correctly read in?""" self._copy_file("files/submitted-unchanged.ipynb", "source/ps1/p1.ipynb") run_command('nbgrader assign ps1 --db="{}" '.format(gradebook)) self._copy_file("files/submitted-unchanged.ipynb", "submitted/foo/ps1/p1.ipynb") self._make_file('submitted/foo/ps1/timestamp.txt', "2015-02-02 15:58:23.948203 PST") self._copy_file("files/submitted-changed.ipynb", "submitted/bar/ps1/p1.ipynb") self._make_file('submitted/bar/ps1/timestamp.txt', "2015-02-01 14:58:23.948203 PST") run_command('nbgrader autograde ps1 --db="{}"'.format(gradebook)) assert os.path.isfile("autograded/foo/ps1/p1.ipynb") assert os.path.isfile("autograded/foo/ps1/timestamp.txt") assert os.path.isfile("autograded/bar/ps1/p1.ipynb") assert os.path.isfile("autograded/bar/ps1/timestamp.txt") gb = Gradebook(gradebook) submission = gb.find_submission('ps1', 'foo') assert submission.total_seconds_late > 0 submission = gb.find_submission('ps1', 'bar') assert submission.total_seconds_late == 0 # make sure it still works to run it a second time run_command('nbgrader autograde ps1 --db="{}"'.format(gradebook))
def test_grade_timestamp(self, gradebook): """Is a timestamp correctly read in?""" self._copy_file("files/submitted-unchanged.ipynb", "source/ps1/p1.ipynb") run_command(["nbgrader", "assign", "ps1", "--db", gradebook]) self._copy_file("files/submitted-unchanged.ipynb", "submitted/foo/ps1/p1.ipynb") self._make_file('submitted/foo/ps1/timestamp.txt', "2015-02-02 15:58:23.948203 PST") self._copy_file("files/submitted-changed.ipynb", "submitted/bar/ps1/p1.ipynb") self._make_file('submitted/bar/ps1/timestamp.txt', "2015-02-01 14:58:23.948203 PST") run_command(["nbgrader", "autograde", "ps1", "--db", gradebook]) assert os.path.isfile("autograded/foo/ps1/p1.ipynb") assert os.path.isfile("autograded/foo/ps1/timestamp.txt") assert os.path.isfile("autograded/bar/ps1/p1.ipynb") assert os.path.isfile("autograded/bar/ps1/timestamp.txt") gb = Gradebook(gradebook) submission = gb.find_submission('ps1', 'foo') assert submission.total_seconds_late > 0 submission = gb.find_submission('ps1', 'bar') assert submission.total_seconds_late == 0 # make sure it still works to run it a second time run_command(["nbgrader", "autograde", "ps1", "--db", gradebook])
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 test_find_comment(assignmentWithSubmissionWithMarks: Gradebook) -> None: s = assignmentWithSubmissionWithMarks.find_submission('foo', 'hacker123') for n in s.notebooks: comments = n.comments for c1 in comments: c2 = assignmentWithSubmissionWithMarks.find_comment(c1.name, n.name, 'foo', 'hacker123') assert c1 == c2 with pytest.raises(MissingEntry): assignmentWithSubmissionWithMarks.find_comment('asdf', n.name, 'foo', 'hacker123')
def export(self, gradebook: Gradebook) -> None: """Creates a CSV file from nbgrader's gradebook. Args: gradebook (Gradebook): an nbgrader gradebook instance. """ if self.canvas_export == "": dest = "canvas_grades.csv" else: dest = self.to if self.canvas_import == "": canvas_import = "canvas.csv" else: canvas_import = self.canvas_import self.log.info("Exporting grades to %s", dest) with open(canvas_import, "r") as csv_file, open(dest, "w") as op_csv_file: csv_reader = csv.DictReader(csv_file) fields = csv_reader.fieldnames csv_writer = csv.DictWriter(op_csv_file, fields) csv_writer.writeheader() for row in csv_reader: if "Points Possible" in row["Student"]: self.log.info("Skipping second row") csv_writer.writerow(row) continue self.log.info("Finding student with ID %s", row["ID"]) for column in fields: if " (" not in column: continue assignment_name = column.split(" (")[0] self.log.info( "Finding submission of Student '%s' for Assignment '%s'", row["ID"], assignment_name, ) submission = None try: submission = gradebook.find_submission( assignment_name, row["ID"] ) row[column] = max( 0.0, submission.score - submission.late_submission_penalty ) except MissingEntry: self.log.info( "Submission of Student '%s' for Assignment '%s' not found", row["ID"], assignment_name, ) continue csv_writer.writerow(row)
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))
def test_grades_include_taskcells(assignmentWithSubmissionWithMarks: Gradebook) -> None: s = assignmentWithSubmissionWithMarks.find_submission('foo', 'hacker123') for n in s.notebooks: grades = n.grades assert len(grades) == 6
# Loop over each student in the database for student in gb.students: # 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())