Source code for nbgrader.plugins.export

from traitlets import Unicode, List

from .base import BasePlugin
from ..api import MissingEntry, Gradebook


[docs] class ExportPlugin(BasePlugin): """Base class for export plugins.""" to = Unicode("", help="destination to export to").tag(config=True) student = List( [], help="list of students to export").tag(config=True) assignment = List( [], help="list of assignments to export").tag(config=True)
[docs] def export(self, gradebook: Gradebook) -> None: """Export grades to another format. This method MUST be implemented by subclasses. Users should be able to pass the ``--to`` flag on the command line, which will set the ``self.to`` variable. By default, this variable will be an empty string, which allows you to specify whatever default you would like. Arguments --------- gradebook: An instance of the gradebook """ raise NotImplementedError
class CsvExportPlugin(ExportPlugin): """CSV exporter plugin.""" def export(self, gradebook: Gradebook) -> None: if self.to == "": dest = "grades.csv" else: dest = self.to if len(self.student) == 0: allstudents = [] else: # make sure studentID(s) are a list of strings allstudents = [str(item) for item in self.student] if len(self.assignment) == 0: allassignments = [] else: # make sure assignment(s) are a list of strings allassignments = [str(item) for item in self.assignment] self.log.info("Exporting grades to %s", dest) if allassignments: self.log.info("Exporting only assignments: %s", allassignments) if allstudents: self.log.info("Exporting only students: %s", allstudents) fh = open(dest, "w") keys = [ "assignment", "duedate", "timestamp", "student_id", "last_name", "first_name", "email", "raw_score", "late_submission_penalty", "score", "max_score" ] fh.write(",".join(keys) + "\n") fmt = ",".join(["{" + x + "}" for x in keys]) + "\n" # Loop over each assignment in the database for assignment in gradebook.assignments: # only continue if assignment is required if allassignments and assignment.name not in allassignments: continue # Loop over each student in the database for student in gradebook.students: # only continue if student is required if allstudents and student.id not in allstudents: continue # Create a dictionary that will store information # about this student's submitted assignment score = {} score['assignment'] = assignment.name score['duedate'] = assignment.duedate score['student_id'] = student.id score['last_name'] = student.last_name score['first_name'] = student.first_name score['email'] = student.email score['max_score'] = assignment.max_score # 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 = gradebook.find_submission( assignment.name, student.id) except MissingEntry: score['timestamp'] = '' score['raw_score'] = 0.0 score['late_submission_penalty'] = 0.0 score['score'] = 0.0 else: penalty = submission.late_submission_penalty score['timestamp'] = submission.timestamp score['raw_score'] = submission.score score['late_submission_penalty'] = penalty score['score'] = max(0.0, submission.score - penalty) for key in score: if score[key] is None: score[key] = '' if not isinstance(score[key], str): score[key] = str(score[key]) fh.write(fmt.format(**score)) fh.close()