vimgolf_gym

VimGolfGym: A gym environment for VimGolf challenges.

 1"""
 2
 3VimGolfGym: A gym environment for VimGolf challenges.
 4"""
 5
 6import os
 7from vimgolf_gym.lib import (
 8    get_local_challenge_definition,
 9    get_local_challenge_metadata,
10    get_local_challenge_worst_solution,
11    get_local_challenge_worst_solution_header,
12    list_local_challenge_ids,
13    make,
14)
15
16if os.environ.get("PDOC_PROCESS"):
17    from vimgolf_gym import dataclasses
18    from vimgolf_gym import lib
19    from vimgolf_gym import log_parser
20    from vimgolf_gym import terminal_executor
21    from vimgolf_gym import vimgolf
22
23    __all__ = [
24        "make",
25        "list_local_challenge_ids",
26        "get_local_challenge_definition",
27        "get_local_challenge_metadata",
28        "get_local_challenge_worst_solution",
29        "get_local_challenge_worst_solution_header",
30        "dataclasses",
31        "lib",
32        "log_parser",
33        "terminal_executor",
34        "vimgolf",
35    ]
36else:
37
38    __all__ = [
39        "make",
40        "list_local_challenge_ids",
41        "get_local_challenge_definition",
42        "get_local_challenge_metadata",
43        "get_local_challenge_worst_solution",
44        "get_local_challenge_worst_solution_header",
45    ]
def make( env_name: str, custom_challenge: Optional[vimgolf_gym.dataclasses.VimGolfCustomChallenge] = None, use_docker: bool = False, log_buffer: bool = False) -> vimgolf_gym.lib.VimGolfEnv:
 73def make(
 74    env_name: str,
 75    custom_challenge: typing.Optional[dataclasses.VimGolfCustomChallenge] = None,
 76    use_docker: bool = False,
 77    log_buffer: bool = False,
 78) -> "VimGolfEnv":
 79    """
 80    Create a VimGolf environment.
 81
 82    The env_name can be one of the following:
 83    - `vimgolf-test`: A simple test environment.
 84    - `vimgolf-local-<challenge_id>`: A local environment for a specific challenge.
 85    - `vimgolf-online-<challenge_id>`: An online environment for a specific challenge.
 86    - `vimgolf-custom`: A custom environment. The `custom_challenge` parameter will be used.
 87
 88    Args:
 89        env_name (str): The name of the environment to create.
 90        use_docker (bool, optional): Whether to use a dockerized executor. Defaults to False.
 91        log_buffer (bool, optional): Whether to log the editor buffer or not. Defaults to False.
 92        custom_challenge (Optional[VimGolfCustomChallenge], optional): The custom challenge to use. Defaults to None.
 93
 94    Raises:
 95        NotImplementedError: If the environment name is not recognized.
 96
 97    Returns:
 98        VimGolfEnv: The created environment
 99    """
100    if use_docker:
101        os.environ["VIMGOLF_GYM_USE_DOCKER"] = "1"
102    else:
103        os.environ["VIMGOLF_GYM_USE_DOCKER"] = "0"
104
105    if log_buffer:
106        os.environ["VIMGOLF_GYM_LOG_BUFFER"] = "1"
107    else:
108        os.environ["VIMGOLF_GYM_LOG_BUFFER"] = "0"
109
110    if env_name == "vimgolf-test":
111        env = make_test()
112    elif env_name == "vimgolf-custom":
113        assert (
114            custom_challenge
115        ), "custom_challenge must be provided for vimgolf-custom environment"
116        env = make_env_with_text(
117            input=custom_challenge.input, output=custom_challenge.output
118        )
119    elif env_name.startswith("vimgolf-local-"):
120        challenge_id = env_name[len("vimgolf-local-") :]
121        assert_challenge_id_length(challenge_id)
122        env = make_offline_with_cybergod_dataset(challenge_id)
123    elif env_name.startswith("vimgolf-online-"):
124        challenge_id = env_name[len("vimgolf-online-") :]
125        assert_challenge_id_length(challenge_id)
126        env = make_online(challenge_id)
127    else:
128        raise NotImplementedError
129    return env

Create a VimGolf environment.

The env_name can be one of the following:

  • vimgolf-test: A simple test environment.
  • vimgolf-local-<challenge_id>: A local environment for a specific challenge.
  • vimgolf-online-<challenge_id>: An online environment for a specific challenge.
  • vimgolf-custom: A custom environment. The custom_challenge parameter will be used.
Arguments:
  • env_name (str): The name of the environment to create.
  • use_docker (bool, optional): Whether to use a dockerized executor. Defaults to False.
  • log_buffer (bool, optional): Whether to log the editor buffer or not. Defaults to False.
  • custom_challenge (Optional[VimGolfCustomChallenge], optional): The custom challenge to use. Defaults to None.
Raises:
  • NotImplementedError: If the environment name is not recognized.
Returns:

VimGolfEnv: The created environment

def list_local_challenge_ids() -> list[str]:
242def list_local_challenge_ids() -> list[str]:
243    """
244    List all challenge ids in the local dataset.
245
246    This function will download the local dataset if it does not exist yet.
247
248    Returns:
249        list[str]: a list of all challenge ids in the local dataset.
250    """
251
252    init_cybergod_vimgolf_dataset()
253    challenges_dir = os.path.join(
254        _CYBERGOD_VIMGOLF_DATASET_BASEDIR,
255        "challenges",
256    )
257    challenge_ids = os.listdir(challenges_dir)
258    return challenge_ids

List all challenge ids in the local dataset.

This function will download the local dataset if it does not exist yet.

Returns:

list[str]: a list of all challenge ids in the local dataset.

def get_local_challenge_definition(challenge_id: str):
360def get_local_challenge_definition(challenge_id: str):
361    """
362    Load a VimGolf challenge definition from the local dataset.
363
364    Given a challenge_id, find the corresponding JSON file in the dataset
365    and parse it into a VimGolfChallengeDefinition object.
366
367    Args:
368        challenge_id (str): Unique identifier for the challenge.
369
370    Returns:
371        VimGolfChallengeDefinition: Parsed challenge definition.
372
373    Raises:
374        AssertionError: If the challenge file does not exist.
375    """
376    challenge_file = os.path.join(
377        _CYBERGOD_VIMGOLF_DATASET_BASEDIR, "challenges", challenge_id, "challenge.json"
378    )
379    assert os.path.exists(challenge_file), (
380        "Challenge file '%s' does not exist" % challenge_file
381    )
382    with open(challenge_file, "r") as f:
383        challenge = dataclasses.VimGolfChallengeDefinition.parse_raw(f.read())
384    return challenge

Load a VimGolf challenge definition from the local dataset.

Given a challenge_id, find the corresponding JSON file in the dataset and parse it into a VimGolfChallengeDefinition object.

Arguments:
  • challenge_id (str): Unique identifier for the challenge.
Returns:

VimGolfChallengeDefinition: Parsed challenge definition.

Raises:
  • AssertionError: If the challenge file does not exist.
def get_local_challenge_metadata(challenge_id: str):
281def get_local_challenge_metadata(challenge_id: str):
282    """
283    Load a VimGolf challenge's metadata from the local dataset.
284
285    Given a challenge_id, find the corresponding JSON file in the dataset
286    and parse it into a VimGolfChallengeMetadata object.
287
288    Args:
289        challenge_id (str): Unique identifier for the challenge.
290
291    Returns:
292        VimGolfChallengeMetadata: Parsed challenge metadata.
293
294    Raises:
295        AssertionError: If the metadata file does not exist.
296    """
297    metadata_file = os.path.join(
298        _CYBERGOD_VIMGOLF_DATASET_BASEDIR, "challenges", challenge_id, "metadata.json"
299    )
300    assert os.path.exists(metadata_file), (
301        "Metadata file '%s' does not exist" % metadata_file
302    )
303    with open(metadata_file, "r") as f:
304        metadata = dataclasses.VimGolfChallengeMetadata.parse_raw(f.read())
305    return metadata

Load a VimGolf challenge's metadata from the local dataset.

Given a challenge_id, find the corresponding JSON file in the dataset and parse it into a VimGolfChallengeMetadata object.

Arguments:
  • challenge_id (str): Unique identifier for the challenge.
Returns:

VimGolfChallengeMetadata: Parsed challenge metadata.

Raises:
  • AssertionError: If the metadata file does not exist.
def get_local_challenge_worst_solution(challenge_id: str):
308def get_local_challenge_worst_solution(challenge_id: str):
309    """
310    Load the worst solution for a challenge from the local dataset.
311
312    Given a challenge_id, find the corresponding JSON file in the dataset
313    and parse it into a VimGolfPublicSolution object.
314
315    Args:
316        challenge_id (str): Unique identifier for the challenge.
317
318    Returns:
319        VimGolfPublicSolution: Parsed worst solution.
320
321    Raises:
322        AssertionError: If the worst solution file does not exist.
323    """
324    metadata_file = os.path.join(
325        _CYBERGOD_VIMGOLF_DATASET_BASEDIR,
326        "challenges",
327        challenge_id,
328        "worst_solution.json",
329    )
330    assert os.path.exists(metadata_file), (
331        "Worst solution file '%s' does not exist" % metadata_file
332    )
333    with open(metadata_file, "r") as f:
334        Worst_solution = dataclasses.VimGolfPublicSolution.parse_raw(f.read())
335    return Worst_solution

Load the worst solution for a challenge from the local dataset.

Given a challenge_id, find the corresponding JSON file in the dataset and parse it into a VimGolfPublicSolution object.

Arguments:
  • challenge_id (str): Unique identifier for the challenge.
Returns:

VimGolfPublicSolution: Parsed worst solution.

Raises:
  • AssertionError: If the worst solution file does not exist.
def get_local_challenge_worst_solution_header(challenge_id: str):
338def get_local_challenge_worst_solution_header(challenge_id: str):
339    """
340    Parse the worst solution's header string from the local dataset.
341
342    Given a challenge_id, find the corresponding worst solution file in the dataset
343    and parse its header string into a VimGolfParsedPublicSolutionHeader object.
344
345    Args:
346        challenge_id (str): Unique identifier for the challenge.
347
348    Returns:
349        VimGolfParsedPublicSolutionHeader: Parsed header string.
350
351    Raises:
352        AssertionError: If the worst solution file does not exist.
353    """
354    solution = get_local_challenge_worst_solution(challenge_id)
355    header = solution.header
356    ret = dataclasses.parse_public_solution_header(header)
357    return ret

Parse the worst solution's header string from the local dataset.

Given a challenge_id, find the corresponding worst solution file in the dataset and parse its header string into a VimGolfParsedPublicSolutionHeader object.

Arguments:
  • challenge_id (str): Unique identifier for the challenge.
Returns:

VimGolfParsedPublicSolutionHeader: Parsed header string.

Raises:
  • AssertionError: If the worst solution file does not exist.