Gradebook
et al.
- class gradelib.Gradebook(points_earned: DataFrame, points_possible: Series, lateness: DataFrame | None = None, dropped: DataFrame | None = None, notes: Mapping[Student, Mapping[str, Sequence[str]]] | None = None, grading_groups: Mapping[str, float | Tuple[Sequence[str], float] | Tuple[Mapping[str, float], float] | GradingGroup] | None = None, scale: Mapping | None = None, options: GradebookOptions | None = None)
Stores the grades for a class.
Typically a Gradebook is not created manually, but is instead produced by reading grades exported from Gradescope or Canvas, using
gradelib.io.gradescope.read()
orgradelib.io.canvas.read()
.- Parameters:
points_earned (pandas.DataFrame) – A dataframe with one row per student, and one column for each assignment. Each entry should be the raw number of points earned by the student on the given assignment (or NaN if the student did not turn in the assignment). The index of the dataframe should consist of
Student
objects.points_possible (pandas.Series) – A series containing the maximum number of points possible for each assignment. The index of the series should match the columns of the points_earned dataframe.
lateness (Optional[pandas.DataFrame]) – A dataframe of pd.Timedelta objects with the same columns/index as points_earned. An entry in the dataframe records how late a student turned in the assignment. If None is passed, a dataframe of zero second timedeltas is used by default, effectively indicating that no assignments were late.
dropped (Optional[pandas.DataFrame]) – A Boolean dataframe with the same columns/index as points_earned. An entry that is True indicates that the assignment should be dropped. If None is passed, a dataframe of all False is used by default.
notes (Optional[Mapping[Student, Mapping[str, Sequence[str]]]]) – A nested dictionary of notes, possibly used by report generating code. The keys of the outer dictionary should be
Student
objects, and the values should be dictionaries. The keys of the inner dictionary should specify a note channel, and can be either “late”, “drop”, or “misc”; these are signals to reporting code that help determine where to display notes. The values of the inner dictionary should be sequences of strings, each one a message.options (Optional[GradebookOptions]) – Options controlling the behavior of the Gradebook. If not provided, default options are used.
grading_groups (Mapping[str, GradingGroup]) –
A mapping from assignment group names (strings) to
GradingGroup
objects representing a group of assignments. The default is simply{}
.To prevent unintentional errors, the grading groups must be set before accessing summative attributes, such as
overall_score
.While the dictionary returned by this attribute has
GradingGroup
instances as values, the attribute can be set in several ways. See the documentation for the setter for more details.scale (Optional[Mapping]) – An ordered mapping from letter grades to score thresholds used to determine overall letter grades. If not provided,
gradelib.scales.DEFAULT_SCALE
is used.
- notes
A nested dictionary of notes, possibly used by report generating code.
- Type:
dict[Student, dict[str, list[str]]]
- options
Options controlling the behavior of the Gradebook.
- Type:
- scale
An ordered mapping from letter grades to score thresholds used to determine overall letter grades.
- Type:
dict
- add_assignment(name: str, points_earned: Series, points_possible: float | int, lateness: Series | None = None, dropped: Series | None = None)
Adds a single assignment to the gradebook, mutating it.
Usually gradebooks do not need to have individual assignments added to them. Instead, gradebooks are read from Canvas, Gradescope, etc. In some instances, though, it can be useful to manually add an assignment to a gradebook – this method makes it easy to do so.
- Parameters:
name (str) – The name of the new assignment. Must be unique.
points_earned (Series[float]) – A Series of points earned by each student.
points_possible (float) – The maximum number of points possible on the assignment.
lateness (Series[pd.Timedelta]) – How late each student turned in the assignment. Turning in the assignment on time should be represented by a pd.Timedelta of zero seconds. Default: all zero seconds.
dropped (Series[bool]) – Whether the assignment should be dropped for any given student. Default: all False.
- Raises:
ValueError – If an assignment with the given name already exists, or if grades for a student are missing / grades for an unknown student are provided.
- add_note(student: Student, channel: str, message: str)
Add a grading note.
Mutates the gradebook.
- Parameters:
student (Student) – The student for which the note should be added.
channel (str) –
- The channel that the note should be added to. Valid channels are:
lates
drops
attempts
misc
message (str) – The note’s message.
- property assignments: Assignments
All assignments in the gradebook.
This is a derived attribute; it should not be modified.
- Return type:
- property attempted: DataFrame
A table of whether each assignment was attempted (i.e., turned in).
Produces a DataFrame with a row for each student and a column for each assignment. Each entry is True if the student attempted the assignment and False otherwise. An assignment is considered “attempted” if points_earned is not NaN.
- copy() Gradebook
Copy the gradebook.
- Returns:
A new gradebook with all attributes copied.
- Return type:
- property grading_group_scores: DataFrame
A table of the scores earned in each grading group.
Produces a DataFrame with a row for each student and a column for each grading group in which each entry is the student’s score within that grading group.
This takes into account dropped assignments.
If an assignment has a score of NaN, it is treated as a zero for the purposes of computing the grading group score. Conceptually, an individual assignment may not be attempted by a student, but a grading group score is always “attempted” and so it cannot be NaN.
If
grading_groups
has not yet been set, all entries are NaN.This is a derived attribute; it should not be modified.
- property grading_groups: dict[str, GradingGroup]
A grouping of assignments and their weight in the overall grade.
This attribute should be set directly. The value should be a dict mapping group names to grading group definitions. A group definition can be any of the following:
A single number. In this case, the group name is treated as an assignment name.
A tuple of the form
(assignments, group_weight)
, whereassignments
is an iterable of assignment names or a dict mapping assignment names to weights. Ifassignments
is an iterable, the weights are inferred to be proportional to the points possible for each assignment. Ifassignments
is a dict, the weights are taken directly from the dict.A
GradingGroup
instance.
To normalize the weights of assignments (so that they are all weighed the same) use the
gradelib.normalize()
function.Example
>>> gradebook.grading_groups = { ... # list of assignments, followed by group weight. assignment weights ... # are inferred to be proportional to points possible ... "homeworks": (['hw 01', 'hw 02', 'hw 03'], 0.25), ... ... # dictionary of assignment weights, followed by group weight. ... "labs": ({"lab 01": .25, "lab 02": .75}, 0.25), ... ... # a single number. the key is interpreted as an assignment name, ... # and an assignment group consisting only of that assignment is ... # created. ... "exam": 0.5 ... }
- property late: DataFrame
A boolean dataframe telling which assignments were turned in late.
Will have the same index and columns as the points_earned attribute.
This is computed from the
lateness
attribute using theGradebookOptions.lateness_fudge
option. If the lateness is less than the lateness fudge, the assignment is considered on-time; otherwise, it is considered late. This can be useful to work around grade sources whose reported lateness is not always reliable, such as Gradescope.This is a derived attribute; it should not be modified.
- property letter_grades: Series
A series containing the letter grade earned by each student.
A pandas Series with an entry for each student in the Gradebook. The index is the same as the series returned by the
students
attribute. Each entry is the letter grade the class, taking drops into account, and calculated using the value of thescale
attribute.This is a dynamically-computed property; it should not be modified.
- Raises:
ValueError – If
grading_groups
has not yet been set.
- property overall_score: Series
A series containing the overall score earned by each student.
A pandas Series with an entry for each student in the Gradebook. The index is the same as the series returned by the
students
attribute. Each entry is the overall score in the class, taking drops into account.This is a derived attribute; it should not be modified.
- Raises:
ValueError – If
grading_groups
has not yet been set.
- property overall_weight: DataFrame
A table of assignment weights relative to all other assignments.
If
grading_groups
is set, this computes a table of the same size aspoints_earned
containing for each student and assignment, the overall weight of that assignment relative to all other assignments.If an assignment is not in an assignment group, the weight for that assignment is NaN. If no grading groups have been defined, all weights are Nan.
If the assignment is dropped for that student, the weight is zero. If all assignments in a group have been dropped, ValueError is raised.
Note that this is not the weight of the assignment relative to the total weight of the assignment group it is in. That is computed in
weight
.This is a derived attribute; it should not be modified.
- Raises:
ValueError – If all assignments in a group have been dropped for a student, the weights are undefined.
- property pids: set[str]
All student PIDs.
This is a derived attribute; it should not be modified.
- Return type:
set
- remove_assignments(assignments: Collection[str])
Removes assignments from the gradebook.
Modifies the gradebook in-place.
If the
grading_groups
attribute been set, it is reset to an empty dictionary by this operation.- Parameters:
assignments (Collection[str]) – A collection of assignments names that will be removed.
- rename_assignments(mapping: Mapping[str, str])
Renames assignments.
Modifies the gradebook in-place.
If the
grading_groups
attribute been set, it is reset to an empty dictionary by this operation.- Parameters:
mapping (dict[str, str]) – A mapping from existing column names to new names.
- Raises:
ValueError – If a new name clashes with an existing name.
- restrict_to_assignments(assignments: Collection[str])
Restrict the gradebook to only the supplied assignments, removing all others.
Modifies the gradebook in-place.
If the
grading_groups
attribute been set, it is reset to an empty dictionary by this operation.- Parameters:
assignments (Collection[str]) – A collection of assignment names.
- restrict_to_students(to: Collection[str | Student])
Restrict the gradebook to only the supplied PIDs.
- Parameters:
to (Collection[Union[str, Student]]) – A collection of PIDs or Students.
- Raises:
KeyError – If a PID was specified that is not in the gradebook.
- property score: DataFrame
A table of scores on each assignment.
Produces a DataFrame with a row for each student and a column for each assignment containing the number of points earned on that assignment as a proportion of the number of points possible on that assignment.
If the student did not attempt the assignment (and so the points_earned entry is NaN), the score is also NaN.
Does not take into account drops.
This is a derived attribute; it should not be modified.
- property students: Students
All students as Student objects.
Returned in the order they appear in the indices of the points_earned attribute.
This is a derived attribute; it should not be modified.
- Return type:
- property value: DataFrame
A table containing the value of each assignment for each student.
This produces a table of the same size as
points_earned
where each entry contains the value of an assignment for a given student. The “value” of an assignment is the amount that it contributes to the student’s overall score in the class. In short, it is the product of that assignment’s score with its overall weight.If
grading_groups
is not set, all entries are NaN.The total of a student’s assignment values equals their score in the class.
This is a derived attribute; it should not be modified.
- Raises:
ValueError – If all assignments in a group have been dropped for a student, the weights are undefined.
- property weight_in_group: DataFrame
A table of assignment weights relative to their assignment group.
If
grading_groups
is set, this computes a table of the same size aspoints_earned
containing for each student and assignment, the weight of that assignment relative to the assignment group.If an assignment is not in an assignment group, the weight for that assignment is NaN. If no grading groups have been defined, all weights are Nan.
If the assignment is dropped for that student, the weight is zero. If all assignments in a group have been dropped, ValueError is raised.
Note that this is not the overall weight towards to the overall score. That is computed in
overall_weight
.This is a derived attribute; it should not be modified.
- Raises:
ValueError – If all assignments in a group have been dropped for a student, the weights are undefined.
- class gradelib.GradebookOptions(lateness_fudge: int = 300, allow_extra_credit: bool = True)
Configures the behavior of a
Gradebook
.- lateness_fudge
Number of seconds within which a late assignment is not considered late by
Gradebook.late()
. This can be useful to work around grade sources where the lateness may not be reliable, such as Gradescope. Default: 300.- Type:
int
- allow_extra_credit
If True, grading group weights are allowed to sum to beyond one, effectively allowing extra credit. Default: True.
- Type:
bool
- class gradelib.GradingGroup(assignment_weights: Mapping[str, float], group_weight: float)
Represents a logical group of assignments and their weights.
- assignment_weights
A dictionary mapping assignment names (strings) to their weight within the group (as a float between 0 and 1). Their weights should add to one.
- Type:
Mapping[str, float]
- group_weight
The overall weight of the group.
- Type:
float
- Raises:
ValueError – If the assignment weights are not between 0 and 1, they do not add to one, or if the group weight is not between 0 and 1.
- property assignments: Assignments
The assignments in the group.