Python library which can build special judge for running result judging.
Project description
pyspj
A light-weighted special support utils.
Installation
You can simply install it with pip
command line from the official PyPI site.
pip install pyspj
For more information about installation, you can refer to the installation guide.
Quick Start
Use with CLI
You can use pyspj
CLI to judge the running result, the help information is as follows
Usage: pyspj [OPTIONS]
Options:
-v, --version Show package'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).
-t, --type [free|simple|continuity]
Type of the final result. [default: free]
-s, --spj TEXT Special judge script to be used. [required]
-p, --pretty Use pretty mode to print json result.
-h, --help Show this message and exit.
Here is a simple example, a spj file namedtest_spj.py
import io
def spj_func(stdin: io.StringIO, stdout: io.StringIO):
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)
)
__spj__ = spj_func
You can use CLI to judge the result
# input: 1 2 3 4 5
# output: 15
pyspj -i '1 2 3 4 5' -o '15' -s test_spj:spj_func
It means import special judge function spj_func
from package test_spj
, the output result should be
{"correctness": true, "detail": "Oh yeah, well done ^_^.", "message": "Correct result."}
Besides, a simpler command line can be used due to the definition of __spj__
variable
pyspj -i '1 2 3 4 5' -o '15' -s test_spj
This command is equivalent to the above command.
Input & Output from File
When the scale of input or output is huge, you can load them from -I
and -E
option.
Here is an exmaple, a input file namedtest_input.txt
1 2 3 4 5
Output file namedtest_output.txt
15
You can use CLI to judge the result in the txt files
pyspj -I test_input.txt -O test_output.txt -s test_spj
The output should be
{"correctness": true, "detail": "Oh yeah, well done ^_^.", "message": "Correct result."}
Actually, -I
and -o
can be used together, so are the -i
and -E
options. There will be nothing different.
Pretty Json Output
If you need pretty print the result (especially when you are debugging), you can use -p
option.
pyspj -i '1 2 3 4 5' -o '15' -s test_spj -p
The output should be
{
"correctness": true,
"detail": "Oh yeah, well done ^_^.",
"message": "Correct result."
}
Additional Arguments
Sometimes, you can use additional arguments to support more complex cases.
Such as the special judge function below
import io
def spj_func(stdin: io.StringIO, stdout: io.StringIO, fxxk=None):
inputs = [int(item.strip()) for item in stdin.read().strip().split(' ') if item]
_correct_sum = sum(inputs)
if not fxxk:
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)
)
else:
return False, 'Result error because {value} detected in fxxk.'.format(value=repr(fxxk))
__spj__ = spj_func
An extra fxxk
argument is used, so the following command line can be used to set the value of argument fxxk
to 2
(string)
pyspj -i '1 2 3 4 5' -o '15' -s test_spj -p -V fxxk=2
The output should be
{
"correctness": false,
"detail": "Result error because '2' detected in fxxk.",
"message": "Result error because '2' detected in fxxk."
}
ATTENTION:
- Addtional argument should has a default value, otherwise when the value is not provided by command line, it will raise error.
- The default type of addtional arguments are string, you need to convert it to the type you actually need in your special judge function.
Use Special Judge in Python
pyspj
can be used in native Python by importing package
from pyspj import execute_spj_from_string
if __name__ == '__main__':
result = execute_spj_from_string('test_spj', '1 2 3 4 5', '15')
print(result.to_json())
The output should be
{'correctness': True, 'message': 'Correct result.', 'detail': 'Oh yeah, well done ^_^.'}
File input or file output are supported as well, like the following code
from pyspj import execute_spj_from_file
if __name__ == '__main__':
result = execute_spj_from_file('test_spj', 'test_input.txt', 'test_output.txt')
print(result.to_json())
The output should be the same as the abovementioned code.
Addtional arguments are also supported like the CLI.
import codecs
import io
from pyspj import execute_spj
if __name__ == '__main__':
with codecs.open('test_input.txt') as stdin, \
io.StringIO('15') as stdout:
result = execute_spj('test_spj', stdin, stdout, arguments={'fxxk': 2})
print(result.to_json())
The output should be
{'correctness': False, 'message': 'Result error because 2 detected in fxxk.', 'detail': 'Result error because 2 detected in fxxk.'}
Make My Special Judge Runnable
You can add entry for your special judge function by using pyspj_entry
function and call it in __main___
import io
from pyspj import pyspj_entry
def spj_func(stdin: io.StringIO, stdout: io.StringIO):
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('test_spj', spj_func, version='0.1.1')()
Save the code above to test_spj.py
, and then you can run it like pyspj cli.
python test_spj.py -h
The output should be
Usage: test_spj.py [OPTIONS]
Test_spj - 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.
And test the input
python test_spj.py -i '1 2 3 4 5' -o 15
{"correctness": true, "detail": "Oh yeah, well done ^_^.", "message": "Correct result."}
Besides, if the target environment does not have python, you can build this script with pyinstaller
pip install pyspj[build]
pyinstaller -D -F -n test_spj -c test_spj.py
A standalone executable file will be created.
License
pyspj
released under the Apache 2.0 license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.