This function, implemented in checks/func_check.py, subjects a function written by a student to a list of
tests provided by the teacher. This ensures that the implementation of the function is correct for any valid
arguments, and because the students do not know what these tests will be, they cannot "cheat" or write
over-specialised code.
When this check is used (if the check_func field is set in the parameters), the answer
provided by the teacher is interpreted differently. It must contain at least two items:
- A function with the same name as the
check_funcparameter, which provides a "reference implementation" that all the tests are run against. - A variable called
tests, which is a list of tuples. Each tuple represents an individual test case, and the values in the tuple are the arguments that will be passed to the function for each case. If the function takes only one argument, it is not necessary to wrap it in a tuple.
For each test case in the tests variable, the student's response function and the reference function will both
be evaluated with the arguments for that case. Their return values will then be compared.
By default, this comparison is done using the == operator, and there is a built-in special case for
NumPy arrays. If a more advanced comparison is required, the answer can include a function called equals.
This function takes two arguments and returns a boolean indicating if its arguments were considered equal.
If this function is present, it is always used instead of the built-in comparisons.
If the output of the two functions is equal for each test case, the student's response will be marked correct.
An example question might test a trivial function called sum that simply adds together its two arguments.
The answer for this question might be the following:
def sum(a, b):
return a + b
tests = [
(0, 0),
(1, 0),
(100, 165),
(730, 21),
#etc...
]The student's response will be evaluated with arguments of (0, 0), (1, 0), (100, 165) etc., and if any value it returns differs from the value returned by the reference function, it will be marked incorrect.
Since tests is a normal Python variable, it need not be declared statically, so test cases can be dynamically
generated. An example where you may want to do this would be to generate a large number of random tests with
problem-specific constraints. Arbitrary code can be used to generate the tests, and any built-in Python library
can be used, as well as some others like NumPy.
The following example creates 1000 random tests to ensure that the sum function works as intended.
Answer:
from random import randint
def sum(a, b):
return a + b
tests = [(randint(0, 10), randint(0, 10)) for _ in range(1000)]