Skip to content

Commit e7a75af

Browse files
authored
Merge pull request #385 from datacamp/templated-expr-code
Add templated expr_code
2 parents 5599e7e + 9c7ddad commit e7a75af

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

pythonwhat/checks/has_funcs.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,12 @@ def parse_tree(tree):
230230
You can also use ``set_context()`` for this.
231231
pre_code (str): the code in string form that should be executed before the expression is executed.
232232
This is the ideal place to set a random seed, for example.
233-
expr_code (str): if this argument is set, the expression in the student/solution code will not
233+
expr_code (str): If this argument is set, the expression in the student/solution code will not
234234
be ran. Instead, the given piece of code will be ran in the student as well as the solution environment
235-
and the result will be compared.
235+
and the result will be compared. However if the string contains one or more placeholders ``__focus__``,
236+
they will be substituted by the currently focused code.
236237
name (str): If this is specified, the {0} of running this expression after running the focused expression
237-
is returned, instead of the {0} of the focussed expression in itself. This is typically used to inspect the
238+
is returned, instead of the {0} of the focused expression in itself. This is typically used to inspect the
238239
{0} of an object after executing the body of e.g. a ``for`` loop.
239240
copy (bool): whether to try to deep copy objects in the environment, such as lists, that could
240241
accidentally be mutated. Disable to speed up SCTs. Disabling may lead to cryptic mutation issues.
@@ -282,6 +283,9 @@ def has_expr(
282283
else:
283284
error_msg = DEFAULT_ERROR_MSG
284285

286+
if state.solution_code is not None and isinstance(expr_code, str):
287+
expr_code = expr_code.replace("__focus__", state.solution_code)
288+
285289
get_func = partial(
286290
evalCalls[test],
287291
extra_env=extra_env,

tests/test_messaging.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ def test_limited_stacking(sct, patt):
789789
assert message(output, patt)
790790

791791

792-
## test has_expr --------------------------------------------------------------
792+
# test has_expr --------------------------------------------------------------
793793

794794

795795
@pytest.mark.parametrize(
@@ -815,7 +815,45 @@ def test_has_expr(sct, patt):
815815
assert message(output, patt)
816816

817817

818-
## check_if_else --------------------------------------------------------------
818+
def test_has_expr_replace_focus():
819+
# Given
820+
sct = "Ex().check_if_else().check_test().has_equal_value(expr_code = '__focus__ == \\'valid\\'')"
821+
feedback_msg = "Great work!"
822+
823+
# When
824+
output = helper.run(
825+
{
826+
"DC_SOLUTION": "u = 'valid'\nif u:\n print('')",
827+
"DC_CODE": "u = 'valid'\nif u:\n print('')",
828+
"DC_SCT": sct,
829+
}
830+
)
831+
832+
# Then
833+
assert output["correct"]
834+
assert message(output, feedback_msg)
835+
836+
837+
def test_has_expr_replace_focus_fail():
838+
# Given
839+
sct = "Ex().check_if_else().check_test().has_equal_value(expr_code = '__focus__ == \\'valid\\'')"
840+
feedback_msg = "Check the first if statement. Did you correctly specify the condition? Running the expression <code>u == 'valid'</code> didn't generate the expected result." # nopep8
841+
842+
# When
843+
output = helper.run(
844+
{
845+
"DC_SOLUTION": "u = 'valid'\nif u:\n print('')",
846+
"DC_CODE": "u = 'wrong'\nif u:\n print('')",
847+
"DC_SCT": sct,
848+
}
849+
)
850+
851+
# Then
852+
assert not output["correct"]
853+
assert message(output, feedback_msg)
854+
855+
856+
# check_if_else --------------------------------------------------------------
819857

820858

821859
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)