test_if_else¶
-
test_if_else
(index=1, test=None, body=None, orelse=None, expand_message=True, use_if_exp=False, state=None)¶ Test parts of the if statement.
This test function will allow you to extract parts of a specific if statement and perform a set of tests specifically on these parts. A for loop consists of three potential parts: the condition test,
test
, which specifies the condition of the if statement, thebody
, which is what’s executed if the condition is True and a else part,orelse
, which will be executed if the condition is not True.:if 5 == 3: print("success") else: print("fail")
Has
5 == 3
as the condition test,print("success")
as the body andprint("fail")
as the else part.Parameters: - index (int) – index of the function call to be checked. Defaults to 1.
- test – this argument holds the part of code that will be ran to check the condition test of the if statement. It should be passed as a lambda expression or a function definition. The functions that are ran should be other pythonwhat test functions, and they will be tested specifically on only the condition test of the if statement.
- body – this argument holds the part of code that will be ran to check the body of the if statement. It should be passed as a lambda expression or a function definition. The functions that are ran should be other pythonwhat test functions, and they will be tested specifically on only the body of the if statement.
- orelse – this argument holds the part of code that will be ran to check the else part of the if statement. It should be passed as a lambda expression or a function definition. The functions that are ran should be other pythonwhat test functions, and they will be tested specifically on only the else part of the if statement.
- expand_message (bool) – if true, feedback messages will be expanded with
in the ___ of the if statement on line ___
. Defaults to True. If False,test_if_else()
will generate no extra feedback.
Example: Student code:
a = 12 if a > 3: print('test %d' % a)
Solution code:
a = 4 if a > 3: print('test %d' % a)
SCT:
test_if_else(1, body = test_expression_output( extra_env = { 'a': 5 } incorrect_msg = "Print out the correct things"))
This SCT will pass as
test_expression_output()
is ran on the body of the if statement and it will output the same thing in the solution as in the student code.
test_if_else(index=1,
test=None,
body=None,
orelse=None,
expand_message=True)
test_if_else()
allows you to robustly check if
statements, optionally extended with elif
and else
components. For each of the components of an if-else construct test_if_else()
takes several ‘sub-SCTs’. These ‘sub-SCTs’, that you have to pass in the form of lambda functions or through a function that defines all tests, are executed on these separate parts of the submission.
Example 1¶
Suppose an exercise asks the student to code up the following if-else construct:
*** =solution
```{python}
# a is set to 5
a = 5
# If a < 5, print out "It's small", else print out "It's big"
if a < 5:
else:
print("It's big")
```
The if-else
construct here consists of three parts:
- The condition to check:
a < 5
. Thetest
argument oftest_if_else()
specifies the sub-SCT to test this. - The body of the
if
statement:print("It's small")
. Thebody
argument oftest_if_else()
specifies the sub-SCT to test this. - The else part:
print("It's big")
. Theorelse
argument oftest_if_else()
specifies the sub-SCT to ttest this.
You can thus write our SCT as follows. Notice that for the test
argument a function is used to specify different tests; for the body
and orelse
arguments two lambda functions suffise.
*** =sct
```{python}
def sct_on_condition_test():
test_expression_result({"a": 4})
test_expression_result({"a": 5})
test_expression_result({"a": 6})
test_if_else(index = 1,
test = sct_on_condition_test,
body = lambda: test_function("print")
orelse = lambda: test_function("print"))
```
The test
part¶
Have a look at the sct_on_condition_test()
, that is used to specify the sub-SCT for the test
part of the if-else-construct, so a < 5
. It contains three calls of the test_expression_result
function. These functions are executed in a ‘narrow scope’ that only considers the condition of the student code, and the condition of the solution code.
More specifically, test_expression_result({"a": 5})
will check whether executing the if
condition that the student coded when a
equals 5 leads to the same result as executing the if
condition that is coded in the solution when a
equals 5. That way, you can robustly check the validity of the if
test. There are three test_expression_result()
calls to see if the condition makes sense for different inputs.
Suppose that the student incorrectly used the condition a < 6
instead of a < 5
. test_expression_result({"a": 5})
will see what the result is of a < 6
if a
equals 5. The result is True
. Next, it checks the result of a < 5
, the if
condition of the solution, which is False
. There is a mismatch between the ‘student result’ and the ‘solution result’, and a meaningful feedback messages is generated.
The body
and orelse
parts¶
In a similar way, the functions that are used as lambda functions in both the body
and orelse
part, will also be executed in a ‘narrow scope’, where only the body
and orelse
part of the student’s submission and the solution are used.