Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions sensors_diff/.gitmastery-exercise.json
Original file line number Diff line number Diff line change
@@ -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
}
}
16 changes: 16 additions & 0 deletions sensors_diff/README.md
Original file line number Diff line number Diff line change
@@ -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

<details>
<summary>How do I see what's staged vs unstaged?</summary>

Use `git status` to see which files are staged and which are modified but unstaged.

</details>
Empty file added sensors_diff/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions sensors_diff/download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from exercise_utils.git import add

__resources__ = {
"south.csv": "south.csv",
"north.csv": "north.csv",
"west.csv": "west.csv",
}


def setup(verbose: bool = False):
add(["north.csv"], verbose)
11 changes: 11 additions & 0 deletions sensors_diff/res/answers.txt
Original file line number Diff line number Diff line change
@@ -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:
20 changes: 20 additions & 0 deletions sensors_diff/res/north.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
6841
2307
9754
4169
5823
3086
7590
8420
1679
5034
2918
7645
8301
4576
9208
3461
5789
6940
1235
8890
20 changes: 20 additions & 0 deletions sensors_diff/res/south.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
7412
5068
8921
3754
2809
6197
4531
9674
1185
7326
5401
8937
2640
7083
5914
3208
8745
4069
1592
6831
20 changes: 20 additions & 0 deletions sensors_diff/res/west.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
5193
8042
6721
4389
2075
9510
3642
7281
5904
1837
4416
9032
7765
6208
3589
8471
2940
1683
7352
5129
Empty file added sensors_diff/tests/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions sensors_diff/tests/specs/base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
initialization:
steps:
- type: commit
empty: true
message: Empty commit
id: start
205 changes: 205 additions & 0 deletions sensors_diff/tests/test_verify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
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),
],
)
48 changes: 48 additions & 0 deletions sensors_diff/verify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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,
)