From 0348b499475df4c96cb0e4896593c7a775f84e7b Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Thu, 11 Dec 2025 13:10:03 +0800 Subject: [PATCH 1/3] [sensors-diff] Implement download and verification logic --- sensors_diff/.gitmastery-exercise.json | 18 ++++++ sensors_diff/README.md | 16 +++++ sensors_diff/__init__.py | 0 sensors_diff/download.py | 84 ++++++++++++++++++++++++++ sensors_diff/res/answers.txt | 11 ++++ sensors_diff/verify.py | 38 ++++++++++++ 6 files changed, 167 insertions(+) create mode 100644 sensors_diff/.gitmastery-exercise.json create mode 100644 sensors_diff/README.md create mode 100644 sensors_diff/__init__.py create mode 100644 sensors_diff/download.py create mode 100644 sensors_diff/res/answers.txt create mode 100644 sensors_diff/verify.py diff --git a/sensors_diff/.gitmastery-exercise.json b/sensors_diff/.gitmastery-exercise.json new file mode 100644 index 0000000..ad8d4be --- /dev/null +++ b/sensors_diff/.gitmastery-exercise.json @@ -0,0 +1,18 @@ +{ + "exercise_name": "sensors-diff", + "tags": [ + "git-diff" + ], + "requires_git": true, + "requires_github": true, + "base_files": { + "answers.txt": "answers.txt" + }, + "exercise_repo": { + "repo_type": "remote", + "repo_name": "sensors", + "repo_title": "gm-sensors", + "create_fork": false, + "init": null + } +} \ No newline at end of file diff --git a/sensors_diff/README.md b/sensors_diff/README.md new file mode 100644 index 0000000..9198ba4 --- /dev/null +++ b/sensors_diff/README.md @@ -0,0 +1,16 @@ +# sensors-diff + +A system is using Git to record data received daily from for sensors, each monitoring one of directions east, west, north, south. Each sensor provides 20 integer values, which are stored in a csv file (e.g., values from the sensor monitoring the east direction are recorded as `east.csv`). Data for each day is recorded as one commit. + +## Task + +Examine the revision history to answer the questions in `answers.txt`. + +## Hints + +
+How do I see what's staged vs unstaged? + +Use `git status` to see which files are staged and which are modified but unstaged. + +
diff --git a/sensors_diff/__init__.py b/sensors_diff/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sensors_diff/download.py b/sensors_diff/download.py new file mode 100644 index 0000000..0a0a98b --- /dev/null +++ b/sensors_diff/download.py @@ -0,0 +1,84 @@ +from exercise_utils.git import add +from exercise_utils.file import create_or_update_file + + +def setup(verbose: bool = False): + create_or_update_file( + "west.csv", + """ + 5193 + 8042 + 6721 + 4389 + 2075 + 9510 + 3642 + 7281 + 5904 + 1837 + 4416 + 9032 + 7765 + 6208 + 3589 + 8471 + 2940 + 1683 + 7352 + 5129 + """, + ) + + create_or_update_file( + "north.csv", + """ + 6841 + 2307 + 9754 + 4169 + 5823 + 3086 + 7590 + 8420 + 1679 + 5034 + 2918 + 7645 + 8301 + 4576 + 9208 + 3461 + 5789 + 6940 + 1235 + 8890 + """, + ) + + create_or_update_file( + "south.csv", + """ + 7412 + 5068 + 8921 + 3754 + 2809 + 6197 + 4531 + 9674 + 1185 + 7326 + 5401 + 8937 + 2640 + 7083 + 5914 + 3208 + 8745 + 4069 + 1592 + 6831 + """, + ) + + add(["north.csv"], verbose) \ No newline at end of file diff --git a/sensors_diff/res/answers.txt b/sensors_diff/res/answers.txt new file mode 100644 index 0000000..6219e37 --- /dev/null +++ b/sensors_diff/res/answers.txt @@ -0,0 +1,11 @@ +Q: Which are the new values in staged files? +A: + +Q: Which are the new values in modified but unstaged files? +A: + +Q: Which files have changed from Jan 09th to Jan 15th? +A: + +Q: Which new values are new in north.csv on Jan 10th, compared to Jan 01st? +A: diff --git a/sensors_diff/verify.py b/sensors_diff/verify.py new file mode 100644 index 0000000..34045a5 --- /dev/null +++ b/sensors_diff/verify.py @@ -0,0 +1,38 @@ +from git_autograder import ( + GitAutograderOutput, + GitAutograderExercise, + GitAutograderStatus, +) +from git_autograder.answers.rules import HasExactValueRule, NotEmptyRule, HasExactListRule + +QUESTION_ONE = "Which are the new values in staged files?" +QUESTION_TWO = "Which are the new values in modified but unstaged files?" +QUESTION_THREE = "Which files have changed from Jan 09th to Jan 15th?" +QUESTION_FOUR = "Which new values are new in north.csv on Jan 10th, compared to Jan 01st?" +SUCCESS_MESSAGE = "Great work comparing commits in git history!" + +def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: + ( + exercise.answers.add_validation(QUESTION_ONE, NotEmptyRule()) + .add_validation( + QUESTION_ONE, + HasExactValueRule("7590", is_case_sensitive=True)) + .add_validation( + QUESTION_TWO, + NotEmptyRule(), + HasExactListRule(["4531", "3642"], is_case_sensitive=True)) + .add_validation( + QUESTION_THREE, + NotEmptyRule(), + HasExactListRule(["north.csv", "south.csv", "west.csv"], is_case_sensitive=True)) + .add_validation( + QUESTION_FOUR, + NotEmptyRule(), + HasExactValueRule("3471", is_case_sensitive=True)) + .validate() + ) + + return exercise.to_output( + [SUCCESS_MESSAGE], + GitAutograderStatus.SUCCESSFUL, + ) From 3c7258fed44ad93883c37af1e09dd5f31d358aa1 Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Thu, 11 Dec 2025 13:10:22 +0800 Subject: [PATCH 2/3] [sensors-diff] Add repo-smith tests for exercise --- sensors_diff/tests/__init__.py | 0 sensors_diff/tests/specs/base.yml | 6 + sensors_diff/tests/test_verify.py | 202 ++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 sensors_diff/tests/__init__.py create mode 100644 sensors_diff/tests/specs/base.yml create mode 100644 sensors_diff/tests/test_verify.py diff --git a/sensors_diff/tests/__init__.py b/sensors_diff/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sensors_diff/tests/specs/base.yml b/sensors_diff/tests/specs/base.yml new file mode 100644 index 0000000..00c3a53 --- /dev/null +++ b/sensors_diff/tests/specs/base.yml @@ -0,0 +1,6 @@ +initialization: + steps: + - type: commit + empty: true + message: Empty commit + id: start diff --git a/sensors_diff/tests/test_verify.py b/sensors_diff/tests/test_verify.py new file mode 100644 index 0000000..5e8aff0 --- /dev/null +++ b/sensors_diff/tests/test_verify.py @@ -0,0 +1,202 @@ +from git_autograder.answers.rules import NotEmptyRule, HasExactValueRule, HasExactListRule +from git_autograder.status import GitAutograderStatus +from git_autograder.test_utils import assert_output +from git_autograder import GitAutograderTestLoader + +from ..verify import QUESTION_ONE, QUESTION_TWO, QUESTION_THREE, QUESTION_FOUR, SUCCESS_MESSAGE, verify + +REPOSITORY_NAME = "sensors-diff" + +loader = GitAutograderTestLoader(__file__, REPOSITORY_NAME, verify) + +CORRECT_QUESTION_ONE_ANSWER = "7590" +CORRECT_QUESTION_TWO_ANSWER = """ +- 3642 +- 4531 +""" +CORRECT_QUESTION_TWO_ANSWER_DIFFERENT_ORDER = """ +- 4531 +- 3642 +""" +INCORRECT_QUESTION_TWO_MISSING_VALUE = """ +- 4531 +""" +CORRECT_QUESTION_THREE_ANSWER = """ +- south.csv +- north.csv +- west.csv +""" +CORRECT_QUESTION_FOUR_ANSWER = "3471" +INCORRECT_ANSWER = "incorrect answer" + + +def test_valid_answers(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, + QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, + QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.SUCCESSFUL, + [SUCCESS_MESSAGE] + ) + + +def test_valid_answers_different_order(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER_DIFFERENT_ORDER, + QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, + QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.SUCCESSFUL, + [SUCCESS_MESSAGE] + ) + + +def test_no_answers(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: "", + QUESTION_TWO: "", + QUESTION_THREE: "", + QUESTION_FOUR: "", + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + NotEmptyRule.EMPTY.format(question=QUESTION_ONE), + NotEmptyRule.EMPTY.format(question=QUESTION_TWO), + NotEmptyRule.EMPTY.format(question=QUESTION_THREE), + NotEmptyRule.EMPTY.format(question=QUESTION_FOUR), + ] + ) + + +def test_incomplete_answers(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: "", + QUESTION_THREE: "", + QUESTION_FOUR: "", + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + NotEmptyRule.EMPTY.format(question=QUESTION_TWO), + NotEmptyRule.EMPTY.format(question=QUESTION_THREE), + NotEmptyRule.EMPTY.format(question=QUESTION_FOUR), + ] + ) + + +def test_incorrect_question_one_answer(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: INCORRECT_ANSWER, + QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, + QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, + QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + HasExactValueRule.NOT_EXACT.format(question=QUESTION_ONE), + ] + ) + + +def test_incorrect_question_two_answer(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: INCORRECT_ANSWER, + QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, + QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + HasExactListRule.INCORRECT_UNORDERED.format(question=QUESTION_TWO), + ] + ) + + +def test_incorrect_question_two_answer_missing_value(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: INCORRECT_QUESTION_TWO_MISSING_VALUE, + QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, + QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + HasExactListRule.INCORRECT_UNORDERED.format(question=QUESTION_TWO), + ] + ) + + +def test_incorrect_question_three_answer(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, + QUESTION_THREE: INCORRECT_ANSWER, + QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + HasExactListRule.INCORRECT_UNORDERED.format(question=QUESTION_THREE), + ] + ) + + +def test_incorrect_question_four_answer(): + with loader.load( + "specs/base.yml", + mock_answers={ + QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, + QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, + QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, + QUESTION_FOUR: INCORRECT_ANSWER, + } + ) as output: + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [ + HasExactValueRule.NOT_EXACT.format(question=QUESTION_FOUR), + ] + ) From c38c1fcfdaa53773e1bf825e292c27fcc427ff36 Mon Sep 17 00:00:00 2001 From: jovnc <95868357+jovnc@users.noreply.github.com> Date: Thu, 11 Dec 2025 18:14:23 +0800 Subject: [PATCH 3/3] [sensors-diff] Refactor download.py to use __resources__ and run ruff linter --- sensors_diff/download.py | 87 +++---------------------------- sensors_diff/res/north.csv | 20 +++++++ sensors_diff/res/south.csv | 20 +++++++ sensors_diff/res/west.csv | 20 +++++++ sensors_diff/tests/test_verify.py | 79 ++++++++++++++-------------- sensors_diff/verify.py | 28 ++++++---- 6 files changed, 127 insertions(+), 127 deletions(-) create mode 100644 sensors_diff/res/north.csv create mode 100644 sensors_diff/res/south.csv create mode 100644 sensors_diff/res/west.csv diff --git a/sensors_diff/download.py b/sensors_diff/download.py index 0a0a98b..a3896c0 100644 --- a/sensors_diff/download.py +++ b/sensors_diff/download.py @@ -1,84 +1,11 @@ from exercise_utils.git import add -from exercise_utils.file import create_or_update_file +__resources__ = { + "south.csv": "south.csv", + "north.csv": "north.csv", + "west.csv": "west.csv", +} -def setup(verbose: bool = False): - create_or_update_file( - "west.csv", - """ - 5193 - 8042 - 6721 - 4389 - 2075 - 9510 - 3642 - 7281 - 5904 - 1837 - 4416 - 9032 - 7765 - 6208 - 3589 - 8471 - 2940 - 1683 - 7352 - 5129 - """, - ) - - create_or_update_file( - "north.csv", - """ - 6841 - 2307 - 9754 - 4169 - 5823 - 3086 - 7590 - 8420 - 1679 - 5034 - 2918 - 7645 - 8301 - 4576 - 9208 - 3461 - 5789 - 6940 - 1235 - 8890 - """, - ) - create_or_update_file( - "south.csv", - """ - 7412 - 5068 - 8921 - 3754 - 2809 - 6197 - 4531 - 9674 - 1185 - 7326 - 5401 - 8937 - 2640 - 7083 - 5914 - 3208 - 8745 - 4069 - 1592 - 6831 - """, - ) - - add(["north.csv"], verbose) \ No newline at end of file +def setup(verbose: bool = False): + add(["north.csv"], verbose) diff --git a/sensors_diff/res/north.csv b/sensors_diff/res/north.csv new file mode 100644 index 0000000..93a6a92 --- /dev/null +++ b/sensors_diff/res/north.csv @@ -0,0 +1,20 @@ +6841 +2307 +9754 +4169 +5823 +3086 +7590 +8420 +1679 +5034 +2918 +7645 +8301 +4576 +9208 +3461 +5789 +6940 +1235 +8890 \ No newline at end of file diff --git a/sensors_diff/res/south.csv b/sensors_diff/res/south.csv new file mode 100644 index 0000000..60eabd4 --- /dev/null +++ b/sensors_diff/res/south.csv @@ -0,0 +1,20 @@ +7412 +5068 +8921 +3754 +2809 +6197 +4531 +9674 +1185 +7326 +5401 +8937 +2640 +7083 +5914 +3208 +8745 +4069 +1592 +6831 \ No newline at end of file diff --git a/sensors_diff/res/west.csv b/sensors_diff/res/west.csv new file mode 100644 index 0000000..3da0d79 --- /dev/null +++ b/sensors_diff/res/west.csv @@ -0,0 +1,20 @@ +5193 +8042 +6721 +4389 +2075 +9510 +3642 +7281 +5904 +1837 +4416 +9032 +7765 +6208 +3589 +8471 +2940 +1683 +7352 +5129 diff --git a/sensors_diff/tests/test_verify.py b/sensors_diff/tests/test_verify.py index 5e8aff0..c9fa37d 100644 --- a/sensors_diff/tests/test_verify.py +++ b/sensors_diff/tests/test_verify.py @@ -1,9 +1,20 @@ -from git_autograder.answers.rules import NotEmptyRule, HasExactValueRule, HasExactListRule +from git_autograder.answers.rules import ( + NotEmptyRule, + HasExactValueRule, + HasExactListRule, +) from git_autograder.status import GitAutograderStatus from git_autograder.test_utils import assert_output from git_autograder import GitAutograderTestLoader -from ..verify import QUESTION_ONE, QUESTION_TWO, QUESTION_THREE, QUESTION_FOUR, SUCCESS_MESSAGE, verify +from ..verify import ( + QUESTION_ONE, + QUESTION_TWO, + QUESTION_THREE, + QUESTION_FOUR, + SUCCESS_MESSAGE, + verify, +) REPOSITORY_NAME = "sensors-diff" @@ -32,47 +43,39 @@ def test_valid_answers(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, - } + }, ) as output: - assert_output( - output, - GitAutograderStatus.SUCCESSFUL, - [SUCCESS_MESSAGE] - ) + assert_output(output, GitAutograderStatus.SUCCESSFUL, [SUCCESS_MESSAGE]) def test_valid_answers_different_order(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER_DIFFERENT_ORDER, QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, - } + }, ) as output: - assert_output( - output, - GitAutograderStatus.SUCCESSFUL, - [SUCCESS_MESSAGE] - ) + assert_output(output, GitAutograderStatus.SUCCESSFUL, [SUCCESS_MESSAGE]) -def test_no_answers(): +def test_no_answers(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: "", QUESTION_TWO: "", QUESTION_THREE: "", QUESTION_FOUR: "", - } + }, ) as output: assert_output( output, @@ -82,19 +85,19 @@ def test_no_answers(): NotEmptyRule.EMPTY.format(question=QUESTION_TWO), NotEmptyRule.EMPTY.format(question=QUESTION_THREE), NotEmptyRule.EMPTY.format(question=QUESTION_FOUR), - ] + ], ) def test_incomplete_answers(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: "", QUESTION_THREE: "", QUESTION_FOUR: "", - } + }, ) as output: assert_output( output, @@ -103,100 +106,100 @@ def test_incomplete_answers(): NotEmptyRule.EMPTY.format(question=QUESTION_TWO), NotEmptyRule.EMPTY.format(question=QUESTION_THREE), NotEmptyRule.EMPTY.format(question=QUESTION_FOUR), - ] + ], ) def test_incorrect_question_one_answer(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: INCORRECT_ANSWER, QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, - } + }, ) as output: assert_output( output, GitAutograderStatus.UNSUCCESSFUL, [ HasExactValueRule.NOT_EXACT.format(question=QUESTION_ONE), - ] + ], ) def test_incorrect_question_two_answer(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: INCORRECT_ANSWER, QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, - } + }, ) as output: assert_output( output, GitAutograderStatus.UNSUCCESSFUL, [ HasExactListRule.INCORRECT_UNORDERED.format(question=QUESTION_TWO), - ] + ], ) def test_incorrect_question_two_answer_missing_value(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: INCORRECT_QUESTION_TWO_MISSING_VALUE, QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, - } + }, ) as output: assert_output( output, GitAutograderStatus.UNSUCCESSFUL, [ HasExactListRule.INCORRECT_UNORDERED.format(question=QUESTION_TWO), - ] + ], ) def test_incorrect_question_three_answer(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, QUESTION_THREE: INCORRECT_ANSWER, QUESTION_FOUR: CORRECT_QUESTION_FOUR_ANSWER, - } + }, ) as output: assert_output( output, GitAutograderStatus.UNSUCCESSFUL, [ HasExactListRule.INCORRECT_UNORDERED.format(question=QUESTION_THREE), - ] + ], ) def test_incorrect_question_four_answer(): with loader.load( - "specs/base.yml", + "specs/base.yml", mock_answers={ QUESTION_ONE: CORRECT_QUESTION_ONE_ANSWER, QUESTION_TWO: CORRECT_QUESTION_TWO_ANSWER, QUESTION_THREE: CORRECT_QUESTION_THREE_ANSWER, QUESTION_FOUR: INCORRECT_ANSWER, - } + }, ) as output: assert_output( output, GitAutograderStatus.UNSUCCESSFUL, [ HasExactValueRule.NOT_EXACT.format(question=QUESTION_FOUR), - ] + ], ) diff --git a/sensors_diff/verify.py b/sensors_diff/verify.py index 34045a5..63149c1 100644 --- a/sensors_diff/verify.py +++ b/sensors_diff/verify.py @@ -3,32 +3,42 @@ GitAutograderExercise, GitAutograderStatus, ) -from git_autograder.answers.rules import HasExactValueRule, NotEmptyRule, HasExactListRule +from git_autograder.answers.rules import ( + HasExactValueRule, + NotEmptyRule, + HasExactListRule, +) QUESTION_ONE = "Which are the new values in staged files?" QUESTION_TWO = "Which are the new values in modified but unstaged files?" QUESTION_THREE = "Which files have changed from Jan 09th to Jan 15th?" -QUESTION_FOUR = "Which new values are new in north.csv on Jan 10th, compared to Jan 01st?" +QUESTION_FOUR = ( + "Which new values are new in north.csv on Jan 10th, compared to Jan 01st?" +) SUCCESS_MESSAGE = "Great work comparing commits in git history!" -def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: + +def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: ( exercise.answers.add_validation(QUESTION_ONE, NotEmptyRule()) - .add_validation( - QUESTION_ONE, - HasExactValueRule("7590", is_case_sensitive=True)) + .add_validation(QUESTION_ONE, HasExactValueRule("7590", is_case_sensitive=True)) .add_validation( QUESTION_TWO, NotEmptyRule(), - HasExactListRule(["4531", "3642"], is_case_sensitive=True)) + HasExactListRule(["4531", "3642"], is_case_sensitive=True), + ) .add_validation( QUESTION_THREE, NotEmptyRule(), - HasExactListRule(["north.csv", "south.csv", "west.csv"], is_case_sensitive=True)) + HasExactListRule( + ["north.csv", "south.csv", "west.csv"], is_case_sensitive=True + ), + ) .add_validation( QUESTION_FOUR, NotEmptyRule(), - HasExactValueRule("3471", is_case_sensitive=True)) + HasExactValueRule("3471", is_case_sensitive=True), + ) .validate() )