Skip to content

Commit 5445912

Browse files
committed
Merge branch 'spec-test-object' into spec-consolidate-tasks
These were the first spec changes made, will tweak.
2 parents 57d1f36 + 4c6a05c commit 5445912

3 files changed

Lines changed: 122 additions & 121 deletions

File tree

pythonwhat/test_funcs/test_data_frame.py

Lines changed: 30 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,53 @@
33
from pythonwhat.Test import DefinedProcessTest, InstanceProcessTest, DefinedCollProcessTest, EqualValueProcessTest
44
from pythonwhat.Feedback import Feedback
55
from pythonwhat.tasks import isDefinedInProcess, isInstanceInProcess, getColumnsInProcess, getValueInProcess, ReprFail
6+
from .test_object import check_object
7+
from .test_dictionary import is_instance, test_key, has_key
68

79
import pandas as pd
810

11+
MSG_UNDEFINED = "Are you sure you defined the pandas DataFrame: `{name}`?"
12+
MSG_NOT_INSTANCE = "`{name}` is not a pandas DataFrame."
13+
MSG_KEY_MISSING = "There is no column `{key}` inside `{name}`."
14+
MSG_INCORRECT_VAL = "Column `{key}` of your pandas DataFrame, `{name}`, is not correct."
15+
916
def test_data_frame(name,
1017
columns=None,
11-
undefined_msg=None,
12-
not_data_frame_msg=None,
13-
undefined_cols_msg=None,
14-
incorrect_msg=None,
18+
undefined_msg=MSG_UNDEFINED,
19+
not_data_frame_msg=MSG_NOT_INSTANCE,
20+
undefined_cols_msg=MSG_KEY_MISSING,
21+
incorrect_msg=MSG_INCORRECT_VAL,
1522
state=None):
1623
"""Test a pandas dataframe.
1724
"""
25+
1826
rep = Reporter.active_reporter
1927
rep.set_tag("fun", "test_data_frame")
2028

21-
solution_process = state.solution_process
22-
student_process = state.student_process
23-
24-
if not isDefinedInProcess(name, solution_process):
25-
raise NameError("%r not in solution environment" % name)
26-
27-
if not isInstanceInProcess(name, pd.DataFrame, solution_process):
28-
raise ValueError("%r is not a pandas.DataFrame in the solution environment" % name)
29+
check_df(name, undefined_msg, not_data_frame_msg, state=state)
2930

31+
sol_cols = getColumnsInProcess(name, state.solution_process)
32+
if sol_cols is None:
33+
raise ValueError("Something went wrong in figuring out the columns for %s in the solution process" % name)
3034

31-
# Check if defined
32-
if not undefined_msg:
33-
undefined_msg = "Are you sure you defined the pandas DataFrame: `%s`?" % name
34-
_msg = state.build_message(undefined_msg)
35-
rep.do_test(DefinedProcessTest(name, student_process, Feedback(_msg)))
35+
# set columns or check if manual columns are valid
36+
if columns is None: columns = sol_cols
3637

37-
if not not_data_frame_msg:
38-
not_data_frame_msg = "`%s` is not a pandas DataFrame." % name
39-
_msg = state.build_message(not_data_frame_msg)
40-
rep.do_test(InstanceProcessTest(name, pd.DataFrame, student_process, Feedback(_msg)))
38+
for col in columns:
39+
# check if column available
40+
test_key(name, col, incorrect_msg, undefined_cols_msg, state=state)
4141

42-
sol_columns = getColumnsInProcess(name, solution_process)
43-
if sol_columns is None:
44-
raise ValueError("Something went wrong in figuring out the columns for %s in the solution process" % name)
42+
# Check functions -------------------------------------------------------------
4543

46-
# set columns or check if manual columns are valid
47-
if columns is None:
48-
columns = sol_columns
49-
elif set(columns) > set(sol_columns):
50-
raise NameError("Not all columns you specified are actually columns in %s in the solution process" % name)
44+
def check_df(name, undefined_msg, not_instance_msg, state=None):
45+
rep = Reporter.active_reporter
5146

52-
for column in columns:
47+
# Check if defined
48+
undefined_msg = undefined_msg.format(name=name)
5349

54-
# check if column available
55-
if not undefined_cols_msg:
56-
msg = "There is no column `%s` inside `%s`." % (column, name)
57-
else:
58-
msg = undefined_cols_msg
59-
_msg = state.build_message(msg)
60-
rep.do_test(DefinedCollProcessTest(name, column, student_process, Feedback(_msg)))
50+
# check but don't get solution object representation
51+
state = check_object(name, undefined_msg, state=state)
6152

62-
sol_value, sol_str = getValueInProcess(name, column, solution_process)
63-
if isinstance(sol_value, ReprFail):
64-
raise NameError("Value from %r can't be fetched from the solution process: %s" % c(name, sol_value.info))
53+
is_instance(name, pd.DataFrame, not_instance_msg, state=state)
6554

66-
# check if actual column ok
67-
if not incorrect_msg:
68-
msg = "Column `%s` of your pandas DataFrame, `%s`, is not correct." % (column, name)
69-
else:
70-
msg = incorrect_msg
71-
_msg = state.build_message(msg)
72-
rep.do_test(EqualValueProcessTest(name, column, student_process, sol_value, Feedback(_msg)))
55+
return state

pythonwhat/test_funcs/test_dictionary.py

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,82 @@
22
from pythonwhat.Reporter import Reporter
33
from pythonwhat.Test import DefinedProcessTest, InstanceProcessTest, DefinedCollProcessTest, EqualValueProcessTest
44
from pythonwhat.Feedback import Feedback
5-
from pythonwhat.tasks import isDefinedInProcess, isInstanceInProcess, getKeysInProcess, getValueInProcess, ReprFail
5+
from pythonwhat.tasks import isDefinedInProcess, isInstanceInProcess, getKeysInProcess, getValueInProcess, isDefinedCollInProcess, ReprFail
6+
from .test_object import check_object
7+
8+
MSG_UNDEFINED = "Are you sure you defined the dictionary `{name}`?"
9+
MSG_NOT_INSTANCE = "`{name}` is not a dictionary."
10+
MSG_KEY_MISSING = "Have you specified a key `{key}` inside `{name}`?"
11+
MSG_INCORRECT_VAL = "Have you specified the correct value for the key `{key}` inside `{name}`?"
612

713
def test_dictionary(name,
814
keys=None,
9-
undefined_msg=None,
10-
not_dictionary_msg=None,
11-
key_missing_msg=None,
12-
incorrect_value_msg=None,
15+
undefined_msg=MSG_UNDEFINED,
16+
not_dictionary_msg=MSG_NOT_INSTANCE,
17+
key_missing_msg=MSG_KEY_MISSING,
18+
incorrect_value_msg=MSG_INCORRECT_VAL,
1319
state=None):
1420
"""Test the contents of a dictionary.
1521
"""
1622

1723
rep = Reporter.active_reporter
1824
rep.set_tag("fun", "test_dictionary")
1925

20-
solution_process = state.solution_process
21-
student_process = state.student_process
26+
check_dict(name, undefined_msg, not_dictionary_msg, state=state)
27+
28+
# set keys or check if manual keys are valid
29+
if not keys:
30+
keys = getKeysInProcess(name, state.solution_process)
31+
32+
for key in keys:
33+
# check if key in dictionary
34+
test_key(name, key, incorrect_value_msg, key_missing_msg, state=state)
2235

23-
if not isDefinedInProcess(name, solution_process):
24-
raise NameError("%r not in solution environment" % name)
36+
# Check functions -------------------------------------------------------------
2537

26-
if not isInstanceInProcess(name, dict, solution_process):
27-
raise ValueError("%r is not a dictionary in the solution environment" % name)
38+
def check_dict(name, undefined_msg, not_instance_msg, state=None):
39+
rep = Reporter.active_reporter
2840

2941
# Check if defined
30-
if not undefined_msg:
31-
undefined_msg = "Are you sure you defined the dictionary `%s`?" % name
42+
undefined_msg = undefined_msg.format(name=name)
3243
_msg = state.build_message(undefined_msg)
33-
rep.do_test(DefinedProcessTest(name, student_process, Feedback(_msg)))
3444

35-
if not not_dictionary_msg:
36-
not_dictionary_msg = "`%s` is not a dictionary." % name
37-
_msg = state.build_message(not_dictionary_msg)
38-
rep.do_test(InstanceProcessTest(name, dict, student_process, Feedback(_msg)))
45+
# check but don't get solution object representation
46+
state = check_object(name, _msg, state=state)
3947

40-
sol_keys = getKeysInProcess(name, solution_process)
41-
if sol_keys is None:
42-
raise ValueError("Something went wrong in figuring out the keys for %s in the solution process" % name)
48+
is_instance(name, dict, not_instance_msg, state=state)
4349

44-
# set keys or check if manual keys are valid
45-
if keys is None:
46-
keys = sol_keys
47-
elif set(keys) > set(sol_keys):
50+
return state
51+
52+
def is_instance(name, inst, not_instance_msg, state=None):
53+
rep = Reporter.active_reporter
54+
55+
if not isInstanceInProcess(name, inst, state.solution_process):
56+
raise ValueError("%r is not a %s in the solution environment" % (name, type(inst)))
57+
58+
feedback = Feedback(not_instance_msg.format(name=name))
59+
rep.do_test(InstanceProcessTest(name, inst, state.student_process, feedback))
60+
61+
def has_key(name, key, key_missing_msg, state=None):
62+
rep = Reporter.active_reporter
63+
64+
if not isDefinedCollInProcess(name, key, state.solution_process):
4865
raise NameError("Not all keys you specified are actually keys in %s in the solution process" % name)
4966

50-
# Check if keys and values ok
51-
for key in keys:
67+
# check if key available
68+
msg = key_missing_msg.format(key=key, name=name)
69+
rep.do_test(DefinedCollProcessTest(name, key, state.student_process, Feedback(msg)))
70+
71+
def test_key(name, key, incorrect_value_msg, key_missing_msg, state=None):
72+
rep = Reporter.active_reporter
73+
74+
has_key(name, key, key_missing_msg, state=state)
75+
76+
sol_value, sol_str = getValueInProcess(name, key, state.solution_process)
77+
if isinstance(sol_value, ReprFail):
78+
raise NameError("Value from %r can't be fetched from the solution process: %s" % c(name, sol_value.info))
5279

53-
# check if key available
54-
if not key_missing_msg:
55-
msg = "Have you specified a key `%s` inside `%s`?" % (str(key), name)
56-
else:
57-
msg = key_missing_msg
58-
_msg = state.build_message(msg)
59-
rep.do_test(DefinedCollProcessTest(name, key, student_process, Feedback(_msg)))
60-
61-
62-
sol_value, sol_str = getValueInProcess(name, key, solution_process)
63-
if isinstance(sol_value, ReprFail):
64-
raise NameError("Value from %r can't be fetched from the solution process: %s" % c(name, sol_value.info))
65-
66-
# check if value ok
67-
if not incorrect_value_msg:
68-
msg = "Have you specified the correct value for the key `%s` inside `%s`?" % (str(key), name)
69-
else:
70-
msg = incorrect_value_msg
71-
_msg = state.build_message(msg)
72-
rep.do_test(EqualValueProcessTest(name, key, student_process, sol_value, Feedback(_msg)))
80+
# check if value ok
81+
msg = incorrect_value_msg.format(key=key, name=name)
82+
_msg = state.build_message(msg)
83+
rep.do_test(EqualValueProcessTest(name, key, state.student_process, sol_value, Feedback(_msg)))

pythonwhat/test_funcs/test_object.py

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,46 +44,53 @@ def test_object(name,
4444
rep = Reporter.active_reporter
4545
rep.set_tag("fun", "test_object")
4646

47-
student_obj_ass = state.student_object_assignments
47+
state = check_object(name, undefined_msg, do_eval=do_eval, state=state)
4848

49-
if not undefined_msg:
50-
undefined_msg = "Have you defined `%s`?" % name
49+
if do_eval:
50+
is_equal(name, incorrect_msg, state)
5151

52-
if not incorrect_msg:
53-
incorrect_msg = "The contents of `%s` aren't correct." % name
52+
def get_assignment_node(obj_ass, name):
53+
nodes = obj_ass[name] if name in obj_ass else None
54+
55+
# found a single case of assigning name
56+
if nodes and len(nodes) == 1:
57+
return nodes[0]
5458

55-
eq_map = {"equal": EqualProcessTest}
56-
student_process = state.student_process
57-
solution_process = state.solution_process
59+
# Check functions -------------------------------------------------------------
5860

59-
if eq_condition not in eq_map:
60-
raise NameError("%r not a valid equality condition " % eq_condition)
61+
MSG_UNDEFINED = "Have you defined `{name}`?"
62+
MSG_INCORRECT = "The contents of `{name}` aren't correct."
63+
64+
def check_object(name, undefined_msg, do_eval=True, state=None):
65+
rep = Reporter.active_reporter
66+
if not undefined_msg:
67+
undefined_msg = MSG_UNDEFINED.format(name=name)
6168

62-
if not isDefinedInProcess(name, solution_process):
69+
if not isDefinedInProcess(name, state.solution_process):
6370
raise NameError("%r not in solution environment " % name)
6471

6572
_msg = state.build_message(undefined_msg)
66-
rep.do_test(DefinedProcessTest(name, student_process, Feedback(_msg)))
73+
rep.do_test(DefinedProcessTest(name, state.student_process, Feedback(_msg)))
6774

6875
if do_eval:
69-
ass_node = get_assignment_node(student_obj_ass, name)
70-
71-
sol_obj = getRepresentation(name, solution_process)
76+
sol_obj = getRepresentation(name, state.solution_process)
7277
if isinstance(sol_obj, ReprFail):
7378
raise NameError(sol_obj.info)
7479

75-
_msg = state.build_message(incorrect_msg)
76-
rep.do_test(eq_map[eq_condition](name,
77-
student_process,
78-
sol_obj,
79-
Feedback(_msg, ass_node)))
80+
state.solution_object = sol_obj
81+
82+
return state
8083

81-
def get_assignment_node(student_obj_ass, name):
82-
if (name not in student_obj_ass):
83-
return(None)
84+
def is_equal(name, incorrect_msg, state=None):
85+
rep = Reporter.active_reporter
86+
if not incorrect_msg:
87+
incorrect_msg = MSG_INCORRECT.format(name=name)
8488

85-
# For now, only pass along node if single assignment
86-
if (len(student_obj_ass[name]) != 1):
87-
return(None)
89+
ass_node = get_assignment_node(state.student_object_assignments, name)
90+
_msg = state.build_message(incorrect_msg)
91+
rep.do_test(EqualProcessTest(name,
92+
state.student_process,
93+
state.solution_object,
94+
Feedback(_msg, ass_node)))
95+
return state
8896

89-
return(student_obj_ass[name][0])

0 commit comments

Comments
 (0)