Comprehensive suite for competitive programming
PCU is licensed under the BSD 3-clause license (see LICENSE file).
All installations require Python 3.6+ with setuptools.
The simplest method:
pip3 install pcu
Almost as simple:
git clone https://github.com/jma127/pcu.git cd pcu python3 setup.py install
If you'd like to keep dependencies separate from your system python, then you may use the venv_install.py script:
git clone https://github.com/jma127/pcu.git cd pcu python3 venv_install.py
After installing PCU with the tool above, you may run the tools from whichever directory you wish to work in. The basic format for the pcu tool is:
$ pcu command problem
The command
field is the utility you would like to use. See the Available
Tools section for more information. The problem
field should be the name
of the problem you're currently working on.
Here is an example to get you started. Here (and in the rest of this README), we
are trying to solve the particularly challenging add_two_numbers
problem,
where the program should read two numbers from stdin and write their sum to
stdout:
# initialize the problem # (by default, using the ``cpp`` environment) # this also creates the source file add_two_numbers.cpp using a template pcu make add_two_numbers # add the sample input and output pcu setin add_two_numbers sample < sample_input.txt pcu setans add_two_numbers sample < sample_expected_output.txt # then, edit your source file however you like vim add_two_numbers.cpp # run your program (against the sample input, since you added it above) pcu run add_two_numbers
The command for initializing a problem is pcu make <problem>
. By default,
this will generate a code skeleton according to predefined templates in your
current working directory. The name of the source file is specified by the
current environment's source_file
setting.
To make the source file for the add_two_numbers
problem in the default
environment:
pcu make add_two_numbers
To make the source file for the add_two_numbers
problem in the Java
environment:
pcu make -e java add_two_numbers
If you already have the source file, you can use the -S
flag (short for
--nosrc
) to skip creating the source file (otherwise, PCU will overwrite
your precious code).
If you've already initialized the problem and just want to generate a new source
file, you can use the -C
flag (short for --noclean
) to preserve the
environment and just generate the source file.
You can use PCU to manage your custom test cases for a problem. This is
particularly useful when combined with pcu run
(see below). In PCU, each
test case has a unique identifier (set by the user) and may have an input file
and an expected output (answer) file.
The two commands for adding and editing test data are:
pcu setin <problem> <testcase>
pcu setans <problem> <testcase>
.
Let's say we are still working on the problem add_two_numbers
, and we are
trying to add the sample input and output (which we want to call
sample_test
). To add the sample input, run:
pcu setin add_two_numbers sample_test # Now you will be prompted to enter the input.
To add the sample output, run:
pcu setans add_two_numbers sample_test # Now you will be prompted to enter the expected output.
Of course, both these commands work with stdin redirection:
pcu setin add_two_numbers sample_test < sample_input.txt pcu setans add_two_numbers sample_test < sample_expected_output.txt
The commands for viewing test cases are:
- Viewing list of test cases:
pcu info <problem>
- Get a specific test case's input:
pcu getin <problem> <testcase>
- Get a specific test case's expected output:
pcu getin <problem> <testcase>
Example with our add_two_numbers
problem:
# Will show us what test cases exist for "add_two_numbers" pcu info add_two_numbers pcu getin add_two_numbers sample_test > sample_in.txt pcu getans add_two_numbers sample_test > sample_ans.txt
The command for deleting test cases is pcu delcases <problem> <testcase>
.
Example:
pcu delcases add_two_numbers sample_test
You may specify more than one test case:
pcu delcases add_two_numbers sample_test another_test
Or omit the testcase
argument entirely to delete all testcases:
pcu delcases add_two_numbers
After you have created the source file, added some test cases, and written up
your solution, you'd naturally like to run your code. The command for this is
pcu run <problem>
. Example:
pcu run add_two_numbers
The command compiles your program and, if compiled successfully, runs it against all test cases. To only test against specific test cases, you can specify the test case names after the problem name:
pcu run add_two_numbers sample_test another_test
If all you want to do is compile, use the pcu comp <problem>
command.
Example:
pcu comp add_two_numbers
You may modify how PCU compiles and runs your program via environment settings.
pcu run
prints out per-test-case results, including the status (e.g.
correct, wrong answer, runtime error), diffs between expected and actual output,
and stderr output from your program. However, it does not print the full
output of the program for each test case. The commands for getting the output
for a specific test case is pcu getout <problem> <testcase>
(similarly, to
get stderr, run pcu geterr <problem> <testcase>
). Example:
pcu getout add_two_numbers sample_test > my_sample_out.txt pcu geterr add_two_numbers sample_test > my_sample_stderr.txt
If you would like to programmatically generate test data for problems, you may
use the testgen
command. This module uses a user-specified executable (such
as a script or a binary) to create testcases. The command for test case
generation is pcu testgen <problem> <generator_executable>
. The optional
argument -n
specifies the number of tests that should be generated, and the
optional argument -p
specifies the prefix for the generated test case names.
To generate 50 test cases for add_two_numbers
with the executable
gen_test.py
:
$ pcu testgen -n 50 add_two_numbers gen_test.py
Make sure that your generator is actually executable (e.g. with chmod 755
in
Unix).
Generator executables are passed two command-line arguments:
seq_num
: the number of the current test case to be generated. This argument is not very useful unless you're trying to generate test cases with different characteristics (e.g. 10 "small" cases and 10 "large" cases).seed
: a seed (different for each test case) that can be used for randomly generating test data. Guaranteed to be nonnegative and to fit within a 32-bit signed integer.
The generator executable should then output the test case input data to stdout,
and the expected output (answer) to stderr. Below is an example of a test
generator for add_two_numbers
:
#!/usr/bin/env python3 import random, sys random.seed(sys.argv[2]) # the second argument is the random seed a, b = random.randint(0, 1000000), random.randint(0, 1000000) print(a, b) print(a + b, file=sys.stderr)
You may run pcu -h
to get a list of commands with descriptions, and pcu
<command> -h
to get help for any individual command.
PCU is configurable via the following (case-sensitive) settings:
user
: your name. You may useos_username
to tell PCU to use your system username.default_env
: the default environment.datetime_format
: a strftime-compatible format string to use in PCU-generated timestamps.max_lines_output
: maximum number of output/diff lines to show for each testcase inpcu run
.max_lines_error
: maximum number of stderr lines to show for each testcase inpcu run
.envs
: the environments available to PCU. Specified as a YAML mapping of environment name to environment settings.
Default values for these settings are in pcu/static/default_settings.yaml.
You may override defaults by specifying your own settings in
~/.pcu/settings.yaml
. YAML references can be googled (here is a basic one).
An environment is simply a coherent group of settings for a specific language, contest, etc. While the settings above are global settings, the following are per-environment settings:
template_file
: name of the environment's template file. This is required to usepcu make
. See the Templates section for more information.compile_timelimit_msec
: number of milliseconds the compiler gets.run_timelimit_msec
: number of milliseconds for each test case before a judgement of "Time Limit Exceeded".format_strictness
: eitherstrict
orlax
.strict
tellspcu run
to check for an exact match between expected and actual output.lax
tellspcu run
to ignore whitespace errors when checking output.
aliases
: a list of alternative names for this environment.
For the following per-environment settings, you may use ${PCU_PROBLEM_NAME}
to refer to the current problem's name:
source_file
: name of the source file (e.g. output ofpcu make
).
For the following per-environment settings, in addition to
${PCU_PROBLEM_NAME}
, you may use ${PCU_SOURCE_FILE}
to refer to the
source file name, and ${PCU_SOURCE_FILE_NOEXT}
to refer to the source file
name without the extension:
compile_command
: command to compile the program. Note that this is passed as raw shell input, and you are solely responsible for any security implications.run_command
: command to run the program. Same caveat as above.input_file
: file where the program will expect its input data.PCU_STDIN
is a special value meaning that the program reads from stdin.output_file
: file where PCU will expect the program to output its results.PCU_STDOUT
is a special value meaning that the program writes to stdout.
pcu make
uses templates to generate source files. A template looks very much
like a source file, except that pcu make
will substitute all parameter names
with their respective values. The following are valid template parameters:
${PCU_USER}
: theuser
setting.${PCU_DATETIME}
: the current date and time (formatted via thedatetime_format
setting)${PCU_PROBLEM_NAME}
: the current problem's name.${PCU_ENV_NAME}
: the current environment's name.${PCU_COMPILE_TIMELIMIT_MSEC}
: thecompile_timelimit_msec
environment setting.${PCU_RUN_TIMELIMIT_MSEC}
: therun_timelimit_msec
environment setting.${PCU_FORMAT_STRICTNESS}
: theformat_strictness
environment setting.${PCU_SOURCE_FILE}
: the current problem's source file name.${PCU_SOURCE_FILE_NOEXT}
: the above, without the extension.${PCU_COMPILE_COMMAND}
: the shell command used to compile the program.${PCU_RUN_TIMELIMIT_MSEC}
: the shell command used to run the program.${PCU_INPUT_FILE}
: the current problem's input file name.${PCU_OUTPUT_FILE}
: the current problem's output file name.
Templates are per-environment, and PCU uses the environment's template_file
setting to search for the template in ~/.pcu/templates/
. If not found, PCU
will look for it in pcu/static/default_templates/.