Advanced Usage
Continuity Special Judge
Sometimes, we need to use special judge not only for predicating the correctness of output result, but the quality of result as well. So we can return a tuple of values which represent correctness and score to do this. Like the following code which is named spj_continuity.py
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | def continuity_spj_func(stdin, stdout):
_expected_sum = int(stdin.read().strip())
output_items = [int(item.strip()) for item in stdout.read().strip().split(' ') if item]
_actual_sum = sum(output_items)
_actual_cnt = len(output_items)
if _expected_sum == _actual_sum:
return (True, 1 - (_actual_cnt - 1) / _expected_sum), 'Correct result.', 'Oh yeah, well done ^_^.'
else:
return (False, 0), f'Result {_expected_sum} expected but {_actual_sum} found.'
__spj__ = continuity_spj_func
|
Here is an example of correct result, but it is obviously not the best one.
| pyspj -i '15' -o '1 2 3 4 5' -s spj_continuity -p
|
| {
"correctness": true,
"detail": "Oh yeah, well done ^_^.",
"message": "Correct result.",
"score": 0.7333333333333334
}
|
Another example of correct result, which is better than the abovementioned one.
| pyspj -i '15' -o '7 8' -s spj_continuity -p
|
| {
"correctness": true,
"detail": "Oh yeah, well done ^_^.",
"message": "Correct result.",
"score": 0.9333333333333333
}
|
And then a wrong example as shown in following part.
| pyspj -i '15' -o '7 8 8' -s spj_continuity -p
|
| {
"correctness": false,
"detail": "Result 15 expected but 23 found.",
"message": "Result 15 expected but 23 found.",
"score": 0.0
}
|
Addtional Arguments
In some complex cases, additional arguments need to be passed into the special judge function, such as the mode of special judge, or something like the extra required data file’s path. Like the following code which is named spj_additional.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | def additional_spj_func(stdin, stdout, sep=' '):
inputs = [int(item.strip()) for item in stdin.read().strip().split(sep) if item]
_correct_sum = sum(inputs)
outputs = stdout.read().strip().split(' ', maxsplit=2)
if len(outputs) >= 1:
_result = int(outputs[0])
else:
return False, 'No output found.'
if _result == _correct_sum:
return True, 'Correct result.', 'Oh yeah, well done ^_^.'
else:
return False, 'Result {correct} expected but {actual} found.'.format(
correct=repr(_correct_sum), actual=repr(_result)
)
__spj__ = additional_spj_func
|
Here is an common example
| pyspj -i '1 2 3 4 5' -o 15 -s spj_additional -V 'sep= '
|
| {"correctness": true, "detail": "Oh yeah, well done ^_^.", "message": "Correct result."}
|
And, if you want the input to be separated by ,
, just use the -V
option, like the command line below
| pyspj -i '1,2,3,4,5' -o 15 -s spj_additional -V 'sep=,'
|
| {"correctness": true, "detail": "Oh yeah, well done ^_^.", "message": "Correct result."}
|
Note
File import features (like -I
and -O
options`) are not supported in addtional arguments.
If you need to load the content of a data file, just pass the path of the data file by additional arguments, and then manually load the file in your special judge function.
Create My Runnable Special Judge CLI
You can create your own special judge CLI with the pyspj_entry
function. Like the following code named spj_runnable.py
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 | from pyspj.entry import pyspj_entry
def spj_func(stdin, stdout):
inputs = [int(item.strip()) for item in stdin.read().strip().split(' ') if item]
_correct_sum = sum(inputs)
outputs = stdout.read().strip().split(' ', maxsplit=2)
if len(outputs) >= 1:
_result = int(outputs[0])
else:
return False, 'No output found.'
if _result == _correct_sum:
return True, 'Correct result.', 'Oh yeah, well done ^_^.'
else:
return False, 'Result {correct} expected but {actual} found.'.format(
correct=repr(_correct_sum), actual=repr(_result)
)
if __name__ == '__main__':
pyspj_entry(
'demo_pyspj', spj_func,
version='2.3.3', # optional
author='spj-dev', # optional
email='spj-demo@my-email.com', # optional
)()
|
You can see its version information.
| python spj_runnable.py -v
|
| Special judge - demo_pyspj, version 2.3.3.
Developed by spj-dev, spj-demo@my-email.com.
Powered by pyspj, version 0.1.0.
Based on Python 3.7.13.
|
And see its help information, which is almost the same as the native pyspj
CLI.
| python spj_runnable.py -h
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | Usage: spj_runnable.py [OPTIONS]
Demo_pyspj - test a pair of given input and output.
Options:
-v, --version Show special judge's version information.
-i, --input TEXT Input content of special judge.
-o, --output TEXT Output content of special judge
-I, --input_file FILE Input file of special judge (if -i is given, this
will be ignored).
-O, --output_file FILE Output file of special judge (if -o is given, this
will be ignored).
-V, --value TEXT Attached values for special judge (do not named as
"stdin" or "stdout").
-p, --pretty Use pretty mode to print json result.
-h, --help Show this message and exit.
|
The cli script spj_runnable.py
created by yourself can be used like the pyspj
CLI.
Besides, this runnable special judge script can be built to a standalone special judge executable file if needed.
| pyinstaller -D -F -n demo_spj -c spj_runnable.py
|