CLI toolkit for managing competitive programming contests and solutions.
Project description
cptools
CLI toolkit for managing competitive programming contests and solutions.
Supports Codeforces, AtCoder, CSES, Yosupo, SPOJ, vJudge, and custom judges.
Extensible: Want to add support for another platform? See docs/ADDING_JUDGES.md for a complete guide on adding new judges.
Dependencies
CPTools requires:
- Python 3.10+
- g++ (or another C++ compiler)
- git
- browser-cookie3 (Python package - installed automatically)
The installation will automatically handle Python dependencies.
For developers, additional test dependencies are available:
pip install -e ".[dev]" # Installs pytest and pytest-cov
Installation
Quick Install (Recommended)
Install from PyPI:
pip install lgf-cptools
Or with pipx (recommended for CLI tools):
pipx install lgf-cptools
After installing, the cptools and cpt commands will be available.
Post-install setup:
cptools config # Set your author name
cptools completion --install # Install shell completions (optional)
Install from Source
For development or the latest unreleased features:
git clone https://github.com/src-lua/cptools.git
cd cptools
# Option 1: Install with pipx (recommended for CLI tools)
pipx install .
# Option 2: Install with pip in editable mode (for development)
pip install --user -e .
# Option 3: Install with pip in editable mode with dev dependencies
pip install --user -e ".[dev]"
After installing, make sure ~/.local/bin is in your PATH.
Post-install setup:
cptools config # Set your author name
cptools completion --install # Install shell completions (optional)
Shell Completion
cptools provides intelligent tab completion for bash and zsh shells.
Setup
cptools completion --install
This will:
- Auto-detect your shell (bash or zsh)
- Generate a completion script
- Install it to
~/.config/cptools/completion.{bash,zsh} - Add a source line to your
~/.bashrcor~/.zshrc
After installation, restart your terminal or run source ~/.bashrc (or ~/.zshrc).
Features
- Command completion: Tab-completes all cptools subcommands
- Flag completion: Context-aware flag suggestions for each command
- File completion: Automatically completes
.cppfiles for commands likeadd,rm,mark,open,test,bundle - Directory completion: Completes directories for commands like
update,new
Manual Installation
To generate a completion script for a specific shell without installing:
cptools completion --shell bash # Output bash completion script
cptools completion --shell zsh # Output zsh completion script
Configuration
cptools config
Opens ~/.config/cptools/config.json in your editor. Default configuration:
{
"author": "Dev",
"default_group_id": "yc7Yxny414",
"compiler": "g++",
"compiler_flags": ["-O2", "-std=c++17"],
"cookie_cache_enabled": true,
"cookie_cache_max_age_hours": 24,
"preferred_browser": null
}
Configuration Options
author: Your name, used in file headersdefault_group_id: Default Codeforces group ID for training contestscompiler: C++ compiler command (e.g.,g++,clang++)compiler_flags: Array of compiler flags for building solutions. Note: Add-I<path>flags here to support bundling custom libraries.cookie_cache_enabled: Enable/disable browser cookie caching for competitive programming sites (default:true)cookie_cache_max_age_hours: How long to cache cookies in hours. Set to-1to never expire (only refresh on auth failure)preferred_browser: Browser to use for authentication. Set tonullfor auto-detection, or specify"firefox","chrome", etc.
Commands
cptools provides commands for the complete competitive programming workflow.
Quick Reference:
| Command | Description |
|---|---|
new |
Create a new contest |
init |
Initialize repository |
update |
Update info.md |
status |
Show contest progress |
add |
Add a solution file |
rm |
Remove problem files |
mark |
Update problem status |
open |
Open problem in browser |
add_header |
Add metadata header to file |
test |
Compile and test solution |
fetch |
Fetch sample test cases |
stress |
Stress test with brute force |
bundle |
Bundle includes for submission |
clean |
Remove binaries |
commit |
Commit and push changes |
config |
Edit configuration |
completion |
Generate shell completion |
hash |
Generate context-aware hash |
For detailed documentation of all commands, see docs/COMMANDS.md.
Common Usage
# Create and setup contest
cpt new https://codeforces.com/contest/1234
cd Codeforces/1234
cpt fetch A~E
# Work on problems
cpt test A
cpt mark A AC
cpt open B
# Remove unwanted files
cpt rm A-brute
# Submit
cpt bundle A
cpt commit
Advanced Usage Examples
Complete Contest Workflow
From start to finish:
# Create contest and fetch all samples
cpt new https://codeforces.com/contest/1234
cd Codeforces/1234
cpt fetch A~E # fetch samples for all problems
# Solve problems
cpt test A # test solution A
cpt mark A # mark as AC
cpt open B # open problem B in browser
cpt test B
cpt mark B
# Check progress and commit
cpt status # view contest progress
cpt commit # commit and push changes
Stress Testing Workflow
Complete setup for finding edge cases:
# Create necessary files
cpt add A # main solution
cpt add A-brute # brute force solution
cpt add gen # test case generator
cpt add checker # custom checker (optional)
# Run stress test
cpt stress A A-brute gen --checker checker
# When a failing case is found, add it to test suite
cpt test A --add < failing_case.txt
The generator receives iteration number as argument (./gen 1, ./gen 2, ...) and should output a random test case.
Managing Multiple Solutions
Different approaches for the same problem:
cpt add A # first attempt
cpt add A-dp # dynamic programming approach
cpt add A-greedy # greedy approach
cpt add A-brute # brute force for verification
# Test each approach
cpt test A-dp
cpt test A-greedy
# Compare solutions with stress testing
cpt stress A-greedy A-brute gen
Custom Test Cases
Adding your own test cases:
cpt test A # test with official samples
cpt test A --add # add custom input + expected output
cpt test A --add --no-out # add input only (manual verification)
cpt test A < edge_case.txt # test specific case from file
cpt test A --interactive # run interactively even if samples exist
cpt test A -i # short form of --interactive
Custom test cases are saved as A_3.in/A_3.out (next available index).
Bundling with Local Libraries
You can bundle your personal library or templates into a single submission file. The bundler resolves headers by looking at paths defined in your config.json.
1. Configure the Include Paths: *Add your library paths using the -I flag in the compiler_flags list. Tilde expansion (~) is supported.
// ~/.config/cptools/config.json
{
"compiler_flags": [
"-O2",
"-std=c++17",
"-I/home/user/my-library",
"-I~/cp-templates"
]
}
2. Use Quotes for Includes:
The bundler only processes headers included with double quotes (""). System headers using angle brackets (<>) are ignored and left as-is.
#include <vector> // Ignored (system header)
#include "segtree.hpp" // Bundled! (Found in -I paths)
#include "graph/dsu.hpp" // Bundled!
3. Run the Bundle Command:
cpt bundle A # Copy expanded code to clipboard
cpt bundle A -o submit.cpp # Save bundled version to file
cpt bundle A -i # Replace original file in-place
Batch Operations with Ranges
Work with multiple problems at once:
cpt fetch A~F # fetch samples for A, B, C, D, E, F
cpt mark A~C AC # mark A, B, C as accepted
cpt mark D~E WA # mark D, E as wrong answer
Isolated Problems (Problemset)
Problems outside contests are organized in Platform/Problemset/:
# Add isolated problems
cpt add https://codeforces.com/problemset/problem/1234/A
# Creates: Codeforces/Problemset/1234A.cpp
cpt add https://atcoder.jp/contests/abc300/tasks/abc300_a
# Creates: AtCoder/Problemset/abc300_a.cpp
# Add and fetch test cases automatically
cpt add https://codeforces.com/problemset/problem/1234/A -f
# Work with them
cd Codeforces/Problemset
cpt test 1234A
cpt mark 1234A AC
Repository Maintenance
Keep your repository clean:
cpt clean --all # remove all binaries recursively
cpt update --all # regenerate info.md for all contests
cpt commit Codeforces/1234 # commit specific contest
Advanced Configuration
Example of customized ~/.config/cptools/config.json:
{
"author": "YourName",
"compiler": "g++",
"compiler_flags": ["-O2", "-std=c++20", "-Wall", "-Wextra", "-fsanitize=address"],
"cookie_cache_max_age_hours": -1,
"preferred_browser": "firefox"
}
Tips:
- Add
-fsanitize=addressto catch memory errors during testing - Set
cookie_cache_max_age_hoursto-1to never expire (only refresh on auth failure) - Use
-std=c++20or-std=c++17based on judge requirements
Directory Structure
Contests are organized by platform:
contests/
├── Trainings/ # Codeforces group contests
│ └── 2024.01.15/
│ ├── A.cpp
│ ├── B.cpp
│ └── info.md
├── Codeforces/
│ ├── 1234/
│ ├── Gym/
│ └── Problemset/
├── AtCoder/
│ └── Problemset/
├── CSES/
├── Yosupo/
├── SPOJ/
├── vJudge/
└── Other/
Each .cpp file includes a metadata header:
/**
* Author: Lua
* Problem: A - Example Problem
* Link: https://codeforces.com/contest/1234/problem/A
* Status: AC
* Created: 15-01-2024 14:30:00
**/
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lgf_cptools-1.0.1.tar.gz.
File metadata
- Download URL: lgf_cptools-1.0.1.tar.gz
- Upload date:
- Size: 79.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88ee12f667e9b36299557ba5b0761c4af0239b09838abb30ddb7c936b27eaea4
|
|
| MD5 |
a60d92cd9b57bb5bbb9405cee9eb9978
|
|
| BLAKE2b-256 |
bc31fd79ad4424909e0772220de73bf80879aa8387cc6b651509bf11e5378d31
|
Provenance
The following attestation bundles were made for lgf_cptools-1.0.1.tar.gz:
Publisher:
release.yml on src-lua/cptools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lgf_cptools-1.0.1.tar.gz -
Subject digest:
88ee12f667e9b36299557ba5b0761c4af0239b09838abb30ddb7c936b27eaea4 - Sigstore transparency entry: 953636737
- Sigstore integration time:
-
Permalink:
src-lua/cptools@11a9a334eff434daf6ea39d557d6eb4b3fbf3707 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/src-lua
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@11a9a334eff434daf6ea39d557d6eb4b3fbf3707 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lgf_cptools-1.0.1-py3-none-any.whl.
File metadata
- Download URL: lgf_cptools-1.0.1-py3-none-any.whl
- Upload date:
- Size: 64.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ccd159b531aa75ba85ae3891e966a166aa1de11361a9ebac159559bb0722db7
|
|
| MD5 |
e102e606189de9023d2a78403c4a0591
|
|
| BLAKE2b-256 |
44ee53f901881238d284b09a45aa1d26363c0093a8f11bc8e3508349886203df
|
Provenance
The following attestation bundles were made for lgf_cptools-1.0.1-py3-none-any.whl:
Publisher:
release.yml on src-lua/cptools
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lgf_cptools-1.0.1-py3-none-any.whl -
Subject digest:
7ccd159b531aa75ba85ae3891e966a166aa1de11361a9ebac159559bb0722db7 - Sigstore transparency entry: 953636740
- Sigstore integration time:
-
Permalink:
src-lua/cptools@11a9a334eff434daf6ea39d557d6eb4b3fbf3707 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/src-lua
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@11a9a334eff434daf6ea39d557d6eb4b3fbf3707 -
Trigger Event:
push
-
Statement type: