Source code for codegrade.models.extended_assignment_extra

"""The module that defines the ``ExtendedAssignmentExtra`` model.

SPDX-License-Identifier: AGPL-3.0-only OR BSD-3-Clause-Clear
"""

from __future__ import annotations

import typing as t
from dataclasses import dataclass, field

import cg_request_args as rqa

from .. import parsers
from ..utils import to_dict
from .assignment_anonymization_algo import AssignmentAnonymizationAlgo
from .assignment_percentage_grading_settings import (
    AssignmentPercentageGradingSettings,
)
from .assignment_points_grading_settings import AssignmentPointsGradingSettings
from .cg_ignore_version import CGIgnoreVersion
from .group_set import GroupSet
from .submission_validator_input_data import SubmissionValidatorInputData


[docs] @dataclass(kw_only=True) class ExtendedAssignmentExtra: """The fields that the full serialization of an assignment adds to the short one, for every type of assignment. """ #: The cginore. cgignore: t.Optional[t.Union[SubmissionValidatorInputData, str]] #: The version of the cignore file. cgignore_version: t.Optional[CGIgnoreVersion] #: The fixed value for the maximum that can be achieved in a rubric. This #: can be higher and lower than the actual max. Will be `None` if unset. fixed_max_rubric_points: t.Optional[float] #: The maximum grade you can get for this assignment. This is based around #: the idea that a 10 is a 'perfect' score. So if this value is 12 a user #: can score 2 additional bonus points. If this value is `None` it is unset #: and regarded as a 10. max_grade: float #: Settings that influence how the grade for a submission can be #: determined. TODO: Should we also move `max_grade` and/or #: `fixed_max_rubric_points` to the grading object? grading: t.Union[ AssignmentPointsGradingSettings, AssignmentPercentageGradingSettings ] #: The group set of this assignment. This is `None` if this assignment is #: not a group assignment. group_set: t.Optional[GroupSet] #: The LMS providing this LTI assignment. lms_name: t.Optional[str] #: The assignment id of the assignment that determines the grader division #: of this assignment. This will be `null` if you do not have permissions #: to see this information, or if no such parent is set. division_parent_id: t.Optional[int] #: The anonymization algorithm used for this assignment. anonymized_grading: t.Optional[AssignmentAnonymizationAlgo] raw_data: t.Optional[t.Dict[str, t.Any]] = field(init=False, repr=False) data_parser: t.ClassVar[t.Any] = rqa.Lazy( lambda: rqa.FixedMapping( rqa.RequiredArgument( "cgignore", rqa.Nullable( parsers.make_union( parsers.ParserFor.make(SubmissionValidatorInputData), rqa.SimpleValue.str, ) ), doc="The cginore.", ), rqa.RequiredArgument( "cgignore_version", rqa.Nullable(rqa.EnumValue(CGIgnoreVersion)), doc="The version of the cignore file.", ), rqa.RequiredArgument( "fixed_max_rubric_points", rqa.Nullable(rqa.SimpleValue.float), doc="The fixed value for the maximum that can be achieved in a rubric. This can be higher and lower than the actual max. Will be `None` if unset.", ), rqa.RequiredArgument( "max_grade", rqa.SimpleValue.float, doc="The maximum grade you can get for this assignment. This is based around the idea that a 10 is a 'perfect' score. So if this value is 12 a user can score 2 additional bonus points. If this value is `None` it is unset and regarded as a 10.", ), rqa.RequiredArgument( "grading", parsers.make_union( parsers.ParserFor.make(AssignmentPointsGradingSettings), parsers.ParserFor.make( AssignmentPercentageGradingSettings ), ), doc="Settings that influence how the grade for a submission can be determined. TODO: Should we also move `max_grade` and/or `fixed_max_rubric_points` to the grading object?", ), rqa.RequiredArgument( "group_set", rqa.Nullable(parsers.ParserFor.make(GroupSet)), doc="The group set of this assignment. This is `None` if this assignment is not a group assignment.", ), rqa.RequiredArgument( "lms_name", rqa.Nullable(rqa.SimpleValue.str), doc="The LMS providing this LTI assignment.", ), rqa.RequiredArgument( "division_parent_id", rqa.Nullable(rqa.SimpleValue.int), doc="The assignment id of the assignment that determines the grader division of this assignment. This will be `null` if you do not have permissions to see this information, or if no such parent is set.", ), rqa.RequiredArgument( "anonymized_grading", rqa.Nullable(rqa.EnumValue(AssignmentAnonymizationAlgo)), doc="The anonymization algorithm used for this assignment.", ), ) ) def to_dict(self) -> t.Dict[str, t.Any]: res: t.Dict[str, t.Any] = { "cgignore": to_dict(self.cgignore), "cgignore_version": to_dict(self.cgignore_version), "fixed_max_rubric_points": to_dict(self.fixed_max_rubric_points), "max_grade": to_dict(self.max_grade), "grading": to_dict(self.grading), "group_set": to_dict(self.group_set), "lms_name": to_dict(self.lms_name), "division_parent_id": to_dict(self.division_parent_id), "anonymized_grading": to_dict(self.anonymized_grading), } return res @classmethod def from_dict( cls: t.Type[ExtendedAssignmentExtra], d: t.Dict[str, t.Any] ) -> ExtendedAssignmentExtra: parsed = cls.data_parser.try_parse(d) res = cls( cgignore=parsed.cgignore, cgignore_version=parsed.cgignore_version, fixed_max_rubric_points=parsed.fixed_max_rubric_points, max_grade=parsed.max_grade, grading=parsed.grading, group_set=parsed.group_set, lms_name=parsed.lms_name, division_parent_id=parsed.division_parent_id, anonymized_grading=parsed.anonymized_grading, ) res.raw_data = d return res