Skip to content

Commit

Permalink
refactor: [FC-0063] Code quality is improved
Browse files Browse the repository at this point in the history
  • Loading branch information
myhailo-chernyshov-rg committed Feb 27, 2025
1 parent 3cc738f commit 9d1a3e2
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 125 deletions.
37 changes: 26 additions & 11 deletions src/cc2olx/content_processors/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,22 @@ class AssignmentSubmissionFormatType(str, Enum):
TEXT = "text"
URL = "url"

@classmethod
def get_not_file_types(cls) -> Set["AssignmentSubmissionFormatType"]:
"""
Provide submission format types except file.
"""
return {cls.HTML, cls.TEXT, cls.URL}


class AssignmentContentProcessor(AbstractContentProcessor):
"""
Assignment content processor.
Process Common Cartridge Assignment Extension Resource (its data model
description: https://www.imsglobal.org/cc/ccv1p3/AssignmentContentType.html)
by parsing the CC Assignment XML and producing OLX Open Response
Assessment (ORA) blocks. Assignment are problems that require a written
response from a student, an answer in the form of a file, a link to a
resource with the solution (or a combination of these response types) and
cannot be graded automatically.
Assignment maps to ORA not completely: Assignment has attachments but ORA
does not, ORA has rubrics but Assignments does not. So, only similar
functionalities are processed, for some missed Assignment features ORA
defaults are provided.
"""

DEFAULT_ACCEPTED_FORMAT_TYPES = {AssignmentSubmissionFormatType.HTML, AssignmentSubmissionFormatType.FILE}
Expand All @@ -51,9 +56,13 @@ def _parse(self, resource: dict) -> Optional[dict]:
return self._parse_assignment(resource)
return None

def _parse_assignment(self, resource: dict) -> Dict[str, Union[str, Dict[str, str]]]:
def _parse_assignment(self, resource: dict) -> Dict[str, Union[bool, str, List[str]]]:
"""
Parse the assignment resource.
Take the resource data dictionary and extract from it data required for
ORA blocks creation, along with some defaults that are not specified in
Common Cartridge specification. Produce the dictionary with this data.
"""
resource_file = resource["children"][0]
tree = filesystem.get_xml_tree(self._cartridge.build_resource_file_path(resource_file.href))
Expand Down Expand Up @@ -122,15 +131,21 @@ def _is_file_submission_allowed(accepted_format_types: Set[str]) -> bool:
"""
Decide whether submitting a file as an answer to assignment is allowed.
"""
return not accepted_format_types or AssignmentSubmissionFormatType.FILE in accepted_format_types
return AssignmentSubmissionFormatType.FILE in accepted_format_types

@staticmethod
def _is_textual_submission_allowed(accepted_format_types: Set[str]) -> bool:
"""
Decide whether submitting a textual answer to assignment is allowed.
"""
return not accepted_format_types or bool(
AssignmentSubmissionFormatType.get_not_file_types().intersection(accepted_format_types)
return bool(
accepted_format_types.intersection(
{
AssignmentSubmissionFormatType.HTML,
AssignmentSubmissionFormatType.TEXT,
AssignmentSubmissionFormatType.URL,
}
)
)

@staticmethod
Expand Down
183 changes: 71 additions & 112 deletions src/cc2olx/content_processors/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from cc2olx.content_processors import AbstractContentProcessor
from cc2olx.enums import CommonCartridgeResourceType
from cc2olx.models import Cartridge
from cc2olx.utils import element_builder


def parse_web_link_content(resource: dict, cartridge: Cartridge) -> Optional[Dict[str, str]]:
Expand Down Expand Up @@ -40,117 +39,77 @@ def generate_default_ora_criteria() -> List[xml.dom.minidom.Element]:
"""
Generate default ORA criteria OLX.
"""
doc = xml.dom.minidom.Document()
el = element_builder(doc)
ideas_criterion = """
<criterion feedback="optional">
<name>Ideas</name>
<label>Ideas</label>
<prompt>Determine if there is a unifying theme or main idea.</prompt>
<option points="0">
<name>Poor</name>
<label>Poor</label>
<explanation>
Difficult for the reader to discern the main idea. Too brief or too repetitive to establish or maintain
a focus.
</explanation>
</option>
<option points="3">
<name>Fair</name>
<label>Fair</label>
<explanation>
Presents a unifying theme or main idea, but may include minor tangents. Stays somewhat focused on topic
and task.
</explanation>
</option>
<option points="5">
<name>Good</name>
<label>Good</label>
<explanation>
Presents a unifying theme or main idea without going off on tangents. Stays completely focused on topic
and task.
</explanation>
</option>
</criterion>
"""
content_criterion = """
<criterion feedback="optional">
<name>Content</name>
<label>Content</label>
<prompt>Assess the content of the submission</prompt>
<option points="0">
<name>Poor</name>
<label>Poor</label>
<explanation>
Includes little information with few or no details or unrelated details. Unsuccessful in attempts to
explore any facets of the topic.
</explanation>
</option>
<option points="1">
<name>Fair</name>
<label>Fair</label>
<explanation>
Includes little information and few or no details. Explores only one or two facets of the topic.
</explanation>
</option>
<option points="3">
<name>Good</name>
<label>Good</label>
<explanation>
Includes sufficient information and supporting details. (Details may not be fully developed; ideas may
be listed.) Explores some facets of the topic.
</explanation>
</option>
<option points="5">
<name>Excellent</name>
<label>Excellent</label>
<explanation>
Includes in-depth information and exceptional supporting details that are fully developed. Explores all
facets of the topic.
</explanation>
</option>
</criterion>
"""

return [
el(
"criterion",
[
el("name", "Ideas"),
el("label", "Ideas"),
el("prompt", "Determine if there is a unifying theme or main idea."),
el(
"option",
[
el("name", "Poor"),
el("label", "Poor"),
el(
"explanation",
"Difficult for the reader to discern the main idea. Too brief or too repetitive to "
"establish or maintain a focus.",
),
],
{"points": "0"},
),
el(
"option",
[
el("name", "Fair"),
el("label", "Fair"),
el(
"explanation",
"Presents a unifying theme or main idea, but may include minor tangents. Stays "
"somewhat focused on topic and task.",
),
],
{"points": "3"},
),
el(
"option",
[
el("name", "Good"),
el("label", "Good"),
el(
"explanation",
"Presents a unifying theme or main idea without going off on tangents. Stays "
"completely focused on topic and task.",
),
],
{"points": "5"},
),
],
{"feedback": "optional"},
),
el(
"criterion",
[
el("name", "Content"),
el("label", "Content"),
el("prompt", "Assess the content of the submission"),
el(
"option",
[
el("name", "Poor"),
el("label", "Poor"),
el(
"explanation",
"Includes little information with few or no details or unrelated details. Unsuccessful "
"in attempts to explore any facets of the topic.",
),
],
{"points": "0"},
),
el(
"option",
[
el("name", "Fair"),
el("label", "Fair"),
el(
"explanation",
"Includes little information and few or no details. Explores only one or two facets of "
"the topic.",
),
],
{"points": "1"},
),
el(
"option",
[
el("name", "Good"),
el("label", "Good"),
el(
"explanation",
"Includes sufficient information and supporting details. (Details may not be fully "
"developed; ideas may be listed.) Explores some facets of the topic.",
),
],
{"points": "3"},
),
el(
"option",
[
el("name", "Excellent"),
el("label", "Excellent"),
el(
"explanation",
"Includes in-depth information and exceptional supporting details that are fully "
"developed. Explores all facets of the topic.",
),
],
{"points": "5"},
),
],
{"feedback": "optional"},
),
xml.dom.minidom.parseString(ideas_criterion).documentElement,
xml.dom.minidom.parseString(content_criterion).documentElement,
]
4 changes: 2 additions & 2 deletions tests/test_content_processors/test_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_get_text_response_editor_results(
@pytest.mark.parametrize(
"accepted_format_types,is_file_submission_allowed",
[
(set(), True),
(set(), False),
({"html"}, False),
({"text"}, False),
({"url"}, False),
Expand All @@ -109,7 +109,7 @@ def test_is_file_submission_allowed_results(
@pytest.mark.parametrize(
"accepted_format_types,is_textual_submission_allowed",
[
(set(), True),
(set(), False),
({"html"}, True),
({"text"}, True),
({"url"}, True),
Expand Down

0 comments on commit 9d1a3e2

Please sign in to comment.