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.3.tar.gz (30.2 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.3-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: contest_helper-0.4.3.tar.gz
  • Upload date:
  • Size: 30.2 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.3.tar.gz
Algorithm Hash digest
SHA256 4493f909572a734bcecab5358fba9ad94ba589cf6194644303dc83aa8aa9eeb8
MD5 a604a17711d1e4eb649786f87640fe46
BLAKE2b-256 2c2775c3da7559cacb57867825c8f49c423edb106789d6564f3b500e00e061fc

See more details on using hashes here.

File details

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

File metadata

  • Download URL: contest_helper-0.4.3-py3-none-any.whl
  • Upload date:
  • Size: 33.2 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 d960d85e066a781e40e3c4d7a6a6d362402d9fa198aa047fd8892f8a7fc211aa
MD5 c9e0a81feb3071aa7c559fe23cf96983
BLAKE2b-256 212706712a2b40e122dab1780b674338b692a481c0c541bcfc70c5fedef15884

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