Skip to content

Commit cbb9ecb

Browse files
authored
Merge pull request #30 from datacamp/jh/protowhat-update
Update to latest protowhat
2 parents cdafae2 + 404d2aa commit cbb9ecb

25 files changed

+617
-432
lines changed

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[pytest]
2-
testpaths = tests
2+
testpaths = tests/

requirements.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# pkg deps
2-
protowhat==1.3.0
3-
attrs==18.2.0
4-
glom==18.3.1
2+
protowhat~=1.7.0
3+
attrs~=18.2.0
4+
glom~=18.3.1
55

66
# test deps
7-
pytest==3.7.4
8-
codecov==2.0.15
9-
pytest-cov==2.5.1
7+
pytest~=3.7.4
8+
codecov~=2.0.15
9+
pytest-cov~=2.5.1
1010

1111
# doc deps
12-
sphinx==1.7.7
13-
sphinx_rtd_theme==v0.4.1
12+
sphinx~=1.7.7
13+
sphinx_rtd_theme~=0.4.1

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
VERSION = str(ast.literal_eval(_version_re.search(fp.read()).group(1)))
1919
with open(REQUIREMENTS_FILE, encoding="utf-8") as fp:
2020
req_txt = fp.read()
21-
_requirements_re_template = r"^({}(?:\s*[<>=]+\s*\S*)?)\s*(?:#.*)?$"
21+
_requirements_re_template = r"^({}(?:\s*[~<>=]+\s*\S*)?)\s*(?:#.*)?$"
2222
REQUIREMENTS = [
2323
re.search(_requirements_re_template.format(requirement), req_txt, re.M).group(0)
2424
for requirement in REQUIREMENT_NAMES

sheetwhat/Reporter.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

sheetwhat/State.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
1+
from protowhat.Feedback import Feedback
12
from protowhat.State import State as BaseState
23
import copy
34

5+
from protowhat.Test import Fail
6+
7+
from sheetwhat.selectors import Dispatcher
8+
49

510
class State(BaseState):
6-
def __init__(self, student_data, solution_data, sct_range, reporter):
11+
def __init__(
12+
self, student_data, solution_data, sct_range, reporter, force_diagnose=False
13+
):
714
self.student_data = student_data
815
self.solution_data = solution_data
916
self.sct_range = sct_range
1017
self.reporter = reporter
18+
self.messages = []
19+
self.dispatcher = Dispatcher()
1120
self.node_name = "root"
12-
self.root_message = ""
13-
14-
def set_root_message(self, message):
15-
assert isinstance(message, str)
16-
self.root_message = message
21+
self.force_diagnose = force_diagnose
1722

18-
def do_test(self, message_or_issues, *args, **kwargs):
19-
is_list = isinstance(message_or_issues, list)
20-
is_str = isinstance(message_or_issues, str)
21-
assert is_list or is_str
22-
if is_list:
23-
return self.reporter.do_test(
24-
self.root_message, message_or_issues, *args, **kwargs
25-
)
26-
if is_str:
27-
return self.reporter.do_test(message_or_issues)
23+
def report(self, feedback: str):
24+
return self.do_test(Fail(Feedback(feedback)))
2825

29-
def to_child(self, student_data, solution_data, node_name=None):
26+
def to_child(self, append_message="", node_name=None, **kwargs):
3027
"""Basic implementation of returning a child state"""
3128
child = copy.deepcopy(self)
32-
child.student_data = student_data
33-
child.solution_data = solution_data
29+
for kwarg in kwargs:
30+
setattr(child, kwarg, kwargs[kwarg])
3431
child.node_name = node_name
35-
child.parent = self
32+
if not isinstance(append_message, dict):
33+
append_message = {"msg": append_message, "kwargs": {}}
34+
child.messages = [*self.messages, append_message]
3635
return child
3736

3837
def to_message_exposed_dict(self):

sheetwhat/Test.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import copy
2+
3+
from abc import ABC
4+
5+
from protowhat import selectors
6+
from protowhat.Test import Test
7+
from protowhat.Feedback import Feedback
8+
9+
from sheetwhat.utils import is_empty
10+
11+
12+
class SolutionBasedTest(Test, ABC):
13+
def __init__(self, student_data, solution_data, feedback):
14+
super().__init__(feedback)
15+
self.student_data = student_data
16+
self.solution_data = solution_data
17+
18+
def __repr__(self):
19+
return f"{self.__class__.__name__}:" \
20+
f"student data = {self.student_data}" \
21+
f"solution data = {self.solution_data}"
22+
23+
24+
def array_element_tests(test, student_data, solution_data, feedback, *args, **kwargs):
25+
tests = []
26+
if not isinstance(student_data, list) or not isinstance(solution_data, list):
27+
# If student data is None; Feedback will be provided by a different test.
28+
return tests
29+
for i, (element_student_data, element_solution_data) in enumerate(
30+
zip(student_data, solution_data)
31+
):
32+
if isinstance(feedback, str):
33+
item_feedback = Feedback(feedback)
34+
else:
35+
item_feedback = copy.deepcopy(feedback)
36+
item_feedback.message = item_feedback.message.format(
37+
ordinal=selectors.get_ord(i + 1),
38+
expected=element_solution_data,
39+
actual=element_student_data,
40+
)
41+
tests.append(
42+
test(
43+
element_student_data,
44+
element_solution_data,
45+
item_feedback,
46+
*args,
47+
**kwargs,
48+
)
49+
)
50+
return tests
51+
52+
53+
class ArrayEqualLengthTest(SolutionBasedTest):
54+
def test(self):
55+
if (
56+
not isinstance(self.student_data, list)
57+
or not isinstance(self.solution_data, list)
58+
or len(self.solution_data) == 0
59+
):
60+
self.result = True
61+
else:
62+
solution_array_len = len(self.solution_data)
63+
student_array_len = len(self.student_data)
64+
if solution_array_len != student_array_len:
65+
self.result = False
66+
self.feedback.message = self.feedback.message.format(
67+
expected=solution_array_len, actual=student_array_len
68+
)
69+
else:
70+
self.result = True
71+
72+
73+
class DictKeyEqualityTest(SolutionBasedTest):
74+
def test(self):
75+
if not isinstance(self.student_data, dict) or not isinstance(
76+
self.solution_data, dict
77+
):
78+
self.result = True
79+
else:
80+
solution_key_set = set(self.solution_data.keys())
81+
student_key_set = set(self.student_data.keys())
82+
if solution_key_set != student_key_set:
83+
self.result = False
84+
self.feedback.message = self.feedback.message.format(
85+
solution_keys=solution_key_set, student_keys=student_key_set
86+
)
87+
else:
88+
self.result = True
89+
90+
91+
class EqualityTest(SolutionBasedTest):
92+
def __init__(
93+
self, student_data, solution_data, feedback, equal_func=lambda x, y: x == y
94+
):
95+
super().__init__(student_data, solution_data, feedback)
96+
self.equal_func = equal_func
97+
98+
def test(self):
99+
if self.equal_func(self.student_data, self.solution_data):
100+
self.result = True
101+
else:
102+
self.result = False
103+
self.feedback.message = self.feedback.message.format(
104+
expected=self.solution_data, actual=self.student_data
105+
)
106+
107+
108+
class ExistenceTest(SolutionBasedTest):
109+
def test(self):
110+
if not is_empty(self.solution_data) and is_empty(self.student_data):
111+
self.result = False
112+
else:
113+
self.result = True
114+
115+
116+
class OverExistenceTest(SolutionBasedTest):
117+
def test(self):
118+
if is_empty(self.solution_data) and not is_empty(self.student_data):
119+
self.result = False
120+
else:
121+
self.result = True
122+
123+
124+
class SetEqualityTest(SolutionBasedTest):
125+
def test(self):
126+
if not isinstance(self.student_data, list) or not isinstance(
127+
self.solution_data, list
128+
):
129+
self.result = True
130+
else:
131+
solution_set = set(self.solution_data)
132+
student_set = set(self.student_data)
133+
if solution_set != student_set:
134+
self.result = False
135+
else:
136+
self.result = True

sheetwhat/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
__version__ = "0.4.0"
2-

sheetwhat/checks/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
# - no check_file related functionality
2828
from protowhat.checks.check_logic import fail, multi, check_not, check_or, check_correct
2929
from protowhat.checks.check_simple import has_chosen, success_msg
30+
from protowhat.utils import _debug

0 commit comments

Comments
 (0)