Skip to main content

A flexible framework for generating randomized test cases with input/output validation, designed for competitive programming and algorithmic testing.

Project description

Contest Helper Framework

A powerful Python framework for competitive programming problem creation, test generation, and package management.

Features

  • Problem Initialization: Quickly scaffold new problem directories with templates
  • Randomized Test Generation: Flexible system for creating diverse test cases
  • Problem Packaging: Combine all components into ready-to-use zip archives
  • Statement Management: Automatically update problem statements with examples
  • Custom Postprocessors: Configure scoring systems with various options

Installation

pip install contest-helper

Command Line Tools

Start a New Problem

ch-start-problem problem_name [--language en|ru] [--checker]

Create Custom Postprocessor

ch-make-postprocessor --max-value 100 [--groups "10,20,30"] [--different] [--by-groups]

Package Problem for Import

ch-combine problem_directory [options]

Update Statement with Examples

ch-statement-preview problem_directory [--lang en|ru]

Core Components

Test Generators

  • Random numbers, strings, lists, dictionaries
  • Configurable ranges and constraints
  • Composition of generators for complex cases

Problem Configuration

  • Time/memory limits
  • Input/output settings
  • Checker configuration
  • Solution validation

File Management

  • Automatic test case processing
  • File categorization (compile/run/post)
  • Sample test detection

Usage Examples

  1. Create a new problem:
ch-start-problem my_problem -l en -c
  1. Generate tests: Edit the generated generator.py to define your test cases

  2. Preview statement:

ch-statement-preview my_problem --lang en
  1. Package for import:
ch-combine my_problem --time-limit 2000 --memory-limit 256000000

Test Generation Examples

1. Basic Number Generation

from contest_helper import RandomNumber, Generator

# Generate 20 random numbers between 1-100
generator = Generator(
    tests_generator=RandomNumber(1, 101),
    tests_count=20,
    input_printer=lambda x: [str(x)],
    output_printer=lambda x: [str(x**2)]  # Output is input squared
)
generator.run()

2. String Manipulation Problem

from contest_helper import RandomWord

# Generate 15 random words (3-10 chars) and reverse them
generator = Generator(
    tests_generator=RandomWord(),
    tests_count=15,
    input_printer=lambda x: [x],
    output_printer=lambda x: [x[::-1]]  # Reversed string
)
generator.run()

3. Matrix Generation

from contest_helper import RandomNumber, RandomList

# Generate 10 random 3x3 matrices (values 0-9)
matrix_gen = RandomList(
    value_generator=RandomList(RandomNumber(0, 10), 3),
    length=3
)

generator = Generator(
    tests_generator=matrix_gen,
    tests_count=10,
    input_printer=lambda m: [f"{n}" for row in m for n in row],
    output_printer=lambda m: [str(sum(sum(row) for row in m))]  # Sum of all elements
)
generator.run()

4. Graph Problem (Edges List)

from contest_helper import RandomNumber, RandomDict

# Generate graphs with 5-10 nodes and random edges
graph_gen = RandomDict(
    key_generator=RandomNumber(1, 11),  # Node IDs 1-10
    value_generator=RandomList(RandomNumber(1, 11), RandomNumber(1, 4)),  # Adjacent nodes
    length=RandomNumber(5, 11)  # Node count
)

def print_graph(g):
    edges = []
    for node, neighbors in g.items():
        edges.extend(f"{node} {n}" for n in neighbors)
    return edges

generator = Generator(
    tests_generator=graph_gen,
    tests_count=5,
    input_printer=print_graph,
    output_printer=lambda _: ["1"]  # Dummy output
)
generator.run()

5. Combined Generators

from contest_helper import CombineValues, RandomWord, RandomNumber

# Generate tests with multiple values per case
combined_gen = CombineValues([
    RandomWord(min_length=5, max_length=10),  # String
    RandomNumber(1, 100),                     # Number
    RandomNumber(0, 2)                        # Boolean-like
])

generator = Generator(
    tests_generator=combined_gen,
    tests_count=8,
    input_printer=lambda vals: [str(v) for v in vals],
    output_printer=lambda vals: [str(len(vals[0]) * vals[1])]  # String length repeated N times
)
generator.run()

Grouped Test Generation Examples

1. Basic Grouped Tests

from contest_helper import RandomNumber, Generator

# Different groups with different number ranges
generator = Generator(
    tests_generator={
        'small': RandomNumber(1, 11),      # 1-10
        'medium': RandomNumber(10, 101),   # 10-100
        'large': RandomNumber(100, 1001)   # 100-1000
    },
    tests_count={
        'small': 5,    # 5 small tests
        'medium': 3,   # 3 medium tests
        'large': 2     # 2 large tests
    },
    input_printer=lambda x: [str(x)],
    output_printer=lambda x: [str(x % 10)]  # Last digit
)
generator.run()

2. String Problems with Difficulty Groups

from contest_helper import RandomWord, RandomSentence

generator = Generator(
    tests_generator={
        'easy': RandomWord(min_length=3, max_length=5),
        'medium': RandomWord(min_length=10, max_length=20),
        'hard': RandomSentence(min_length=3, max_length=5)  # Multi-word sentences
    },
    tests_count={
        'easy': 3,
        'medium': 2,
        'hard': 1
    },
    input_printer=lambda x: [x],
    output_printer=lambda x: [x.upper()]  # Convert to uppercase
)
generator.run()

3. Graph Problems with Increasing Complexity

from contest_helper import RandomDict, RandomNumber, RandomList

generator = Generator(
    tests_generator={
        'trees': RandomDict(
            key_generator=RandomNumber(1, 6),
            value_generator=RandomList(RandomNumber(1, 6), 1),  # Trees have 1 parent
            length=5
        ),
        'graphs': RandomDict(
            key_generator=RandomNumber(1, 11),
            value_generator=RandomList(RandomNumber(1, 11), RandomNumber(1, 3)),
            length=10
        )
    },
    tests_count={
        'trees': 3,
        'graphs': 2
    },
    input_printer=lambda g: [f"{k}:{','.join(map(str,v))}" for k,v in g.items()],
    output_printer=lambda _: ["1"]  # Dummy output
)
generator.run()

4. Combined Groups with Custom Logic

from contest_helper import CombineValues, RandomWord, RandomNumber

generator = Generator(
    tests_generator={
        'arithmetic': RandomNumber(1, 100),
        'strings': RandomWord(min_length=5, max_length=10),
        'mixed': CombineValues([
            RandomWord(min_length=3, max_length=5),
            RandomNumber(10, 20)
        ])
    },
    tests_count={
        'arithmetic': 4,
        'strings': 3,
        'mixed': 2
    },
    input_printer=lambda x: [str(x) if isinstance(x, int) else x],
    output_printer=lambda x: (
        [str(x*2)] if isinstance(x, int) 
        else [x[::-1]] if isinstance(x, str)
        else [x[0]*x[1]]  # string repeated N times
    )
)
generator.run()

5. Scientific Formatting with Groups

from contest_helper import RandomNumber, Generator
import math

generator = Generator(
    tests_generator={
        'precision_low': RandomNumber(1.0, 5.0, 0.1),   # 1 decimal
        'precision_high': RandomNumber(1.0, 5.0, 0.001) # 3 decimals
    },
    tests_count={
        'precision_low': 3,
        'precision_high': 2
    },
    input_printer=lambda x: [f"{x:.3f}"],
    output_printer=lambda x: [f"{math.sin(x):.5e}"]  # Scientific notation
)
generator.run()

Advanced Features

  • Group-based test generation: Organize tests into logical groups
  • Custom scoring: Differential scoring by test difficulty
  • Multi-language support: English and Russian statements
  • Flexible configuration: Override defaults via command line

Requirements

  • Python 3.10+
  • Standard library only (no external dependencies)

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

MIT

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

contest_helper-0.4.0.tar.gz (26.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

contest_helper-0.4.0-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file contest_helper-0.4.0.tar.gz.

File metadata

  • Download URL: contest_helper-0.4.0.tar.gz
  • Upload date:
  • Size: 26.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for contest_helper-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f06d3fc4dab02bbf3d2bc7acefe40126e2800f5318dcb80cd2c53620f80f0ca2
MD5 1155c695c15936aa57fd0bbc069a8bbf
BLAKE2b-256 f8d14d482242c562882c837cbde62e94400a3ce24778809677b390e42c991bcc

See more details on using hashes here.

File details

Details for the file contest_helper-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: contest_helper-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 29.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for contest_helper-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 713da5024a2a6fd769bf38598b01b6826f4703f84c3388e293cb62709d21dbf9
MD5 6ea2bb493b17718e256d4c90356f0983
BLAKE2b-256 cdc86c97e18d322ee8fed52925eadc29f274bd8a24072fd39da917b00bec959d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page